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

Windows 應用程式入口函數 WinMain 完整手寫教學

     編輯:關於VC++

前言

C 語言以 main() 為入口,Windows GUI 應用程式則以 WinMain() 為入口。MFC 將此封裝於框架內,但理解原生 WinMain 流程對於掌握視窗機制至關重要。本文手把手教學撰寫完整的 WinMain 程式,涵蓋視窗類別註冊、視窗建立、訊息迴圈、視窗程序四大核心環節。

必要標頭檔

#include <windows.h>
#include <stdio.h>

視窗程序宣告

LRESULT CALLBACK WinMyProc(
    HWND hWnd,      // 視窗控制代碼
    UINT uMsg,      // 訊息識別碼
    WPARAM wParam,  // 訊息參數 1
    LPARAM lParam   // 訊息參數 2
);

WinMain 完整實作

int WINAPI WinMain(
    HINSTANCE hInstance,     // 目前實例控制代碼
    HINSTANCE hPrevInstance, // 前一實例 (Win32 恆為 NULL)
    LPSTR lpCmdLine,         // 命令列參數
    int nCmdShow             // 顯示狀態 (SW_SHOWNORMAL 等)
)
{
    // 1. 定義並填寫視窗類別結構
    WNDCLASS wndcls = {0};
    wndcls.cbClsExtra = 0;
    wndcls.cbWndExtra = 0;
    wndcls.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); // 白色背景
    wndcls.hCursor = LoadCursor(NULL, IDC_ARROW);               // 標準箭頭
    wndcls.hIcon = LoadIcon(NULL, IDI_WINLOGO);                 // Windows Logo 圖示
    wndcls.hInstance = hInstance;                               // 應用程式實例
    wndcls.lpfnWndProc = WinMyProc;                             // 視窗程序指標
    wndcls.lpszClassName = "BEYOND";                            // 類別名稱
    wndcls.lpszMenuName = NULL;                                 // 無選單
    wndcls.style = CS_HREDRAW | CS_VREDRAW;                     // 水平/垂直重繪

    // 2. 註冊視窗類別
    if (!RegisterClass(&wndcls))
        return 0; // 註冊失敗

    // 3. 建立視窗
    HWND hWnd = CreateWindow(
        "BEYOND",           // 類別名稱
        "LoveBeyond",       // 視窗標題
        WS_OVERLAPPEDWINDOW, // 標準重疊視窗樣式
        0, 0,               // 預設位置
        600, 400,           // 寬、高
        NULL,               // 父視窗
        NULL,               // 選單
        hInstance,          // 實例
        NULL                // 額外參數
    );

    if (!hWnd)
        return 0;

    // 4. 顯示與更新視窗
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    // 5. 訊息迴圈
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0)) // 收到 WM_QUIT 回傳 FALSE 跳出
    {
        TranslateMessage(&msg); // 處理鍵盤訊息 (WM_KEYDOWN → WM_CHAR)
        DispatchMessage(&msg);  // 分派至視窗程序
    }

    return (int)msg.wParam; // 返回退出碼
}

視窗程序 WinMyProc 實作

LRESULT CALLBACK WinMyProc(
    HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_CHAR: // 字元輸入 (經 TranslateMessage 產生)
    {
        char szChar[20];
        sprintf(szChar, "char is %d", wParam); // wParam 為字元碼
        MessageBox(hWnd, szChar, "Keyboard", MB_OK);
        break;
    }

    case WM_LBUTTONDOWN: // 滑鼠左鍵按下
        MessageBox(hWnd, "Mouse clicked", "Mouse", MB_OK);
        break;

    case WM_PAINT: // 視窗重繪
    {
        PAINTSTRUCT ps;
        HDC hDC = BeginPaint(hWnd, &ps);
        TextOut(hDC, 0, 0, "LoveBeyond", strlen("LoveBeyond"));
        EndPaint(hWnd, &ps);
        break;
    }

    case WM_CLOSE: // 使用者點擊關閉鈕
        if (IDYES == MessageBox(hWnd, "想要結束嗎?", "Confirm", MB_YESNO))
        {
            DestroyWindow(hWnd); // 發送 WM_DESTROY
        }
        break;

    case WM_DESTROY: // 視窗銷毀
        PostQuitMessage(0); // 發送 WM_QUIT 結束訊息迴圈
        break;

    default:
        return DefWindowProc(hWnd, uMsg, wParam, lParam); // 預設處理
    }
    return 0;
}

關鍵概念總結

階段關鍵 API說明
類別註冊RegisterClass向系統登記視窗類別屬性,lpfnWndProc 指定處理函數
視窗建立CreateWindow依類別建立視窗實例,回傳 HWND
顯示更新ShowWindow/UpdateWindow使視窗可見並觸發首次 WM_PAINT
訊息迴圈GetMessage/TranslateMessage/DispatchMessage核心事件迴圈,WM_QUIT 時結束
視窗程序WndProc處理特定訊息,未處理者交給 DefWindowProc

常見訊息對照

  • WM_CREATE:視窗建立時 (初始化資源)
  • WM_DESTROY:視窗銷毀時 (釋放資源,發送 PostQuitMessage)
  • WM_PAINT:需重繪客戶區 (BeginPaint/EndPaint 配對)
  • WM_CLOSE:使用者要求關閉 (可攔截詢問)
  • WM_COMMAND:選單/控制項通知
  • WM_KEYDOWN/WM_CHAR:鍵盤輸入
  • WM_MOUSEMOVE/WM_LBUTTONDOWN:滑鼠事件

MFC 如何封裝 WinMain

MFC 在 AfxWinMain 中完成上述流程:

  1. AfxWinInit 初始化 MFC 狀態
  2. 呼叫 CWinApp::InitApplication、InitInstance (建立主視窗)
  3. 進入 CWinThread::Run 訊息迴圈 (含 OnIdle 處理)
  4. AfxWinTerm 清理

theApp 全域物件在 WinMain 前建構,提供應用程式單一入口。

結語

手寫 WinMain 能深入理解 Windows 視窗機制核心:類別註冊 → 實例建立 → 訊息迴圈 → 程序分派。這是所有 Windows GUI 程式設計的基石,MFC、WTL、Qt 等框架皆在此模型之上封裝。建議初學者親自撰寫並除錯一次,體會 WM_PAINT 重繪機制與訊息迴圈運作。

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