Windos系统提供了各种各样的函数,这些函数是windows操作系统提供给应用程序的接口 Application Progress Interface,所有主要的windows函数都在Windows.h头文件中进行了声明。
Win32 SDK(Soft Development Kit)是Windows 32平台下的软件开发包,包括API函数,帮助文档和一些辅助开发工具。
Windows是基于消息机制的,消息分标准消息,命令消息和通告消息。Windows程序中的消息又分进队消息和不进队消息,两种消息都由消息响应函数进行处理。
在VC中创建一个win32应用程序的大概流程如下:
编写WinMain函数
设计窗口类(WNDCLASS);
注册窗口类(RegisterClass);
创建窗口(CreateWindow);
显示并更新窗口(ShowWindow|UpdateWindow);
编写消息循环;
编写窗口过程函数。
一个WinMain函数的原型如下:
int WINAPI WinMain(
HINSTANCE hInstance, // handle to current instance
HINSTANCE hPrevInstance, // handle to previous instance
LPSTR lpCmdLine, // command line
int nCmdShow // show state
);此处WINAPI是一个_stdcall宏定义,VC有很多宏定义,这个很让人头大,需要慢慢去习惯,从网络上找了2中函数定义的说明与区别解释。
__cdecl:这是编译器默认的函数调用转换方式,它可以处理可变参数的函数调用。参数的入栈顺序是从右向左。在函数运行结束后,由调用函数负责清理入栈的参数。在编译时,在每个函数前面加上下划线(_),没有函数名大小写的转换。即_functionname。每一个调用它的函数都包含清空堆栈的代码,所以产生的可执行文件大小会比调用_stdcall函数的大。函数采用从右到左的压栈方式。
__stdcall:函数参数从右向左入栈,被调用函数负责入栈参数的清理工作。函数名转换格式如下:_functionname@number。函数参数个数固定。
WINDOWS 的函数调用时需要用到栈( STACK ,一种先入后出的存储结构)。当函数调用完成后,栈需要清除,这里就是问题的关键,如何清除?
如果函数使用 _cdecl ,那么栈的清除工作是由调用者,用 COM 的术语来讲就是客户来完成的。这样带来了一个棘手的问题,不同的编译器产生栈的方式不尽相同,那么调用者能否正常的完成清除工作呢?答案是不能。
如果使用 __stdcall ,上面的问题就解决了,函数自己解决清除工作。所以,在跨(开发)平台的调用中,我们都使用 __stdcall (虽然有时是以 WINAPI 的样子出现)。
那么为什么还需要 _cdecl 呢?当我们遇到这样的函数如 fprintf() 它的参数是可变的,不定长的,被调用者事先无法知道参数的长度,事后的清除工作也无法正常的进行,因此,这种情况我们只能使用 _cdecl 。
到这里有一个结论,如果你的程序中没有涉及可变参数,最好使用 __stdcall 关键字,我们创建一个Win32应用程序都是用的系统API函数,参数固定,所以都用__stdcall了。
设计窗口类、册窗口类、创建窗口、显示并更新窗口通常一起完成,MSDN中有详细的说明,可以根据一些默认参数修改窗口样式。在完成窗口的设计,创建更新后,需要创建一个消息循环。