首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Win32 API 創建對話框失敗:缺少消息循環與窗口類註冊

     編輯:程式設計綜合問答

錯誤代碼分析

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    CreateWindowEx(0, TEXT("#32770"), TEXT(""), WS_OVERLAPPEDWINDOW,
        50, 50, 100, 100, NULL, NULL, hInstance, NULL);
    return 0; // 程序立即退出
}

核心問題

  1. 無消息循環:Win32 GUI 程序必須運行 GetMessage/DispatchMessage 循環,否則窗口無法接收繪制、輸入等消息,創建後立即銷毀。
  2. 直接使用系統類 "#32770":該類為對話框專用,**不可直接用 CreateWindowEx 創建**,需用 DialogBox 或 CreateDialog 系列函數。
  3. 缺少窗口類註冊:普通窗口需先 RegisterClassEx 定義 WNDCLASSEX(窗口過程、圖標、光標、背景刷等)。

正確框架:最小 Win32 GUI 程序

#include 

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    switch (msg) {
        case WM_DESTROY: PostQuitMessage(0); return 0;
        case WM_PAINT: {
            PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps);
            TextOut(hdc, 10, 10, L"Hello Win32", 11);
            EndPaint(hwnd, &ps); return 0;
        }
    }
    return DefWindowProc(hwnd, msg, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, int nCmdShow) {
    // 1. 註冊窗口類
    WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_HREDRAW|CS_VREDRAW, WndProc,
        0, 0, hInst, LoadIcon(NULL, IDI_APPLICATION), LoadCursor(NULL, IDC_ARROW),
        (HBRUSH)(COLOR_WINDOW+1), NULL, L"MinWinClass", LoadIcon(NULL, IDI_APPLICATION) };
    if (!RegisterClassEx(&wc)) return 0;

    // 2. 創建窗口
    HWND hwnd = CreateWindowEx(0, L"MinWinClass", L"最小窗口", WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, 400, 300, NULL, NULL, hInst, NULL);
    if (!hwnd) return 0;

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

    // 3. 消息循環
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return (int)msg.wParam;
}

若確需模態對話框

// 資源腳本 .rc 中定義
IDD_MYDIALOG DIALOGEX 0, 0, 200, 150
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "我的對話框"
FONT 9, "微軟雅黑"
BEGIN
    DEFPUSHBUTTON "確定", IDOK, 70, 120, 50, 14
    PUSHBUTTON "取消", IDCANCEL, 130, 120, 50, 14
END

// 代碼調用
INT_PTR CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
    switch (msg) {
        case WM_INITDIALOG: return TRUE;
        case WM_COMMAND:
            if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) {
                EndDialog(hDlg, LOWORD(wParam)); return TRUE;
            }
            break;
    }
    return FALSE;
}

int WINAPI WinMain(...) {
    DialogBox(hInst, MAKEINTRESOURCE(IDD_MYDIALOG), NULL, DlgProc);
    return 0;
}

關鍵差異總結

特性普通窗口模態對話框無模對話框
創建函數CreateWindowExDialogBoxCreateDialog
窗口類自定義 RegisterClassEx系統類 #32770 (內部)系統類 #32770
消息循環手寫 GetMessage 循環系統內部運行主循環需 IsDialogMessage
窗口過程WndProc 返回 LRESULTDlgProc 返回 INT_PTR (BOOL)同模態

學習建議

  1. 先掌握「註冊類 → 創建窗口 → 消息循環 → 窗口過程」四步核心流程。
  2. 使用 Visual Studio 「Windows Desktop Application」模板生成完整樣板代碼。
  3. 參考《Windows 核心編程》第 1-3 章或 MSDN「Windows 經典桌面應用程序」教程。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved