按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
倾向于直接调用Win32 API,因为这有时候可以获得更高的效率,并
且有着更大的自由度。而且,使用MFC编写的新风格的Windows应用程
序的工作方式基本上与使用SDK编写的同一程序一样,它们往往有着
很多的共同之处,只是使用MFC更加的方便,因为它隐藏了大量的复
杂性。
…………………………………………………………Page 122……………………………………………………………
前面提到过,面向对象的编程方式是当前最流行的程序设计方法,但
是,Win32 API本身却是基于C语言的过程式编程的,SDK和MFC的最主
要的不同之处也就是以C与C++之间的差别,使用MFC进行Windows应用
程序设计需要面向对象的编程思想和方法,好在我们已经在前面这此
进行了大量的铺垫。
第三节 使用SDK编写Windows应用程序
传统的DOS程序以main函数作为进入程序的初始入口点,在Windows应
用程序中,main函数被WinMain函数取而代之,WinMain函数的原型如
下:
int WINAPI WinMain (HINSTANCE hInstance; // 当前实例句柄
HINSTANCE hPrevInstance; // 前一实例句柄
LPSTR lpCmdLine; // 指向命令行参数的指针
int nCmdShow) // 窗口的显示状态
这里出现了一个新的名词 “句柄”(handle),所谓的句柄是一个标识
对象的变量,或者是一个对操作系统资源的间接引用。
在上面的函数原型中,我们看到了一些 “奇怪”的数据类型,如前面
的HINSTANCE和LPSTR等,事实上,很多这样的数据类型只是一些基本
数据类型的别名,表3。2列出了一些在Windows编程中常用的基本数据
类型的别名,表3。3列出了常用的预定义句柄,它们的类型均为void
*,即一个32位指针。
表3。 2 Windows基本数据类型
Windows中 对应的基本数据 说明
所用的数 类型
据类型
BOOL int 布尔值
BSTR unsigned short 32位字符指针
*
BYTE unsigned char 8位无符号整数
COLORREF unsigned long 用作颜色值的32位值
DWORD unsigned long 32位无符号整数,段地址和相关的偏移地
址
…………………………………………………………Page 123……………………………………………………………
LONG long 32位带符号整数
LPARAM long 作为参数传递给窗口过程或回调函数的32
位值
LPCSTR const char * 指向字符串常量的32位指针
LPSTR char * 指向字符串的32位指针
LPCTSTR const char * 指向可移植的Unicode和DBCS字符串常量
(注1) 的32位指针
LPTSTR char *(注1) 指向可移植为Unicode和DBCS字符串的32
位指针
LPVOID void * 指向未定义类型的32位指针
LRESULT long 来自窗口过程或回调函数的32位返回值
UINT unsigned int 32位无符号整数
WNDPROC long 指向窗口过程的32位指针
(__stdcall *)
(void
*;unsigned
int;unsigned
int;long)(注2)
WORD unsigned short 16位无符号整数
WPARAM unsigned int 当作参数传递给窗口过程或回调函数的32
位值
注1: 这是在DBCS版本下的情况,在Unicode版本下LPCTSTR和LPTSTR将代表
其它的数据类型。
注2: 事实上,WNDPROC被定义为LRESULT (CALLBACK*)(HWND; UINT;
WPARAM; LPARAM),这个定义最终被编译器解释为long (__stdcall *)(void
*;unsigned int;unsigned int;long)。
表3。 3 Windows公用句柄类型
句柄类型 说明
HBITMAP 保存位图信息的内存域的句柄
HBRUSH 画刷句柄
HCTR 子窗口控件句柄
HCURSOR 鼠标光标句柄
…………………………………………………………Page 124……………………………………………………………
HDC 设备描述表句柄
HDLG 对话框句柄
HFONT 字体句柄
HICON 图标句柄
HINSTANCE 应用程序的实例句柄
HMENU 菜单句柄
HMODULE 模块句柄
HPALETTE 颜色调色板句柄
HPEN 在设备上画图时用于指明线型
的笔的句柄
HRGN 剪贴区域句柄
HTASK 独立于已执行任务的句柄
HWND 窗口句柄
查看Win32 SDK文档或者浏览Windows头文件 (如windef。h、ctype。h以
及winnt。h等)可以获得关于其它数据类型的定义,这些定义往往使用
了#define和typedef等关键字。
这里解释什么是应用程序的一个实例 (instance)。最简单的理解可以
用下面的例子来说明:比如说已经在Windows中打开了一个 “写字
板”(可以在 “开始”菜单中的 “程序 |附件”下面找到它的快捷方
式),现在你需要从另一篇文章里复制一部分内容到你正在写的这篇
文章中,那么,你可以再打开一个 “写字板”(注意写字板不是一个
多文档应用程序,不能像在Word中那样打开多个不同的文件),然后
从该写字板中复制文件的内容到在前一个写字板内打开的文章中。这
里,我们多次运行了同一个应用程序,在这个例子中,我们将所打开
的两个写字板叫做该应用程序的两个实例。对于实例的更精确 (当然
也要比上面的例子要更难懂得多)的定义,在Win32 SDK中是这样给出
的:实例就是类中一特定对象类型的一个实例化对象
(instantiation),如一个特定的进程或线程,在多任务操作系统
中,一个实例指所加载的应用程序或动态链接库的一份拷贝。刚开始
时我们也许看不懂这一定义,不过没有关系,慢慢的就理解了。
l 注意:
…………………………………………………………Page 125……………………………………………………………
l 尽管在前面给出的WinMain函数的原型中包括了一个名为
hPrevInstance的HINSTANCE类型的参数,按照其字面上的意义,
它所传递的是应用程序的前一个实例的句柄,但是,在Win32平台
下,该参数的值总是为NULL,而不管是否有当前应用程序的实例
在运行。在过去的Windows 3。x环境下编程,我们常常使用下面的
代码来检查应用程序是否已有一个实例在运行:
l if (!hPrevInstance)
l {
l // 在此添加没有应用程序实例在运行时的所需执行的代码。
l // 对于大多数应用程序,我们常在这里注册窗口类。
l }
然而,在Win32操作系统——Windows 95、Windows NT 以及其
后续版本中,上面的if条件体中的代码总会被执行,因为
hPrevInstance总是为NULL,因此!hPrevInstance恒为真。
之所以这样,是因为在Win32环境下,每一个应用程序的实例
都有自已独立的地址空间,因此,它们之间互相独立,互不
干涉。但是,对于一些应用程序,只需要而