一、开发流程
首先介绍windows程序开发流程:Windows 程序分为「程序代码」和「UI资源」两大部份,两部份最后以RC编译器整合为一个完整的EXE 文件(图1-1)。所谓UI 资源是指功能菜单、对话框外貌、程序图标、光标形状等等东西。这些UI 资源的实际内容(二进制代码)系借助各种工具产生,并以各种扩展名存在,如.ico、.bmp、.cur 等等。程序员必须在一个所谓的资源描述档(.rc)中描述它们。RC 编译器(RC.EXE)读取RC 档的描述后将所有UI资源档集中制作出一个.RES 档,再与程序代码结合在一起,这才是一个完整的Windows可执行文件。
二、事件驱动
Windows 程序的进行系依靠外部发生的事件来驱动。换句话说,程序不断等待(利用一个while 循环),等待任何可能的输入,然后做判断,然后再做适当的处理。上述的「输入」是由操作系统捕捉到之后,以消息形式(一种数据结构)进入程序之中。具体过程由图1-2所示
三、Windows窗口生命周期
1、程序初始化过程中调用CreateWindow,为程序建立了一个窗口,作为程序的屏幕
舞台。CreateWindow产生窗口之后会送出WM_CREATE直接给窗口函数,后者
于是可以在此时做些初始化操作(例如配置内存、打开文件、读初始数据…)。
2、在程序运行的过程中,不断以GetMessage从消息队列中抓取消息。如果这个消
息是WM_QUIT,GetMessage会传回0而结束whle循环,进而结束整个程序。/3、DispatchMessage通过Windows USER模块的协助与监督,把消息分派至窗口函
数。消息将在该处被判别并处理。
3、程序不断进行2.和3.的操作。
4、当使用者按下系统菜单中的Close命令项时,系统送出WM_CLOSE。通常程序的
窗口函数不拦截此消息,于是DefWindowProc处理它。DefWindowProc收到WM_CLOSE后,调用DestroyWindow把窗口清除。Destroy Window本身又会送出WM_DESTROY。
5、程序对WM_DESTROY的标准反应是调用PostQuitMessage。PostQuitMessage没什么其它操作,就只送出WM_QUIT消息,准备让消息循环中的GetMessage取得,如步骤2,结束消息循环。
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("HelloWin") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
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 (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass)) //注册窗口类
{
MessageBox (NULL, TEXT ("This program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
hwnd = CreateWindow (szAppName, //窗口类名称
TEXT ("The Hello Program"), //窗口标题
WS_OVERLAPPEDWINDOW, //窗口类型
CW_USEDEFAULT, //初始X坐标
CW_USEDEFAULT, //初始Y坐标
CW_USEDEFAULT, //窗口宽度
CW_USEDEFAULT, //窗口高度
NULL, //父窗口句柄
NULL, //窗口菜单句柄
hInstance, //程序实例句柄
NULL) ; //创建参数
ShowWindow (hwnd, iCmdShow) ; //显示窗口
UpdateWindow (hwnd) ; //刷新窗口
while (GetMessage (&msg, NULL, 0, 0)) //消息循环
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
参考: