MSDN原文(英文)
繪製窗口
你已經創建了你的窗口,現在你想在它裏面顯示東西。在WIndows術語裏,這就是所謂的繪製窗口。混合隱喻,一個窗口是一個空白畫布,等待你去填充它。
有時你的程序將啓動繪製更新你窗口的外觀。在其它時候,操作系統會通知你,你必須重繪部分窗口。當這種情況發生時,操作系統個窗口發送一個WM_PAINT消息,窗口中必須重繪的部分被稱爲更新區域。
一個窗口在第一時間顯示時,窗口的整個客戶區一定要繪製。因此,當你顯示一個窗口,你總是會收到至少一個WM_PAINT消息。
插圖顯示一個窗口更新區域
你只負責繪製客戶區。周圍的框架,包括標題欄,由操作系統自動繪製。在你完成客戶區的繪製,你要清除更新區域,這是告訴操作系統,它不需要發送另一個WM_PAINT消息直到有新的變化。
現在假設用戶移動另一個窗口,使它掩蓋你的窗口的一部分。當被掩蓋的部分再次成爲可見,該部分被添加到更新區域,並你的窗口接受另一個WM_PAINT消息。
插圖顯示兩個窗口重疊時如何更改更新區域
如果用戶拉伸窗口,更新區域也會改變,在下面的插圖,用戶拉伸窗口到右邊,在窗口右側新暴露的區域添加到更新區域:
插圖顯示窗口調整大小是如何更改更新區域
在我們的一個例子程序,繪製程序是非常簡單的。它只是用純色填充整個客戶區。儘管如此,這個例子足以證明一些重要的概念。
switch(uMsg)
{
case WM_PAINT:
{
PAINTSTRUCTS ps;
HDC hdc = BeginPaint(hwnd,&ps);
//所有的繪製都在這裏,BeginPaint和EndPaint之間
FillRect(hdc,&ps.rcPaint,(HBRUSH)(COLOR_WINDOW+1));
EndPaint(hwnd,&ps);
}
return 0;
}
通過調用BeginPaint函數開始繪製操作,這個函數在重繪請求時填充信息到PAINTSTRUCTS結構,PAINTSTRUCTS結構的成員rcPaint給出了當前的更新區域,此更新區域相對於客戶區:
插圖顯示客戶區的原點
在你的繪製代碼中,你有兩個基本的選擇:
- 繪製整個客戶區,無論更新區域的大小。更新區域以外任何範圍被裁剪,也就是說操作系統也忽略它。
- 優化繪製,只是窗口的更新區域部分。
如果你總是繪製整個客戶區,代碼會更簡單。如果你具有複雜的繪製邏輯,但是,它可以更有效的調到更新區域以外的區域。
下面的代碼用一個單一的顏色填充更細區域,使用系統定義的窗口背景顏色(COLOR_WINDOW),由COLOR_WINDOW表示的實際顏色取決於用戶的當前配色方案。
FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));
在這個例子中,FillRect的細節並不重要,但第二個參數給出的要填充的矩形,在這種情況下,我們傳入整個更新區域(PAINTSTRUCTS結構的成員rcPaint)。在第一次WM_PAINT消息,整個客戶區需要繪製,所以rcPaint包含整個客戶區。在隨後的WM_PAINT消息,rcPaint可能包含一個較小的矩形。
FillRect函數是圖形設備接口(GDI)的一部分,已經支持WINDOWS圖形很長一段時間。在WINDOWS7,微軟推出了新的圖形引擎,取名Direct2D,支持高性能的圖形操作,例如硬件加速。另外Windows Vista和Windows Server 2008通過各自的平臺更新也支持Direct2D(GDI仍然完全支持)。
當你繪製完成以後,調用EndPaint函數。這個函數清除更新區域,某些信號傳到WINDOWS窗口已經完成本身的繪製。