Win32 程序開發:創建一個應用程序窗口


一、創建一個應用程序窗口

代碼如下:

// 頭文件
#include <windows.h>
 
// 全局變量
WCHAR g_lpszClassName[] = L"CLASSNAME";
WCHAR g_lpszWindowName[] = L"哈嘍,新的征程";
 
// 函數聲明
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
 
// 應用程序主函數
INT APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, INT nCmdShow)
{
    // 1.設計一個窗口類
    WNDCLASSEX wcex;
    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style = CS_HREDRAW | CS_VREDRAW;        
    wcex.cbClsExtra = 0;    
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    wcex.lpfnWndProc = WndProc;
    wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = g_lpszClassName;
    wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
 
    // 2.注冊這個窗口類
    if (RegisterClassEx(&wcex) == ((ATOM)0))
    {
        MessageBox(NULL, L"注冊窗口類失敗!", L"錯誤", MB_YESNO | MB_ICONERROR);
        exit(-1);
    }
 
    // 3.創建窗口
    HWND hWnd = CreateWindowEx(NULL, g_lpszClassName, g_lpszWindowName, WS_OVERLAPPEDWINDOW, 10, 10, 800, 800, NULL, NULL, hInstance, NULL);
    if (hWnd == NULL)
    {
        MessageBox(NULL, L"創建窗口失敗!", L"錯誤", MB_YESNO | MB_ICONERROR);
        exit(-1);
    }
 
    // 4.更新和顯示窗口
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
 
    // 5.應用程序消息循環
    MSG msg = { 0 };
    BOOL bRet;
    // 調用 GetMessage 函數從調用線程的消息隊列中取得一個消息
    while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
    {
        if (bRet != -1)
        {
            TranslateMessage(&msg); // 將虛擬鍵消息轉換為字符消息
            DispatchMessage(&msg); // 將消息分發到窗口處理
        }
    }
 
    return msg.wParam;
}
 
// 應用程序消息處理回調函數
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_DESTROY:
        PostQuitMessage(0); // 程序退出
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam); // 默認的窗口處理程序
    }
    return 0;
}

二、程序分析

1.首先設計一個窗口類。

不懂可以看我的這篇文章:Win32 程序開發:窗口類結構體 WNDCLASS 和 WNDCLASSEX ,此處就不多贅述了。


2.注冊先前設計的窗口類。

調用 RegisterClassEx 函數注冊窗口。函數原型:

// 返回值(ATOM,原子):成功返回注冊的原子,失敗返回 0。
ATOM WINAPI RegisterClassExW(_In_ CONST WNDCLASSEXW *); // 參數:為我們設計的窗口類

3.創建窗口。

調用 CreateWindowEx 函數創建窗口。函數原型:

// 返回值:創建成功返回創建的窗口句柄,失敗返回NULL
HWND WINAPI CreateWindowExW(
    _In_ DWORD dwExStyle, // 窗口擴展風格
    _In_opt_ LPCWSTR lpClassName, // 我們注冊的窗口類的名稱
    _In_opt_ LPCWSTR lpWindowName, // 窗口的名稱(說白了就是窗口的標題)
    _In_ DWORD dwStyle, // 窗口創建的風格(跟dwExStyle不同)
    _In_ int X, // 窗口左上角的點位於屏幕的橫坐標
    _In_ int Y, // 窗口左上角的點位於屏幕的縱坐標
    _In_ int nWidth, // 窗口的寬度
    _In_ int nHeight, // 窗口的高度
    _In_opt_ HWND hWndParent, // 窗口所有者的句柄
    _In_opt_ HMENU hMenu, // 菜單句柄
    _In_opt_ HINSTANCE hInstance, // 所在模塊的實例句柄
    _In_opt_ LPVOID lpParam); // 在WM_CREATE中進行傳遞的參數

4.更新和顯示窗口。

調用 ShowWindow 函數顯示窗口。函數原型:

// 返回值:成功返回非0,失敗返回0
BOOL WINAPI ShowWindow(
    _In_ HWND hWnd, // 顯示的窗口句柄
    _In_ int nCmdShow); // 窗口顯示的方式(全屏,最大化窗口,最小化窗口,······)

調用 UpdateWindow 函數更新窗口。函數原型:

// 返回值:成功返回非0,失敗返回0
BOOL WINAPI UpdateWindow(
    _In_ HWND hWnd); // 更新的窗口

5.應用程序消息循環。

調用 GetMessage 函數從調用線程的消息隊列中取得一個消息。函數原型:

// 返回值:獲取錯誤返回-1,消息為WM_QUIT返回0,其他為非0
BOOL WINAPI GetMessageW(
    _Out_ LPMSG lpMsg, // 接收從消息隊列中獲取的消息
    _In_opt_ HWND hWnd, // 接收消息的窗口句柄
    _In_ UINT wMsgFilterMin, // 指定被檢測的最小消息值
    _In_ UINT wMsgFilterMax); // 指定被檢測的最大消息值

調用 TranslateMessage 函數將虛擬鍵消息轉換為字符消息。函數原型:

// 返回值:成功返回非0,失敗返回0
BOOL WINAPI TranslateMessage(
    _In_ CONST MSG *lpMsg); // 接收的消息

調用 DispatchMessage 函數將消息分發到窗口處理。函數原型:

// 返回值:窗口處理過程的返回值
LRESULT WINAPI DispatchMessageW(
    _In_ CONST MSG *lpMsg); // 分發的消息

示例中的使用:

while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
{
    if (bRet != -1)
	{
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}

while 循環的結束,當 GetMessage 獲取到的消息為 WM_QUIT 窗口退出,則返回 0(false) 當 GetMessage 的返回值不為 -1(獲取消息失敗)的時候,進行虛擬鍵轉換和分發消息。


6.窗口消息處理過程。

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_DESTROY:
        PostQuitMessage(0); // 程序退出
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam); // 默認的窗口處理程序
    }
 
    return 0;
}

參數:

  • hWnd:窗口處理過程的窗口句柄

  • message:消息ID

  • wParam:附加消息

  • lParam:附加消息


參考:

Win32 程序開發:創建一個應用程序窗口



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM