2017-02-14 19 views
2

Я создаю окна сообщений из своего консольного приложения. Класс окна зарегистрирован правильно, и окно создается правильно, но оно никогда не имеет названия (в то время как мой вызов функции createwindow указывает заголовок). Подумал, могут ли консольные программы создавать окна с именем? Погубил его, ничего не нашел. Это мой код, сведен к минимуму:Созданные окна не имеют названия

using namespace std; 
hInstance = GetModuleHandle(NULL); 
WNDCLASS WndClass = {}; 
WndClass.style = CS_HREDRAW | CS_VREDRAW; // == 0x03 
WndClass.lpfnWndProc = pWndProc; 
WndClass.cbClsExtra = 0; 
WndClass.cbWndExtra = 0; 
WndClass.hIcon = 0; 
WndClass.hCursor = 0; 
WndClass.hbrBackground = (HBRUSH)COLOR_WINDOWFRAME; 
WndClass.lpszMenuName = 0; 
WndClass.lpszClassName = "EME.LauncherWnd"; 
int style = WS_OVERLAPPED | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU | WS_THICKFRAME | WS_CAPTION; 
if (RegisterClassA(&WndClass)) 
{ 
    cout << "class registered. Hinstance : " << hInstance << " style : (expect 0xcf0000) " << std::hex << style << endl; 
    HWND hwind2 = CreateWindowExA(0, "EME.LauncherWnd", "Mytitle", style, 0x80000000, 0x80000000, 0x80000000, 0x80000000, NULL, NULL, hInstance, NULL); 
    if (hwind2 == 0) 
     cout << "Couldn't create window" << endl; 
    else 
     cout << "created window" << endl; 
} 

выход:

class registered. Hinstance : 00E40000 
created window 

Проверка с Winlister NirSoft, в окне существует, имеет право класса ("EME.LauncherWnd"), но имеет без имени. Кроме того, добавление этих строк кода в блоке:

if (0 == SetWindowText(hwind2, "aTitle")) 
      cout << "couldn't set a title" << endl; 
     else 
      cout << "title set " << endl; 

Выход

title set 

И все же, окно еще не имеет названия. Если консольная программа не могла иметь заголовок, я бы предположил, что вызов SetWindowText вернет 0. Что я делаю неправильно? Edit: Добавление pWndProc по запросу

LRESULT CALLBACK pWndProc(HWND hwnd,   // Handle to our main window 
    UINT Msg,    // Our message that needs to be processed 
    WPARAM wParam,  // Extra values of message 
    LPARAM lParam)  // Extra values of message 
{ 
     switch (Msg) 

     { 
    case WM_DESTROY: 
.... 
break; 
     } 
} 

Хотя после того, как комментарий указывая на pWndProc (что тело я думал, не имеет никакого отношения к строительству окна), то получается, вставив эту строку кода по умолчанию в переключателе case

return DefWindowProc(hwnd, Msg, wParam, lParam); 

решает проблему.

+2

"* Может ли консольные программы создавать окна с именем? *" - да, конечно. Сама консоль - это просто обычное приложение Win32, afterall. Консольные приложения имеют полный доступ к API Win32. При этом, что именно указывает 'pWndProc', правильно ли он обрабатывает оконные сообщения? –

+0

u nead массажная петля –

+0

Голосование, чтобы закрыть как невоспроизводимый пример. –

ответ

0

Я отвечаю на вопрос, как это предложено в комментарии: Ответ заключается в том, что для завершения создания окна pWndProc, переданного в RegisterClass, WINAPI должен обрабатывать сообщения по умолчанию (в частности сообщения ОС). Во время выполнения CreateWindow (после запуска вызова и до его возврата) функция pWndProc уже получает сообщения, которые она должна обрабатывать, в моем случае она не обрабатывала их. Это стандартная функция pWndProc:

LRESULT CALLBACK pWndProc(HWND hwnd,   // Handle to our main window 
    UINT Msg,    // Our message that needs to be processed 
    WPARAM wParam,  // Extra values of message 
    LPARAM lParam)  // Extra values of message 
{ 
     switch (Msg) 

     { 
    case WM_DESTROY: 
... 
    default: 
     return DefWindowProc(hwnd, Msg, wParam, lParam); 
     } 
} 

источник:

Процедура окна обычно не игнорирует сообщение. Если он не обрабатывает сообщение, он должен отправить сообщение обратно в систему для обработки по умолчанию. Процедура окна делает это, вызывая функцию DefWindowProc, которая выполняет действие по умолчанию и возвращает результат сообщения. Затем оконная процедура должна вернуть это значение в качестве собственного результата сообщения. Большинство оконных процедур обрабатывают всего несколько сообщений и передают другие в систему, вызывая DefWindowProc.

+0

Хм, интересно, что он вообще работает. Не обрабатывая WM_NCCREATE, как правило, также ставит его конец. Ну, окна сообщений являются особенными, возможно, почему. Вы не должны устанавливать свой текст, так как никто не может его увидеть, они должны были быть дешевыми. Такой инструмент, как Spy ++, может показать имя класса, достаточно хорошего. –

+0

@ HansPassant Хотя опрашивающий говорит о окнах сообщений, он не передает 'HWND_MESSAGE', поэтому это не окно сообщений. Я думаю, он просто надеется выставить его на экран и надеется, что его не заметили! –

+0

Я на самом деле обратное проектирование программы для развлечения и получения знаний (без прибыли). Я кодирую свою собственную пусковую установку MMORPG, целью которой является логин и запуск игры за 5 с вместо 1 минуты с розничной пусковой установкой. Я создал свое окно так же, как и оригинальная компания (я отлаживал свои аргументы и вызовы функций на createwindow и registerclass), и я использую те же названия/имена классов, которые не соответствуют мне. – user