联系WeChat:i-xiaodi,交流,付费课程学习
简单介绍Windows API:
Windows API(Application Programming Interface)是Microsoft Windows平台的应用程序编程接口,其主要目的是让应用程序开发人员可以调用操作系统提供的一组例程功能,而无须考虑其底层的源代码实现及内部工作机制。API函数是构筑整个Windows框架的基石,它基于Windows的操作系统核心,上层是所有的Windows应用程序。
简单来说,这些API接口就是函数,就像C语言调用的stdio.h中的函数一样。只不过这些函数是微软提供给我们的,也放在了对应的头文件.h中,用到的时候包含相应的头文件即可。
创建一个使用Windows API的程序:
添加源文件,然后编译代码,生成程序
代码如下:
#include <Windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int
nCmdShow)
{
MessageBox(NULL, TEXT("Hello World!"), TEXT("Caption"), MB_OKCANCEL | MB_ICONINFORMATION | MB_DEFBUTTON2);
return 0;
}
弹出一个消息框,标题为Caption,内容为Hello World!
解释:
1.Windows.h
头文件,包含我们所用的一些函数的声明,比如WinMain(入口函数)、MessageBox(信息框)
2.WinMain函数
入口函数,类似于C语言的main函数,这个是Windows应用程序的入口函数
3.WINAPI
这个是函数的调用约定,只不过用宏进行了重新定义
拓展:
CALLBACK、WINAPI、APIENTRY等都代表__stdcall,__stdcall是一种函数调用约定,也称为标准调用约定。函数调用约定描述函数参数的传递方式和由谁来平衡堆栈,在程序中调用一个函数时,函数参数的传递是通过堆栈进行的,也就是说调用者把要传递给函数的参数压入堆栈,函数在执行过程中从堆栈中取出相应的参数使用。
4.批注
程序生成成功后,会出现绿色波浪线,提示批注不一致
我们转到WinMain函数的声明
我们可以看到微软WinMain函数声明的每个参数的数据类型前都有一个参数说明符:_In_、_In_opt_等,这些参数说明符称为参数批注。
我们只需要把微软正规的代码抄过来,就可以了。
关于批注:
参数批注用于说明函数参数的性质和类型,可以帮助开发人员更好地了解如何使用这些参数。
与上面4个参数批注对应的还有_In_opt_、_Inout_opt_、_Out_opt_和_Outptr_opt_,opt表示可选择(optional),表示可以不使用该参数,也可以设置为0或者NULL(0),而表格中的4个不带opt的参数批注表示该参数必须指定一个合理的值,也就是说,你必须得填。
在VS 2019以前,并不要求在函数声明和定义中设置参数批注,参数批注仅用于指导程序员正确使用函数参数。为了正规一些,我们列出参数批注更好一些,以帮助大家正确使用函数参数。
5.WinMain函数参数解释
一、_In_ HINSTANCE hInstance:
h是handle的首字母,表示当前应用程序的实例句柄,在Windows程序中句柄无非就是一个数值,程序中用它来标识某些对象,本次代码中hInstance实例句柄就唯一地标识了正在运行中的exe程序文件。
内存中的样子(随机基址)
固定基址(0x00400000)
拓展:
模块:
模块代表的是一个运行中的.exe或.dll文件,表示这个文件中的所有代码和资源。磁盘上的文件不是模块,载入内存后运行时叫作模块。另外,一个应用程序调用其他动态链接库中的API时,这些.dll文件也会被载入内存,这就产生了一些动态链接库模块。
因为有这么多的模块,所以,为了区分地址空间中的不同模块,每个模块都有一个唯一的模块句柄来标识。模块句柄实际上就是一个内存基地址,系统将.exe或.dll文件加载到地址空间的这个位置
实例:
实例的概念源于Win16,Win16系统中运行的不同程序的地址空间并非是完全隔离的。一个可执行文件运行后形成模块,多次加载同一个可执行文件时,这个模块是公用的。为了区分多次加载的“复制”,把每个“复制”叫作实例,每个实例均用不同的实例句柄(HINSTANCE)值来标识。
但在Win32中,每一个运行中的程序的地址空间是隔离的,每个实例都使用自己私有的4GB虚拟地址空间,不存在一个模块具有多个实例的问题。即使同一程序同时运行了多个,它们之间通常也是互不影响的。在Win32中,实例句柄就是模块句柄,但很多API函数中用到模块句柄的时候使用的名称还是实例句柄。
随着历史的发展与进步,很多词语已经不是他本来的含义,不过我们也能理解,这正是一种文化的延续。
二、_In_opt_ HINSTANCE hPrevInstance
表示应用程序上一个实例的句柄。在Win16中,当同时运行一个程序的多个副本时,同一程序的所有实例共享代码以及只读数据(例如菜单或对话框模板之类的资源),一个程序可以通过査看hPrevInstance参数从而得知是否有它的其他实例在运行,这样就可以把一些数据从前一个实例移到自己的数据区来。
对于Win32应用程序,该参数始终为NULL。这个是历史残留。
三、_In_ LPSTR lpCmdLine
指向应用程序命令行参数字符串的指针,不包括可执行文件名。要获取整个命令行,可以调用GetCommandLine函数。例如,在D盘下有一个111.txt文件,当我们用鼠标双击这个文件时将启动记事本程序(notepad.exe),此时系统会将D:\111.txt作为命令行参数传递给记事本程序的WinMain函数,记事本程序得到这个文件的路径后,在窗口中显示该文件的具体内容。
拓展:
关于LPSTR,LPSTR是一种Windows数据类型
_Null_terminated_表示以零结尾的字符串,LPSTR表示一个以零结尾的char类型字符串的指针。LPSTR中的LP是Long Pointer(长指针),这是Win16遗留的概念。在Win32中不区分长短指针,指针都是32位。以零结尾,有时候也称为以空字符结尾、以NULL结尾等。
四、_In_ int nShowCmd
指定应用程序最初如何显示,例如在任务栏上正常显示、最大化到全屏显示或最小化显示。