《MFC初探》之变量类型

 

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 void

typedef unsigned long       DWORD; //双字
typedef unsigned short      WORD;  //单字

所有的无符号变量都加上 来区分。如:

typedef unsigned int        UINT;

所有的指针类型变量都加上 来区分。如:

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        LPCWSTR

BSTR                    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               COLORREFwindef.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/CCHARwinnt.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位

 

 

 

  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值