Win32学习
1、导入
关于Win32的错误认知:
(1)已经有malloc()函数了,为什么还要学Win32 API?
(2)学MFC就可以了,为什么要学Win32?
Win32课程包含的内容:
01、字符 09、文件系统
02、多线程 10、内存映射
03、线程同步 11、DLL
04、窗口的本质 12、远程注入
05、Windows消息机制 13、模块隐藏
06、子窗口的使用 14、进程通信
2、字符编码
在我们的Win32 编程中有许多的字符串,有些是ASCII码,有些是Unicode编码,Unicode编码又分为 UTF-8和UTF-16
①原始的ASCII编码:
ASCII ----- Ameriacan Standard Code for Information Interchange
②ASCII编码的扩展:GB2312或GB2312-80
将两个 ASCII码拼成一个 GBK(汉字编码)
很大的弊端:难以避免出现乱码(因为各个国家标准不尽相同)
③UNICODE编码 <1>什么是UNICODE? 这是一个编码方案,说白了就是一张包含全世界所有文字的一个编码表,只要这个世界上存在的文字符号,统统给你一个唯一的编码: Unicode编码范围是:0-0x10FFFF,可以容纳100多万个符号! <2> UNICODE的问题: Unicode只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。(因为Unicode可能是一个字节或者多个字节)
④如何存储UNICODE: UTF-16 / UTF-8 是Unicode的实现方式 <1> UTF-16(默认): UTF-16编码以16位无符号整数为单位,注意是16位为一个单位,不表示一个字符就只有16位。(即为一个存储单位是两个字节的大小)这个要看字符的unicode编码处于什么范围而定,有可能是2个字节,也可能是4个字节(当两个字节储存不下,就需要用两个单位的Unicode,而就是因为这种原因导致之后的网络传输,增大了传输的的大小,但是更加直观)现在机器上的unicode编码一般指的就是UTF-16。 <2> UTF-8: Unicode编码(16进制) || UTF-8 字节流(二进制) 000000 - 00007F || 0xxxxxxx 000080 - 0007FF || 110xxxxx 10xxxxxx 000800 - 00FFFF || 1110xxxx 10xxxxxx 10xxxxxx 010000 - 10FFFF || 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
UTF-8字节流中的xxxxx取出来转为16进制即为Unicode编码
UTF-16 的优点是:拆分解析的时候很简单,很直观
UTF-8 的优点是:节约空间,变长字符
在网络传输中,如果英文字母比较多的话,推荐使用UTF-8编码;如果中文汉字比较多的话,推荐使用UTF-16编码。
(以此推出 UTF-32即为所有编码都是四个字节,更加简洁明了,能够直接解析)
<3>BOM(Byte Order Mark 字节顺序标识):
UTF - 8 || EF BB BF
UTF - 16LE(小端存储) || FF FE
UTF - 16BE(大端存储) || FE FF
在文本文件的起始位置存储顺序标识,来表明自己是以什么方式存储的
3、C语言中的宽字符
①字符和字符串在内存中的值 我们观察以下在内存中的值: char szStr[] =“中国”; (vc6会默认以ASCII码的形式进行编码) wchar_t swzStr[]=L“中国”; (vc6这样表示字符串以Unicode格式进行编码)
且字符串结尾会有一个 "/0" 在 ASCII码中占一个字节,而在Unicode中最小的单位是两个字节,所以在Unicode编码中,结尾的 “/0” 占两个字节。
②打印宽字符
③字符串长度
char szStr]] = "中国";
wchar_t swzStr[] = L"中国";
strlen(szStr); //取得多字节字符串中字符长度,不包含00
wcslen(swzStr); //取得多字节字符串中字符长度,不包含00 00
④常用函数
char wchar_t //多字节字符类型 宽字符类型 printf wprintf //打印到控制台函数 strlen wcslen //获取长度 strcpy wcscpy //字符串复制 strcat wcscat //字符串拼接 strcmp wcscmp //字符串比较 strstr wcsstr //字符串查找
4、Win32 API 中的宽字符
①什么是Win32 API?有哪些?在哪里?
API (application process interface) 应用程序接口
主要是存放在 C:\WINDOWS\system32 下面所有的dll(实际上system32中存储的是 64位的dll,而sysWOW64中存储的是 32位的dll)
几个重要的DLL: <1> Kernel32.dll:最核心的功能模块,比如管理内存、进程和线程相关的函数等。 <2> User32.dll:是Windows用户界面相关应用程序接口,如创建窗口和发送消息等。 <3> GDI32.dll:全称是Graphical Device Interface(图形设备接口),包含用于画图和显示文本的函数。
②关于Win32的数据类型:
int MessageBox
{
HWND hWnd, //handle to owner window
LPCTSTR IpText, //text in message box
LPCTSTR IpCaption, //message box title
UINT uType // message box style
};
如果想要使用Win32 API 只需要包含 windows.h 这个头文件,初学者看到许多不认识的数据类型,可以通过编译器查询发现实际上的不同的数据类型,本质上都是我们所熟知的。
汇编: byte BYTE PBYTE word WORD PWORD dword DWORD PDWORD C语言: char CHAR PCHAR unsigned char UCHAR PUCHAR short SHORT PSHORT unsigned short USHORT PUSHORT int INT PINT unsigned int UINT PUINT
C++语言:
bool BOOL
而给类型起别名,是为了适应不同的平台以及版本的更新,如果出现需要修改,可以直接在宏定义中修改,程序可以不做任何的变动。
④在Win32中使用字符串:
字符类型: CHAR szStr[] = "中国”; //ASCII WCHAR swzStr[] = L"中国”; //Unicode TCHAR stzSr[] = TEXT(“中国”); //能够自动的选择默认的编码格式,更适应跨平台操作 字符串指针: PSTR pszStr = “中国”; PWSTR pwszStr =L“中国”; PTSTR ptszStr = TEXT("中国”);
因为编码格式的不同,Win32 API中的函数都是提供的两份函数,一个是 ASCII 码,一个是Unicode编码的。
在理论上来讲,在Windows 内核当中所有的字符串都是宽字符的,使用Unicode编码格式更好,不需要重复转化,性能更加的好。
⑤第一个Win32 API的使用:
CHAR szTitle[]= "标题";
CHAR szContent]= "欢迎大家来的Win32 API世界!";
MessageBoxA(O,szContent,szTitle,MB_OK);
WCHAR swzTitle[]=L"标题";
WCHAR swzContent[]= L"欢迎大家来的Win32 API世界!";
MessageBoxW(O,swzContent,swzTitle,MB_OK);
TCHAR stzTitle[] = TEXT("标题"); //第三个是自动适配的
TCHAR stzConten[]=TEXT("欢迎大家来的Win32 API世界!");
MessageBox(0,stzContent,stzTitle,MB_OK);