2016-03-01 197 views
1

的錯誤,我在Visual Studio 2015年創建了一個基本的Windows C++應用程序,我有幾個誤區:的Visual Studio 2015年WinAPI的上的MessageBox

Erorrs image

#include <windows.h> 
#include <stdlib.h> 
#include <string.h> 
#include <tchar.h> 

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) 
{ 
    MessageBox(NULL, "Test_text", "Message Test", MB_ICONINFORMATION | MB_OKCANCEL); 
    return 0; 
} 

錯誤:

'int MessageBoxW(HWND,LPCWSTR,LPCWSTR,UNIT)': cannot convert argument 2 from 
'const char [10]' to 'LPCWSTR' 

argument of type "const char *" is incompatible with parameter of type "LPCWSTR" 
argument of type "const char *" is incompatible with parameter of type "LPCWSTR" 
+3

不要通過圖像顯示錯誤或代碼(內嵌或外部鏈接)。始終將錯誤的完整文本顯示爲文本。 – crashmstr

+0

如果您要搜索消息文本,則應該已經找到了解決方案。 – MSalters

回答

2

你不能傳遞像這樣的裸字符串。

MessageBox(NULL, TEXT("Test_text"), TEXT("Message Test"), MB_ICONINFORMATION | MB_OKCANCEL); 

TEXT是根據編譯方式展開爲正確字符串類型的宏。

+0

'_T'用於CRT,'TEXT'用於Windows API,因此在這種情況下使用'TEXT'更好。 – MikeCAT

+0

@MikeCAT更新。 –

4

在這種情況下MessageBox實際上是MessageBoxW,它需要unicode字符串。您可以通過這種方式解決它:

MessageBoxW(NULL, L"Test_text", L"Message Test", MB_ICONINFORMATION | MB_OKCANCEL); 

MessageBox(NULL, TEXT("Test_text"), TEXT("Message Test"), MB_ICONINFORMATION | MB_OKCANCEL); 
5

您選擇使用ANSI文本,所以你應該使用MessageBoxA明確,而不是宏觀MessageBox

#include <windows.h> 
#include <stdlib.h> 
#include <string.h> 
#include <tchar.h> 

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) 
{ 
    MessageBoxA(NULL, "Test_text", "Message Test", MB_ICONINFORMATION | MB_OKCANCEL); 
    return 0; 
} 

或者,您可以使用TEXT宏讓編譯器自動匹配字符串和函數的類型。

#include <windows.h> 
#include <stdlib.h> 
#include <string.h> 
#include <tchar.h> 

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) 
{ 
    MessageBox(NULL, TEXT("Test_text"), TEXT("Message Test"), MB_ICONINFORMATION | MB_OKCANCEL); 
    return 0; 
} 
0

您需要爲您的項目選擇Character Set的正確設置。在您的Visual Studio項目的屬性中,導航到General類別。有一個條目Character Set

如果選擇Unicode Character Set編譯器將定義_UNICODE爲你喜歡MessageBox所有功能會評估他們的寬字符的變體,如MessageBoxW

如果您選擇Multi-Byte(不建議使用),編譯器將爲您定義_MBCS,函數將評估爲多字節變體,如MessageBoxA

字符串也是一樣,答案中提到的宏(如TEXT)會在unicode環境中的所有字符串前添加一個L

在這裏看到更多的信息:https://msdn.microsoft.com/en-us/library/ey142t48.aspx

恕我直言,有一個地方要對WA方法明確寫入很少的原因。如果你必須這樣做才能讓你的編譯器高興,那麼你應該重新檢查你的設置。

4

這裏的問題是Win32 TCHAR模型

這事實上沒有MessageBox功能:MessageBox預處理#define,即擴展到MessageBoxAMessageBoxW,根據您的項目設置(ANSI/MBCS或Unicode,分別)。

與VS2005起,在Visual Studio中默認設置已的Unicode(更精確地說:UTF-16)。因此編譯器在這種情況下挑選MessageBoxW API(即Unicode版本)。

MessageBoxW API需要的Unicode(UTF-16)串,經由wchar_t指針(晦澀LPCWSTR預處理宏擴展到const wchar_t*,即封端NUL C風格的Unicode UTF-16串)表示。

的Unicode(UTF-16)字符串文字使用L"..."語法(注意加上L前綴)表示。
因此,雖然"Test_text"是ANSI字符串文字,L"Test_text"是Unicode(UTF-16)字符串文字。

MessageBox(nullptr, // <--- prefer nullptr to NULL in modern C++ code 
      L"Test_text",  // <--- Unicode (UTF-16) string literal 
      L"Message Test", // <--- Unicode (UTF-16) string literal 
      MB_ICONINFORMATION | MB_OKCANCEL); 

另一種是裝飾字符串:

由於您的是:(隱式,通過Visual Studio中的默認設置)做一個Unicode版本,您應與加上L前綴,如裝飾你的字符串字面量文字使用_T("...") or TEXT("...") macros。這些將擴展爲簡單的"..." ANSI/MBCS構建中的ANSI字符串文本,以及Unicode構建中的Unicode(UTF-16)字符串文字L"..."(這是現代版本的Visual Studio中的默認值)。

// TEXT("...") works in both ANSI/MBCS and Unicode builds 
MessageBox(nullptr, 
      TEXT("Test_text"),  
      TEXT("Message Test"), 
      MB_ICONINFORMATION | MB_OKCANCEL); 

就個人而言,我認爲TCHAR模式從過去的(我認爲沒有理由產生ANSI建立的現代C++的Win32應用程序)的陳舊模式,並考慮到現代的Windows API是僅Unicode(如DrawThemeText()) ,我只是使用L"..."前綴來裝飾字符串文字,還有一些忘記了ANSI構建。

+0

傳遞寬字符字符串時,應顯式調用API的寬字符版本(即'MessageBoxW'而不是'MessageBox')。 – IInspectable

+0

@IInspectable:我不同意。 'MessageBoxW'(或'一般'DoSomethingW')在Unicode編譯中是一個無用的_code uglification_:結尾'W'只是清晰的'MessageBox'(或'DoSomething')形式的噪聲。 –

+0

這不是關於意見,而是關於語言規則。 'MessageBox'是通用的文本映射版本。 MessageBoxW是Unicode版本。我會採取你認爲的「醜化」*,依靠任何一天我無法控制的環境。 – IInspectable