|
windows sdk编程系列文章 ---- 消息框
网站:http://edu.teamsourcing.com.cn
在本课中,我们将用C语言写一个 Windows 程序,程序运行时将弹出一个消息框并显示"hello world"。
理论:
Windows 为编写应用程序提供了大量的资源。其中最重要的是Windows API (Application Programming Interface)。 Windows API是一大组功能强大的函数,它们本身驻扎在 Windows 中供人们随时调用。这些函数的大部分被包含在几个动态链接库(DLL)中,譬如:kernel32.dll、 user32.dll 和 gdi32.dll。 Kernel32.dll中的函数主要处理内存管理和进程调度;user32.dll中的函数主要控制用户界面;gdi32.dll中的函数则负责图形方面的操作。除了上面主要的三个动态链接库,您还可以调用包含在其他动态链接库中的函数,当然您必须要有关于这些函数的足够的资料。
动态链接库,顾名思义,这些 API 的代码本身并不包含在 Windows 可执行文件中,而是当要使用时才被加载。为了让应用程序在运行时能找到这些函数,就必须事先把有关的重定位信息嵌入到应用程序的可执行文件中。这些信息存在于引入库中,由链接器把相关信息从引入库中找出插入到可执行文件中。您必须指定正确的引入库,因为只有正确的引入库才会有正确的重定位信息。
当应用程序被加载时 Windows 会检查这些信息,这些信息包括动态链接库的名字和其中被调用的函数的名字。若检查到这样的信息,Windows 就会加载相应的动态链接库,并且重定位调用的函数语句的入口地址,以便在调用函数时控制权能转移到函数内部。
如果从和字符集的相关性来分,API 共有两类:一类是处理 ANSI 字符集的,另一类是处理 UNICODE 字符集的。前一类函数名字的尾部带一个"A"字符,处理UNICODE的则带一个"W"字符(我想"W"也许是代表宽字符的意思吧)。我们比较熟悉的ANSI字符串是以 NULL 结尾的一串字符数组,每一个ANSI字符是一个 BYTE 宽。对于欧洲语言体系,ANSI 字符集已足够了,但对于有成千上万个唯一字符的几种东方语言体系来说就只有用 UNICODE 字符集了。每一个 UNICODE 字符占有两个 BYTE 宽,这样一来就可以在一个字符串中使用 65336 个不同字符了。
几乎每一个API都有处理这两种字符集的形式,例如:MessageBoxA和MessageBoxW, 其中MessageBoxA是适用于处理ANSI字符集的API。MessageBoxW是适用于UNICODE字符集的API。在c中为了调用方便,对这两个API进行了宏定义。统一使用MessageBox 。编译的时候会根据编译设置决定是使用MessageBoxA还是使用MessageBoxW。
下面摘自WINUSER.H中关于MessageBox 的定义。
WINUSERAPI
int
WINAPI
MessageBoxA(
HWND hWnd ,
LPCSTR lpText,
LPCSTR lpCaption,
UINT uType);
WINUSERAPI
int
WINAPI
MessageBoxW(
HWND hWnd ,
LPCWSTR lpText,
LPCWSTR lpCaption,
UINT uType);
#ifdef UNICODE
#define MessageBox MessageBoxW
#else
#define MessageBox MessageBoxA
#endif
其中WINUSERAPI 是一个宏,该宏定义了其修饰的函数是从其他库中导入的,还是自身定义的。
#if !defined(_USER32_)
#define WINUSERAPI DECLSPEC_IMPORT
#else
#define WINUSERAPI
#endif
为了两种字符集都可以支持,在处理字符时,我们使用_T("")宏。该宏会根据你的设置,将你的字符串转变为相应的字符集。
例子:(见光盘Helloword)
#include "windows.h"
#include "tchar.h"
int _stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
MessageBox(NULL,_T("hello world"),_T("My First Windows Program"),MB_OK);
return 1;
}
分析:
当我们在工程中Settings里面设置如下图所示的UNICODE,_UNICODE时,代码中的_T("hello world")和_T("My First Windows Program")编译时都转化为unicode字符。MessageBox也会使用MessageBoxW函数。
如果按照下图的设置,使用_MBCS. 代码中的_T("hello world")和_T("My First Windows Program")编译时都转化为ANSI字符。MessageBox也会使用MessageBoxA函数。
由于WINDOWS 2000以上内核都是采用UNICODE字符集,因此在这样的系统环境下,对于MessageBoxA函数的调用,最终会转化为MessageBoxW的函数调用。从运行效率上讲,采用UNICODE字符集,无需这种转换,运行效率高。然而使用ANSI,存储空间占用小。本质上讲,还是空间换时间的问题。 |
|