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

C++ Builder 繪圖於 Windows 開始按鈕:GDI 跨進程繪圖實戰

     編輯:VC 教學

突破視窗邊界:在開始按鈕上繪製滑鼠背景的 GDI 黑科技

本文展示一個經典的 C++ Builder 技巧:透過跨進程 GDI 操作,將滑鼠游標周圍的桌面畫面即時繪製到任務列的「開始」按鈕上,創造透視/鏡像視覺效果。涉及視窗句柄搜尋、裝置內容獲取、位元塊傳輸 (BitBlt/StretchBlt) 核心技術。

任務列視窗結構分析

Windows 任務列 (SYSTRAY.EXE/explorer.exe) 包含層級視窗:

  • 任務列主視窗:類別名 Shell_TrayWnd
  • 開始按鈕:類別名 Button,為主視窗子視窗

透過 FindWindow + FindWindowEx 兩層搜尋定位開始按鈕句柄。

核心繪圖流程

// 初始化:取得裝置內容
wnd = FindWindow("Shell_TrayWnd", NULL);
wnd = FindWindowEx(wnd, 0, "Button", NULL);
hdcButton = GetDC(wnd);                    // 開始按鈕 DC
wnd = GetDesktopWindow();
hdcDesktop = GetDC(wnd);                   // 桌面 DC

// 定時器觸發:即時繪製
GetCursorPos(&pt);                          // 取得滑鼠位置
StretchBlt(hdcButton, 0, 0, 60, 25,        // 目標:開始按鈕區域
           hdcDesktop, pt.x-30, pt.y-12, 60, 25,  // 來源:滑鼠周圍 60x25 區域
           SRCCOPY);                        // 直接複製像素

關鍵 API 解析

API用途
FindWindow/FindWindowEx跨進程視窗句柄搜尋
GetDC取得視窗用戶區裝置內容
GetDesktopWindow取得桌面視窗句柄
GetCursorPos取得螢幕座標滑鼠位置
StretchBlt拉伸/縮放位元塊傳輸,支援縮放
ReleaseDC釋放裝置內容(程式結束時必須呼叫)

完整程式架構

  • 全域變數:HWND wnd; HDC hdcButton, hdcDesktop; TPoint pt;
  • FormCreate:初始化句柄與 DC,停用定時器,按鈕標籤設為「開始繪圖」
  • BitBtn1Click:切換定時器啟用/關閉,更新按鈕標題
  • Timer1Timer:核心繪圖邏輯,Interval=1 近似每幀更新
  • FormDestroy:必須呼叫 ReleaseDC 釋放兩個 DC,否則造成 GDI 物件洩漏

技術限制與現代替代方案

  1. 僅適用經典主題:Win7+ 視覺樣式/任務列合併按鈕導致類別名/結構變化
  2. GDI 物件洩漏風險:異常退出未釋放 DC 會耗盡系統 GDI 配額
  3. 安全性限制:UIPI (User Interface Privilege Isolation) 可能阻擋跨完整性等級視窗操作
  4. 現代替代:WPF/WinUI 合成引擎、DirectComposition、Desktop Window Manager (DWM) 縮圖 API (DwmRegisterThumbnail) 提供更安全、高效能的跨視窗內容共享

教學價值總結

雖具時代侷限性,但本範例完美示範:

  • Windows 視窗體系與訊息機制
  • GDI 裝置內容跨進程共享原理
  • 位元塊傳輸 (BitBlt 系列) 核心繪圖模型
  • 定時器驅動動畫迴圈基本範式

適合 Windows 系統程式設計入門教學,理解底層繪圖管線運作。

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