你的第一個Windows程序——創建一個窗口

MSDN在線原文(英文)

你的第一個Windows程序——創建一個窗口

 窗口類

一個窗口類定義了一組數個窗口可以共有的行爲。比如有一組按鈕,當用戶單擊按鈕,每個按鈕都有類似的行爲。當然,按鈕也不是完全相同的;每個按鈕都有自己的顯示文本字符串和自己的屏幕座標。對於被稱爲實例數據的每個窗口的數據是唯一的。每個窗口必須有一個窗口類關聯,即使你的程序只創建該類的一個實例。重要的是要明白,一個窗口類不是C++意義上的類。切確的說,它是一個操作系統內部使用的數據結構,窗口類是向系統運行時註冊的。註冊一個新的窗口類,通過填充一個WNDCLASS(英文)結構開始:
// Register the window class.
    const wchar_t CLASS_NAME[]  = L"Sample Window Class";
    
    WNDCLASS wc = { };

    wc.lpfnWndProc   = WindowProc;
    wc.hInstance     = hInstance;
    wc.lpszClassName = CLASS_NAME;

你必須設置一下結構成員:
  • lpfnWndProc 是一個指針,指向應用程序定義的被稱爲窗口過程(或"window proc")的的函數。窗口過程定義了大部分窗口行爲,窗口過程的細節我們將在以後研究。現在,只是把這個作爲一個前瞻性的參考。
  • hInstance 是應用程序的實例句柄,從wWinMain的hInstance參數獲取這個值。
  • lpszClassName 是一個表示窗口類的字符串。
類名是局部的,屬於當前進程,所以這個名字只需要在當前進程中是唯一的。然而標準的windows控件也同樣是類,如果你使用任何這些控件,你必須選擇不與控件類名衝突的類名。比如按鈕控件的窗口類名是"Button"。

這裏沒有顯示WNDCLASS結構的其它成員,你可以設置它們爲零,就如在這個例子所示的,或者填寫它們,在MSDN文檔中有描述這個結構的詳細信息。

下一步,傳遞WNDCLASS結構的地址給RegisterClass 函數,這個函數註冊窗口類給操作系統。
RegisterClass(&wc);

創建窗口

創建一個窗口的一個新實例,調用CreateWindowEx函數:

HWND hwnd = CreateWindowEx(
        0,                              // Optional window styles(可選的窗口樣式).
        CLASS_NAME,                     // Window class(窗口類)
        L"Learn to Program Windows",    // Window text(窗口標題)
        WS_OVERLAPPEDWINDOW,            // Window style(窗口樣式)

        // Size and position(大小和定位)
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,

        NULL,       // Parent window (父窗口)  
        NULL,       // Menu (菜單)
        hInstance,  // Instance handle (實例句柄)
        NULL        // Additional application data(額外的應用程序數據)
        );

    if (hwnd == NULL)
    {
        return 0;
    }

你可以閱讀MSDN上詳細的參數說明,這裏只是一個簡略的總結。


  • 第一個參數可以讓你指定的窗口的一些可選的行爲(比如透明窗口),這個參數設置零爲缺省行爲。
  • CLASS_NAME是窗口類名,這個定義了你正在創建窗口的類型。
  • WIndow text 根據不同的窗口類型使用不同的方式,如果這個窗口有標題欄,在標題欄顯示文本。
  • window style 是窗口風格的設置,常量 WS_OVERLAPPEDWINDOW實際上是幾個標記按位或運算的組合。分別是標題欄、邊框、系統菜單、最小化和最大化按鈕。這組標記是一個頂層應用程序最常見的窗口風格。
  • size and position 常量CW_USEDEFAULT表示默認值。
  • parent window 設置了新窗口是所有者窗口還是父窗口,如果是創建子窗口就設置父窗口,如果是創建頂層窗口就是NULL。
  • 對於應用程序,下個參數定義窗口的菜單,這個例子沒有菜單,所以值是NULL。
  • hInstance是示例句柄,前面描述過。(參考:應用程序入口點WinMain
  • 最後一個參數是個指針,指向void*類型的任意數據。您可以使用這個值來傳遞一個數據結構到你的窗口過程,我們將在 Managing Application State這節中演示一個可能的方式使用這個參數。
CreateWindowEx返回新窗口的句柄,若是創建窗口失敗則返回零值。要顯示窗口,使窗口可見,傳遞句柄給 ShowWindow 函數:
ShowWindow(hwnd, nCmdShow);
hwnd是CreateWindowEx返回的窗口句柄。nCmdShow可用來最小化和最大化窗口,這個參數通過操作系統傳給wWinMain函數。
下面是完整的代碼來創建窗口。記住WindowProc函數仍然只是一個預先的聲明。
// Register the window class.
    const wchar_t CLASS_NAME[]  = L"Sample Window Class";
    
    WNDCLASS wc = { };

    wc.lpfnWndProc   = WindowProc;
    wc.hInstance     = hInstance;
    wc.lpszClassName = CLASS_NAME;

    RegisterClass(&wc);

    // Create the window.

    HWND hwnd = CreateWindowEx(
        0,                              // Optional window styles.
        CLASS_NAME,                     // Window class
        L"Learn to Program Windows",    // Window text
        WS_OVERLAPPEDWINDOW,            // Window style

        // Size and position
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,

        NULL,       // Parent window    
        NULL,       // Menu
        hInstance,  // Instance handle
        NULL        // Additional application data
        );

    if (hwnd == NULL)
    {
        return 0;
    }

    ShowWindow(hwnd, nCmdShow);

恭喜!你已經創建了一個窗口。目前,窗口不包含任何內容或與用戶交互。在一個真正的GUI應用程序,窗口會響應來自用戶和操作系統的事件。下一節描述窗口消息如何提供這種互動。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章