
異形窗體實現需解決兩大問題:背景透明 與 窗口區域裁剪。
WM_ERASEBKGND,用位圖填充客戶區,返回 TRUE 阻止默認擦除。SetWindowRgn() 將窗口可見區域限制為位圖中非透明色素區域。採用「掩模位圖」像素級掃描:白色 (RGB(255,255,255)) 視為透明,創建 1x1 微區域並以 RGN_XOR 從完整矩形區域中排除。
void CMyWnd::Display(CDC* pDC, UINT nMaskId)
{
CRect rectWnd; GetWindowRect(rectWnd);
CBitmap bmp; bmp.LoadBitmap(nMaskId);
CDC memDC; memDC.CreateCompatibleDC(pDC);
CBitmap* pOld = memDC.SelectObject(&bmp);
CRgn rgnWnd, rgnTemp;
rgnWnd.CreateRectRgn(0, 0, rectWnd.Width(), rectWnd.Height());
for (int x = 0; x < rectWnd.Width(); ++x) {
for (int y = 0; y < rectWnd.Height(); ++y) {
if (memDC.GetPixel(x, y) == RGB(255,255,255)) {
rgnTemp.CreateRectRgn(x, y, x+1, y+1);
rgnWnd.CombineRgn(&rgnWnd, &rgnTemp, RGN_XOR);
rgnTemp.DeleteObject();
}
}
}
memDC.SelectObject(pOld);
SetWindowRgn((HRGN)rgnWnd, TRUE);
}
CMyWnd : public CWnd 封裝初始化、顯示、區域計算、背景繪製。OnEraseBkgnd 繪製前景位圖(IDB_SHOW)。WM_NCHITTEST 返回 HTCAPTION 實現任意拖動。WM_CHAR 捕獲 VK_ESCAPE 退出程序。CMyWnd 類(基類 CWnd)。IDB_SHOW 與掩模圖 IDB_MASK(BMP 格式,可真彩色)。InitInstance 中創建窗口、調用 Initialize、ShowWindow。該方法適用於所有 CWnd 派生類(對話框、視圖、框架窗口等),可創建任意不規則形狀窗體。