Ⅰ error C2664: 「CreateWindowExW」: 不能將參數 3 從「char [18]」轉換為「LPCWSTR」 1> 與指向的類型無關
如下來自一個不錯的分析。收藏了,希望也對你有幫助!
一.ANSI和UNICODE
2.ANSI字元和Unicode字元
ANSI字元類型為CHAR,指向字元串的指針PSTR(LPSTR),指向一個常數字元串的指針PCSTR(LPCSTR);
對應的Windows定義的Unicode字元類型為WCHAR(typedef WCHAR wchar_t) ,指向Unicode字元串的指針PWSTR ,指向一個常數Unicode字元串的指針PCWSTR 。
ANSI 「ANSI」
Unicode L「UNICODE」
ANSI/Unicode T(「string」)或_TEXT(「string」)
3.ANSI字元和Unicode字元串的操作
雙位元組(DBCS)字元集中,字元串的每個字元可以包含一個或兩個位元組。如果只是調用strlen()函數,那麼你就無法知道字元串到底有多少個字元,它只能告訴你到達結尾的0之前有多少個位元組。
標准c中的strcpy,strchr,strcat等只能用於ANSI字元串,不能正確處理Unicode字元串,因此也提供了一組補充函數,功能等價,但用於Unicode碼。我們來看看string .h字元串頭文件中是怎樣處理char*和wchar_t*兩個字元串版本的:
char *strcat(char*,const char*);
wchar_t *wcschr(wchat_t*,const wchar_t *)
類似的還有strchr/wcschr,strcmp/wcscmp,strlen/wcslen etc.
ANSI 操作函數以str開頭 strcpy
Unicode 操作函數以wcs開頭 wcscpy
MBCS 操作函數以_mbs開頭 _mbscpy
ANSI/Unicode 操作函數以_tcs開頭 _tcscpy(C運行期庫)
ANSI/Unicode 操作函數以lstr開頭 lstrcpy(Windows函數)
二.ANSI/UNICODE通用字元/字元串類型TCHAR/LPTSTR/LPCTSTR
Neutral ANSI/UNICODE types
1.通用字元型TCHAR
TCHAR
ifdef UNICODE it is wchar_t(WCHAR)for Unicode platforms;
else it is char for ANSI and DBCS platforms.
2.通用字元串指針LPTSTR
LPTSTR
ifdef UNICODE it is LPWSTR(*wchar_t) for Unicode platforms;
else it is LPSTR (*char) for ANSI and DBCS platforms.
3.通用通用常數字元串指針LPCTSTR
LPCTSTR
ifdef UNICODE it is LPCWSTR(*const wchar_t) for Unicode platforms;
else it is LPCSTR (*const char)for ANSI and DBCS platforms.
typedef LPWSTR LP;
#define __TEXT(quote) L##quote // r_winnt
<1>_UNICODE宏用於C運行期頭文件,UNICODE宏則用於Windows頭文件,當編譯代碼模塊時,通常必須同時定義這兩個宏。
<2>如果定義了_UNICODE,若要生成一個Unicode字元串,字元串前要加L宏,用於告訴編譯器該字元串應該作為Unicode字元串來編譯處理。但是這樣又有個問題就是如果沒有定義_UNICODE則編譯出錯。為了解決這個問題我們必須用到_TEXT宏,這個宏也在TChar.h中做了定義。使用該宏後,無論源文件有沒有定義_UNICODE都不會出現編譯錯誤。
<3>Unicode與ANSI字元串的轉換:Windows函數MultiByteToWideChar函數用於將多位元組字元串轉換成寬字元串,函數WideCharToMultiByte將寬字元串轉換成等價的多位元組字元串。
有的人愛用strcpy等標准ANSI函數,有的人愛用_tXXXX函數,有必要把來龍去脈搞清楚。 為了搞清這些函數,就必須理請幾種字元類型的寫法。char就不用說了,先說一些wchar_t。wchar_t是Unicode字元的數據類型,它實際定義在<string.h>里:
typedef unsigned short wchar_t;
不能使用類似strcpy這樣的ANSI C字元串函數來處理wchar_t字元串,必須使用wcs前綴的函數,例如wcscpy。為了讓編譯器識別Unicode字元串,必須以在前面加一個「L」,例如:
wchar_t *szTest=L"This is a Unicode string."
wchar_t是Unicode字元的數據類型,它實際定義在<string.h>里:
typedef unsigned short wchar_t;
下面在看看TCHAR。如果你希望同時為ANSI和Unicode編譯的源代碼,那就要include TChar.h。TCHAR是定義在其中的一個宏,它視你是否定義了_UNICODE宏而定義成char或者wchar_t。如果你使用了TCHAR,那麼就不應該使用ANSI的strXXX函數或者Unicode的wcsXXX函數了,而必須使用TChar.h中定義的_tcsXXX函數。另外,為了解決剛才提到帶「L」的問題,TChar.h中定義了一個宏:「_TEXT」。
以strcpy函數為例子,總結一下:
.如果你想使用ANSI字元串,那麼請使用這一套寫法:
char szString[100];
strcpy(szString,"test");
.如果你想使用Unicode字元串,那麼請使用這一套:
wchar_t szString[100];
wcscpyszString,L"test");
.如果你想通過定義_UNICODE宏,而編譯ANSI或者Unicode字元串代碼:
TCHAR szString[100];
_tcscpy(szString,_TEXT("test"));
2, ANSI與Unicode
Unicode稱為寬字元型字串,COM里使用的都是Unicode字元串。
將ANSI轉換到Unicode
(1)通過L這個宏來實現,例如: CLSIDFromProgID( L"MAPI.Folder",&clsid);
(2)通過MultiByteToWideChar函數實現轉換,例如:
char *szProgID = "MAPI.Folder";
WCHAR szWideProgID[128];
CLSID clsid;
long lLen = MultiByteToWideChar(CP_ACP,0,szProgID,strlen(szProgID),szWideProgID,sizeof(szWideProgID));
szWideProgID[lLen] = '
(3)通過A2W宏來實現,例如:
USES_CONVERSION;
CLSIDFromProgID( A2W(szProgID),&clsid);
將Unicode轉換到ANSI
(1)使用WideCharToMultiByte,例如:
// 假設已經有了一個Unicode 串 wszSomeString...
char szANSIString [MAX_PATH];
WideCharToMultiByte ( CP_ACP, WC_COMPOSITECHECK, wszSomeString, -1, szANSIString, sizeof(szANSIString), NULL, NULL );
(2)使用W2A宏來實現,例如:
USES_CONVERSION;
pTemp=W2A(wszSomeString);