WindowsAPI程序的入口函数为WinMain
下面是一个最基本的WinAPI程序,用于打印 “hello world”
#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;
}
运行结果如下:
分析源码内容:
其中MessageBox为窗口函数,前一个TEXT为内容,后一个TEXT为标题,
MB_OKCANCEL
表示消息框将显示一个“确定”按钮和一个“取消”按钮,MB_ICONINFORMATION
表示消息框将显示一个感叹号图标,MB_DEFBUTTON2
表示将第二个按钮(在这种情况下是“取消”按钮)设置为默认按钮,即我们对程序按下回车键的话会选择第二个选项执行。
这些函数句柄后面后会有详细表述,这里就不过多赘述了
此外,在上述示例代码中,WinMain函数中有四个函数参数,分别是:
-
1.HINCTANCE hInstance:
hInstance
是一个表示当前应用程序实例的句柄(handle)。使用hInstance
可以访问应用程序的资源,比如图标、对话框、菜单等。在编写 Windows 应用程序时,通常需要在启动应用程序时获取hInstance
,以便正确地加载和使用这些资源。 -
2.HINSTANCE hPrevInstace:
hPrevInstance
是一个表示先前实例的句柄(handle)的参数。这个参数通常用于指示先前运行的实例是否仍然在内存中。在早期的 Windows 版本中,当一个应用程序被启动时,Windows 会检查是否已经有一个相同的实例正在运行。如果是,则将先前的实例句柄传递给新实例,以便新实例可以与先前的实例进行通信或共享资源。但是,从 Windows XP 开始,这个参数始终为 NULL,因为 Windows 已经不再使用它来传递先前实例的句柄。因此,虽然hPrevInstance
参数仍然存在于 WinMain 函数的参数列表中,但它基本上被弃用了,现在几乎总是被设置为 NULL。在编写 Windows 应用程序时,通常不需要关注hPrevInstance
参数。 -
3.LPSTR lpCmdLine:这是一个指向应用程序命令行参数字符串的指针,不包括可执行文件名。要获取整个命令行,可以调用GetCommangLine函数,例如,在D盘下有一个111.txt文件,当我们用鼠标双击启动这个.txt文件的时候,我们先启动的是记事本程序,此时系统会将
D:\111.txt
作为命令行参数传递给记事本程序的WinMain函数,记事本程序在得到这个文件的路径后,就会在窗口中显示该文件。 -
4.int nCmdShow:指定应用程序最初如何显示,例如这里是正常显示,但我们还可以将窗口最大化显示等多种显示方式
介绍完了WinMain的参数,下面来讲一下MessageBox函数,其同样也包含四个参数:
int WINAPI MessageBoxW(
_In_opt_ HWND hWnd, //窗口句柄
_In_opt_ LPCWSTR lpText, //要显示的消息内容
_In_opt_ LPCWSTR lpCaption, //消息框标题
_In_ UINT uType); //消息框显示的图标和按钮样式
MessageBox
函数的功能是显示一个参数提示框,其中可以包含一个系统图标,一组按钮、一个消息标题和一条简短的消息内容,这个函数有很多常量,这里会一一给大家介绍
这里是一些按钮的样式:
常量 | 显示的按钮 |
---|---|
MB_ABORTRETRYIGNORE | 中止、重试和忽略 |
MB_CANCELTRYCONTINUE | 取消、重试和忽略 |
MB_HELP | 确定、帮助 |
MB_OK | 确定 |
MB_OKCANCLE | 确定、取消 |
MB_RETRYCANCEL | 重试、取消 |
MB_YESNO | 是、否 |
MB_YESNOANCEL | 是、否和取消 |
这是一些图标的样式:
常量 | 显示的图标 |
---|---|
MB_ICONEXCLAMATION | 感叹号图标 |
MB_ICONWARNING | 感叹号图标 |
MB_ICONINFORMATION | 在一个圆圈中有一个小写字母i组成的图标 |
MB_ICONASTERISK | 在一个圆圈中有一个小写字母i组成的图标 |
MB_ICONQUESTION | 问号图标 |
MB_ICONSTOP | 停止标志图标 |
MB_ICONERROR | 停止标志图标 |
MB_ICONHAND | 停止标志图标 |
虽然它们的描述相同,但具体的图标还是有一些区别的
下面是用来指定消息框默认按钮的参数,按下Enter键就相当于单击了这个按钮
常量 | 含义 |
---|---|
MB_DEFBUTTON1 | 第1个按钮是默认按钮 |
MB_DEFBUTTON2 | 第2个按钮是默认按钮 |
MB_DEFBUTTON3 | 第3个按钮是默认按钮 |
MB_DEFBUTTON4 | 第4个按钮是默认按钮 |
MessageBox函数执行成功会返回一个整数值,用于指明用户单击了哪个按钮,如下表
返回值 | 含义 |
---|---|
IDABORT | 单击了中止按钮 |
IDCANCEL | 单击了取消按钮,若消息框有取消按钮,则当按下Esc键或单击取消按钮时,函数都将返回IDCANCEL |
IDCONTINUE | 单击了继续按钮 |
IDIGNORE | 单击了忽略按钮 |
IDNO | 单击了否按钮 |
IDOK | 单击了确定按钮 |
IDRETRY | 单击了重试按钮 |
IDTRYAGAIN | 单击了重试按钮 |
IDYES | 单击了是按钮 |
下面是一个示例程序:
#include<Windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
int nRet=MessageBox(NULL, TEXT("Hello World"), TEXT("Caption"), MB_OKCANCEL | MB_ICONINFORMATION | MB_DEFBUTTON2);
switch (nRet) {
case IDOK:
MessageBox(NULL, TEXT("用户单击了确定按钮"), TEXT("Caption"), MB_OK);
break;
case IDCANCEL:
MessageBox(NULL, TEXT("用户单击了取消按钮"), TEXT("Caption"), MB_OK);
break;
}
return 0;
}
当我们单击确定或者取消时,就会显示对应的输出窗口。此外,在这段代码中,出现了非常重要的一个东西——TEXT宏,在头文件中有如下定义
#define __TEXT(quote) L##quote // r_winnt
#else /* UNICODE */ // r_winnt
#ifndef _TCHAR_DEFINED
typedef char TCHAR, *PTCHAR;
typedef unsigned char TBYTE , *PTBYTE ;
#define _TCHAR_DEFINED
#endif /* !_TCHAR_DEFINED */
typedef LPCH LPTCH, PTCH;
typedef LPCCH LPCTCH, PCTCH;
typedef LPSTR PTSTR, LPTSTR, PUTSTR, LPUTSTR;
typedef LPCSTR PCTSTR, LPCTSTR, PCUTSTR, LPCUTSTR;
typedef PZZSTR PZZTSTR, PUZZTSTR;
typedef PCZZSTR PCZZTSTR, PCUZZTSTR;
typedef PZPSTR PZPTSTR;
typedef PNZCH PNZTCH, PUNZTCH;
typedef PCNZCH PCNZTCH, PCUNZTCH;
#define __TEXT(quote) quote // r_winnt
#endif /* UNICODE */ // r_winnt
#define TEXT(quote) __TEXT(quote) // r_winnt
其中##
为”令牌粘贴“,表示把字母L和宏参数拼接在一起。例如,假设宏参数quote是”Hello“,那么L##quote
就是L"Hello"
。
也许用代码的形式会更加便于理解:
TCHAR szBuf[] = TEXT("C语言");
至此,我们对WinAPI也许有了一个大概的认知,这一节的内容已经可以带我们离开黑漆漆的控制台窗口,之后的程序会更加丰富多彩
佬真强