你的第一個Windows程序——繪製窗口

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窗口已經完成本身的繪製。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章