Все современные версии Windows используют Unicode для внутреннего использования, и по умолчанию Visual Studio создает проект #define _UNICODE
/ UNICODE
, который заставляет ваше приложение ссылаться на версии Unicode заголовков Windows.
Однако, когда вы компилируете приложение как Unicode, символьные (и, следовательно, «строковые») типы различаются. Вместо char
они теперь wchar_t
. Это означает, что вы должны явно объявить свои строковые литералы как длинные строки, поставив перед ними префикс L
.
В качестве альтернативы, заголовки Windows скрывают все это за макросами, но в этом больше нет необходимости, поскольку Windows долгое время была Unicode, и это вряд ли изменится.
Кроме того, вы упускаете несколько вещей при инициализации структуры WNDCLASSEX
, например, элемент hInstance
. Все эти вещи должны быть установлены идеально, иначе все рухнет. Кроме того, функциям RegisterClass(Ex)
и CreateWindow(Ex)
должны быть переданы значения точно такой же строки , соответствующие имени класса окна, иначе они будут предполагать, что вы говорите о двух разных вещах. Опечатки не прощены!
Я настоятельно рекомендую использовать мастера Visual Studio для создания пустого (но работающего!) Шаблона проекта.
Правильный шаблонный код выглядит примерно так:
#include <windows.h>
#include <tchar.h>
// Define these here to minimize typos, or preferably, load them from a
// resource file at the top of the main function
#define MYCLASSNAME TEXT("MainWndClass")
#define MYWINDOWNAME TEXT("Main Window")
// Global variable to keep track of your hInstance
HINSTANCE g_hInstance;
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
// If you don't process any of the messages yourself, you
// must pass them to DefWindowProc for default handling.
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
// Save the instance handle in a global variable.
g_hInstance = hInstance;
// Register your window class.
// (A full-featured app will probably want to set additional members.)
WNDCLASSEX wcex = {0};
wcex.cbSize = sizeof(wcex);
wcex.lpfnWndProc = WndProc;
wcex.hInstance = hInstance;
wcex.lpszClassName = MYCLASSNAME;
if (!RegisterClassEx(&wcex))
{
MessageBox(NULL, TEXT("Call to RegisterClassEx failed!"), NULL, MB_OK);
return 1;
}
// Create your main window.
HWND hwndMain = CreateWindowEx(0, MYCLASSNAME, MYWINDOWNAME, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL,
hInstance, NULL);
if (!hwndMain)
{
MessageBox(NULL, TEXT("Call to CreateWindowEx failed!"), NULL, MB_OK);
return 1;
}
// Show your main window.
ShowWindow(hwndMain, nCmdShow);
UpdateWindow(hwndMain);
// Run the main message loop.
BOOL bRetVal;
MSG msg;
while ((bRetVal = GetMessage(&msg, NULL, 0, 0)) != 0)
{
if (bRetVal == -1)
{
MessageBox(NULL, TEXT("Error encountered in message loop!"), NULL, MB_OK);
return 1;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}