Не создается окно Hello world, все компилируется без ошибок, но окна нет
Не создается окно Hello world, всё компилируется без ошибок, но окна нет.
#include <windows.h>
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
HWND hMainWnd;
char szClassName[] = "FirstClass";
MSG msg;
WNDCLASSEX wc;
wc.lpfnWndProc = WndProc;
wc.cbSize = sizeof(wc);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_CROSS);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = (LPWSTR)szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if (!RegisterClassEx(&wc))
{
MessageBox(NULL, (LPCWSTR)L"Cannot register class!", (LPCWSTR)L"ERROR", MB_OK);
return 0;
}
hMainWnd = CreateWindow(
(LPCWSTR)szClassName, (LPCWSTR)L"A Hello1 Application ", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
(HWND)NULL, (HMENU)NULL,
(HINSTANCE)hInstance, NULL
);
ShowWindow(hMainWnd, nCmdShow);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC hDC;
PAINTSTRUCT ps;
RECT rect;
switch (uMsg)
{
case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rect);
DrawText(hDC, (LPCWSTR)"Hello, mthrfckr!", -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint(hWnd, &ps);
break;
case WM_CLOSE:
DestroyWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
Ответы (2 шт):
Судя по коду, у вас программа Unicode. Тогда wc.lpszClassName должен быть Unicode string:
WCHAR szClassName[] = L"FirstClass";
wc.lpszClassName = szClassName;
Добавьте проверку реультата CreateWindow.
Удалите весь string casting: (LPWSTR). Когда у вас есть проблема с преобразованием строк, не пытайтесь решить ее с помощю casting. Почитайте здесь про MBCS и Unicode: https://www.codeproject.com/Articles/446/Unicode-MBCS-and-Generic-text-mappings
Во первых, вы используете при отображении окна в функции ShowWindow (hMainWnd, nCmdShow); в качестве второго параметра значение из входного параметра nCmdShow функции WinMain(). Вы уверены, что там находится не SW_HIDE (т.е. не 0), а хотя бы SW_SHOWNORMAL (1) или SW_SHOW (5)? Попробуйте для проверки заменить ShowWindow (hMainWnd, nCmdShow); на ShowWindow (hMainWnd, SW_SHOWNORMAL);
Во-вторых, у вас по тексту программы смешаны UNICODE-строки с ANSI-строками. Такое, в принципе, возможно, но с определенными ограничениями: при вызове ANSI-варианта функции ей должны передаваться только ANSI-строки, при вызове UNICODE-варианта функции ей должны передаваться только UNICODE-строки.
В WinAPI (по крайней мере в основных библиотеках), все функции, которые работают со строками, существуют в 2 версиях: для ANSI-строк и для UNICODE-строк.
Таким образом, ваша функция RegisterClassEx() на самом деле существует в 2 вариантах:
в ANSI-варианте: RegisterClassExA()
и в UNICODE-варианте: RegisterClassExW()
В этом контексте "обычные" имена функций (без постфиксов A или W) являются лишь псевдонимами к одной из двух версий функции. В зависимости от настроек проекта или объявления/необъявления в заголовках вашей программы #define UNICODE компилятор подставляет вместо "обычного" имени функции либо ее UNICODE-имя, либо ANSI-имя.
Из кода видно, что при регистрации класса в функции RegisterClassEx() в параметре wc.lpszClassName вы передаете ANSI-строку (char szClassName[] = "FirstClass";), и тут же, далее по тексту при вызове других функций тоже в "обычном" виде (MessageBox(), CreateWindow()) вы передаете UNICODE-строки.
Такое однозначно не будет работать! Если у вас в программе по умолчанию используются ANSI-варианты функций, сбой будет в MessageBox(), CreateWindow(). Если UNICODE-варианты функций, то сбой будет в RegisterClassEx().
Исправьте это:
1) либо сделайте все строки UNICODE или ANSI, и тогда в настройках / заголовках объявите UNICODE или ANSI вариант компиляции соответственно;
2) либо вызывайте напрямую функции с символами A / W на конце, передавая каждой из них либо только ANSI-строки (если используете A), либо только UNICODE-строки (если используете W).