Windows 数据类型
2.1.1 常用Windows 数据类型演示
要熟练使用 Windows API 必须要熟悉 Windows 数据类型。
这些数据类型是 Windows特有的, 在 SDK 的相关头文件中有定义。
在众多的 Windows 数据类型中, 最常用的有 DWORD、HANDLE,LPTSTR,WORD、 BYTE、CHAR 等。 在 Windows 系统中, DWORD 用于表示无符号整型的数据, 意为 double word, 32 位。
在一般情况下 BYTE 是 8 位 的 * 而 WORD 是 16 位, DWORD 就是 32 位的。
这里书本中此章节没有提到x64位的数据类型,x64位的数据就是DWORD64 ,这里具体可以到"WinUser.h"中自行查看。
Windows 系统的应用程序中还具有一个特有的数据类型—HANDLE,通常 HANDLE 类型的变量用于唯一标识一个“ 对象”, 如窗口、 控件、 文件等, 平台中存在众多这样的对象,对象是程序操作的目标。 HANDLE 也是一个 32 位的数据类型。
0X1 DWORD/LPSTR/CHAR/INT
课本中的实例代码:
#include <windows.h>
#include <stdio.h>
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR iCmdLine,
int nCmdShow)
{
//定义字符串
LPSTR szString ="Windows 字符串数据类型;
//定义字符数组
CHAR lpString[120]; //要大于szString的长度
//定义DWORD类型的数据
DWORD dwMax = 0xFFFFFFFF;
DWORD dwOne = 0x1;
//定义INT类型的数据
INT iMax = 0xFFFFFFFF;
INT iOne = 0x1;
//显示字符串
MessageBox(NULL, szString,"LPSTR", MB_OK);
//复制内存,将字符串复制到数组中(包括NULL结束符)
CopyMemory(lpString, szString, lstrlen(szString) + 1);
//显示复制的字符串
MessageBox(NULL, lpString, "CHAR[]"), MB_OK);
//比较DWORD并显示结果
if (dwMax > dwOne)
{
MessageBox(NULL, "DWORD 类型的数据 0xFFFFFFFF>0x1","DWORD", MB_OK);
}
//比较INT并显示结果
if (iMax < iOne)
{
MessageBox(NULL, "INT类型的数据0xFFFFFFFF<0x1", "INT", MB_OK);
}
return 0;
}
这里我这边这么写的话除了很多错误,这里可能是版本问题,把.cpp文件改成.c文件能解决一小部分问题
但是还是有很多错误,进本都是处在LPSTR 这个类型上面,而且MessageBox全是乱码,所以考虑可能是编码问题,然后我搜索了一下如下:
注意事项:
VS2012以后版本中默认编码字符集为Unicode,LPSTR被LPCWSTR取代。几乎所有之前版本中形参类型为LPSTR的函数都被改成了形参类型为LPCWSTR,比如CreateWindow的第一和第二个形参。
所以在VS2012以后版本中应避免使用LPSTR而改成LPCWSTR。
另外,若是传入字符串常量必须使用TEXT()宏,否则会报错为类型不匹配。
按照自己的思路,把代码修改了下:
int WINAPI WinMain(_In_ HINSTANCE hInstance,_In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR iCmdLine, _In_ int nCmdShow)
{
//定义字符串
LPCWSTR szString =TEXT("Windows 字符串数据类型");
//定义字符数组
CHAR lpString[MAX_PATH] = { 0 }; //要大于szString的长度
//定义DWORD类型的数据
DWORD dwMax = 0xFFFFFFFF;
DWORD dwOne = 0x1;
//定义INT类型的数据
INT iMax = 0xFFFFFFFF;
INT iOne = 0x1;
//显示字符串
MessageBox(NULL, szString,TEXT( "LPSTR"), MB_OK);
//复制内存,将字符串复制到数组中(包括NULL结束符)
CopyMemory(lpString, szString, lstrlen(szString)*2 + 1);
//显示复制的字符串
MessageBox(NULL, (LPCWSTR) lpString, TEXT("CHAR[]"), MB_OK);
//比较DWORD并显示结果
if (dwMax > dwOne)
{
MessageBox(NULL, TEXT("DWORD 类型的数据 0xFFFFFFFF>0x1"),TEXT( "DWORD"), MB_OK);
}
//比较INT并显示结果
if (iMax < iOne)
{
MessageBox(NULL,TEXT( "INT类型的数据0xFFFFFFFF<0x1"), TEXT("INT"), MB_OK);
}
return 0;
这样就没有错误了,而且编译也不乱码,程序逻辑也没有问题。
在 Visual Studio 中可以查看数据类型的定义,再定数据类型的类型名上点击右键转到定义就可以。
typedef int INT;
typedef unsigned long DWORD;
typedef char CHAR;
这就可以看出 有符号和无符号的区别,dwMax是无符号整形就是 “4294967295 ”
有符号整形INT的iMax实际是“-1”。
0X2 最常见的Windows数据类型
类 型 | 描 述 |
---|---|
BOOL | 布尔型变量( 值只能是 True 或 False) |
BYTE | 字节类型( 8 位) |
CHAR | 8 比特字节(ANSI) |
CONST | 常量, 相当于标准 C 中的 const 关键字 |
DWORD | 32 字节无符号整型数据 |
DWORD32 | 32 字节无符号整型数据 |
DWORD64 | 64 字节无符号整型数据 |
FLOAT | 浮点数据类型 |
HANDLE | 对象的句柄, 最基本的句柄类型 |
HICON | 图标的句柄 |
HINSTANCE | 程序实例的句柄 |
HKEY | 注册表键的句柄 |
HMODULE | 模块的句柄 |
HWND | 窗口的句柄 |
INT | 32 位符兮整型数据类型 |
INT_PTR | 指向 INT 类型数据的指针类型 |
INT32 | 32 位符号整型 |
INT64 | 64 位符号整型 |
LONG | 32位符号整型,相当于 C 语言的标准数据类型 long |
LONGLONG | 64 位符号整型 |
LONG32 | 32 位符号整型 |
LONG64 | 64 位符号整型 |
LPARAM | 消息的 L 参数 |
WPARAM | 消息的 W 参数 |
LPCSTR | Windows ( ANSI) 宇符串常量 |
LPCTSTR | 据环境配置, 如果定义了 UNICODE 宏, 则是 LPCWSTR 类型, 否则是 LPCSTR 类型 |
LPCWSTR | UNICODE 字符串常量 |
LPDWORD | 指向 DWORD 类型数据的指针 |
LPSTR | Windows (ANSI)字符串变 |
LPTSTR | 根据环境配置, 如果定义了 UNICODE、 则是 LPWSTR 类型,否则是 LPSTR 类型 |
LPWSTR | UNICODE 字符串变量 |
SHOR | T 无符号短整型 (16 位) |
SIZE_T | 表示内存大小,以字节为单位, 其最大值是 CPU 最大寻址范围 |
TCHAR | 如果定义了 UNICODE, 则为 WCHAR, 否则为 CHAR |
UCHAR | 无符号 CHAR |
UINT | 无符号 INT |
ULONG | 无符号 LONG |
VOID | 无类型, 相当于标准 C 语言的 void |
WCHAR | 16 位 Unicode 字符 |
WINAPI | Windows API 的函数调用方式, 常见于 SDK 头文件中对 API 函数的声明中, 相当__stdcall (更严格地讲, 这不是数据类型, 而是一种函数调用约定) |
WORD | 16 位无符号整型数据 |
Windows数据类型不止上述表格列出类型,还包括其他很多种, 主要有各种数据的指针、 句柄、无符号类型等, 读者可以査看数据类型的定义来了解 Windows 数据类型。
0X3 数据类型的命名规律
这里推荐驼峰命名法。
基本数据类型包括 BYTE、 CHAR、 WORD,SHORT、 DOWRD、 INT 等 。
指针数据类型“LP”或“P”等,一般为 lpXxxxx或者pXxxx
句柄HANDLE 一般为hXxxxx
无符号“U”开头 一般为uXxxxx
2.1.2 Windows数据类型与标准C数据类型的关系
所有的 Windows 数据类型都是由 C 数据类型经过类型重定义得到的。
如 DWORD 实质上就是 unsigned long 数据类型, 32 位的无符号整型。
而将在 Windows 程序设计中经常用到的 HANDLE 类型实质上是无类型指针 void。
所有的 Windows 数据类型都是在 SDK 的头文件中进行定义的, 它们都是來源于标准 C 的数据类型。
而实际上 VC 编译器是一个完整的 C 编译器, 此外并没有过多的扩展。
Windows 数据类型也不是 VC 的内建类型, 而从标准 C 类型重定义得到。
2.1.3 Windows数据类型与与Windows API
Windows API 函数的参数、 返回值或一些重要的常量使用的数据类型都是 Windows 数据类型。
比如MessageBox:
int MessageBox(
HWND hWnd,
LPCTSTR lpText,
LPCTSTR lpCaption,
UINT uType);
可见MessageBox函数的返回值是int型的,是标准 C 数据类型, 但是所有的参数都使用了 Windows数据类型。如函数参数定义中如 HWND 是一种 Windows 数据类型, 用于表示窗口的句柄;: LPCTSTR 也是 Windows数据类型, 表示字符串常量; UINT 也是 Windows 数据类型, 为无符号整型。
再来看一个ReadFile函数:
BOOL Read File(
HANDLE hFile,
LPVOID lpBuffer,
DWORD nNumberOfBytesToRead,
LPDWORD lpNumberOfBytesRead,
LPOVERLAPPED lpOverlapped);
返回值类型是BOOL,值可以是TRUE,和FALSE。
HANDLE 是文件句柄类型
LPVOID 是无类型指针, 相当于 void *
DWORD 是无符号整型
LPDWORD 是指向 DWORD 类型数据的指针类型。
LPOVERLAPPED 是指向OVERLAPPED结构体的指针类型。
很多API函数采用结构体作为参数或者返回结果。
2.1.4 Windows中的数据结构
Windows 中包含很多种数据结构类型, 在不同类型的 API 中会使用到不同的数据结构,数据结构通常会作为一些 API 的参数输入。
先看一个数据结构WIN32_FILE_ATTRIBUTE_DATA的定义:
typedef struct _WIN32_FILE_ATTRIBUTE_DATA{
DWORD dwFileAttribuets;
FILETIME ftCreationTime;
FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime;
DWORD nFileSizeHigh;
DWORD nFileSizeLow;
}WIN32_FILE_ATTRIBUTE_DATA,*LPWIN32_FILE_ATTRIBUTE_DATA;
相当于
struct _WIN32_FILE_ATTRIBUTE_DATA{
DWORD dwFileAttribuets;
FILETIME ftCreationTime;
FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime;
DWORD nFileSizeHigh;
DWORD nFileSizeLow;
};
typedef _WIN32_FILE_ATTRIBUTE_DATA WIN32_FILE_ATTRIBUTE_DATA;
typedef _WIN32_FILE_ATTRIBUTE_DATA *LPWIN32_FILE_ATTRIBUTE_DATA;
对于有一定基础的读者,这样的数据结构定义应该很熟悉。
Windows SDK 中, 结构体也有自己的命名规范, 一般情况下, Windows 系统中使用全大写字母来命名结构体、 共用体, 并使用来分隔单词, 在结构名加“LP”或“P”表示指向数据结构的指针。