首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Windows程式設計基礎:視窗用戶區文字繪製與WM_PAINT訊息處理

     編輯:關於C語言

前言

前一章示範的程式僅建立一個基本視窗,除了標題列顯示視窗名稱外,並未在用戶區呈現任何資訊。實際應用程式需在視窗用戶區內繪製文字與圖形。本章專注於文字列顯示,透過範例程式介紹數個 Windows 文字輸出函數、有效與無效矩形區概念,以及裝置內容與字型尺寸的基礎觀念。此外,還將說明幾個關鍵的 Windows 訊息,應用程式可利用它們進行初始化、終止處理與任務執行。

2.1 顯示資訊

以下程式自用戶區左上角起始座標 (0,0) 開始顯示「Hello,Welcome to Windows」。

// 2-1.c 顯示文字資訊
#include <windows.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int PASCAL WinMain(
    HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpszCmdLine,
    int nCmdShow)
{
    char szAppName[] = "DispText";
    HWND hwnd;
    MSG msg;
    WNDCLASS wndclass;

    if (!hPrevInstance) {
        wndclass.style = CS_VREDRAW | CS_HREDRAW;
        wndclass.lpfnWndProc = WndProc;
        wndclass.cbClsExtra = 0;
        wndclass.cbWndExtra = 0;
        wndclass.hInstance = hInstance;
        wndclass.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
        wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
        wndclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
        wndclass.lpszMenuName = NULL;
        wndclass.lpszClassName = szAppName;

        if (!RegisterClass(&wndclass))
            return FALSE;
    }

    hwnd = CreateWindow(
        szAppName,
        "Display Text",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT,
        CW_USEDEFAULT, CW_USEDEFAULT,
        NULL, NULL, hInstance, NULL);

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    char msg[] = "Hello, Welcome to Windows!";
    PAINTSTRUCT ps;
    HDC hDC;

    switch (message) {
    case WM_PAINT:
        hDC = BeginPaint(hwnd, &ps);
        TextOut(hDC, 0, 0, msg, sizeof(msg) - 1);
        EndPaint(hwnd, &ps);
        return 0;

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}

核心資料型別與結構

HDC - 裝置內容控制代碼

HDC 定義於 windows.h,類似 HWND,用於識別一個裝置內容;所有繪圖函數皆需此控制代碼,繪圖動作將發生在該裝置內容所代表的物件上。

PAINTSTRUCT 結構

此結構包含重繪視窗用戶區所需的資訊,以下列出應用程式關心的欄位:

typedef struct tagPAINTSTRUCT {
    HDC hdc;          // 顯示裝置內容控制代碼
    BOOL fErase;      // 非零表示背景已重繪
    RECT rcPaint;     // 需重繪矩形區域的左上、右下座標
    // ... 其他保留欄位供系統使用
} PAINTSTRUCT;

RECT 結構

typedef struct tagRECT {
    int left;   // 左上角 X 座標
    int top;    // 左上角 Y 座標
    int right;  // 右下角 X 座標
    int bottom; // 右下角 Y 座標
} RECT;

關鍵函數解析

BeginPaint() 與 EndPaint()

BeginPaint() 接收視窗控制代碼與 PAINTSTRUCT 指標,除填充結構欄位外,還會向系統申請一個顯示裝置內容供繪圖使用,並傳回其控制代碼。EndPaint() 必須與 BeginPaint() 成對出現於 WM_PAINT 訊息處理中,具備雙重功能:歸還借用的裝置內容(系統僅管理五個公用顯示裝置內容),以及從訊息佇列移除 WM_PAINT 訊息。

TextOut() 函數

使用 BeginPaint() 取得的裝置內容,在用戶區繪製字串。參數說明如下:

參數說明
HDC hDC裝置內容控制代碼
int x字串起始點邏輯 X 座標(相對用戶區左上角)
int y字串起始點邏輯 Y 座標
LPSTR lpString欲繪製的字串指標
int nCount欲繪製的字元數

函數原型:BOOL TextOut(HDC hDC, int x, int y, LPSTR lpString, int nCount);

WM_PAINT 訊息機制

當視窗用戶區部分需重繪時(如視窗被遮蔽後再顯示),Windows 會將 WM_PAINT 放入應用程式訊息佇列。應用程式必須在 WM_PAINT 處理中完成所有繪圖工作,並呼叫 BeginPaint()/EndPaint() 組合,否則訊息會持續重發導致程式無法正常運作。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved