Win32 SDK基礎(十二)之WM_PAINT訊息的處理(圖)
一、引言
在電腦中,螢幕上顯示的一切東西幾乎都是繪製的,包括視窗、對話方塊、圖片、以及所有文字,而WM_PAINT訊息就是在繪製這些物件時,系統觸發的訊息。我們在電腦中的每一個操作,幾乎都會觸發這個訊息,它也是WIndows中最重要的訊息之一。本文主要針對該訊息進行試驗,以進行全面的學習。
二、WM_PAINT基礎
2.1 巨集定義
#define WM_PAINT 0x000F
2.2 攜帶參數
我們知道,使用sendmessage/ postmessage傳送訊息時,往往會攜帶WPARAM和LPARAM兩個參數,而使用GetMessage或PeekMessage接收訊息時,也會接收到這兩個參數。其中部分訊息,會在參數中攜帶一些必要資訊,例如滑鼠位置、視窗長度和寬度等等。 WM_PAINT的這兩個參數為空,沒有攜帶訊息。
2.3 觸發時機
為了取得到該訊息的觸發時機,我們先建立一個Win32視窗項目作為試驗物件。其視窗的處理函數定義如下:
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_DESTROY: PostQuitMessage(0);//可以使GetMessage返回0 break; case WM_PAINT: { WriteConsole(hOutput,"WM_PAIN\n",10,NULL,NULL); } break; default: break; } return DefWindowProc(hWnd, uMsg, wParam, lParam); }
我們WM_PAINT的處理語句中,向控制台的標準輸出,寫入了一個"WM_PAINT\n"的字串,以此來驗證觸發了WM_PAINT訊息。以下就WM_PAINT的觸發時機分別進行驗證:
1、程式啟動時,繪製視窗時觸發。
在我們啟動程式時,由於需要繪製窗口,因此會觸發WM_PAINT訊息,此時會列印上述字串:
2、用滑鼠調整視窗的大小,時會連續觸發:
由於調整視窗大小時,需要不斷的重繪窗口,所以此時表現出來的就是不斷的觸發WM_PAINT訊息:
3、最小化時不會觸發WM_PAINT訊息,但從最小化還原時會進行觸發
# 下面這張圖,是在兩次從最小化到還原視窗的過程,可以看到多了兩次字串的列印
4、最大化時會觸發WM_PAINT訊息
當圖片最大化和還原後分別觸發一次WM_PAINT訊息,如下圖所示:
#5、當向螢幕外拖曳視窗時,不會觸發WM_PAINT訊息,但拉回螢幕內時會不斷的觸發WM_PAINT訊息
下面的截圖,就是將視窗拉回螢幕時,視窗會在不斷的進行重繪,觸發WM_PAINT訊息。
6、使用InvalidateRect函數觸發WM_PAINT訊息
InvalidateRect的函數原型如下,每次呼叫都會觸發一次WM_PAINT訊息:
BOOL InvalidateRect( HWND hWnd, // handle of window with changed update region CONST RECT *lpRect, // address of rectangle coordinates BOOL bErase // erase-background flag );
hWnd:要更新的客戶區所在的窗體的句柄。如果為NULL,則係統將在函數返回前重新繪製所有的視窗, 然後發送 WM_ERASEBKGND 和 WM_PAINT 給視窗過程處理函數。
lpRect:無效區域的矩形代表,它是一個結構體指標,存放著矩形的大小。如果為NULL,全部的視窗客戶區域將會被增加到更新區域。
bErase:指出無效矩形被標記為有效後,是否重畫該區域,重畫時用預先定義好的畫刷。指定TRUE時需要重畫。
傳回值:
函數成功則傳回非零值,否則傳回零值。
為了驗證InvalidateRect函數的作用,我們需要在視窗處理函數中增加一個對WM_LBUTTONDOWN訊息的處理,每點擊一次滑鼠左鍵就呼叫一次InvalidateRect:
//窗口处理函数 LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_DESTROY: PostQuitMessage(0);//可以使GetMessage返回0 break; case WM_PAINT: { WriteConsole(hOutput,"WM_PAIN\n",10,NULL,NULL); } case WM_LBUTTONDOWN: { InvalidateRect(hWnd,NULL,true); } break; default: break; } return DefWindowProc(hWnd, uMsg, wParam, lParam); }
下图为执行结果,点击了3次鼠标左键,触发了3次WM_PAINT消息。
总结:
触发WM_PAINT消息的本质是改变窗口对应的显存的大小就触发一次,我们进行的每一次窗口最大化、最小化并恢复都是因为改变了窗口的显存而触发了该消息。在我们向屏幕外面拖动窗口时,这点比较特殊,窗口的显存是在一点点被擦除的,此时不会触发WM_PAINT,但是拉回窗口后,显存需要将擦除的部分重新绘制,这就又会触发一次该消息。而InvalidateRect函数,就是通过强制的清除并重绘显存来实现触发WM_PAINT消息。
三、WM_PAINT消息的处理
我们尝试处理WM_PAINT消息,并在窗口上绘制一个矩形,绘图步骤如下:
1、开始绘图处理
HDC BeginPaint( HWND hwnd,//绘图窗口 LPPAINTSTRUCT lpPaint );
我们利用BeginPaint获取绘图设备的句柄---一个HDC对象,然后在改绘图设备上进行绘制。
2、利用HDC对象进行绘图
3、结束绘图处理
Bool EndPoint( HWND hWnd, CONST PAINTSTRUCT *lpPaint );
绘制过程参考下面的代码:
//窗口处理函数 LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_DESTROY: PostQuitMessage(0);//可以使GetMessage返回0 break; case WM_PAINT: { PAINTSTRUCT pt; HDC hdc; hdc=BeginPaint(hWnd,&pt); Rectangle(hdc,0,0,100,100); EndPaint(hWnd,&pt); } case WM_LBUTTONDOWN: { //InvalidateRect(hWnd,NULL,true); } break; default: break; } return DefWindowProc(hWnd, uMsg, wParam, lParam); }
执行结果如下,我们成功绘制了一个矩形:
以上是Win32 SDK基礎(十二)之WM_PAINT訊息的處理(圖)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Windows 11 的原生應用程式(如檔案總管)和其他 shell 應用程式預設使用圓角和 Fluent Design 元素(如 Acrylic)。除了圓角,Windows 11 的另一個重要設計特點是雲母等材質,它將應用程式的背景顏色與桌面對齊。雲母與壓克力類似,但其工作方式略有不同。正如微軟所描述的,Windows Mica 材料透過將背景與應用程式對齊來創建「顏色層次結構

用於build22523的新Windows11SDK透露,微軟正在為Windows11開發新的模糊效果。此效果稱為Tabbed,並且是對Acrylic和Mica的補充。 22523SDK中的新DWMWA_SYSTEMBACKDROP_TYPE、雲母、亞克力的公共Win32API及其奇怪的新「選項卡」混合:pic.twitter.com/dbsu7ZFiIi-一切都回來了(@StartIsBack)2021年12月15日可以在以下SDK的範例應用程式

防毒軟體有時可能會在 Windows 32 筆記型電腦上顯示警告,指出 Trojan/win11.casdet rfn。它表示PC感染了特洛伊木馬惡意軟體,導致其故障。幸運的是,有一些可能的方法可以解決此問題,如下所述。此外,您可能對我們關於 cdn.districtm.io 是否為彈出視窗/病毒/惡意軟體的詳細指南感興趣。什麼是 Trojan/win32.casdet rfn? Trojan/win32.casdet rfn 是一種嚴重的木馬病毒感染,可以超越系統並殺死其進程,使其容易

win32和win64的差別是:1、win32是指Microsoft Windows作業系統的32位元環境,win64是指Microsoft Windows作業系統的64位元版本,比32位元版本更穩定快速;2、win32最高支援2G的內存, win64必須是4G以上記憶體;3、win64支援基於64位元的處理器,而win32卻無法完全支援;4、win32追求簡潔,win64追求效能。

掌握Java海康SDK二次開發的必備技巧引言:隨著資訊科技的快速發展,視訊監控系統在各領域得到了廣泛的應用。而作為國內領先的視訊監控解決方案提供商,海康威視的產品和技術一直在市場中佔有重要的地位。為了滿足不同專案的需求,海康威視提供了SDK供開發者進行二次開發。本文將介紹一些掌握Java海康SDK二次開發的必備技巧,並附上對應的程式碼範例。一、了解海康威視

早在2021年8月,微軟就承諾Windows10和Windows11上的OneNote將在未來幾個月內收到一系列主要功能更新,這是這家科技巨頭將多個版本的筆記應用程式統一為單一版本的努力的一部分客戶。 OneNote在過去幾年中發生了許多變化。 2018年,當微軟真正希望人們使用其UWP版本的OneNote時,該公司停止將原始且功能豐富的OneNote版本與預先安裝的Office應用程式捆綁在一起。相反,微軟只提供了UWP客戶端並為現代版本添加了新功能。微軟後來改

sdk全名為“Software Development Kit”,中文意思是“軟體開發工具包”,是由硬體平台、作業系統(OS)或程式語言的製造商提供的一套工具。 SDK可協助軟體開發人員為特定的平台、系統或程式語言建立應用程式。一個基本的SDK通常由編譯器、偵錯器和應用程式介面(API)組成,但也可能包含其他內容,例如:文件、函式庫、執行時間/開發環境、測試/分析工具、網路協定等。

WindowsAppSDK是一組工具和API,開發人員可以在其Windows應用程式中使用這些工具和API,以便在使用Windows10(版本1809及更高版本)和Windows11的各種裝置上提供「一致」的功能。了解它確實很重要它不會取代現有的應用程式類型,例如.NET或WindowsSDK,它只是提供一個統一的API工具集,可以用來補充您現有的應用程式。今天,微軟發布了具有許多新功能的WindowsAppSDK1.2版本。此版本的亮點可能是第三方開發人
