win32 API中的宽字符
什么是API
API(Application Programming Interface)应用程序接口,windows操作系统为我们提供已经实现好了的函数
几个重要DLL:
- kernel32.dll:最核心的功能模块,比如管理内存、进程和线程相关的函数等
- user32.dll:是Windows用户界面相关应用程序接口,如创建窗口和发送消息等
- GDI32.dll:全称是Graphical Device Interface(图形设备接口),包含用于画图和显示文本的函数
简单使用一个API
其实只要写过代码,就用API,只是不知道而已,比如printf,scanf等,一个打印,一个输入,这些也算API,需要包含stdio.h这个库,一样的
#include <windows.h>//要使用这个函数就要用这个库
int main()
{
MessageBox(0, 0, 0, 0);
return 0;
}
如代码所示,就是调用了一个弹窗的函数
因为什么都没写,所以才啥都没有,然后看看MessageBox的定义
可以在MSDN上看,也可以在micoft上看都可以
int MessageBox(
HWND hWnd,
LPCTSTR lpText,
LPCTSTR lpCaption,
UINT uType
);
可以看到这里参数类型,似乎不认识,其实不然,这些都是我们认识的类型换了个名字而已
比如,我是在VS2022里编译的
[index]
如果那个不认识,点击一下不认识的类型,按F12,就可以看到他到底是什么类型,如果还不认识,那就再来一次
hWnd,我记得是默认为0的,就不用管,是个句柄
以LPCTSTR为例
typedef LPCWSTR PCTSTR, LPCTSTR;
发现还是不认识,那就继续
typedef _Null_terminated_ CONST WCHAR *LPCWSTR, *PCWSTR;
可以发现是CONST WCHAR类型的了,如果还是不知道,那还是一样,
CONST
#define CONST const
WCHAR
typedef wchar_t WCHAR; // wc, 16-bit UNICODE character
所以他真实的类型就是const wchar_t LPCTSTR,所以不要被这些类型给迷惑了,无非就是给认识的类型套上了更华丽的衣服而已
常用的语言类型:
汇编 |
|
|
byte |
BYTE |
PBYTE |
word |
WORD |
PWORD |
dword |
DWORD |
PDWORD |
C/C++ |
|
|
char |
CHAR |
PCHAR |
unsigned char |
UCHAR |
PUCHAR |
short |
SHORT |
PSHORT |
unsigned short |
USHORT |
PUSHORT |
int |
INT |
PINT |
unsigned int |
UINT |
PUINT |
bool |
BOOL |
|
向上面的类型,都是从基本类型开始演化的,遇到不认识的就去查一查
好处是什么呢?
第一:全部统一成自己新定义的类型,可读性好
第二:利于跨平台和系统更新的代码修改
怎么合理使用win32 API的字符串
//字符
CHAR str[] = "吾爱破解";
WCHAR wstr[] = L"吾爱破解";
这里可以知道其实都是char类型,上面是ASCII码,下面是Unicode的编码形式
其实还有一种更加通用的方式
TCHAR tstr[] = TEXT("吾爱破解");
看看TCHAR
typedef WCHAR TCHAR
可以看到这是个WCHAR,其实这是个宏,看你当前编译器默认的编码格式是什么,编译的时候就会转成什么编码格式
有利程序跨平台
//字符指针
PSTR pstr = "吾爱破解";
PWSTR pwstr = L"吾爱破解";
PTSTR ptstr = TEXT("吾爱破解");
这个在VS2022中需要关闭个东西
char*的表达方式会造成程序崩溃,所以对其进行了控件管理。控件管理。
参考:“const char “ 类型的值不能用于初始化 “char “ 类型的实体的三种解决方法_const char " 类型的值不能用于初始化 "char " 类型的实体-CSDN博客
所以PSTR也就是char*,其他的也同理
然后回到MessageBox
#ifdef UNICODE
#define MessageBox MessageBoxW
#else
#define MessageBox MessageBoxA
#endif // !UNICODE
查看之后会发现其实没有MessageBox这个函数,只有MessageBoxA和MessageBoxW,所以MessageBox也只是跟TCHAR一样的方式而已,取决你的编译器而已
所以只要涉及到字符串的API,Windows都会设计两套方案,一套是ASCII码,一套是Unicode码
MessageBoxW的性能会更好,因为系统默认是宽字符,所以如果是ASCII码的话,到内核还要转成Unicode
传个真正的参数进去
//这是ASCII码的方式
CHAR a[] = "标题";
CHAR b[] = "欢迎来到吾爱大家庭";
MessageBoxA(0, b, a, 0);
return 0;
//这是Unicode码的方式
WCHAR a[] = L"标题";
WCHAR b[] = L"欢迎来到吾爱大家庭";
MessageBoxW(0, b, a, 0);
//这是通用的方式
TCHAR a[] = TEXT("标题");
TCHAR b[] = TEXT("欢迎来到吾爱大家庭");
MessageBox(0, b, a, 0);
还有一个参数是按钮类型,这里不多赘述
总结
- 所有类型都是从最基本的类型演化过来的,只是换了个名字
- 推荐使用通用的类型,方便跨平台