兰陵月 发表于 2018-10-26 13:45:21

《WINDOWS程序设计》(026)2.3 宽字符和Windows-2.3.2 Windows函数调用

2.3.2Windows函数调用

    从Windows 1.0到Windows 3.1的过去的16位版本的Windows中,MessageBox函数是存在于动态链接库USER.EXE中的。在Windows 3.1软件开发工具包所包含的WINDOWS.H中,MessageBox函数的定义如下:
    int WINAPI MessageBox(HWND, LPCSTR, LPCSTR, UINT);
注意,函数的第二个和第三个参数是指向常量字符串的指针。当Windows编译和链接一个Win16程序时,它并不处理MessageBox调用。而是通过执行程序.EXE文件中的一张表格,允许Windows程序将该程序的调用与动态链接库USER中的MessageBox函数动态链接起来。

    而32位的Windows(这包括Windows NT的所有版本、Windows 95和Windows 98),除了含有与16位Windows兼容的USER.EXE外,还含有一个称为USER32.DLL的动态链接库,该动态链接库含有32位用户界面函数的入口点,其中包括了32位版本的函数MessageBox。

    但是Windows支持Unicode的关键是:在USER32.DLL中,并没有32位MessageBox函数的入口点。实际上,它有2个入口点,一个名为MessageBoxA(ASCII版),另一个名为MessageBoxW(宽字符版)。像这样的用字符串作参数的每个Win32函数,都在操作系统中有两个入口点!幸运的是,通常不必担心这个问题,只需在程序中调用MessageBox即可。像在TCHAR头文件中一样,每个Windows头文件都会使用些技巧。

    MessageBoxA在WINUSER.H中的定义如下。这与MessageBox早期的定义极其相似:
    WINUSERAPI int WINAPI MessageBoxA(HWND hWnd, LPCSTR lpText,LPCSTR lpCaption, UINT uType);
MessageBoxW的定义如下:
    WINUSERAPI int WINAPI MessageBoxW(HWND hWnd, LPCWSTR lpText,LPCWSTR lpCaption, UINT uType);
注意,MessageBoxW函数的第二个和第三个参数是指向宽字符的指针。

    如果需要在程序中混合调用并匹配ASCII和宽字符函数,则可以明确使用MessageBoxA和MessageBoxW函数。但大多数程序员会继续使用MessageBox。根据是否已定义UNICODE标识符,MessageBox将实际调用MessageBoxA或是MessageBoxW。下面演示了如何在WINUSER.H中轻松实现这一技巧:
    #ifdef UNICODE
    #define MessageBox MessageBoxW
    #else
    #define MessageBox MessageBoxA
    #endif
这样,如果定义了UNICODE标识符,那么程序中所有的MessageBox函数调用实际上就是MessageBoxW函数;否则,就是MessageBoxA函数。

    执行此程序时,Windows将程序中不同的函数调用与不同的Windows动态链接库的入口点链接在一起,不过,仍有少数几个例外,Windows98并不支持Unicode版的Windows函数。虽然这些函数也有入口点,但它们通常会返回错误代码。应用程序需要注意这些返回的错误并采取相应的合理动作。

newu 发表于 2018-10-28 22:28:16

这么认真的嘛{:10_266:}

兰陵月 发表于 2018-10-29 11:28:59

newu 发表于 2018-10-28 22:28
这么认真的嘛

呵呵,原文抄写,然后加相关个人学习理解。{:5_109:}
页: [1]
查看完整版本: 《WINDOWS程序设计》(026)2.3 宽字符和Windows-2.3.2 Windows函数调用