
目標:金山毒霸 2002 附屬工具 Duba_GOP.exe 介面。工具:freeRes 提取資源、Spy++ 分析視窗結構、VC++ 開發。
Button 控制項(OwnerDraw)Static 控制項void CInterfaceDlg::OnPaint()
{
if (IsIconic()) { /* 圖示繪製 */ }
else
{
// CDialog::OnPaint(); // 註解掉預設繪製
CPaintDC dc(this);
CRect rect; GetClientRect(&rect);
CDC dcMem; dcMem.CreateCompatibleDC(&dc);
CBitmap bmp; bmp.LoadBitmap(IDB_BITMAPBACKGROUND);
BITMAP bm; bmp.GetBitmap(&bm);
CBitmap* pOld = dcMem.SelectObject(&bmp);
dc.StretchBlt(0, 0, rect.Width(), rect.Height(), &dcMem, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
// 建議:位圖載入移至 OnInitDialog,成員變數保存,提升效能
}
}
對話框屬性:Border = Thin(移除 Dialog Frame 邊框)。
void CInterfaceDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
PostMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x, point.y));
// 欺騙系統認為點擊在標題列上
}
// 成員變數
CBitmapButton m_HomeBtn, m_CloseBtn, m_BrowseBtn, m_StartBtn;
// OnInitDialog
m_StartBtn.LoadBitmaps(IDB_BTN_ON_NORMAL, IDB_BTN_ON_DOWN); // 一般/按下
// 「開始掃描」需切換兩組圖示
BOOL m_bScanning = TRUE;
void CInterfaceDlg::OnStartBtn()
{
if (m_bScanning)
m_StartBtn.LoadBitmaps(IDB_BTN_OFF_NORMAL, IDB_BTN_OFF_DOWN);
else
m_StartBtn.LoadBitmaps(IDB_BTN_ON_NORMAL, IDB_BTN_ON_DOWN);
m_bScanning = !m_bScanning;
m_StartBtn.RedrawWindow();
}
衍生 CColorButton 處理 WM_CTLCOLOR 回傳自訂畫筆:
class CColorButton : public CButton {
CBrush m_brush; COLORREF m_clr;
public:
void SetBackColor(COLORREF clr) { m_clr = clr; m_brush.CreateSolidBrush(clr); }
afx_msg HBRUSH CtlColor(CDC* pDC, UINT) { pDC->SetBkMode(TRANSPARENT); return m_brush; }
DECLARE_MESSAGE_MAP()
};
// 使用
m_chk1.SubclassDlgItem(IDC_CHECK1, this);
m_chk1.SetBackColor(RGB(222,223,222)); // 背景色
衍生 CColorStatic,處理 OnPaint 繪製文字與背景:
void CColorStatic::OnPaint()
{
CPaintDC dc(this); CRect r; GetClientRect(&r);
dc.SetBkColor(m_backClr); dc.SetBkMode(TRANSPARENT);
CFont* pFont = GetParent()->GetFont();
CFont* pOld = dc.SelectObject(pFont);
dc.SetTextColor(m_textClr);
dc.DrawText(m_caption, &r, DT_CENTER);
dc.SelectObject(pOld);
}
無標題列導致任務列無圖示。解決:
// OnInitDialog
SetWindowText("金山毒霸專殺工具"); // 設定標題
ModifyStyle(WS_CAPTION, WS_MINIMIZEBOX, SWP_DRAWFRAME); // 保留最小化按鈕樣式但隱藏標題列
// 微調底部 Static 位置避免遮蓋背景圖文字
CRect r; m_link3.GetWindowRect(&r); r.OffsetRect(0, 17); m_link3.MoveWindow(r);
ListCtrl 移除邊框樣式。專案在 VC6 + Win98/2K/XP 測試通過。