#include<windows.h> // 必須的頭文件
#include<stdio.h>
LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );
// LRESULT 是一個32位的數值,對於一個回調函數其返回類型是LRESULT。
// 其定義爲:
// typedef LONG_PTR LRESULT;
// 關於回調函數(CALLBACK),它可以和一個窗口類相關聯。
//MSDN中的解釋是:CALLBACK Calling convention for callback functions.
//
//This type is declared in WinDef.h as follows:
//
//
//#define CALLBACK __stdcall
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow )
// 同CALLBACK一樣 WINAPI 也是 Calling convention for the Win32 API,
// 個人目前無法理解。。。
// WinMain各個參數的解釋:
// HINSTANCE hInstance -- 應用程序的實例信息,一個程序可以有兩個實例同時運行(開兩個QQ)
// HINSTANCE hPrevInstance -- 一般情況下爲NULL,沒有實際用處。
// PSTR szCmdLine -- 傳給應用程序的參數,PSTR就是字符串。
// int iCmdShow -- 保存關於窗口的信息,諸如最大化、最小化等等。
{
HWND hwnd; // HWND -- 窗口句柄,用它來追蹤窗口,應用程序可以有多個窗口。
MSG msg; // MSG -- 消息,傳遞給窗口的。
WNDCLASSEX wndclass; // WNDCLASSEX -- 窗口類,存有窗口的常用信息如圖標、標題、大小等。
// 設置窗口屬性。
wndclass.cbSize = sizeof( wndclass );
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc; // 指定窗口過程,告知窗口去調用哪個回調函數來處理窗口消息。
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0; // 通常都賦值爲0
wndclass.hInstance = hInstance; // ?不解啊
// 設置圖標和箭頭,空值爲HINSTANCE類型。
wndclass.hIcon = LoadIcon( NULL, IDI_WINLOGO );
wndclass.hCursor = LoadCursor( NULL, IDC_ARROW );
wndclass.hbrBackground = ( HBRUSH ) GetStockObject( WHITE_BRUSH );
// The GetStockObject function retrieves a handle to one of the stock pens, brushes, fonts, or palettes.
// 返回值是VOID* 因此需要類型轉換。
wndclass.lpszMenuName = NULL;
// 爲窗口類起的名字,在創建窗口時將會用到。
wndclass.lpszClassName = TEXT( "Window Class" );
wndclass.hIconSm = LoadIcon( NULL, IDI_WINLOGO );
RegisterClassEx( &wndclass ); // 註冊窗口類。
hwnd = CreateWindow( TEXT( "Window Class" ),
TEXT( "BLIZZARD Window" ), // 窗口標題。
WS_OVERLAPPEDWINDOW, // 窗口類型。
CW_USEDEFAULT, // 初始X位置。
CW_USEDEFAULT, // 初始Y位置。
CW_USEDEFAULT, // 初始X大小。
CW_USEDEFAULT, // 初始Y大小。
NULL, // 父窗口句柄。
NULL, // 菜單句柄。
hInstance, // 實例句柄。
NULL // 可以利用最後一個參數給WndProc傳遞變量,當然也可以用全局變量的方式。
);
ShowWindow( hwnd, iCmdShow ); // MSDN中的註釋:The ShowWindow function sets the specified window's show state.
// 因此不能從翻譯上理解ShowWindow函數調用後會顯示窗口。
UpdateWindow( hwnd ); // 繪製窗口,會向窗口發送一個WM_PAINT消息。
// 消息循環。
// 如果收到WM_QUIT消息將返回0。
while( GetMessage( &msg, NULL, 0, 0 ) ) {
TranslateMessage( &msg );
DispatchMessage( &msg ); // 將消息發送給窗口過程。
}
UnregisterClass( TEXT( "Window Class" ), hInstance );
return msg.wParam;
}
LRESULT CALLBACK WndProc( HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam )
{
switch( iMsg ) {
case WM_CREATE : // 創建窗口。
break;
case WM_SIZE : // 改變窗口大小。
break;
case WM_PAINT : // 窗口重繪。
break;
case WM_DESTROY :
PostQuitMessage( 0 ); // 必須調用PostQuitMessage。
break;
}
return DefWindowProc( hwnd, iMsg, wParam, lParam );
// 調用DefWindowProc採用默認方式處理未處理消息。
}
學習WIN 32離不開MSDN,這點深有體會,許多東西必須查!
WIN 32 編程的一般步驟是:
1) 初始化窗口類。
2) 註冊窗口類。
3) 創建窗口。
4) 從窗口過程獲取消息。
5) 處理消息。