在螢幕桌面直接繪製圖像(如 Logo、水印、截圖標註),不建立視窗、不進入工作列,純粹繪製於桌面視窗的裝置內容上。
GetDesktopWindow() 取得桌面視窗句柄GetWindowDC(hwnd) 取得整個視窗(含非客戶區)的 DCGetWindowRect() 取得桌面矩形BitBlt/StretchBlt 將位圖繪製到桌面 DCReleaseDC 釋放 DC// 單元檔案:Unit1.h
class TForm1 : public TForm {
private:
Graphics::TBitmap* bmp;
protected:
void __fastcall FormPaint(TObject *Sender);
public:
__fastcall TForm1(TComponent* Owner);
__fastcall ~TForm1();
};
// Unit1.cpp
#include
#pragma hdrstop
#include "Unit1.h"
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) {
bmp = new Graphics::TBitmap();
bmp->LoadFromFile("C:\\AboutLogo.bmp"); // 載入位圖
// 讓視窗最小化,避免遮擋桌面繪製
Application->Minimize();
}
__fastcall TForm1::~TForm1() {
delete bmp;
}
void __fastcall TForm1::FormPaint(TObject *Sender) {
HWND hDesk = GetDesktopWindow();
HDC hdcDesk = GetWindowDC(hDesk);
if (!hdcDesk) return;
RECT rc;
GetWindowRect(hDesk, &rc);
int deskW = rc.right - rc.left;
int deskH = rc.bottom - rc.top;
// 置中繪製
int x = (deskW - bmp->Width) / 2;
int y = (deskH - bmp->Height) / 2;
BitBlt(hdcDesk, x, y, bmp->Width, bmp->Height,
bmp->Canvas->Handle, 0, 0, SRCCOPY);
ReleaseDC(hDesk, hdcDesk);
}
| 議題 | 說明 |
|---|---|
| 視窗最小化 | Application->Minimize() 讓自視窗不遮擋桌面,否則自身重繪會觸發無限迴圈 |
| DC 釋放 | 務必配對 GetWindowDC / ReleaseDC,否則 GDI 物件洩漏導致系統繪圖失效 |
| 桌面重繪 | 其他視窗移動/最小化/最大化會觸發桌面重繪,覆蓋你的圖像。需掛鉤 WM_PAINT 或定時器定期重繪 |
| 透明/Alpha | BitBlt 不支援 Alpha;需用 AlphaBlend (Win2K+) 或 GDI+ / Direct2D 實現半透明 |
| 多顯示器 | GetDesktopWindow 回傳虛擬螢幕範圍;多螢幕置中需自行計算主螢幕座標 |
| 權限 | Vista+ 桌面視窗權限較高,建議以管理員執行或改用桌面小工具/Wallpaper API |
SystemParametersInfo(SPI_SETDESKWALLPAPER) 設定桌布WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_TOPMOST 視窗覆蓋桌面,支援 Alpha、點擊穿透,最穩健直接在桌面 DC 繪製是經典技巧,適合簡單演示、螢幕錄製標註、臨時水印。生產級應用請改用 Layered Window 或現代合成 API,獲得穩定、高效能、支援 Alpha 的覆蓋層體驗。