学习Windows程序必须知道的基础知识
2006-05-10 18:02
771 查看
Windows程序设计的概况
1.我们为什么要学习Windows程序设计而不是一开始就学习MFC???
Windows程序设计是使用C语言和Windows的API函数来进行编程的,而MFC则是封装了WindowsAPI一些琐碎的细节,使用的是C++语言,是面向对象的;因为MFC并不是一个良好的对象模型,使用MFC会在很多方面出现点问题,个人经验:如果对Windows程序不怎么了解,那么调试起来可能让人难以忍受,甚至很多时候不知道错在哪儿,无法调试!!!
2.使用什么工具???
当然是使用微软的VC++6.0了
3.说说Windows程序设计中一些经常出现的概念:
(1).句柄
句柄是WONDOWS用来标识被应用程序所建立或使用的对象的唯一整数,WINDOWS使用各种各样的句柄标识诸如应用程序实例,窗口,控制,位图,GDI对象等等。WINDOWS句柄有点象C语言中的文件句柄。
句柄是一个标识符,是拿来标识对象或者项目的,它就象我们的姓名一样,每个人都会有一个,不同的人的姓名不一样,但是,也可能有一个名字和你一样的人。从数据类型上来看它只是一个16位的无符号整数。应用程序几乎总是通过调用一个WINDOWS函数来获得一个句柄,之后其他的WINDOWS函数就可以使用该句柄,以引用相应的对象。
如果想更透彻一点地认识句柄,我可以告诉大家,句柄是一种指向指针的指针。我们知道,所谓指针是一种内存地址。应用程序启动后,组成这个程序的各对象是住留在内存的。如果简单地理解,似乎我们只要获知这个内存的首地址,那么就可以随时用这个地址访问对象。但是,如果您真的这样认为,那么您就大错特错了。我们知道,Windows是一个以虚拟内存为基础的操作系统。在这种系统环境下,Windows内存管理器经常在内存中来回移动对象,依此来满足各种应用程序的内存需要。对象被移动意味着它的地址变化了。如果地址总是如此变化,我们该到哪里去找该对象呢?
为了解决这个问题,Windows操作系统为各应用程序腾出一些内存储地址,用来专门登记各应用对象在内存中的地址变化,而这个地址(存储单元的位置)本身是不变的。Windows内存管理器在移动对象在内存中的位置后,把对象新的地址告知这个句柄地址来保存。这样我们只需记住这个句柄地址就可以间接地知道对象具体在内存中的哪个位置。这个地址是在对象装载(Load)时由系统分配给的,当系统卸载时(Unload)又释放给系统。
句柄地址(稳定)→记载着对象在内存中的地址────→对象在内存中的地址(不稳定)→实际对象
本质:WINDOWS程序中并不是用物理地址来标识一个内存块,文件,任务或动态装入模块的,相反的,WINDOWS API给这些项目分配确定的句柄,并将句柄返回给应用程序,然后通过句柄来进行操作。
但是必须注意的是程序每次从新启动,系统不能保证分配给这个程序的句柄还是原来的那个句柄,而且绝大多数情况的确不一样的。假如我们把进入电影院看电影看成是一个应用程序的启动运行,那么系统给应用程序分配的句柄总是不一样,这和每次电影院售给我们的门票总是不同的一个座位是一样的道理。
受M$的帮助文档以及很多Windows编程书籍的影响,大家对局柄比较普遍的认识是:句柄是一个整数,用以标识Windows对象,句柄不是一个指针……
而实际上,这些不过是M$进行数据封装的幌子而已,下面我们一起来分析一下HANDLE到底是什么。
请先到Windef.h找绝大多数句柄的定义:
DECLARE_HANDLE(HWND);
DECLARE_HANDLE(HHOOK);
……
DECLARE_HANDLE(HGDIOBJ);
DECLARE_HANDLE(HBITMAP);
DECLARE_HANDLE(HBRUSH);
……
typedef HANDLE HGLOBAL;
typedef HANDLE HLOCAL;
……
OK, 现在大家跟我一起翻到Winnt.h,看看DECLARE_HANDLE和HANDLE到底是什么:
#ifdef STRICT
typedef void *HANDLE;
#define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
#else
typedef PVOID HANDLE;
#define DECLARE_HANDLE(name) typedef HANDLE name
#endif
typedef HANDLE *PHANDLE;
哈哈,现在知道了吧,HANDLE就是PVOID,也就是无类型指针,
而DECLARE_HANDLE(HWND);就是:
struct HWND__ {
int unused;};
typedef struct HWND__ *HWND;
现在实际上都清楚啦,这些Handles都不过是指向struct的指针,至于这个struct的用处,连M$都说unused了,
现在解释下M$这么做的意义,这就是所谓数据封装,你可以在你的程序中把M$的内部结构指针传来传去,可是你却不知道它到底指向的内容是什么,而且可以编个句柄的瞎话防止大家的质疑:)。
(2).微软的数据类型(请允许我这样说,因为我觉得微软每次都喜欢自己搞一套东西出来)
(3).Windows的工作原理
Windows应用程序都是基于消息驱动的,应用程序通过消息与用户进行交互。消息分为标准Windows消息、控件通知消息和命令消息三大类,程序员需要为用户所关心的消息建立消息映射并编写具有特定功能的消息处理函数
消息的种类
l .标准Windows消息
标准Windows消息主要分为三类。
(1)键盘消息
(2)鼠标消息
(3)窗口消息
l .控件消息
l .命令消息
消息的结构
MSG结构在头文件中定义如下:
typedef struct tagMSG
{
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt;
} MSG, *PMSG;
MSG数据成员意义如下:
参数1:hwnd是消息要发送到的那个窗口的句柄,这个窗口就是咱们用CreateWindows函数创建的那一个。如果是在一个有多个窗口的应用程序中,用这个参数就可决定让哪个窗口接收消息。
参数2:message是一个数字,它唯一标识了一种消息类型。每种消息类型都在Windows文件中定义了,这些常量都以WM_开始后面带一些描述了消息特性的名称。比如说当应用程序退出时,Windows就向应用程序发送一条WM_QUIT消息。
参数3:一个32位的消息参数,这个值的确切意义取决于消息本身。
参数4:同上。
参数5:消息放入消息队列中的时间,在这个域中写入的并不是日期,而是从Windows启动后所测量的时间值。Windows用这个域来使用消息保持正确的顺序。
参数6:消息放入消息队列时的鼠标坐标.
消息循环以GetMessage调用开始,它从消息队列中取出一个消息:
GetMessage(&msg,NULL,0,0),第一个参数是要接收消息的MSG结构的地址,第二个参数表示窗口句柄,NULL则表示要获取该应用程序创建的所有窗口的消息;第三,四参数指定消息范围。后面三个参数被设置为默认值,这就是说你打算接收发送到属于这个应用程序的任何一个窗口的所有消息。在接收到除WM_QUIT之外的任何一个消息后,GetMessage()都返回TRUE。如果GetMessage收到一个WM_QUIT消息,则返回FALSE,如收到其他消息,则返回TRUE。因此,在接收到WM_QUIT之前,带有GetMessage()的消息循环可以一直循环下去。只有当收到的消息是WM_QUIT时,GetMessage才返回FALSE,结束消息循环,从而终止应用程序。 均为NULL时就表示获取所有消息。
消息用GetMessage读入后(注意这个消息可不是WM_QUIT消息),它首先要经过函数TranslateMessage()进行翻译,这个函数会转换成一些键盘消息,它检索匹配的WM_KEYDOWN和WM_KEYUP消息,并为窗口产生相应的ASCII字符消息(WM_CHAR),它包含指定键的ANSI字符.但对大多数消息来说它并不起什么作用,所以现在没有必要考虑它。
下一个函数调用DispatchMessage()要求Windows将消息传送给在MSG结构中为窗口所指定的窗口过程。我们在讲到登记窗口类时曾提到过,登记窗口类时,我们曾指定Windows把函数WindosProc作为咱们这个窗口的窗口过程(就是指处理这个消息的东东)。就是说,Windows会调用函数WindowsProc()来处理这个消息。在WindowProc()处理完消息后,代码又循环到开始去接收另一个消息,这样就完成了一个消息循环
1.我们为什么要学习Windows程序设计而不是一开始就学习MFC???
Windows程序设计是使用C语言和Windows的API函数来进行编程的,而MFC则是封装了WindowsAPI一些琐碎的细节,使用的是C++语言,是面向对象的;因为MFC并不是一个良好的对象模型,使用MFC会在很多方面出现点问题,个人经验:如果对Windows程序不怎么了解,那么调试起来可能让人难以忍受,甚至很多时候不知道错在哪儿,无法调试!!!
2.使用什么工具???
当然是使用微软的VC++6.0了
3.说说Windows程序设计中一些经常出现的概念:
(1).句柄
句柄是WONDOWS用来标识被应用程序所建立或使用的对象的唯一整数,WINDOWS使用各种各样的句柄标识诸如应用程序实例,窗口,控制,位图,GDI对象等等。WINDOWS句柄有点象C语言中的文件句柄。
句柄是一个标识符,是拿来标识对象或者项目的,它就象我们的姓名一样,每个人都会有一个,不同的人的姓名不一样,但是,也可能有一个名字和你一样的人。从数据类型上来看它只是一个16位的无符号整数。应用程序几乎总是通过调用一个WINDOWS函数来获得一个句柄,之后其他的WINDOWS函数就可以使用该句柄,以引用相应的对象。
如果想更透彻一点地认识句柄,我可以告诉大家,句柄是一种指向指针的指针。我们知道,所谓指针是一种内存地址。应用程序启动后,组成这个程序的各对象是住留在内存的。如果简单地理解,似乎我们只要获知这个内存的首地址,那么就可以随时用这个地址访问对象。但是,如果您真的这样认为,那么您就大错特错了。我们知道,Windows是一个以虚拟内存为基础的操作系统。在这种系统环境下,Windows内存管理器经常在内存中来回移动对象,依此来满足各种应用程序的内存需要。对象被移动意味着它的地址变化了。如果地址总是如此变化,我们该到哪里去找该对象呢?
为了解决这个问题,Windows操作系统为各应用程序腾出一些内存储地址,用来专门登记各应用对象在内存中的地址变化,而这个地址(存储单元的位置)本身是不变的。Windows内存管理器在移动对象在内存中的位置后,把对象新的地址告知这个句柄地址来保存。这样我们只需记住这个句柄地址就可以间接地知道对象具体在内存中的哪个位置。这个地址是在对象装载(Load)时由系统分配给的,当系统卸载时(Unload)又释放给系统。
句柄地址(稳定)→记载着对象在内存中的地址────→对象在内存中的地址(不稳定)→实际对象
本质:WINDOWS程序中并不是用物理地址来标识一个内存块,文件,任务或动态装入模块的,相反的,WINDOWS API给这些项目分配确定的句柄,并将句柄返回给应用程序,然后通过句柄来进行操作。
但是必须注意的是程序每次从新启动,系统不能保证分配给这个程序的句柄还是原来的那个句柄,而且绝大多数情况的确不一样的。假如我们把进入电影院看电影看成是一个应用程序的启动运行,那么系统给应用程序分配的句柄总是不一样,这和每次电影院售给我们的门票总是不同的一个座位是一样的道理。
受M$的帮助文档以及很多Windows编程书籍的影响,大家对局柄比较普遍的认识是:句柄是一个整数,用以标识Windows对象,句柄不是一个指针……
而实际上,这些不过是M$进行数据封装的幌子而已,下面我们一起来分析一下HANDLE到底是什么。
请先到Windef.h找绝大多数句柄的定义:
DECLARE_HANDLE(HWND);
DECLARE_HANDLE(HHOOK);
……
DECLARE_HANDLE(HGDIOBJ);
DECLARE_HANDLE(HBITMAP);
DECLARE_HANDLE(HBRUSH);
……
typedef HANDLE HGLOBAL;
typedef HANDLE HLOCAL;
……
OK, 现在大家跟我一起翻到Winnt.h,看看DECLARE_HANDLE和HANDLE到底是什么:
#ifdef STRICT
typedef void *HANDLE;
#define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
#else
typedef PVOID HANDLE;
#define DECLARE_HANDLE(name) typedef HANDLE name
#endif
typedef HANDLE *PHANDLE;
哈哈,现在知道了吧,HANDLE就是PVOID,也就是无类型指针,
而DECLARE_HANDLE(HWND);就是:
struct HWND__ {
int unused;};
typedef struct HWND__ *HWND;
现在实际上都清楚啦,这些Handles都不过是指向struct的指针,至于这个struct的用处,连M$都说unused了,
现在解释下M$这么做的意义,这就是所谓数据封装,你可以在你的程序中把M$的内部结构指针传来传去,可是你却不知道它到底指向的内容是什么,而且可以编个句柄的瞎话防止大家的质疑:)。
(2).微软的数据类型(请允许我这样说,因为我觉得微软每次都喜欢自己搞一套东西出来)
Windows数据类型 | 本质类型 | 字节数 | 定义过程(来历) | 含义 | |||
ATOM | unsigned short | 2 | unsigned short→WORD→ATOM | 在Atom表中,一键(16位整数)一值(一个String)为一个Atom。 | |||
BOOL | int | * | int→BOOL | 逻辑变量,布尔值 (取值为 TRUE 或 FALSE) | |||
BOOLEAN | unsigned char | 1 | unsigned char→BYTE→BOOLEAN | 逻辑变量,布尔值 (取值为 TRUE 或 FALSE) | |||
BYTE | unsigned char | 1 | unsigned char→BYTE | 字节型,8位。 | |||
CALLBACK | __stdcall | 调用 | __stdcall→CALLBACK | 回调函数的调用约定 | |||
CHAR | char | 1 | char→CHAR | 8位Windows字符(ANSI) | |||
COLORREF | unsigned long | 4 | unsigned long→DWORD→COLORREF | 红,绿,蓝(RGB)值 | |||
CONST | const | 关键字 | const→CONST | 常量 | |||
CRITICAL_SECTION | RTL_CRITICAL_SECTION结构体 | ? | RTL_CRITICAL_SECTION(结构)→CRITICAL_SECTION | Critical-section对象 | |||
DWORD | unsigned long | 4 | unsigned long→DWORD | 32位无符号整数 | |||
DWORD_PTR | unsigned long | 4 | unsigned long→ULONG_PTR→DWORD_PTR(另有其它路径) | 略……(用处挺大,不过太长了) | |||
DWORD32 | unsigned int | * | unsigned int→DWORD32 | 32位无符号整数 | |||
DWORD64 | unsigned __int64 | 8 | unsigned __int64→DWORD64 | 64位无符号整数 | |||
FLOAT | float | 4 | float→FLOAT | 浮点数变量 | |||
HACCEL | HACCEL__结构体指针 | | 由DECLARE_HANDLE(name)宏定义的指向HACCEL__结构体的指针 | 快捷键列表的句柄 | |||
HANDLE | void *(一个地址) | | void *→HANDLE | 对象的句柄 | |||
HBITMAP | HBITMAP__结构体指针 | | 由DECLARE_HANDLE(name)宏定义的指向HBITMAP__结构体的指针 | 位图的句柄 | |||
HBRUSH | HBRUSH__结构体指针 | | 由DECLARE_HANDLE(name)宏定义…… | 画刷的句柄 | |||
HCONV | HCONV__结构体指针 | | 由DECLARE_HANDLE(name)宏定义…… | 动态数据交换(DDE)会话的句柄 | |||
HCONVLIST | HCONVLIST__结构体指针 | | 由DECLARE_HANDLE(name)宏定义…… | 动态数据交换(DDE)会话列表的句柄 | |||
HCURSOR | HICON__结构体指针 | | HICON__ *→HICON→HCURSOR | 光标的句柄 | |||
HDC | HDC__结构体指针 | | 由DECLARE_HANDLE(name)宏定义…… | 设备上下文(DC)的句柄 | |||
HDDEDATA | HDDEDATA__结构体指针 | | 由DECLARE_HANDLE(name)宏定义…… | 动态数据交换数据的句柄 | |||
HDESK | HDESK__结构体指针 | | 由DECLARE_HANDLE(name)宏定义…… | 桌面(Desktop)的句柄 | |||
HDROP | HDROP__结构体指针 | | 由DECLARE_HANDLE(name)宏定义…… | Handle to an internal drop structure. | |||
HDWP | void *(一个地址) | | void *→HANDLE→HDWP | Handle to a deferred window position structure. | |||
HENHMETAFILE | HENHMETAFILE__结构体指针 | | 由DECLARE_HANDLE(name)宏定义…… | 增强图元文件的句柄 | |||
HFILE | int | * | int→HFILE | 由OpenFile(而不是CreateFile)打开的文件的句柄. | |||
HFONT | HFONT__结构体指针 | | 由DECLARE_HANDLE(name)宏定义…… | 字体的句柄 | |||
HGDIOBJ | void near * | | void NEAR *→HGDIOBJ | GDI对象的句柄 | |||
HGLOBAL | void *(一个地址) | | void *→HANDLE→HGLOBAL | 全局内存块的句柄 | |||
HHOOK | HHOOK__结构体指针 | | 由DECLARE_HANDLE(name)宏定义…… | 句子(hook)的句柄 | |||
HICON | HICON__结构体指针 | | 由DECLARE_HANDLE(name)宏定义…… | 图标的句柄 | |||
HIMAGELIST | _IMAGELIST结构体指针 | | _IMAGELIST *→HIMAGELIST | 图片列表的句柄 | |||
HIMC | HIMC__结构体指针 | | 由DECLARE_HANDLE(name)宏定义…… | 输入上下文的句柄 | |||
HINSTANCE | HINSTANCE__结构体指针 | | 由DECLARE_HANDLE(name)宏定义…… | 实例的句柄 | |||
HKEY | HKEY__结构体指针 | | 由DECLARE_HANDLE(name)宏定义……(另有一条路径,一样) | 注册表键的句柄 | |||
HKL | HKL__结构体指针 | | 由DECLARE_HANDLE(name)宏定义…… | 输入点标识符 | |||
HLOCAL | void *(一个地址) | | void *→HANDLE→HLOCAL | 本地内存块的句柄 | |||
HMENU | HMENU__结构体指针 | | 由DECLARE_HANDLE(name)宏定义…… | 菜单的句柄 | |||
HMETAFILE | HMETAFILE__结构体指针 | | 由DECLARE_HANDLE(name)宏定义…… | 图元文件的句柄 | |||
HMODULE | HINSTANCE__结构体指针 | | HINSTANCE__*→HINSTANCE→HMODULE | 模块的句柄。值由模块的位置来决定。 | |||
HMONITOR | HMONITOR__结构体指针 | | 由DECLARE_HANDLE(name)宏定义…… | 显示器的句柄 | |||
HPALETTE | HPALETTE__结构体指针 | | 由DECLARE_HANDLE(name)宏定义…… | 调色板的句柄 | |||
HPEN | HPEN__结构体指针 | | 由DECLARE_HANDLE(name)宏定义…… | 画(线)笔的句柄 | |||
HRGN | HRGN__结构体指针 | | 由DECLARE_HANDLE(name)宏定义…… | 区域的句柄 | |||
HRSRC | HRSRC__结构体指针 | | 由DECLARE_HANDLE(name)宏定义…… | 资源的句柄 | |||
HSZ | HSZ__结构体指针 | | 由DECLARE_HANDLE(name)宏定义…… | 动态数据交换(DDE)字符串的句柄 | |||
HWINSTA | HWINSTA__结构体指针 | | 由DECLARE_HANDLE(name)宏定义…… | 窗口状态的句柄 | |||
HWND | HWND__结构体指针 | | 由DECLARE_HANDLE(name)宏定义…… | 窗口的句柄 | |||
INT | int | * | int→INT | 32位有符号整数 | |||
INT_PTR | int(_W64 int即__w64 int) | * | _W64 int→INT_PTR,_W64就是__w64,是为了解决32位与64位编译器的兼容性而设置的关键字 | 用于指针运算 | |||
INT32 | signed int | * | signed int→INT32 | 32位有符号整数 | |||
INT64 | signed __int64 | 8 | signed __int64→INT64 | 64位有符号整数 | |||
LANGID | unsigned short | 2 | unsigned short→WORD→LANGID | 语言标识符 | |||
LCID | unsigned long | 4 | unsigned long→DWORD→LCID | Locale identifier. | |||
LCTYPE | unsigned long | 4 | unsigned long→DWORD→LCTYPE | Locale information type. | |||
LONG | long | 4 | long→LONG | 32位有符号整数 | |||
LONG_PTR | long | 4 | _W64 long→LONG_PTR | 用于指针运算 | |||
LONG32 | signed int | * | signed int→LONG32 | 32位有符号整数 | |||
LONG64 | __int64 | 8 | __int64→LONG64 | 64位有符号整数 | |||
LONGLONG | __int64 | 8 | __int64→LONGLONG | 64位有符号整数 | |||
LPARAM | long | 4 | _W64 long→LONG_PTR→LPARAM | 消息的参数 | |||
LPBOOL | int * | | int→BOOL, BOOL far *→LPBOOL | BOOL类型的指针 | |||
LPBYTE | unsigned char * | | unsigned char→BYTE,BYTE far *→LPBYTE | BYTE类型的指针 | |||
LPCOLORREF | unsigned long * | | unsigned long→WORD,DWORD *→LPCOLORREF | 颜色值的指针 | |||
LPCRITICAL_SECTION | RTL_CRITICAL_SECTION结构体指针 | | RTL_CRITICAL_SECTION *PRTL_CRITICAL_SECTION→,PRTL_CRITICAL_SECTION→LPCRITICAL_SECTION | CRITICAL_SECTION的指针 | |||
LPCSTR | 静态char * | | char→CHAR,CONST CHAR *→LPCSTR | 静态8位Windows字符(ANSI)无终结字符串指针 | |||
LPCTSTR | 静态wchar_t * | | wchar_t→WCHAR,CONST WCHAR *→LPCWSTR,LPCWSTR→LPCTSTR | 如果UNICODE已定义则为LPCWSTR,否则为LPCTSTR | |||
LPCVOID | 静态void * | | CONST void far *→LPCVOID | 任何类型的静态指针 | |||
LPCWSTR | 静态wchar_t * | | wchar_t→WCHAR,CONST WCHAR *→LPCWSTR | 静态16位Windows字符(Unicode)无终结字符串指针 | |||
LPDWORD | unsigned long * | | unsigned long→DWORD,DWORD far *→LPDWORD | DWORD的指针 | |||
LPHANDLE | 指向句柄的指针 | | void *→HANDLE,HANDLE FAR *→LPHANDLE | HANDLE的指针 | |||
LPINT | int * | | int far *→LPINT | INT的指针 | |||
LPLONG | long * | | long far *→LPLONG | LONG的指针 | |||
LPSTR | char * | | char→CHAR,CHAR *→LPSTR | 8位Windows字符(ANSI)无终结字符串指针 | |||
LPTSTR | wchar_t * | | wchar_t WCHAR,WCHAR *→LPWSTR,LPWSTR→LPTSTR | An LPWSTR if UNICODE is defined, an LPSTR otherwise. | |||
LPVOID | void * | | void far *→LPVOID | 任何类型的指针 | |||
LPWORD | unsigned short * | | unsigned short→WORD,WORD far *→LPWORD | WORD的指针 | |||
LPWSTR | wchar_t * | | wchar_t→WCHAR,WCHAR *→LPWSTR | 16位Windows字符(ANSI)无终结字符串指针 | |||
LRESULT | long | 4 | _W64 long→LONG_PTR→LRESULT | 有符号的消息处理结果 | |||
LUID | LUID结构 | | | 局部唯一标识符 | |||
PBOOL | int * | | int→BOOL,BOOL near *→PBOOL | BOOL的指针 | |||
PBOOLEAN | unsigned char * | | unsigned char→BYTE→BOOLEAN,BOOLEAN *→PBOOLEAN | BOOL的指针 | |||
PBYTE | unsigned char * | | unsigned char→BYTE,BYTE near *→PBYTE | BYTE的指针 | |||
PCHAR | char * | | char→CHAR,CHAR *→PCHAR | CHAR的指针 | |||
PCRITICAL_SECTION | RTL_CRITICAL_SECTION结构体指针 | | RTL_CRITICAL_SECTION *→PRTL_CRITICAL_SECTION,PRTL_CRITICAL_SECTION→PCRITICAL_SECTION | CRITICAL_SECTION的指针 | |||
PCSTR | 静态char * | | char→CHAR,CONST CHAR *→PCSTR | 静态8位Windows字符(ANSI)无终结字符串指针 | |||
PCTSTR | 静态wchar_t * | | wchar_t→WCHAR,CONST WCHAR *→LPCWSTR,LPCWSTR→PCTSTR | 如果UNICODE已定义则为PCWSTR,否则为PCSTR | |||
PCWCH | 静态wchar_t * | | wchar_t→WCHAR,CONST WCHAR *→PCWCH | WCHAR的静态指针 | |||
PCWSTR | 静态wchar_t * | | wchar_t→WCHAR,CONST WCHAR *→PCWSTR | 静态16位Windows字符(Unicode)无终结字符串指针 | |||
PDWORD | unsigned long * | | unsigned long→DWORD,DWORD near *→PDWORD | DWORD的指针 | |||
PFLOAT | float * | | float→FLOAT,FLOAT *→PFLOAT | FLOAT的指针 | |||
PHANDLE | 指向句柄的指针 | | void *→HANDLE,HANDLE *→PHANDLE | HANDLE的指针 | |||
PHKEY | 指向HKEY的指针 | | HKEY__ *→HKEY *→PHKEY | HKEY的指针 | |||
PINT | int * | | int near *→PINT | INT的指针 | |||
PLCID | unsigned long * | | unsigned long→DWORD,DWORD near *→PDWORD→PLCID | LCID的指针 | |||
PLONG | long * | | long→LONG,LONG *→PLONG | LONG的指针 | |||
PLUID | LUID结构体指针 | | LUID *→PLUID | ||||
POINTER_32 | void * | | void *→POINTER_32 | 32位指针(详解略) | |||
POINTER_64 | void * | | void *→POINTER_64 | 64位指针(详解略) | |||
PSHORT | short * | | short→SHORT,SHORT *→PSHORT | SHORT的指针 | |||
PSTR | char * | | char→CHAR,CHAR *→PSTR | 8位Windows字符(ANSI)无终结字符串指针 | |||
PTBYTE | wchar_t * | | wchar_t→WCHAR,WCHAR *→PTBYTE | TBYTE的指针 | |||
PTCHAR | wchar_t * | | wchar_t→WCHAR,WCHAR *→PTCHAR | TCHAR的指针 | |||
PTSTR | wchar_t * | | wchar_t→WCHAR,WCHAR *→LPWSTR→PTSTR | PWSTR if UNICODE is defined, a PSTR otherwise. | |||
PTBYTE | wchar_t * | | wchar_t→WCHAR,WCHAR *→PTBYTE | TBYTE的指针 | |||
PTCHAR | wchar_t * | | wchar_t→WCHAR,WCHAR *→PTCHAR | TCHAR的指针 | |||
PTSTR | wchar_t * | | wchar_t→WCHAR,WCHAR *→LPWSTR→PTSTR | A PWSTR if UNICODE is defined, a PSTR otherwise. | |||
PUCHAR | unsigned char * | | unsigned char→UCHAR,UCHAR *→PUCHAR | UCHAR的指针 | |||
PUINT | unsigned int * | | unsigned int *→PUINT(呵呵,为什么不用UINT*来定义呢?) | UINT的指针 | |||
PULONG | unsigned long * | | unsigned long→ULONG,ULONG *→PULONG | ULONG的指针 | |||
PUSHORT | unsigned short * | | unsigned short→USHORT,USHORT *→PUSHORT | USHORT的指针 | |||
PVOID | void * | | void *→PVOID | 任何类型的指针 | |||
PWCHAR | wchar_t * | | wchar_t→WCHAR,WCHAR *→PWCHAR | WCHAR的指针 | |||
PWORD | unsigned short * | | unsigned short→WORD,WORD near *→PWORD | WORD的指针 | |||
PWSTR | wchar_t * | | wchar_t→WCHAR,WCHAR *→PWSTR | 16位Windows字符(Unicode)无终结字符串指针 | |||
REGSAM | unsigned long | | unsigned long→DWORD→ACCESS_MASK→REGSAM | 注册表值的安全访问掩码 | |||
SC_HANDLE | SC_HANDLE__结构体指针 | | 由DECLARE_HANDLE(name)宏定义…… | Handle to a service control manager database. | |||
SC_LOCK | void * | | void far *→LPVOID→SC_LOCK | Handle to a service control manager database lock. | |||
SERVICE_STATUS_HANDLE | SERVICE_STATUS_HANDLE__结构体指针 | | 由DECLARE_HANDLE(name)宏定义…… | Handle to a service status value. | |||
SHORT | short | 2 | short→SHORT | 短整数类型(16位) | |||
SIZE_T | unsigned long | 4 | unsigned long→ULONG_PTR→SIZE_T | 指针可指向的最大字节数 | |||
SSIZE_T | long | | _W64 long→LONG_PTR→SSIZE_T | 有符号SIZE_T. | |||
TBYTE | wchar_t | 2 | wchar_t→WCHAR,WCHAR→TBYTE | 如果UNICODE已定义则为WCHAR,否则为CHAR | |||
TCHAR | wchar_t | 2 | wchar_t→WCHAR,WCHAR→TCHAR | 如果UNICODE已定义则为WCHAR,否则为CHAR | |||
UCHAR | unsigned char | 1 | unsigned char→UCHAR | 无符号CHAR | |||
UINT | unsigned int | * | unsigned int→UINT | 无符号INT | |||
UINT_PTR | unsigned int | * | unsigned int→UINT_PTR | 无符号INT_PTR. | |||
UINT32 | unsigned int | 2 | unsigned int→UINT32 | 无符号INT32. | |||
UINT64 | unsigned __int64 | 4 | unsigned __int64→UINT64 | 无符号INT64. | |||
ULONG | unsigned long | 4 | unsigned long→ULONG | 无符号LONG. | |||
ULONG_PTR | unsigned long | 4 | unsigned long→ULONG_PTR | 无符号LONG_PTR. | |||
ULONG32 | unsigned int | 2 | unsigned int→ULONG32 | 无符号LONG32 | |||
ULONG64 | unsigned __int64 | 4 | unsigned __int64→ULONG64 | 无符号LONG64 | |||
ULONGLONG | unsigned __int64 | 4 | unsigned __int64→ULONGLONG | 64位无符号整数 | |||
UNSIGNED | 没查到,大家帮忙吧 | | | 无符号属性 | |||
USHORT | unsigned short | | unsigned short→USHORT | 无符号SHORT类型 | |||
VOID | void | | void→VOID | 任何类型 | |||
WCHAR | wchar_t | 2 | wchar_t→WCHAR | 16位Unicode字符 | |||
WINAPI | __stdcall | 调用 | __stdcall→WINAPI | 系统函数(API函数)调用约定 | |||
WORD | unsigned short | 2 | unsigned short→WORD | 16位无符号整数 | |||
WPARAM | unsigned int | * | unsigned int→UINT_PTR→WPARAM | 消息的参数 | |||
int | * | signed,signed int | 由操作系统决定,即与操作系统的"字长"有关 | ||||
unsigned int | * | unsigned | 由操作系统决定,即与操作系统的"字长"有关 | ||||
__int8 | 1 | char,signed char | –128 到 127 | ||||
__int16 | 2 | short,short int,signed short int | –32,768 到 32,767 | ||||
__int32 | 4 | signed,signed int | –2,147,483,648 到 2,147,483,647 | ||||
__int64 | 8 | 无 | –9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 | ||||
bool | 1 | 无 | false 或 true | ||||
char | 1 | signed char | –128 到 127 | ||||
unsigned char | 1 | 无 | 0 到 255 | ||||
short | 2 | short int,signed short int | –32,768 到 32,767 | ||||
unsigned short | 2 | unsigned short int | 0 到 65,535 | ||||
long | 4 | long int,signed long int | –2,147,483,648 到 2,147,483,647 | ||||
long long | 8 | none (but equivalent to __int64) | –9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 | ||||
unsigned long | 4 | unsigned long int | 0 到 4,294,967,295 | ||||
enum | * | 无 | 由操作系统决定,即与操作系统的"字长"有关 | ||||
float | 4 | 无 | 3.4E +/- 38 (7 digits) | ||||
double | 8 | 无 | 1.7E +/- 308 (15 digits) | ||||
long double | 8 | 无 | 1.7E +/- 308 (15 digits) | ||||
wchar_t | 2 | __wchar_t | 0 到 65,535 | ||||
Windows应用程序都是基于消息驱动的,应用程序通过消息与用户进行交互。消息分为标准Windows消息、控件通知消息和命令消息三大类,程序员需要为用户所关心的消息建立消息映射并编写具有特定功能的消息处理函数
消息的种类
l .标准Windows消息
标准Windows消息主要分为三类。
(1)键盘消息
(2)鼠标消息
(3)窗口消息
l .控件消息
l .命令消息
消息的结构
MSG结构在头文件中定义如下:
typedef struct tagMSG
{
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt;
} MSG, *PMSG;
MSG数据成员意义如下:
参数1:hwnd是消息要发送到的那个窗口的句柄,这个窗口就是咱们用CreateWindows函数创建的那一个。如果是在一个有多个窗口的应用程序中,用这个参数就可决定让哪个窗口接收消息。
参数2:message是一个数字,它唯一标识了一种消息类型。每种消息类型都在Windows文件中定义了,这些常量都以WM_开始后面带一些描述了消息特性的名称。比如说当应用程序退出时,Windows就向应用程序发送一条WM_QUIT消息。
参数3:一个32位的消息参数,这个值的确切意义取决于消息本身。
参数4:同上。
参数5:消息放入消息队列中的时间,在这个域中写入的并不是日期,而是从Windows启动后所测量的时间值。Windows用这个域来使用消息保持正确的顺序。
参数6:消息放入消息队列时的鼠标坐标.
消息循环以GetMessage调用开始,它从消息队列中取出一个消息:
GetMessage(&msg,NULL,0,0),第一个参数是要接收消息的MSG结构的地址,第二个参数表示窗口句柄,NULL则表示要获取该应用程序创建的所有窗口的消息;第三,四参数指定消息范围。后面三个参数被设置为默认值,这就是说你打算接收发送到属于这个应用程序的任何一个窗口的所有消息。在接收到除WM_QUIT之外的任何一个消息后,GetMessage()都返回TRUE。如果GetMessage收到一个WM_QUIT消息,则返回FALSE,如收到其他消息,则返回TRUE。因此,在接收到WM_QUIT之前,带有GetMessage()的消息循环可以一直循环下去。只有当收到的消息是WM_QUIT时,GetMessage才返回FALSE,结束消息循环,从而终止应用程序。 均为NULL时就表示获取所有消息。
消息用GetMessage读入后(注意这个消息可不是WM_QUIT消息),它首先要经过函数TranslateMessage()进行翻译,这个函数会转换成一些键盘消息,它检索匹配的WM_KEYDOWN和WM_KEYUP消息,并为窗口产生相应的ASCII字符消息(WM_CHAR),它包含指定键的ANSI字符.但对大多数消息来说它并不起什么作用,所以现在没有必要考虑它。
下一个函数调用DispatchMessage()要求Windows将消息传送给在MSG结构中为窗口所指定的窗口过程。我们在讲到登记窗口类时曾提到过,登记窗口类时,我们曾指定Windows把函数WindosProc作为咱们这个窗口的窗口过程(就是指处理这个消息的东东)。就是说,Windows会调用函数WindowsProc()来处理这个消息。在WindowProc()处理完消息后,代码又循环到开始去接收另一个消息,这样就完成了一个消息循环
相关文章推荐
- 学习算法你必须知道的一些基础知识(文末福利)
- Python学习第三章《字符串》(成为高手前必须知道的一些基础知识)
- Python学习第三章《变量》(成为高手前必须知道的一些基础知识)
- 学习Linux必须掌握的一些基础知识
- Java 7之基础 - 学习Java类必须知道的几点
- 一些必须知道的JAVA基础知识
- 学习spring必须java基础知识-PropertyEditor
- 【学习DIV+CSS】1. 你必须知道的三个知识
- 学习CSS需要知道的CSS基础知识
- 3. NHibernate基础知识 - 你必须知道的一些事情
- 学习JavaScript必须掌握的基础知识
- Java初学者必须知道的11条基础知识
- VC基础数据类型大全(学习VC必须知道的)
- 学习python的第三十九天-第二章 python必须知道的基础语法
- XML初学者必须知道的十条基础知识
- jquery必须知道必须熟悉的基础知识
- Scrum Master 面试题 – 你必须知道的22个Scrum基础知识
- Java必须知道的基础知识
- 据说程序员是最爱学习的群体,IT男都知道,这个行业日新月异,必须不断地学习新知识,不断地为自己注入新鲜的血液,才能使自己跟上技术的步伐。 今天我们来讲一下Android中BroadcastReceiv
- Scrum Master 面试题 – 你必须知道的22个Scrum基础知识