首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

VC++ 仿製金山毒霸專殺工具無標題列异形介面完整實戰

     編輯:VC 教學

目標

完全模仿《金山毒霸 2002》附屬工具 `Duba_GOP.exe` 介面:無標題列、全背景貼圖、自繪圖片按鈕、視窗任意拖曳、懸掛桌面頂端自動收縮。

資源提取

  • 工具:**FreeRes** (支援已壓縮 EXE) 提取 20 張 BMP:主背景、關閉/首頁按鈕三態、掃描/瀏覽按鈕三態。
  • **Spy++** 確認四大按鈕皆為 `Button` 控制項 (非 Static),適合 `CBitmapButton` 實作。

核心實作

1. 無標題列 + 背景繪製


BOOL CInterfaceDlg::OnInitDialog() {
    CDialog::OnInitDialog();
    ModifyStyle(WS_CAPTION, 0); // 移除標題列
    ModifyStyleEx(0, WS_EX_TOOLWINDOW); // 可選:不顯示在工作列
    m_bmpBg.LoadBitmap(IDB_BG_MAIN); // 成員變數 CBitmap
    return TRUE;
}

void CInterfaceDlg::OnPaint() {
    if (IsIconic()) { CDialog::OnPaint(); return; }

    CPaintDC dc(this);
    CRect rc; GetClientRect(&rc);
    CDC memDC; memDC.CreateCompatibleDC(&dc);
    CBitmap* pOld = memDC.SelectObject(&m_bmpBg);
    BITMAP bm; m_bmpBg.GetBitmap(&bm);
    dc.StretchBlt(0, 0, rc.Width(), rc.Height(), &memDC, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
    memDC.SelectObject(pOld);
}

2. 任意處拖曳視窗


void CInterfaceDlg::OnLButtonDown(UINT nFlags, CPoint point) {
    PostMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x, point.y));
}

3. 圖片按鈕 (CBitmapButton)


// 對話框成員
CBitmapButton m_btnClose, m_btnHome, m_btnScan, m_btnBrowse;

BOOL CInterfaceDlg::OnInitDialog() {
    // ... 前述代碼 ...
    m_btnClose.LoadBitmaps(IDB_CLOSE_N, IDB_CLOSE_D, IDB_CLOSE_H); // 正常/按下/游標懸停
    m_btnClose.SubclassDlgItem(IDC_BTN_CLOSE, this);
    m_btnClose.SizeToContent();
    // 同樣處理 Home, Scan, Browse
    // 手動 MoveWindow 到背景圖對應座標
}

4. 掃描按鈕雙狀態切換


void CInterfaceDlg::OnBtnScan() {
    if (m_bScanning) {
        m_btnScan.LoadBitmaps(IDB_SCAN_N, IDB_SCAN_D, IDB_SCAN_H); // 還原「開始掃描」
        m_bScanning = FALSE;
    } else {
        m_btnScan.LoadBitmaps(IDB_STOP_N, IDB_STOP_D, IDB_STOP_H); // 切換為「停止」
        m_bScanning = TRUE;
    }
}

5. 桌面頂端懸掛 (定時器輪詢)


void CInterfaceDlg::OnTimer(UINT_PTR nID) {
    if (nID == TIMER_HANG) {
        CPoint pt; GetCursorPos(&pt);
        CRect rc; GetWindowRect(&rc);
        if (rc.PtInRect(pt)) {
            if (rc.top <= 2) MoveWindow(rc.left, 0, rc.Width(), rc.Height());
        } else {
            if (rc.top <= 2) MoveWindow(rc.left, 0, rc.Width(), 3); // 只留 3 像素細線
        }
    }
    CDialog::OnTimer(nID);
}

完整資源清單

資源 ID用途尺寸建議
IDB_BG_MAIN主視窗背景 (含標題列、底部 Logo)400x300
IDB_CLOSE_N/D/H關閉按鈕 三態18x18
IDB_HOME_N/D/H首頁按鈕 三態18x18
IDB_SCAN_N/D/H開始掃描 三態80x24
IDB_STOP_N/D/H停止掃描 三態80x24
IDB_BROWSE_N/D/H瀏覽資料夾 三態80x24

避坑指南

  • 背景圖與視窗客戶區尺寸必須一致,否則 `StretchBlt` 會變形;建議 `OnInitDialog` 依圖片尺寸 `SetWindowPos`。
  • `CBitmapButton` 必須設 `BS_OWNERDRAW`,否則不會呼叫自繪。
  • 懸掛細線高度 3px 足夠觸發 `PtInRect`,太細會導致滑鼠難以進入。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved