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;
}