繪製視窗

您已建立視窗。 現在您想要顯示其中的內容。 在 Windows 術語中,這稱為繪製視窗。 若要混用隱喻,視窗是空白畫布,等候您填滿。

有時候,您的程式會起始繪製以更新視窗的外觀。 在其他時候,作業系統會通知您您必須重新繪製視窗的一部分。 發生這種情況時,作業系統會傳送視窗 WM_PAINT 訊息。 必須繪製的視窗部分稱為 更新區域

第一次顯示視窗時,必須繪製視窗的整個工作區。 因此,當您顯示視窗時,您一律會收到至少一 個WM_PAINT 訊息。

顯示視窗更新區域的圖例

您只負責繪製工作區。 作業系統會自動繪製周圍框架,包括標題列。 完成繪製工作區之後,您會清除更新區域,告知作業系統在變更之前不需要傳送另一個 WM_PAINT 訊息。

現在假設使用者移動另一個視窗,使其遮蔽視窗的一部分。 當遮蔽的部分再次顯示時,該部分會新增至更新區域,而您的視窗會收到另一個 WM_PAINT 訊息。

顯示兩個視窗重迭時更新區域如何變更的圖例

如果使用者延展視窗,更新區域也會變更。 在下圖中,使用者會將視窗向右延展。 視窗右側新公開的區域會新增至更新區域:

顯示視窗調整大小時更新區域變更方式的圖例

在我們的第一個範例程式中,繪製常式非常簡單。 它只會以純色填滿整個工作區。 不過,此範例足以示範一些重要的概念。

switch (uMsg)
{
    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hwnd, &ps);

        // All painting occurs here, between BeginPaint and EndPaint.

        FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));

        EndPaint(hwnd, &ps);
    }
    return 0;
}

呼叫 BeginPaint 函式以啟動繪製作業。 此函式會在 PAINTSTRUCT 結構中填入 repaint 要求的相關資訊。 目前的更新區域會在PAINTSTRUCTrcPaint成員中提供。 這個更新區域是相對於工作區所定義的:

顯示工作區原點的圖例

在繪製程式碼中,您有兩個基本選項:

  • 繪製整個工作區,不論更新區域的大小為何。 任何落在更新區域以外的專案都已裁剪。 也就是說,作業系統會忽略它。
  • 藉由只繪製更新區域內視窗的部分來優化。

如果您一律繪製整個工作區,程式碼會比較簡單。 不過,如果您有複雜的繪製邏輯,可以更有效率地略過更新區域以外的區域。

下列程式程式碼會使用系統定義的視窗背景色彩填入單一色彩的更新區域, (COLOR_WINDOW) 。 COLOR_WINDOW所指出的實際色彩取決於使用者的目前色彩配置。

FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));

FillRect的詳細資料對本範例而言並不重要,但第二個參數會提供矩形的座標來填滿。 在此情況下,我們會傳入整個更新區域, (PAINTSTRUCT) 的 rcPaint成員。 在第一 個WM_PAINT 訊息上,必須繪製整個工作區,因此 rcPaint 會包含整個工作區。 在後續 WM_PAINT 訊息上, rcPaint 可能包含較小的矩形。

FillRect函式是圖形裝置介面 (GDI) 的一部分,其已為 Windows 圖形提供很長的時間。 在 Windows 7 中,Microsoft 引進了名為 Direct2D 的新圖形引擎,其支援高效能圖形作業,例如硬體加速。 Direct2D 也可透過 Windows Vista 平臺更新 和 Windows Server 2008 平臺更新,透過 Windows Server 2008 平臺更新提供 Windows Vista。 (GDI 仍受到完全支援。)

完成繪製之後,請呼叫 EndPaint 函式。 此函式會清除更新區域,這會向 Windows 發出訊號,指出視窗已完成繪製本身。

下一個

關閉視窗