前文《自繪按鈕的實現》展示了 XP 風格的 CXPButton,但實際測試發現:當對話框背景色非預設色時,按鈕四個圓角會出現難看的「殘角」。本文詳細分析成因並提供完整解決方案。
修改對話框背景色為藍色(RGB(0,0,255))後執行,按鈕四角出現系統預設色的方形殘留區域:
BOOL CXPButtonDemoDlg::OnEraseBkgnd(CDC* pDC) {
BOOL retValue = CDialog::OnEraseBkgnd(pDC);
CRect rc; GetClientRect(&rc);
pDC->FillSolidRect(&rc, RGB(0,0,255));
return retValue;
}
CRgn 定義非矩形有效區域OnEraseBkgnd 會依預設矩形繪製背景,覆蓋自繪內容void CXPButton::PreSubclassWindow() {
CButton::PreSubclassWindow();
ModifyStyle(0, BS_OWNERDRAW);
CRgn rgn; CRect rc;
GetClientRect(&rc);
// 圓角矩形有效區域,半徑 5
rgn.CreateRoundRectRgn(rc.left, rc.top, rc.right, rc.bottom, 5, 5);
SetWindowRgn(rgn, TRUE);
rgn.DeleteObject();
}
BOOL CXPButton::OnEraseBkgnd(CDC* pDC) {
// 禁止繪製底色,避免殘角出現
return TRUE;
}
編譯執行後,殘角問題徹底解決,按鈕完美融入自訂背景。
文中提供的圓形按鈕範例同樣存在此問題,讀者可嘗試套用相同解法。關鍵在於:
CRgn::CreateEllipticRgn() 建立圓形區域OnEraseBkgnd() 回傳 TRUECRgn 是建立非規則視窗、控制項的核心工具,支援矩形、圓形、多邊形及組合區域操作。建議深入研讀 MSDN 文件,掌握 CombineRgn()、OffsetRgn() 等進階技巧,將介面設計推向更高層次。
自繪按鈕要完美呈現非矩形外觀,必須同時處理「視窗區域裁剪」與「背景繪製攔截」兩個層面。本文提供的方案經實測有效,可直接套用於各類非規則按鈕開發。