共用方式為


建立 Win32 架構的應用程式 (C++)

更新:2010 年 12 月

本逐步解說會示範如何建立於視窗中顯示 "Hello, World!" 的 Win32 應用程式。 您可以使用在這個逐步解說中開發的程式碼做為模板,以建立其他 Win32 應用程式。

Win32 API (又稱為 Windows API) 是建立 Windows 應用程式的 C 架構。 如需 Win32 API 的詳細資訊,請參閱 Windows API

重要事項重要事項

在本文件的各步驟中,為了更清楚解釋特定的程式碼區段,我們可能會省略一般正常的應用程式需要的某些程式碼陳述式,例如 Include 指示詞和全域變數宣告。 本文件最後的範例一節會顯示完整程式碼。

必要條件

若要完成此逐步解說,您必須了解 C++ 語言的基礎。 如果您才剛開始學習 C++,建議您參考 Herb Schildt 所著的《C++ Beginner's Guide》。您可以在 MSDN 網站的初學者開發人員學習中心 (英文) 找到這份文件。

如需觀看示範影片,請參閱 Visual Studio 2008 文件中的影片 HOW TO:建立 Win32 應用程式 (C++) (英文)。

若要建立 Win32 專案

  1. 按一下 [檔案] 功能表上的 [新增],然後按一下 [專案]。

  2. 按一下 [新增專案] 對話方塊左窗格中的 [已安裝的範本],然後按一下 [Visual C++],再選取 [Win32]。 在中間窗格中選取 [Win32 專案]。

    在 [名稱] 方塊中輸入專案的名稱,例如 win32app。 按一下 [確定]。

  3. 在 [Win32 應用程式精靈] 的 [歡迎] 頁面上,按 [下一步]。

  4. 在 [應用程式設定] 頁面的 [應用程式類型] 下,選取 [Windows 應用程式]。 在 [其他選項] 下,選取 [空專案]。 按一下 [完成] 以建立專案。

  5. 在 [方案總管] 中,以滑鼠右鍵按一下 Win32app 專案,然後按一下 [加入],再按一下 [新增項目]。 在 [加入新項目] 對話方塊中,選取 [C++ 檔 (.cpp)]。 在 [名稱] 方塊中輸入檔案名稱,例如 GT_HelloWorldWin32.cpp。 按一下 [加入]。

若要啟動 Win32 應用程式

  1. 就像每個 C 應用程式和 C++ 應用程式都必須有 main 函式做為起點,每個 Win32 應用程式也都必須有 WinMain 函式。 WinMain 具有下列語法。

    int WINAPI WinMain(HINSTANCE hInstance,
                       HINSTANCE hPrevInstance,
                       LPSTR lpCmdLine,
                       int nCmdShow);
    

    如需此函式之參數與傳回值的詳細資訊,請參閱 WinMain 函式

  2. 因為應用程式程式碼必須使用現有的定義,請將 include 陳述式加入至檔案中。

    #include <windows.h>
    #include <stdlib.h>
    #include <string.h>
    #include <tchar.h>
    
  3. 除了 WinMain 函式以外,每個 Win32 應用程式也都必須有視窗程序函式。 這個函式通常名為 WndProcWndProc 具有下列語法。

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

    這個函式可以處理應用程從作業系統所接收的許多「訊息」(Message)。 例如,假設應用程式有個對話方塊具有 [確定] 按鈕,當使用者按一下這個按鈕時,作業系統會將按鈕已按下的訊息傳送給應用程式。 WndProc 會負責回應該事件。 在此範例中,適當的回應可能會是關閉對話方塊。

    如需詳細資訊,請參閱視窗程序

若要將功能加入至 WinMain 函式

  1. WinMain 函式中,建立 WNDCLASSEX 型別的視窗類別結構。 這個結構會包含與視窗有關的資訊,例如應用程式的圖示、視窗的背景色彩、在標題列中顯示的名稱、視窗程序函式的名稱等等。 下列範例示範標準的 WNDCLASSEX 結構。

        WNDCLASSEX wcex;
    
        wcex.cbSize = sizeof(WNDCLASSEX);
        wcex.style          = CS_HREDRAW | CS_VREDRAW;
        wcex.lpfnWndProc    = WndProc;
        wcex.cbClsExtra     = 0;
        wcex.cbWndExtra     = 0;
        wcex.hInstance      = hInstance;
        wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
        wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
        wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
        wcex.lpszMenuName   = NULL;
        wcex.lpszClassName  = szWindowClass;
        wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
    

    如需此結構各欄位的詳細資訊,請參閱 WNDCLASSEX

  2. 現在您已經建立視窗類別,接著必須予以註冊。 請使用 RegisterClassEx 函式,並將視窗類別結構當做引數傳遞。

        if (!RegisterClassEx(&wcex))
        {
            MessageBox(NULL,
                _T("Call to RegisterClassEx failed!"),
                _T("Win32 Guided Tour"),
                NULL);
    
            return 1;
        }
    
  3. 現在您可以建立視窗。 請使用 CreateWindow 函式。

    static TCHAR szWindowClass[] = _T("win32app");
    static TCHAR szTitle[] = _T("Win32 Guided Tour Application");
    
    // The parameters to CreateWindow explained:
    // szWindowClass: the name of the application
    // szTitle: the text that appears in the title bar
    // WS_OVERLAPPEDWINDOW: the type of window to create
    // CW_USEDEFAULT, CW_USEDEFAULT: initial position (x, y)
    // 500, 100: initial size (width, length)
    // NULL: the parent of this window
    // NULL: this application does not have a menu bar
    // hInstance: the first parameter from WinMain
    // NULL: not used in this application
    HWND hWnd = CreateWindow(
        szWindowClass,
        szTitle,
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT,
        500, 100,
        NULL,
        NULL,
        hInstance,
        NULL
    );
    if (!hWnd)
    {
        MessageBox(NULL,
            _T("Call to CreateWindow failed!"),
            _T("Win32 Guided Tour"),
            NULL);
    
        return 1;
    }
    

    這個函式會傳回 HWND,也就是視窗的控制代碼。 如需詳細資訊,請參閱 Windows 資料型別

  4. 現在,使用下列程式碼來顯示視窗。

    // The parameters to ShowWindow explained:
    // hWnd: the value returned from CreateWindow
    // nCmdShow: the fourth parameter from WinMain
    ShowWindow(hWnd,
        nCmdShow);
    UpdateWindow(hWnd);
    

    此時顯示的視窗沒什麼內容,因為您還沒有實作 WndProc 函式。

  5. 現在,加入訊息迴圈以接聽作業系統所傳送的訊息。 當應用程式收到訊息時,這個迴圈會將它分派到 WndProc 函式以進行處理。 這個訊息迴圈看起來像下列程式碼。

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

    如需訊息迴圈中各結構與函式的詳細資訊,請參閱 MSGGetMessageTranslateMessageDispatchMessage

    此時的 WinMain 函式看起來像下列程式碼。

    int WINAPI WinMain(HINSTANCE hInstance,
                       HINSTANCE hPrevInstance,
                       LPSTR lpCmdLine,
                       int nCmdShow)
    {
        WNDCLASSEX wcex;
    
        wcex.cbSize = sizeof(WNDCLASSEX);
        wcex.style          = CS_HREDRAW | CS_VREDRAW;
        wcex.lpfnWndProc    = WndProc;
        wcex.cbClsExtra     = 0;
        wcex.cbWndExtra     = 0;
        wcex.hInstance      = hInstance;
        wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
        wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
        wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
        wcex.lpszMenuName   = NULL;
        wcex.lpszClassName  = szWindowClass;
        wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
    
        if (!RegisterClassEx(&wcex))
        {
            MessageBox(NULL,
                _T("Call to RegisterClassEx failed!"),
                _T("Win32 Guided Tour"),
                NULL);
    
            return 1;
        }
    
        hInst = hInstance; // Store instance handle in our global variable
    
        // The parameters to CreateWindow explained:
        // szWindowClass: the name of the application
        // szTitle: the text that appears in the title bar
        // WS_OVERLAPPEDWINDOW: the type of window to create
        // CW_USEDEFAULT, CW_USEDEFAULT: initial position (x, y)
        // 500, 100: initial size (width, length)
        // NULL: the parent of this window
        // NULL: this application dows not have a menu bar
        // hInstance: the first parameter from WinMain
        // NULL: not used in this application
        HWND hWnd = CreateWindow(
            szWindowClass,
            szTitle,
            WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT, CW_USEDEFAULT,
            500, 100,
            NULL,
            NULL,
            hInstance,
            NULL
        );
    
        if (!hWnd)
        {
            MessageBox(NULL,
                _T("Call to CreateWindow failed!"),
                _T("Win32 Guided Tour"),
                NULL);
    
            return 1;
        }
    
        // The parameters to ShowWindow explained:
        // hWnd: the value returned from CreateWindow
        // nCmdShow: the fourth parameter from WinMain
        ShowWindow(hWnd,
            nCmdShow);
        UpdateWindow(hWnd);
    
        // Main message loop:
        MSG msg;
        while (GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    
        return (int) msg.wParam;
    }
    

若要將功能加入至 WndProc 函式

  1. 為了讓 WndProc 函式處理應用程式所接收到的訊息,請實作 switch 陳述式。

    第一個要處理的訊息是 WM_PAINT 訊息。 當應用程式視窗的某個部分必須更新時,應用程式就會收到這個訊息 (第一次顯示視窗時,整個視窗都必須更新)。

    為了處理 WM_PAINT 訊息,請先呼叫 BeginPaint,然後處理所有的邏輯以安排視窗中的文字、按鈕和其他控制項,最後呼叫 EndPaint。 以這個應用程式而言,在開頭呼叫與結尾呼叫之間的邏輯是要在視窗中顯示 "Hello, World!" 字串。 請注意,下列程式碼中使用了 TextOut 函式來顯示字串。

    PAINTSTRUCT ps;
    HDC hdc;
    TCHAR greeting[] = _T("Hello, World!");
    
    switch (message)
    {
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
    
        // Here your application is laid out.
        // For this introduction, we just print out "Hello, World!"
        // in the top left corner.
        TextOut(hdc,
            5, 5,
            greeting, _tcslen(greeting));
        // End application-specific layout section.
    
        EndPaint(hWnd, &ps);
        break;
    }
    
  2. 應用程式一般都會處理許多其他訊息,例如 WM_CREATEWM_DESTROY。 下列程式碼會顯示基本但完整的 WndProc 函式。

    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        PAINTSTRUCT ps;
        HDC hdc;
        TCHAR greeting[] = _T("Hello, World!");
    
        switch (message)
        {
        case WM_PAINT:
            hdc = BeginPaint(hWnd, &ps);
    
            // Here your application is laid out.
            // For this introduction, we just print out "Hello, World!"
            // in the top left corner.
            TextOut(hdc,
                5, 5,
                greeting, _tcslen(greeting));
            // End application specific layout section.
    
            EndPaint(hWnd, &ps);
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
            break;
        }
    
        return 0;
    }
    

範例

若要建置這個範例

  1. 依照本逐步解說於稍早<若要建立 Win32 專案>中的說明,建立 Win32 專案。

  2. 複製本節步驟之後的程式碼,然後貼到 GT_HelloWorldWin32.cpp 原始程式檔。

  3. 在 [建置] 功能表上,按一下 [建置方案]。

  4. 若要執行應用程式,請按 F5。 畫面左上角會出現含有 "Hello World!" 文字的視窗。

程式碼

// GT_HelloWorldWin32.cpp
// compile with: /D_UNICODE /DUNICODE /DWIN32 /D_WINDOWS /c

#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h>

// Global variables

// The main window class name.
static TCHAR szWindowClass[] = _T("win32app");

// The string that appears in the application's title bar.
static TCHAR szTitle[] = _T("Win32 Guided Tour Application");

HINSTANCE hInst;

// Forward declarations of functions included in this code module:
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int nCmdShow)
{
    WNDCLASSEX wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName   = NULL;
    wcex.lpszClassName  = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));

    if (!RegisterClassEx(&wcex))
    {
        MessageBox(NULL,
            _T("Call to RegisterClassEx failed!"),
            _T("Win32 Guided Tour"),
            NULL);

        return 1;
    }

    hInst = hInstance; // Store instance handle in our global variable

    // The parameters to CreateWindow explained:
    // szWindowClass: the name of the application
    // szTitle: the text that appears in the title bar
    // WS_OVERLAPPEDWINDOW: the type of window to create
    // CW_USEDEFAULT, CW_USEDEFAULT: initial position (x, y)
    // 500, 100: initial size (width, length)
    // NULL: the parent of this window
    // NULL: this application does not have a menu bar
    // hInstance: the first parameter from WinMain
    // NULL: not used in this application
    HWND hWnd = CreateWindow(
        szWindowClass,
        szTitle,
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT,
        500, 100,
        NULL,
        NULL,
        hInstance,
        NULL
    );

    if (!hWnd)
    {
        MessageBox(NULL,
            _T("Call to CreateWindow failed!"),
            _T("Win32 Guided Tour"),
            NULL);

        return 1;
    }

    // The parameters to ShowWindow explained:
    // hWnd: the value returned from CreateWindow
    // nCmdShow: the fourth parameter from WinMain
    ShowWindow(hWnd,
        nCmdShow);
    UpdateWindow(hWnd);

    // Main message loop:
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return (int) msg.wParam;
}

//
//  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_PAINT    - Paint the main window
//  WM_DESTROY  - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT ps;
    HDC hdc;
    TCHAR greeting[] = _T("Hello, World!");

    switch (message)
    {
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);

        // Here your application is laid out.
        // For this introduction, we just print out "Hello, World!"
        // in the top left corner.
        TextOut(hdc,
            5, 5,
            greeting, _tcslen(greeting));
        // End application-specific layout section.

        EndPaint(hWnd, &ps);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
        break;
    }

    return 0;
}

後續步驟

上一個主題:建立 Windows 應用程式 (C++) |下一個主題:使用 .NET Framework 建立 Windows Form 應用程式 (C++)

請參閱

工作

建立 Windows 應用程式 (C++)

變更記錄

日期

記錄

原因

2010 年 12 月

說明我們可能已省略一般正常情況下會需要的某些程式碼陳述式,以更清楚解釋程式碼的其他部分。

客戶回函。