juliusun.com
看了几页基础知识,到本页终于开始写代码了。
MessageBox详细用法,可以点击 MessageBox用法。
为了让代码能同时在ANSI和UNICODE下运行,VC对代码通用做了工作。VC定义了TCHAR类型,当编译选项设置默认编码为ANSI时,TCHAR就是char类型,当为UNICODE时,TCHAR就是WCHAR类型。同样VC还定义了_T()、_TEXT()和TEXT()带有参数的宏,_T、_TEXT和TEXT是一回事,用法相同,仅以TEXT宏为例。TEXT()括号里面接字符或字符串,如TEXT("abcd")或TEXT('a')。当编译译设置默认编码为ANSI时TEXT("abcd")就是"abcd",TEXT('a')就是'a',当为UNICODE时,TEXT("abcd")为L"abcd",TEXT('a')为L'a',这样就通用化了。要使用这些功能,请包含tchar.h头文件。
再介绍一种类型:LPTSTR类型,LPTSTR,即TCHAR *类型。在ANSI环境下,就是LPSTR类型;在UNICODE下,就是LPWSTR类型。
STR一般代表ANSI字符串,WSTR一般代表UNICODE字符串,TSTR代表自动适应编译器环境编码的类型。CHAR是ANSI字符类型,WCHAR是UNICODE字符类型,TCHAR是自动适应类型。一般规律,在字符或字符串方面,含有T前缀的为自动适应类型,含有W前缀的为UNICODE类型,没有前缀的为ANSI类型。
以后我们称自动适合版本为TCHAR版本。
再介绍一种新的数据类型:HINSTANCE类型,HINSTANCE类型为实例句柄类型。事实上,在内部,它是一种指针类型,不过系统就会把他当作指针来用。你可以把它当作一种新的类型。这种类型是用来唯一的标识实例的。解释下实例:在程序运行前,系统会把这个程序文件连同权限、资源等信息作为依据,创建一个进程。一个程序启动两次当然算两个进程。你可以简单的认为,这个进程就是实例。这么多实例如何区分,就是通过实例句柄,你可以认为实例句柄是实例的标识符。好比学校通过学号标识每一个学生,国家通过身份证号标识一个人,学号、身份证号就是标识符。每个进程在系统中都有唯一的标识符。系统可以通过不同的实例句柄,来唯一的确定一个实例。
在C语言里,main函数是入口函数,先于其它函数执行,我们要在main函数里写我们需要的代码。但是,在Win32里,WinMain函数才是入口函数。WinMain函数有ANSI和UNICODE两个版本。我们来看一下WinMain函数原型(函数原型由返回类型、函数名和参数列表三部分组成)。 ANSI版本: int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) UNICODE版本: int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) 自适应版本: int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) ANSI版本和UNICODE版本,函数名不同,由ANSI的WinMain变成了Unicode的wWinMain,第三个参数不同由LPSTR变成了LPWSTR,其它相同。方便解释,换种格式,ANSI版本的注释,适合另外两个版本: ANSI版本: int APIENTRY WinMain( HINSTANCE hInstance, //实例句柄 HINSTANCE hPrevInstance, //为了兼容16位而保留,现已废弃不用,恒为NULL LPSTR lpCmdLine, //命令行参数 int nCmdShow //窗口显示方式 )
UNICODE版本: int APIENTRY wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow ) 自适应版本: int APIENTRY _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow ) WinMain函数返回值是int类型。WinMain参数现在用不到,我们暂时用不着参数,忽略即可。有个很奇怪的东西,就是int后面有个APIENTRY,这个在学习C语言时没有接触过,这是VC的一个宏,是__stdcall,是一种调用约定。初学先不必深入研究,只要知道约定描述符是放在返回类型后、函数名前即可。
在标准C语言里,最常用的头文件是stdio.h。在Windows编程里,最常用的是Windows.h。我们可以写Windows程序代码了,这个程序什么都不干,执行的过程就进直接退出。
我们写一个简单的Windows程序代码: UNICODE版本(适用Visual C++或Visual Studio 2010等): #include int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd) { return 0; } ANSI版本(适用于Visual C++ 6.0等): #include int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { return 0; } TCHAR通用版本(注意TCHAR版本要包含tchar.h头文件): #include #include int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd) { return 0; } 以上代码只看自己需要的版本即可,给出多个版本是考虑到大家编译器使用习惯。未特殊说明,给出多个版本时,均只需要看自己对应的版本即可。
如果你喜欢某一编译器,但是不喜欢默认的字符集,通常情况下,不需要更换编译器,可以在设置中修改默认字符集编码,如VS2010设置选项在“项目属性”-“配置属性”-“常规”-“字符集”中。
上面的代码运行时没有效果,我们再补充一点简单的知识,再创建一个简单对话框程序,就能看出效果了。
在VC中有一种类型叫句柄类型(事实上是复杂的C标准指针类型),句柄用来唯一标识一个对象(这个对象是指系统内核对象,不是面向对象编程中的实例化对象),如实例句柄用来唯一地标识一个实例对象,窗口句柄用来唯一的标识一个窗口对象,字体句柄用来唯一的标识一个字体对象。Windows内核对象有很多种,不一一列举,遇见提及即可。
下面我们介绍一个简单的API函数:MessageBox。MessageBox有两个版本,分别是ANSI版本和UNICODE版本,ANSI版本的函数名为MessageBoxA,UNICODE版本的函数名为MessageBoxW。这里只说明TCHAR版本,另外两个版本大家根据基础可以推测出来,以后都将只说TCHAR版本。调用形式为MessageBox( HWND hWnd, //拥有者窗口句柄 LPTSTR lpText, //提示字符串 LPTSTR lpCaption, //标题 UINT uType //类型 );
注意:严格来说,Windows没有提供MessageBox供开发都调用,Windows只是提供了MessageBoxA和MessageBoxW两个API。VC通过宏定义根据默认编码是ANSI或UNICODE把MessageBox定义成了MessageBoxA或MessageBoxW。开发者完全可以手动调用MessageBoxA或是MessageBoxW,不存在任何问题。
注意:在参数或返回值涉及到字符串时,通常情况API都有ANSI和UNICODE两个版本,ANSI版本通常以A为后缀,如MessageBoxA;UNICODE版本通常以W为后缀,如MessageBoxW。而不以A或W为后缀的API,通常是TCHAR版本,我们经常用的就是这个版本。为了方便说明,以后教程中经常以TCHAR版本的函数名代替以A或W为后缀的API。但是读者要理解,系统不是提供TCHAR版本的API名称的,是VC通过宏定义转化而来的。
注意:Windows系统提供的API接口没有TCHAR版本,TCHAR是VC自行定义的版本。实际TCHAR内部还是调用ANSI版本或是UNICODE版本API。
注意区分:以前提到过,在涉及到字符或字符串时。WinNT内核在执行ANSI版本API时,内部也是将ANSI字符或字符串转换成UNICODE,再调用UNICODE版本API,不过这是Windows内部问题。Windows提供给开发者的接口确实同时存在ANSI和UNICODE两种接口。 一般情况下,API在不涉及到字符或字符串的情况下,只会有一个版本,不存在ANSI或是UNICODE的问题,当然,API函数名称通常也不会包含A或W后缀。
下面我们编写一个弹出简单对话框的程序,代码如下: UNICODE版本: #include int APIENTRY wWinMain(HINSTANCE h,HINSTANCE hPrev,LPWSTR lpCmdLine,int nShow) { MessageBox(NULL,L"这里是内容",L"标题",MB_OK); return 0; } ANSI版本: #include int APIENTRY WinMain(HINSTANCE h,HINSTANCE hPrev,LPSTR lpCmdLine,int nShow) { MessageBox(NULL,"这里是内容","标题",MB_OK); return 0; } TCHAR版本(注意包含tchar.h头文件): #include #include int APIENTRY _tWinMain(HINSTANCE h,HINSTANCE hPrev,LPTSTR lpCmdLine,int nShow) { MessageBox(NULL,TEXT("这里是内容"),TEXT("标题"),MB_OK); return 0; } 程序运行效果类似下图:
终于见到窗口了。
说明:MessageBox就是根据参数弹出一个对话框,第一个参数是拥有者窗口句柄,我们设置为空即可,以后学习大家会多多了解窗口和窗口句柄。第二个参数是内容字符串,第三个参数是标题。第四个参数是UNIT类型参数,这里用的是MB_OK,通过VC-转到定义功能,我们会发现MB_OK是一个宏,值为0。定义形式为#define MB_OK 0。MB_OK的值标识这个对话框的类型是确定对话框。MessageBox这个API我们以后会常用,以后再详细一点介绍。
作者QQ:3304576112 交流QQ群:316930386 本教程内容由 juliusun.com 保留版权,请匆复制传播。
京ICP备15039193号-1