1. 程式人生 > >Directx3D9學習之二:Windows程式設計之最簡單視窗程式

Directx3D9學習之二:Windows程式設計之最簡單視窗程式

Window style

視窗的風格,定義了一些視窗外觀和表現的標誌組合,WS_OVERLAPPEDWINDO是幾個標誌結合的位或,包含最小化,最大化按鈕,邊框,標題欄等等

第五個引數:

Size and position

位置和大小 CW_USEDEFAULT 使用預設值

第六個引數:

Parent window 

父視窗。

第七個引數:

Menu

選單

第八個引數:

Instance handle

例項控制代碼

第九個引數:

Additional application data

指向void*的任意資料結構,傳遞資料所用

最後CreateWindowEx 返回控制代碼建立新視窗,如果失敗返回

0.

(3)顯示視窗

要顯示視窗則將視窗控制代碼傳遞給ShowWindow函式

ShowWindow(hwnd, nCmdShow);

hwnd 引數來自

nCmdShow引數用於最大化或者最小化視窗。作業系統將通過wWinMain函式傳遞該引數給程式

(4)視窗訊息

視窗訊息

MSG msg;GetMessage(&msg, NULL, 0, 0);

提取訊息使用以下兩個函式

TranslateMessage(&msg); DispatchMessage(&msg);

退出提取訊息迴圈

退出提取訊息迴圈

        PostQuitMessage(0);
WM_QUIT是一個特殊的訊息,它會令訊息迴圈結束。訊息迴圈的示例:

// Correct.

MSG msg = { };
while (GetMessage(&msg, NULL, 0, 0))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}
(4)視窗過程
The 
DispatchMessage function calls the window procedure of the window that is the target of the message. The window procedure has the following signature.

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
hwnd:視窗控制代碼 uMSg:訊息程式碼 wParam、lParam:訊息的其他資料 典型的視窗過程如下:
switch (uMsg)
{
case WM_SIZE: // Handle window resizing
    
// etc

}

一個典型的視窗過程可能需要處理幾十條訊息,因此它可能會變得非常長,這樣可以將每個訊息的邏輯處理封裝到一個單獨的函式中n, 然後再在switch中處理。
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_SIZE: 
        {
            int width = LOWORD(lParam);  // Macro to get the low-order word.
            int height = HIWORD(lParam); // Macro to get the high-order word.

            // Respond to the message:
            OnSize(hwnd, (UINT)wParam, width, height);
        }
        break;
        
    }
}

void OnSize(HWND hwnd, UINT flag, int width, int height);
{
    // Handle resizing
}
假如不處理視窗過程特定的訊息,可以直接返回預設的DefWindowProc函式,
    return DefWindowProc(hwnd, uMsg, wParam, lParam);hui

(4)繪製視窗內容

  switch (uMsg)
    {

    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hwnd, &ps);

            // All painting occurs here, between BeginPaint and EndPaint.

            FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));

            EndPaint(hwnd, &ps);
        }
        return 0;

    }
更新繪圖有兩種選擇: *只更新一部分 *更新全部區域 下面程式碼是更新整個區域,使用單一顏色,採用系統預設的COLOR_WINDOW,顏色取決於系統的配色方案
 FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));

完成繪圖後,需要呼叫EndPaint,清除更新區域,表示繪圖已經完成 三、最後的完整程式碼
#ifndef UNICODE
#define UNICODE
#endif

#include <Windows.h>

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
{
	//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);

	//Run the message loop.

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

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg)
	{
	case WM_DESTROY:
			PostQuitMessage(0);
			return 0;
		case WM_PAINT:
			{
				PAINTSTRUCT ps;
				HDC hdc = BeginPaint(hwnd, &ps);
				FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW+1));
				EndPaint(hwnd, &ps);
			}
			return 0;
	}
	return DefWindowProc(hwnd, uMsg, wParam, lParam);
}