win32程序开发流程详解

Win32 程序开发流程


Windows 程序分为「程序代码」和「UI资源」两大部份,两部份最后以RC编译器整合为一个完整的EXE 文件(图1-1)。所谓UI 资源是指功能菜单、对话框外貌、程序图标、光标形状等等东西。这些UI 资源的实际内容(二进制代码)系借助各种工具产生,并以各种扩展名存在,如.ico、.bmp、.cur 等等。程序员必须在一个所谓的资源描述档(.rc)中描述它们。RC 编译器(RC.EXE)读取RC 档的描述后将所有UI资源档集中制作出一个.RES 档,再与程序代码结合在一起,这才是一个完整的Windows可执行档。

需要什么函数库(.LIB)

众所周知Windows 支持动态联结。换句话说,应用程序所调用的Windows API 函数是在「执行时期」才联结上的。那么,「联结时期」所需的函数库做什么用?有哪些? 并不是延伸档名为.dll 者才是动态联结函数库(DLL,Dynamic Link Library)

事实上.exe、.dll、.fon、.mod、.drv、.ocx 都是所谓的动态联结函数库。

Windows 程序调用的函数可分为C Runtimes 以及Windows API 两大部份。早期的C Runtimes 并不支持动态联结,但Visual C++ 4.0 之后已支持,并且在32 位操作系统中已不再有small/medium/large 等内存模式之分。以下是它们的命名规则与使用时机:

  • LIBC.LIB - 这是C Runtime 函数库的静态联结版本。
  • MSVCRT.LIB - 这是C Runtime 函数库动态联结版本(MSVCRT40.DLL)的

import 函数库。如果联结此一函数库,你的程序执行时必须有MSVCRT40.DLL在场。

另一组函数,Windows API,由操作系统本身(主要是Windows 三大模块GDI32.DLL 和U SER32.DLL 和KERNEL32.DLL)提供(注)。虽说动态联结是在执行时期才发生「联结」事实,但在联结时期,联结器仍需先为调用者(应用程序本身)准备一些适当的信息,才能够在执行时期顺利「跳」到DLL 执行。如果该API 所属之函数库尚未加载, 系统也才因此知道要先行加载该函数库。这些适当的信息放在所谓的「import 函数库」中。32 位Windows 的三大模块所对应的import 函数库分别为GDI32.LIB 和USER32.LIB 和KERNEL32.LIB。

需要什么头文件(.H)

所有Windows 程序都必须包含WINDOWS.H。早期这是一个巨大的头文件,大约有5000 行左右,Visual C++ 4.0 已把它切割为各个较小的文件,但还以WINDOWS.H 总括之。除非你十分清楚什么API 动作需要什么头文件,否则为求便利,单单一个WINDOWS.H 也就是了。

不过,WINDOWS.H 只照顾三大模块所提供的API 函数,如果你用到其它system DLLs, 例如COMMDLG.DLL 或MAPI.DLL 或TAPI.DLL 等等,就得包含对应的头文件,例如COMMDLG.H 或MAPI.H 或TAPI.H 等等。

以消息为基础,以事件驱动之

Windows 程序的进行系依靠外部发生的事件来驱动。换句话说,程序不断等待(利用一个while 回路),等待任何可能的输入,然后做判断,然后再做适当的处理。上述的「输入」是由操作系统捕捉到之后,以消息形式(一种数据结构)进入程序之中。操作系统如何捕捉外围设备(如键盘和鼠标)所发生的事件呢?噢,USER 模块掌管各个外围的驱动程序,它们各有侦测回路。

如果把应用程序获得的各种「输入」分类,可以分为由硬件装置所产生的消息(如鼠标移动或键盘被按下),放在系 统队列(system queue)中,以及由Windows 系统或其它Windows 程序传送过来的消息,放在程序队列(application queue)中。以应用程序的眼光来看,消息就是消息,来自哪里或放在哪里其实并没有太大区别,反正程序调用GetMessage API 就取得一个消息,程序的生命靠它来推动。所有的GUI 系统,包括UNIX 的X Window 以及OS/2 的Presentation Manager,都像这样,是以消息为基础的事件驱动系统。

可想而知,每一个Windows 程序都应该有一个回路如下:

MSG msg;

while (GetMessage(&msg, NULL, NULL, NULL)) {

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

}

// 以上出现的函数都是Windows API 函数

消息,也就是上面出现的MSG 结构,其实是Windows 内定的一种资料格式:

/* Queued message structure */ typedef struct tagMSG

{

    HWND hwnd;

UINT message; // WM_xxx,例如WM_MOUSEMOVE,WM_SIZE...

WPARAM wParam;

LPARAM lParam;

DWORD time;

POINT pt;

} MSG;

 

接受并处理消息的主角就是窗口。每一个窗口都应该有一个函数负责处理消息,程序员必须负责设计这个所谓的「窗口函数」(window procedure,或称为window function)。如果窗口获得一个消息,这个窗口函数必须判断消息的类别,决定处理的方式。

以上就是Windows 程序设计最重要的观念。至于窗口的产生与显示,十分简单,有专门的API 函数负责。稍后我们就会看到Windows 程序如何把这消息的取得、分派、处理动作表现出来。

 

 
  

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿尔兹

如果觉得有用就推荐给你的朋友吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值