參考網路 VB 範例,移植至 VC++ 實現螢幕漸暗/網格遮罩效果,類似 Windows 95 關機畫面。核心使用 CreatePatternBrush 建立 8x8 交錯圖案筆刷,配合 PatBlt 以 PATINVERT (0xA000C9) 模式繪製全螢幕。
HDC hdc = ::GetDC(NULL); // 取得全螢幕 DC
int scrW = ::GetSystemMetrics(SM_CXSCREEN);
int scrH = ::GetSystemMetrics(SM_CYSCREEN);
// 8x8 單色位圖模式:0x55=01010101, 0xAA=10101010 交錯形成棋盤格
BYTE bits[16] = {
0x55, 0x00, 0xAA, 0x00,
0x55, 0x00, 0xAA, 0x00,
0x55, 0x00, 0xAA, 0x00,
0x55, 0x00, 0xAA, 0x00
};
HBITMAP hBmp = ::CreateBitmap(8, 8, 1, 1, bits); // 1 plane, 1 bit per pixel
HBRUSH hBrush = ::CreatePatternBrush(hBmp);
::SelectObject(hdc, hBrush);
// PATINVERT (0x00A000C9):目標 = 目標 XOR 模式
::PatBlt(hdc, 0, 0, scrW, scrH, 0xA000C9);
::DeleteObject(hBrush);
::DeleteObject(hBmp);
::ReleaseDC(NULL, hdc);
// 觸發全螢幕重繪,系統會自動重繪所有視窗
::InvalidateRect(NULL, NULL, TRUE);
class CScreenDim {
HBITMAP m_hBmp;
HBRUSH m_hBrush;
public:
CScreenDim() {
BYTE bits[16] = {0x55,0,0xAA,0, 0x55,0,0xAA,0, 0x55,0,0xAA,0, 0x55,0,0xAA,0};
m_hBmp = ::CreateBitmap(8, 8, 1, 1, bits);
m_hBrush = ::CreatePatternBrush(m_hBmp);
}
~CScreenDim() {
::DeleteObject(m_hBrush);
::DeleteObject(m_hBmp);
}
void Dim() {
HDC hdc = ::GetDC(NULL);
::SelectObject(hdc, m_hBrush);
::PatBlt(hdc, 0, 0,
::GetSystemMetrics(SM_CXSCREEN),
::GetSystemMetrics(SM_CYSCREEN),
0xA000C9); // PATINVERT
::ReleaseDC(NULL, hdc);
}
void Restore() { ::InvalidateRect(NULL, NULL, TRUE); }
};
CScreenDim dim;
dim.Dim(); // 螢幕變暗
Sleep(2000); // 停留 2 秒
dim.Restore(); // 還原
PatBlt 重複次數,或使用 Alpha Blending (AlphaBlend API) 疊加半透明黑色層。bits 陣列產生斜線、點陣等不同紋理。EnumDisplayMonitors,對每個監視器獨立 PatBlt。GetDC(NULL) 會失敗。PATINVERT 為可逆操作,連續呼叫兩次可還原,但依賴視窗不重繪;InvalidateRect 更可靠。完整原始碼專案:下載連結