《MFC初探》之变量类型
?
From:https://blog.csdn.net/a1459268562/article/details/70653695
MFC常用數(shù)據(jù)類型:https://www.cnblogs.com/xzxl/p/7955477.html
?
?
剛接觸 MFC 的人一看到里面各種各樣的關(guān)鍵字肯定傻眼了,仿佛完全是另外一門語言了,因?yàn)?MFC 中把 C++ 中的基本數(shù)據(jù)類型的關(guān)鍵字全改了一遍。這還不算變態(tài),因?yàn)橹皇前研∽指某纱髮憽1容^變態(tài)的是 MFC 里面是很多五花八門的類型實(shí)際上對應(yīng)的是同一種基本類型。就算這樣嘛多花點(diǎn)時間也還能熟悉。更加變態(tài)的是它還用自己的類型再定義其他類型。所有這些事都是用 typedef 這個宏干的。所以 MFC 里面到處是一堆堆的宏.
( 實(shí)際上準(zhǔn)確的說很多類型是 Windows API 的數(shù)據(jù)類型,只不過有時在 MFC 用起來也混淆了。也不用去區(qū)分到底是 MFC 的還是API 的了,反正 MFC 說到底也只是通過 OO 手段對 API 的封裝罷了 )
C++?基本數(shù)據(jù)類型
類 型???????字節(jié)數(shù) bool???????????1 char???????????1 wchar_t????????2???(寬字符類型,存儲Unicode代碼值.用法wchart_t letter = L'a') short??????????2 unsigned short?2???(unsigned 表示無符號,只能取非負(fù)數(shù).unsigned short num = 123U ; //數(shù)字后面的U可加可不加) int????????????4???(整形默認(rèn)為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 中與之對應(yīng)的是
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 程序 共同使用的數(shù)據(jù)類型
下面這些是?MFC?和?wind 32?共同使用的數(shù)據(jù)類型
BOOL:布爾值,取值為TRUE or FALSE BSTR:32-bit 字符指針 BYTE:8-bit整數(shù),未帶正負(fù)號 COLORREF:32-bit數(shù)值,代表一個顏色值 DWORD:32-bit整數(shù),未帶正負(fù)號 LONG:32-bit整數(shù),帶正負(fù)號 LPARAM:32-bit整數(shù),作為窗口函數(shù)或callback函數(shù)的一個參數(shù) LPCSTR:32-bit指針,指向一個常數(shù)字符串 LPSTR:32-bit指針,指向一個字符串 LPCTSTR:32-bit指針,指向一個常數(shù)字符串,此字符串可以移植到Unicode和DBCS LPTSTR:32-bit指針,指向一個字符串,此字符串可以移植到Unicode和DBCS LPVOID:32-bit指針,指向一個未指定類型的數(shù)據(jù) LPRESULT:32-bit數(shù)值,作為窗口函數(shù)或callback函數(shù)的返回值 UINT:在Win16中是一個16-bit 未帶正負(fù)號整數(shù),在Win32中是一個32-bit 未帶 正負(fù)號整數(shù), WNDPROC:32-bit指針,指向一個窗口函數(shù) WORD:16-bit 整數(shù) ,未帶正負(fù)號 WPARAM:窗口函數(shù)或callback函數(shù)的一個參數(shù),在Win16中是16-bit,在Win32中是32-bit?
MFC 獨(dú)特的數(shù)據(jù)類型
- POSITION:一個數(shù)值,代表collection對象(例如數(shù)組或鏈表)中的元素位置,常用于MFC collection classes(即數(shù)據(jù)處理類,如CArray)
- LPCRECT:32-bit指針,指向一個不變的RECT結(jié)構(gòu)
- L 表示 long 指針, 這是為了兼容 Windows 3.1 等 16 位操作系統(tǒng)遺留下來的, 在 win32 中以及其他的 32 為操作系統(tǒng)中, long 指針 和 near 指針及 far 修飾符 都是為了兼容的作用。沒有實(shí)際意義。
- P 表示這是一個指針
- C 表示是一個常量
- T 在 Win32 環(huán)境中, 有一個 _T 宏, 這個宏用來表示你的字符是否使用 UNICODE,如果你的程序定義了 UNICODE 或者其他相關(guān)的宏,那么這個字符 或者 字符串 將被作為 UNICODE 字符串,否則就是標(biāo)準(zhǔn)的 ANSI 字符串。
- STR 表示這個變量是一個字符串。
所以 LPCTSTR 就表示一個指向常固定地址的可以根據(jù)一些宏定義改變語義的字符串。
同樣, LPCSTR 就只能是一個ANSI字符串, 在程序中我們大部分時間要使用帶T的類型定義。
LPCTSTR? 等價于??const TCHAR *
?
?
1. 首先,MFC中 所有的變量?都從 小寫 定義成了 大寫。
( 當(dāng)然小寫的變量類型也可以繼續(xù)使用 )如:
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?來區(qū)分。如:
typedef unsigned int UINT;所有的指針類型變量都加上?P?來區(qū)分。如:
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語言相對古老的的用法,用于聲明變量在內(nèi)存中的遠(yuǎn)近(以前16位的dos操作系統(tǒng),最大有64K的內(nèi)存,緊缺的很~)。所有的常量指針都使用??C。如:
typedef CONST void* LPCVOID; typedef CONST CHAR *LPCSTR, *PCSTR; //只讀的字符指針變量?
?
2. 結(jié)構(gòu)體類型。主要有三個,分別是:POINT、SIZE、RECT
typedef struct tagPOINT {LONG x;LONG y; } POINT, *PPOINT, *LPPOINT;//結(jié)構(gòu)體別名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. 最神奇的 **句柄類型** 。
句柄是一種故意隱藏了內(nèi)容的結(jié)構(gòu)體指針。看一下 HWND 的聲明:
… DECLARE_HANDLE (HWND); …#define DECLARE_HANDLE(name) struct name##__{int unused;}; typedef struct name##__ *name可以看到 HWND 就是結(jié)構(gòu)體的指針,而結(jié)構(gòu)體的內(nèi)容是 unused,(拒絕使用~)。
- HWND ? 窗口句柄 - HINSTANCE ?進(jìn)程實(shí)例句柄 - HCURSOR ?光標(biāo)句柄 - HICON ? 圖標(biāo)句柄 - HMENU ? 菜單句柄 - HFONT ? 字體句柄 - HFILE ? 文件句柄 - 等?
?
4. 最復(fù)雜的 **字符串指針類型**
? ? ? ? 首先,談精簡版的歷史。很早以前,各國文字都有自己的編碼方式,而且每個國家字符的字節(jié)也不一樣(多字節(jié)字符)。后來,擁有了統(tǒng)一的編碼方式,統(tǒng)一了編碼 -- Unicode。
? ? ? ? VS?中創(chuàng)建項(xiàng)目時,默認(rèn)是 Unicode 編碼的。可以使用 **wchar_t** 來聲明 Unicode 編碼的字符串,而且字符串聲明時在前面加上 **L**。**TCHAR**是一個怪胎,他是 char 和 wchar_t 的自適應(yīng)版。
?
5.?MFC 中的 指針類型
注意:據(jù)說 far、near 等關(guān)鍵字在16位的系統(tǒng)上有用處,在32位上沒啥用處。
數(shù)據(jù)類型????????????????含義 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規(guī)律:
? ? 貌似前面加不加 L 都沒啥區(qū)別,
? ? P 自然就表示指針,
? ? C 表示是指向常量的指針.
? ? W 表示是寬字符指針
LPTSTR 如果在unicode中表示LPWSTR,否則表示LPSTR
LPCTSTR 如果在unicode中表示LPCWSTR,否則表示LPCSTR
?
// Windows 句柄類型 HANDLE32 位的無符號整數(shù),用于標(biāo)識
窗口句柄 HWND
實(shí)例句柄 HINSTANCE
光標(biāo)句柄 HCURSOR
圖標(biāo)句柄 HICON
位圖句柄 HBITMAP
菜單句柄 HMENU
設(shè)備描述句柄 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 基本數(shù)據(jù)類型詳細(xì)介紹
?
#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數(shù)據(jù)類型,它會把一個參數(shù)強(qiáng)制轉(zhuǎn)換成Windows3.x應(yīng)用中的16位值?或Win32應(yīng)用中的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
?
//?浮點(diǎn)型
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的部分內(nèi)容*/
//?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字符串(以空字符結(jié)束)的32位指針char*
typedef?__nullterminated?CONST CHAR *LPCSTR,?*PCSTR;
//?指向Windows常字符串(以空字符結(jié)束)的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字符串(以空字符結(jié)束)的32位指針,用于移植到雙字節(jié)字符集
LPTSTR For Unicode platforms,it is LPWSTR,For ANSI and DBCS platforms,it is LPSTR
typedef? ??LPCWSTR? ??PCTSTR,? ??LPCTSTR;
//指向Windows常字符串(以空字符結(jié)束)的32位指針const char* ,用于移植到雙字節(jié)字符集
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宏使字符串會自動根據(jù)工程的版本(ANSI還是UNICODE)進(jìn)行轉(zhuǎn)化.
// 使代碼不需修改自動適應(yīng)ASNI和UNICODE版本
?
typedef WCHAR OLECHAR;????????????????? // wtypes.h
typedef OLECHAR* BSTR; unsigned short*? // wtypes.h
//函數(shù)參數(shù)、返回值類型
typedef UINT_PTR WPARAM; //窗口函數(shù)或callback函數(shù)的一個參數(shù),在Win16中是16-bit,在Win32中是32-bit windef.h
typedef LONG_PTR LPARAM; //32位窗口函數(shù)或callback函數(shù)的一個參數(shù)windef.h
typedef LONG_PTR LRESULT; //32位作為窗口函數(shù)或callback函數(shù)的返回值windef.h
//指向函數(shù)的指針類型
typedef int (WINAPI* PROC)();??PROC //指向回調(diào)函數(shù)的指針
typedef LRESULT(CALLBACK* WNDPROC)(HWND, UINT, WPARAM, LPARAM);
// Windows 函數(shù)調(diào)用類型 __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
?
// 關(guān)于調(diào)用宏參考http://blog.163.com/xiang_163_ok/blog/static/6171684520082161551829/
typedef void far* LPVOID;? // 指向任意類型的指針windef.h
?
?
?
常用數(shù)據(jù)類型的使用
?
我們先定義一些常見類型變量借以說明
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;?
一、其它數(shù)據(jù)類型 轉(zhuǎn)換為?字符串
短整型(int) itoa(i,temp,10); // 將i轉(zhuǎn)換為字符串放入temp中,最后一個數(shù)字表示十進(jìn)制 itoa(i,temp,2); // 按二進(jìn)制方式轉(zhuǎn)換長整型(long) ltoa(l,temp,10);?
二、從其它包含字符串的變量中獲取指向該字符串的指針
CString變量 str = "2008北京奧運(yùn)"; buf = (LPSTR)(LPCTSTR)str;BSTR 類型的 _variant_t 變量 v1 = (_bstr_t)"程序員"; buf = _com_util::ConvertBSTRToString((_bstr_t)v1);?
三、字符串?轉(zhuǎn)換為?其它數(shù)據(jù)類型
strcpy(temp,"123");短整型(int) i = atoi(temp);長整型(long) l = atol(temp);浮點(diǎn)(double) d = atof(temp);?
四、其它數(shù)據(jù)類型?轉(zhuǎn)換到?CString
使用 CString 的成員函數(shù) Format 來轉(zhuǎn)換, 例如:整數(shù)(int) str.Format("%d",i);浮點(diǎn)數(shù)(float) str.Format("%f",i);字符串指針(char *)等已經(jīng)被 CString 構(gòu)造函數(shù)支持的數(shù)據(jù)類型可以直接賦值 str = username;?
五、BSTR、_bstr_t 與 CComBSTR
CComBSTR、_bstr_t 是對 BSTR 的封裝,BSTR 是指向字符串的32位指針。
char * 轉(zhuǎn)換到 BSTR 可以這樣: BSTR b=_com_util::ConvertStringToBSTR("數(shù)據(jù)"); //使用前需要加上頭文件comutil.h
反之可以使用char *p=_com_util::ConvertBSTRToString(b);
?
六、VARIANT 、_variant_t 與 COleVariant
VARIANT 的結(jié)構(gòu)可以參考頭文件VC98\Include\OAIDL.H 中關(guān)于結(jié)構(gòu)體tagVARIANT的定義。
對于VARIANT變量的賦值:首先給vt成員賦值,指明數(shù)據(jù)類型,再對聯(lián)合結(jié)構(gòu)中相同數(shù)據(jù)類型的變量賦值,舉個例子:
VARIANT va;
int a = 2001;
va.vt = VT_I4;? //指明整型數(shù)據(jù)
va.lVal = a;? //賦值
對于不馬上賦值的 VARIANT,最好先用 Void VariantInit(VARIANTARG FAR* pvarg); 進(jìn)行初始化,其本質(zhì)是將 vt 設(shè)置為VT_EMPTY,下表我們列舉vt與常用數(shù)據(jù)的對應(yīng)關(guān)系:
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 的封裝類,其賦值可以使用強(qiáng)制類型轉(zhuǎn)換,其構(gòu)造函數(shù)會自動處理這些數(shù)據(jù)類型。
例如:
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;
?
?
七、其它
對消息的處理中我們經(jīng)常需要將 WPARAM 或 LPARAM 等32位數(shù)據(jù)(DWORD)分解成兩個16位數(shù)據(jù)(WORD),
例如:
LPARAM lParam;
WORD loValue = LOWORD(lParam);? //?取低16位
WORD hiValue = HIWORD(lParam);? //?取高16位
?
對于16位的數(shù)據(jù)(WORD)我們可以用同樣的方法分解成高低兩個8位數(shù)據(jù)(BYTE),例如:
WORD wValue;
BYTE loValue = LOBYTE(wValue); //?取低8位
BYTE hiValue = HIBYTE(wValue); //?取高8位
?
?
?
總結(jié)
以上是生活随笔為你收集整理的《MFC初探》之变量类型的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ARM 汇编基础教程番外篇 ——配置实验
- 下一篇: 传输层(知识架构图)