Windows
應用程序基本結構
一個完整的
windos
應用程序通常由下面五種類型的文件組成:
1.????????
擴展名為
.c/.cpp
的C語言程序源文件
2.????????
擴展名為
.h
的頭文件
3.????????
擴展名為
.rc
的資源描述文件
4.????????
擴展名為
.def
的模塊定義文件
5.????????
擴展名為
.mak
的項目文件
前面三種很常見了,不過后面兩個就
……
暫時不管,以后遇見了再說。
源程序組成結構
與
console
程序相對應,
windows
應用程序也有一個入口函數
WinMain
,用于完成一系列的定義和初始化工作,并產生消息循環。消息循環是整個程序運行的核心。此外,窗口函數
WndProc
是處理接收到的消息的函數。其中包含了應用程序對各種可能接收到的消息的處理過程。
?
WinMain
函數的功能:
注冊窗口類,建立窗口及執行其他必要的初始化工作
進入消息循環,根據從應用程序消息隊列接受的消息調用相應的處理過程。
當消息循環檢測到
WM_QUIT
消息時終止程序運行。
WinMian
函數由三個基本組成部分:函數說明、初始化和消息循環。
(1)?????
函數說明
int WINAPI WinMain
(
?????? HINSTANCE hThisInst,??????? //
應用程序當前實例句柄
?????? HINSTANCE hPrevInst,????????????? //
應用程序其它實例句柄
?????? LPSTR lpszCmdLine,?????????? //
指向程序命令行參數的指針
?????? Int nCmdShow??????????????????? //
應用程序開始執行時窗口顯示方式的標識
)
應當注意到,
windows
程序可能并行的進行多次執行,因而可能出現同一個應用程序的多個窗口同時存在的情況。在
windows
中,每執行一次稱其為一個實例(
instance
),并使用一個實例句柄進行唯一的標識。
?
(2)?????
初始化工作包括:窗口類的定義,注冊,創建窗口實例和顯示窗口四個部分。
???????????
窗口類的定義
在
windows
程序中,窗口類定義了窗口的形式與功能。窗口類定義通過給窗口類數據結構
WNDCLASS
賦值完成,該數據結構中包含窗口類的各種屬性。常用函數有:
LoadIcon
在程序中加載一個窗口圖標
LoadCursor
向程序加載一個窗口光標
GetStockObject
可以獲取各種系統默認資源
???????????
注冊窗口類
Windows
系統本身提供部分預定義的窗口類,程序員也可以自定義窗口類。窗口類必須先用函數
RegisterClass
進行注冊后才能使用。
其形式為:
??? BOOL RegisterClass( &wndClass )
???????????
創建窗口
窗口創建由函數
CreateWindow
實現,其原型為:
HWND CreateWinodw
(
LPCTSTR lpszClassName,?????????? //
窗口類名,此窗口名必須是已經注冊過的
LPCTSTR lpszTitile,??????????????????? //
窗口標題
DWORD dwStyle,?????????????????????? //
窗口樣式
int x,?????????????????????????????????????????
int y,???????????????????????????????????????????????? //
窗口左上角坐標
int nWidth,
int nHeight,???????????????????????????????? //
窗口高寬
HWND hwndParent,??????????????????? //
該窗口父窗口句柄
HMENU hMenu,???????????????????????? //
主菜單句柄
HINSTANCE hInstance,???????????????????? //
當前應用程序句柄
LPVOID lpParam??????????????????????? //
指向一個傳遞給窗口參數值的指針
)
???????????
顯示窗口
窗口類顯示由
ShowWindow
和
UpdateWindow
函數實現。
ShowWindow
將窗口顯示在屏幕上,形式為
BOOL ShowWindow( HWND, int )
顯示完窗口后常常使用
UpdateWindow
更新并繪制用戶區,并發出
WM_PAINT
消息,形式為
UpdateWindow( HWND )
?
(3)?????
消息循環
Windows
應用程序的運行以消息為核心。
Windows
將產生的消息放入應用程序的消息隊列中,而應用程序的
WinMain
函數在消息循環中提取隊列中的消息,并將其傳遞給窗口函數的相應過程處理。
消息循環常見格式為:
MSG?msg;

while
(GetMessage(
&
msg,?NULL,?
0
,?
0
))??????
//
讀取一條消息存放在一個MSG結構中
{

???????TranslateMessage(
&
msg);???????????????????
//
將消息的虛擬鍵轉換為字符信息
???????DispatchMessage(
&
msg);???????????????????
//
將參數指向的消息傳送到指定的窗口函數
}
只有當
GetMessage
函數返回
0
值,即檢索到
WM_QUIT
消息時,程序結束退出。
?
窗口函數
窗口函數的主體是消息處理語句,由一系列
case
語句組成。程序員只需要根據窗口可能收到的消息在
case
語句中編寫相應的處理程序段即可。一般形式如下:
LRESULT?CALLBACK?WndProc?(HWND?hwnd,?UINT?message,?

WPARAM?wParam,?LPRARM?lParam)


{

???????…

swithch(message)


{

???????
case
?…

??????????????…

???????
case
?WM_DESTROY:

??????????????PostQuitMessage(
0
);

???????
default
:

??????????????
return
?DefWindowProc(hwnd,?message,?wParam,?lParam);

}
???????
return
?
0
;

}
?
?
???????????
應用程序舉例
Hello Windows API
:
#include?
windows.h
>
?

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
;

}
?

int
?WINAPI?WinMain(HINSTANCE?hInstance,

?????????????????????HINSTANCE?hPrevInstance,

?????????????????????LPSTR?????lpCmdLine,

?????????????????????
int
???????nCmdShow)


{

???????HWND?hwnd;

???????MSG?msg;

???????WNDCLASS?wndclass;

???????
char
?lpszClassName[]?
=
?
"
hello
"
;

???????
char
?lpszTitle[]?
=
?
"
Hello?Windows?API
"
;

???????
//
------------窗口類的定義
???????wndclass.style?
=
?
0
;

???????wndclass.lpfnWndProc?
=
?WndProc;

???????wndclass.cbClsExtra?
=
?
0
;
//
類無擴展
???????wndclass.cbWndExtra?
=
?
0
;
//
窗口無擴展
???????wndclass.hInstance?
=
?hInstance;
//
當前句柄實例
???????wndclass.hIcon?
=
?LoadIcon(NULL,IDI_APPLICATION);
//
最小化為默認圖標
???????wndclass.hCursor?
=
?LoadCursor(NULL,IDC_ARROW);
//
箭頭光標
???????wndclass.hbrBackground?
=
?(HBRUSH)GetStockObject(BLACK_BRUSH);
//
黑色背景
???????wndclass.lpszMenuName?
=
?NULL;
//
無菜單
???????wndclass.lpszClassName?
=
?lpszClassName;
//
窗口類名

?

???????
//
------------窗口類注冊
???????
if
(
!
RegisterClass(
&
wndclass))


???????
{

??????????????MessageBeep(
0
);
//
如果失敗發出警告音
??????????????
return
?FALSE;

???????}
???????
//
創建窗口
???????hwnd?
=
?CreateWindow(lpszClassName,?lpszTitle,

??????????????????????????????????????????WS_SYSMENU,
//
窗口風格
??????????????????????????????????????????CW_USEDEFAULT,
//
左上角坐標為默認值
??????????????????????????????????????????CW_USEDEFAULT,

??????????????????????????????????????????
400
,
//
窗口高寬
??????????????????????????????????????????
300
,

??????????????????????????????????????????NULL,
//
無父窗口
??????????????????????????????????????????NULL,
//
無主菜單
??????????????????????????????????????????hInstance,
//
創建窗口程序的當前句柄
??????????????????????????????????????????NULL);
//
不使用該值
???????ShowWindow(hwnd,?nCmdShow);

???????UpdateWindow(hwnd);

?

???????
//
-------------消息循環
???????
while
(GetMessage(
&
msg,?NULL,?
0
,?
0
))


???????
{

??????????????TranslateMessage(
&
msg);

??????????????DispatchMessage(
&
msg);

???????}
?

???????
return
?msg.wParam;

}