2016-03-01 4 views
1

Я создал базовый Windows C++ приложения в Visual Studio 2015 и у меня есть несколько ошибок: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), добавят L перед всеми вашими строками в среде Юникода.

Смотрите здесь для получения дополнительной информации: https://msdn.microsoft.com/en-us/library/ey142t48.aspx

ИМХО очень мало причин, где один хочет писать явно против W или A методами. Если вам нужно сделать это, чтобы сделать ваш компилятор счастливым, вы должны перепроверить свои настройки.

4

Проблема заключается в том, что Win32 TCHAR модель.

Там нет фактически нет MessageBox функции: MessageBoxявляется препроцессор#define, которая расширяется до MessageBoxA или MessageBoxW, в зависимости от настроек проекта (ANSI/MBCS или Unicode, соответственно).

Начиная с VS2005, то установка по умолчанию в Visual Studio была Unicode (чтобы быть более точным: UTF-16). Таким образом, API MessageBoxW (т. Е. Версия Unicode) выбирается в этом случае компилятором.

MessageBoxW API принимает Unicode (UTF-16) строк, представленный с помощью wchar_t указателей (неясный LPCWSTR макроса препроцессора расширяется до const wchar_t*, т.е. NUL -завершённых в стиле С Unicode UTF-16 строкой).

Unicode (UTF-16) строковые литералы представлены с использованием L"..." синтаксиса (обратите внимание на L префикса).
Итак, хотя "Test_text" является строковым литералом ANSI, L"Test_text" является строковым литералом в формате Unicode (UTF-16).

Поскольку ваш ARE (неявно, через настройки Visual Studio по умолчанию) делает сборку Unicode, вы должны украсить строковые литералы с L префиксом, например:

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); 

альтернатива украсить строку литералов с использованием _T("...") or TEXT("...") macros. Они будут расширены до простых "..." строковых литералов ANSI в сборках ANSI/MBCS и в строковых литералах Unicode (UTF-16) L"..." в Unicode-сборках (которые по умолчанию используются в современных версиях 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), и принимая во внимание, что современные интерфейсы API для Windows являются Unicode-только (например, DrawThemeText()) , Я бы просто украсил струнные литералы, используя префикс L"...", и вроде забудем о сборках ANSI.

+0

При передаче букв с широкими символьными строками вы должны явно называть широкоформатную версию API (т. Е. 'MessageBoxW' вместо' MessageBox'). – IInspectable

+0

@ Подлинный: я не согласен. 'MessageBoxW' (или' DoSomethingW' вообще) является бесполезным _code uglification_ в сборках Unicode: окончание 'W' является просто шумом по более четкой форме MessageBox' (или' DoSomething'). –

+0

Речь идет не о мнениях, а о языковых правилах. 'MessageBox' - это общая версия преобразования текста. 'MessageBoxW' - это версия Unicode. Я бы взял то, что, по вашему мнению, было «uglification» *, полагаясь на среду вне моего контроля в любой день. – IInspectable

Смежные вопросы