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

VC++ 不規則視窗實作 (CBitmapDialog)

     編輯:關於VC++

前言

利用位圖透明色建立任意形狀對話框是打造個性化 UI 常用技術。本文介紹封裝良好的 CBitmapDialog 類別:載入位圖、指定透明色、自動計算區域 (Region)、支援任意拖曳、靜態控件透明化,幾行代碼即可擁有不規則視窗。

效果展示

CBitmapDialog 核心功能

  • LoadBitmap(nID):載入資源位圖 (IDB_BITMAP1)。
  • SetTransparent(TRUE):啟用透明色模式。
  • SetTransColor(RGB(0,0,0)):指定透明色 (位圖中此色像素不顯示、不佔用點擊區域)。
  • SetStaticTransparent(TRUE):子靜態控件背景透明化。
  • SetClickAnywhereMove(TRUE):滑鼠在客戶區任意處按下可拖曳視窗 (無標題列時必備)。
  • 核心 MakeWindowRgn:掃描位圖像素,以非透明色像素構建 HRGN,呼叫 SetWindowRgn 套用。

使用步驟

1. 建立對話框專案,移除邊框與標題列

屬性 → Border: None, Title bar: False。

2. 匯入位圖資源

資源視圖 → 右鍵 Add Resource → Bitmap,編輯位圖:
- 背景繪製所需形狀
- **透明區域統一填滿純色** (如純黑 RGB(0,0,0) 或純洋紅 RGB(255,0,255))
- 位圖尺寸即視窗初始尺寸

3. 修改對話框類別繼承關係


// 原始
class CBitmapDlgDlg : public CDialog
// 修改為
class CBitmapDlgDlg : public CBitmapDialog

同步修改訊息映射:BEGIN_MESSAGE_MAP(CBitmapDlgDlg, CBitmapDialog)。

4. OnInitDialog 設定


BOOL CBitmapDlgDlg::OnInitDialog()
{
    CBitmapDialog::OnInitDialog();

    LoadBitmap(IDB_BITMAP1);        // 載入位圖並建立區域
    SetTransparent(TRUE);           // 啟用透明
    SetTransColor(RGB(0,0,0));      // 透明色 = 位圖背景色
    SetStaticTransparent(TRUE);     // 子靜態文字透明
    SetClickAnywhereMove(TRUE);     // 任意處拖曳

    return TRUE;
}

原理說明:MakeWindowRgn


HRGN CBitmapDialog::MakeWindowRgn()
{
    // 1. 取得位圖資訊
    BITMAP bm; m_bitmap.GetBitmap(&bm);
    // 2. 鎖定像素緩衝區
    BYTE* pBits = (BYTE*)bm.bmBits; // 需 DIBSECTION
    // 3. 掃描每行,合併連續非透明像素為矩形,CombineRgn(RGN_OR)
    // 4. 回傳最終 HRGN
}

為效能考量,掃描時以 **水平掃描線** 為單位合併矩形,而非逐像素 CombineRgn,大幅減少區域複雜度。

進階技巧

  • 多狀態位圖:正常/懸停/按下 三張位圖,OnMouseMove/OnLButtonDown 切換 LoadBitmap 並 Invalidate。
  • 非矩形子控件:按鈕同樣可用 CBitmapButton 或自繪實現異形。
  • 分層視窗 (WS_EX_LAYERED):Win2K+ 支援 Alpha 混合,可實現半透明邊緣、陰影、淡入淡出,比區域法更平滑。

注意事項

  • 位圖**必須為 24/32 位 DIB**,LR_CREATEDIBSECTION 載入才能直接存取像素。
  • 透明色務必與位圖背景色**完全一致**,否則邊緣會有殘留像素。
  • 對話框建立後尺寸固定;若需動態縮放,需重新 LoadBitmap + SetWindowRgn + SetWindowPos。
  • 子控件座標相對於對話框客戶區,**不可超出位圖非透明區域**,否則無法點擊/顯示。

完整 CBitmapDialog.h/cpp 及範例專案可下載,VC6.0/VS2005+ 皆可編譯。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved