From:https://blog.csdn.net/a1459268562/article/details/70653695
MFC常用数据类型:https://www.cnblogs.com/xzxl/p/7955477.html
刚接触 MFC 的人一看到里面各种各样的关键字肯定傻眼了,仿佛完全是另外一门语言了,因为 MFC 中把 C++ 中的基本数据类型的关键字全改了一遍。这还不算变态,因为只是把小字改成大写。比较变态的是 MFC 里面是很多五花八门的类型实际上对应的是同一种基本类型。就算这样嘛多花点时间也还能熟悉。更加变态的是它还用自己的类型再定义其他类型。所有这些事都是用 typedef 这个宏干的。所以 MFC 里面到处是一堆堆的宏.
( 实际上准确的说很多类型是 Windows API 的数据类型,只不过有时在 MFC 用起来也混淆了。也不用去区分到底是 MFC 的还是API 的了,反正 MFC 说到底也只是通过 OO 手段对 API 的封装罢了 )
C++ 基本数据类型
类 型 字节数
bool 1
char 1
wchar_t 2 (宽字符类型,存储Unicode代码值.用法wchart_t letter = L'a')
short 2
unsigned short 2 (unsigned 表示无符号,只能取非负数.unsigned short num = 123U ; //数字后面的U可加可不加)
int 4 (整形默认为int,long型需在后加L,如long lNumber = 123L; //L可加可不加)
unsigned int 4 (可简写为unsigned)
long 4 (貌似不同的编译器中不一样,有时会是8,偶也不太确定)
__int64 8
unsigned long 4
float 4
double 8
long double 8 (有些地方貌似是12)
MFC 中与之对应的是
NULL 0
VOID void
BOOL int
CHAR char
CCHAR char
UCHAR unsigned char
BYTE unsigned char
WCHAR wchar_t
_TCHAR wchar_t
SHORT short
WORD unsigned short
USHORT unsigned short
INT int
UINT unsigned int
LONG long
DWORD unsigned long
ULONG unsigned long
LONGLONG __int64
ULONGLONG unsigned __int64
FLOAT float
DOUBLE double
在 MFC 中定义的基本变量
MFC 和 Win32 程序 共同使用的数据类型
下面这些是 MFC 和 wind 32 共同使用的数据类型
BOOL:布尔值,取值为TRUE or FALSE
BSTR:32-bit 字符指针
BYTE:8-bit整数,未带正负号
COLORREF:32-bit数值,代表一个颜色值
DWORD:32-bit整数,未带正负号
LONG:32-bit整数,带正负号
LPARAM:32-bit整数,作为窗口函数或callback函数的一个参数
LPCSTR:32-bit指针,指向一个常数字符串
LPSTR:32-bit指针,指向一个字符串
LPCTSTR:32-bit指针,指向一个常数字符串,此字符串可以移植到Unicode和DBCS
LPTSTR:32-bit指针,指向一个字符串,此字符串可以移植到Unicode和DBCS
LPVOID:32-bit指针,指向一个未指定类型的数据
LPRESULT:32-bit数值,作为窗口函数或callback函数的返回值
UINT:在Win16中是一个16-bit 未带正负号整数,在Win32中是一个32-bit 未带 正负号整数,
WNDPROC:32-bit指针,指向一个窗口函数
WORD:16-bit 整数 ,未带正负号
WPARAM:窗口函数或callback函数的一个参数,在Win16中是16-bit,在Win32中是32-bit
MFC 独特的数据类型
- POSITION:一个数值,代表collection对象(例如数组或链表)中的元素位置,常用于MFC collection classes(即数据处理类,如CArray)
- LPCRECT:32-bit指针,指向一个不变的RECT结构
- L 表示 long 指针, 这是为了兼容 Windows 3.1 等 16 位操作系统遗留下来的, 在 win32 中以及其他的 32 为操作系统中, long 指针 和 near 指针及 far 修饰符 都是为了兼容的作用。没有实际意义。
- P 表示这是一个指针
- C 表示是一个常量
- T 在 Win32 环境中, 有一个 _T 宏, 这个宏用来表示你的字符是否使用 UNICODE,如果你的程序定义了 UNICODE 或者其他相关的宏,那么这个字符 或者 字符串 将被作为 UNICODE 字符串,否则就是标准的 ANSI 字符串。
- STR 表示这个变量是一个字符串。
所以 LPCTSTR 就表示一个指向常固定地址的可以根据一些宏定义改变语义的字符串。
同样, LPCSTR 就只能是一个ANSI字符串, 在程序中我们大部分时间要使用带T的类型定义。
LPCTSTR 等价于 const TCHAR *
1. 首先,MFC中 所有的变量 都从 小写 定义成了 大写。
( 当然小写的变量类型也可以继续使用 )如:
typedef int BOOL;//TRUE FALSE
typedef unsigned char BYTE;
typedef float FLOAT;
typedef int INT;
typedef char CHAR;
typedef short SHORT;
typedef long LONG;
typedef CHAR* PCHAR, LPSTR; //可写的字符指针变量
#ifndef VOID
#define VOID voidtypedef unsigned long DWORD; //双字
typedef unsigned short WORD; //单字
所有的无符号变量都加上 U 来区分。如:
typedef unsigned int UINT;
所有的指针类型变量都加上 P 来区分。如:
typedef FLOAT *PFLOAT;
typedef BOOL near *PBOOL;
typedef BOOL far *LPBOOL;
typedef BYTE near *PBYTE;
typedef BYTE far *LPBYTE;
typedef int near *PINT;
typedef int far *LPINT;
typedef WORD near *PWORD;
typedef WORD far *LPWORD;
typedef long far *LPLONG;
typedef DWORD near *PDWORD;
typedef DWORD far *LPDWORD;
typedef void far *LPVOID;
typedef CONST void far *LPCVOID;
//near和far是c语言相对古老的的用法,用于声明变量在内存中的远近(以前16位的dos操作系统,最大有64K的内存,紧缺的很~)。
所有的常量指针都使用 C。如:
typedef CONST void* LPCVOID;
typedef CONST CHAR *LPCSTR, *PCSTR; //只读的字符指针变量
2. 结构体类型。主要有三个,分别是:POINT、SIZE、RECT
typedef struct tagPOINT
{LONG x;LONG y;
} POINT, *PPOINT, *LPPOINT;//结构体别名typedef struct tagSIZE
{LONG cx;LONG cy;
} SIZE, *PSIZE, *LPSIZE;typedef struct tagRECT
{LONG left;LONG top;LONG right;LONG bottom;
} RECT, *PRECT, *LPRECT;
3. 最神奇的 **句柄类型** 。
句柄是一种故意隐藏了内容的结构体指针。看一下 HWND 的声明:
…
DECLARE_HANDLE (HWND);
…#define DECLARE_HANDLE(name) struct name##__{int unused;}; typedef struct name##__ *name
可以看到 HWND 就是结构体的指针,而结构体的内容是 unused,(拒绝使用~)。
- HWND 窗口句柄
- HINSTANCE 进程实例句柄
- HCURSOR 光标句柄
- HICON 图标句柄
- HMENU 菜单句柄
- HFONT 字体句柄
- HFILE 文件句柄
- 等
4. 最复杂的 **字符串指针类型**
首先,谈精简版的历史。很早以前,各国文字都有自己的编码方式,而且每个国家字符的字节也不一样(多字节字符)。后来,拥有了统一的编码方式,统一了编码 -- Unicode。
VS 中创建项目时,默认是 Unicode 编码的。可以使用 **wchar_t** 来声明 Unicode 编码的字符串,而且字符串声明时在前面加上 **L**。**TCHAR**是一个怪胎,他是 char 和 wchar_t 的自适应版。
const char * p = “aaa”; //内存中,每个a占有一个字节
const char * pc = “中国”;//内存中,每个汉字占有两个字节
const wchar_t * pU = L”aa”;//内存中,每个a占有两个字节
const wchar_t * pcU = L”中国”;//内存中,每个汉字占有一个字节
const TCHAR * s = L”aa”;//这个TCHAR声明时,必须声明成Unicode编码的串
/*//修改vs的编码方式为 ’多字节字符集’ 后const TCHAR *s =L”aa”;//这就会报错,因为这时候TCHAR是char类型const TCHAR *s =”aa”;//不会报错
*/
5. MFC 中的 指针类型
注意:据说 far、near 等关键字在16位的系统上有用处,在32位上没啥用处。
数据类型 含义
LPVOID typedef void far *
LPCVOID typedef CONST void far *
PWSTR , LPWSTR __nullterminated WCHAR *
PCWSTR ,LPCSWTR __nullterminated CONST WCHAR *
PTSTR,LPTSTR LPWSTR
PCTSTR , LPCTSTR LPCWSTRBSTR wchar_t字符指针。
原因: 1.typedef OLECHAR *BSTR 2.typedef WCHAR OLECHAR 3.typedef wchar_t WCHAR一堆宏绕来绕去真他娘的麻烦.
PSTR,LPSTR __nullterminated CHAR *
PCSTR ,LPCSTR typedef __nullterminated CONST CHAR *
LPCRECT typedef RECT FAR*
HANDLE typedef void*
HFILE typedef int
规律:
貌似前面加不加 L 都没啥区别,
P 自然就表示指针,
C 表示是指向常量的指针.
W 表示是宽字符指针
LPTSTR 如果在unicode中表示LPWSTR,否则表示LPSTR
LPCTSTR 如果在unicode中表示LPCWSTR,否则表示LPCSTR
// Windows 句柄类型 HANDLE32 位的无符号整数,用于标识
窗口句柄 HWND
实例句柄 HINSTANCE
光标句柄 HCURSOR
图标句柄 HICON
位图句柄 HBITMAP
菜单句柄 HMENU
设备描述句柄 HDC
钢笔句柄 HPEN
画刷句柄 HBRUSH
字体句柄 HFONT
文件句柄 HFILE
typedef struct tagRECT
{
LONG left;
LONG top;
LONG right;
LONG bottom;
} RECT, *PRECT, NEAR *NPRECT, FAR *LPRECT;
COLORREF DWORD
64位指针问题
define _W64 __w64
#if defined(_WIN64)
typedef __int64 INT_PTR, *PINT_PTR;
typedef unsigned __int64 UINT_PTR, *PUINT_PTR;
typedef __int64 LONG_PTR, *PLONG_PTR;
typedef unsigned __int64 ULONG_PTR, *PULONG_PTR;
#define __int3264 __int64
#else
typedef _W64 int INT_PTR, *PINT_PTR;
typedef _W64 unsigned int UINT_PTR, *PUINT_PTR;
typedef _W64 long LONG_PTR, *PLONG_PTR;
typedef _W64 unsigned long ULONG_PTR, *PULONG_PTR;
#define __int3264 __int32
#endif
typedef LONG_PTR LPARAM;
typedef LONG_PTR LRESULT;
typedef UINT_PTR WPARAM;
MFC/windows 基本数据类型详细介绍
#define FALSE 0 afx.h
#define TRUE 1 afx.h
#define NULL 0 afx.h
typedef void VOID winnt.h
// 短整型 typedef unsigned short
typedef unsigned short USHORT; windef.h
typedef unsigned short WORD; windef.h
typedef unsigned short wchar_t
typedef short SHORT; winnt.h
// 整型 typedef int
typedef int BOOL; // 取值为TRUE or FALSE windef.h
typedef int INT; windef.h
typedef unsigned int UINT; // 定义一个新的Win32数据类型,它会把一个参数强制转换成Windows3.x应用中的16位值 或Win32应用中的32位值windef.h
// 长整型typedef long
typedef unsigned long ULONG; windef.h
typedef unsigned long DWORD; windef.h
typedef DWORD COLORREF; windef.h
typedef long LONG; winnt.h
typedef __int64 LONGLONG; winnt.h
typedef unsigned __int64 ULONGLONG; winnt.h
typedef ULONGLONG DWORDLONG; winnt.h
// 浮点型
typedef float FLOAT; windef.h
typedef double DOUBLE; wtypes.h
// 字符类型typedef char
typedef char CHAR/CCHAR; winnt.h
typedef unsigned char UCHAR; windef.h
typedef unsigned char BYTE; windef.h
typedef wchar_t WCHAR; // 声明一个16位的UNICODE字符,用来表示世界上所有已知的书写语言的符号winnt.h
// 指向字符串的指针类型 LP*
/*以下为winnt.h的部分内容*/
// UNICODE (Wide Character) types
typedef wchar_t WCHAR; // wc, 16-bit UNICODE character
typedef __nullterminated WCHAR *NWPSTR, *LPWSTR, *PWSTR;
typedef __nullterminated CONST WCHAR *LPCWSTR, *PCWSTR;
// ANSI (Multi-byte Character) types
typedef CHAR *PCHAR, *LPCH, *PCH;
typedef __nullterminated CHAR *NPSTR, *LPSTR, *PSTR;
// 指向Windows字符串(以空字符结束)的32位指针char*
typedef __nullterminated CONST CHAR *LPCSTR, *PCSTR;
// 指向Windows常字符串(以空字符结束)的32位指针const char*
// Neutral ANSI/UNICODE types and macros
// tchar.h
#ifdef _UNICODE
typedef wchar_t _TCHAR;
typedef wchar_t TCHAR;
#else
typedef char _TCHAR;
typedef char TCHAR;
#endif
typedef LPWSTR PTSTR, LPTSTR;
//指向Windows字符串(以空字符结束)的32位指针,用于移植到双字节字符集
LPTSTR For Unicode platforms,it is LPWSTR,For ANSI and DBCS platforms,it is LPSTR
typedef LPCWSTR PCTSTR, LPCTSTR;
//指向Windows常字符串(以空字符结束)的32位指针const char* ,用于移植到双字节字符集
LPCTSTR For Unicode platforms, it is LPCWSTR, For ANSI and DBCS platforms, it is LPCSTR
typedef LPWSTR LP;
#define __T(x) x tchar.h // ndef _UNICODE
#define _T(x) __T(x) tchar.h
#define _TEXT(x) __T(x) tchar.h
#define __TEXT(quote) L##quote winnt.h // r_winnt
// 以上的 _T、__T、_TEXT、__TEXT、L宏使字符串会自动根据工程的版本(ANSI还是UNICODE)进行转化.
// 使代码不需修改自动适应ASNI和UNICODE版本
typedef WCHAR OLECHAR; // wtypes.h
typedef OLECHAR* BSTR; unsigned short* // wtypes.h
//函数参数、返回值类型
typedef UINT_PTR WPARAM; //窗口函数或callback函数的一个参数,在Win16中是16-bit,在Win32中是32-bit windef.h
typedef LONG_PTR LPARAM; //32位窗口函数或callback函数的一个参数windef.h
typedef LONG_PTR LRESULT; //32位作为窗口函数或callback函数的返回值windef.h
//指向函数的指针类型
typedef int (WINAPI* PROC)(); PROC //指向回调函数的指针
typedef LRESULT(CALLBACK* WNDPROC)(HWND, UINT, WPARAM, LPARAM);
// Windows 函数调用类型 __stdcall
#define CALLBACK __stdcall windef.h
#define WINAPI __stdcall windef.h
#define WINAPIV __cdecl windef.h
#define APIENTRY WINAPI windef.h
#define APIPRIVATE __stdcall windef.h
#define PASCAL __stdcall windef.h
// 关于调用宏参考http://blog.163.com/xiang_163_ok/blog/static/6171684520082161551829/
typedef void far* LPVOID; // 指向任意类型的指针windef.h
常用数据类型的使用
我们先定义一些常见类型变量借以说明
int i = 100;
long l = 2001;
float f=300.2;
double d=12345.119;
char username[]="女侠程佩君";
char temp[200];
char *buf;
CString str;
_variant_t v1;
_bstr_t v2;
一、其它数据类型 转换为 字符串
短整型(int)
itoa(i,temp,10); // 将i转换为字符串放入temp中,最后一个数字表示十进制
itoa(i,temp,2); // 按二进制方式转换长整型(long)
ltoa(l,temp,10);
二、从其它包含字符串的变量中获取指向该字符串的指针
CString变量
str = "2008北京奥运";
buf = (LPSTR)(LPCTSTR)str;BSTR 类型的 _variant_t 变量
v1 = (_bstr_t)"程序员";
buf = _com_util::ConvertBSTRToString((_bstr_t)v1);
三、字符串 转换为 其它数据类型
strcpy(temp,"123");短整型(int)
i = atoi(temp);长整型(long)
l = atol(temp);浮点(double)
d = atof(temp);
四、其它数据类型 转换到 CString
使用 CString 的成员函数 Format 来转换, 例如:整数(int)
str.Format("%d",i);浮点数(float)
str.Format("%f",i);字符串指针(char *)等已经被 CString 构造函数支持的数据类型可以直接赋值
str = username;
五、BSTR、_bstr_t 与 CComBSTR
CComBSTR、_bstr_t 是对 BSTR 的封装,BSTR 是指向字符串的32位指针。
char * 转换到 BSTR 可以这样: BSTR b=_com_util::ConvertStringToBSTR("数据"); //使用前需要加上头文件comutil.h
反之可以使用char *p=_com_util::ConvertBSTRToString(b);
六、VARIANT 、_variant_t 与 COleVariant
VARIANT 的结构可以参考头文件VC98\Include\OAIDL.H 中关于结构体tagVARIANT的定义。
对于VARIANT变量的赋值:首先给vt成员赋值,指明数据类型,再对联合结构中相同数据类型的变量赋值,举个例子:
VARIANT va;
int a = 2001;
va.vt = VT_I4; //指明整型数据
va.lVal = a; //赋值
对于不马上赋值的 VARIANT,最好先用 Void VariantInit(VARIANTARG FAR* pvarg); 进行初始化,其本质是将 vt 设置为VT_EMPTY,下表我们列举vt与常用数据的对应关系:
unsigned char bVal; VT_UI1
short iVal; VT_I2
long lVal; VT_I4
float fltVal; VT_R4
double dblVal; VT_R8
VARIANT_BOOL boolVal; VT_BOOL
SCODE scode; VT_ERROR
CY cyVal; VT_CY
DATE date; VT_DATE
BSTR bstrVal; VT_BSTR
IUnknown FAR* punkVal; VT_UNKNOWN
IDispatch FAR* pdispVal; VT_DISPATCH
SAFEARRAY FAR* parray; VT_ARRAY | *
unsigned char FAR * pbVal; VT_BYREF | VT_UI1
short FAR * piVal; VT_BYREF | VT_I2
long FAR * plVal; VT_BYREF | VT_I4
float FAR * pfltVal; VT_BYREF | VT_R4
double FAR * pdblVal; VT_BYREF | VT_R8
VARIANT_BOOL FAR * pboolVal; VT_BYREF | VT_BOOL
SCODE FAR * pscode; VT_BYREF | VT_ERROR
CY FAR * pcyVal; VT_BYREF | VT_CY
DATE FAR * pdate; VT_BYREF | VT_DATE
BSTR FAR * pbstrVal; VT_BYREF | VT_BSTR
IUnknown FAR * FAR * ppunkVal; VT_BYREF | VT_UNKNOWN
IDispatch FAR * FAR * ppdispVal; VT_BYREF | VT_DISPATCH
SAFEARRAY FAR * FAR * pparray; VT_ARRAY | *
VARIANT FAR * pvarVal; VT_BYREF | VT_VARIANT
void FAR * byref; VT_BYREF
_variant_t 是 VARIANT 的封装类,其赋值可以使用强制类型转换,其构造函数会自动处理这些数据类型。
例如:
long l = 222;
int i = 100;
_variant_t tVal(l);
tVal = (long)i;
COleVariant 的使用与 _variant_t 的方法基本一样,请参考如下例子:
COleVariant v3 = "字符串", v4 = (long)1999;
CString str = (BSTR)v3.pbstrVal;
long i = v4.lVal;
七、其它
对消息的处理中我们经常需要将 WPARAM 或 LPARAM 等32位数据(DWORD)分解成两个16位数据(WORD),
例如:
LPARAM lParam;
WORD loValue = LOWORD(lParam); // 取低16位
WORD hiValue = HIWORD(lParam); // 取高16位
对于16位的数据(WORD)我们可以用同样的方法分解成高低两个8位数据(BYTE),例如:
WORD wValue;
BYTE loValue = LOBYTE(wValue); // 取低8位
BYTE hiValue = HIBYTE(wValue); // 取高8位