2015-05-02 3 views
-1

Я действительно не понимаю, как использовать HWND в C++. Я хочу нажать кнопку, и она должна начать поток с запущенным кодом. Но я никогда не получаю команду для нажатия кнопки в другом обратном вызове. Итак, я сделал некоторую отладку, и похоже, что _wndInstance-> GetWndHWND() возвращает что-то недействительное. Метод возвращает частное поле, которое оно хранит.Ручка окна не сохраняет правильно

Если вы посмотрите случай WM_CREATE, содержимое окна не будет отображаться с помощью _wndInstance-> GetWndHWND(). Но если я просто использую hwnd из параметров, он работает. Но как это возможно, если моя первая проверка проверит, что они одинаковы?

static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 
{ 
if (_wndInstance->GetWndHWND() == hwnd) 
    cout << "same" << endl; // Code is getting here! 

switch (msg) 
{ 
case WM_CLOSE: 
    DestroyWindow(hwnd); 
break; 
case WM_DESTROY: 
    PostQuitMessage(0); 
    break; 
case WM_CREATE: 
{ 
    _wndInstance->CreateWndContent(_wndInstance->GetWndHWND()); // not working, but hwnd is! 
} 
    break; 
default: 
    return DefWindowProc(hwnd, msg, wParam, lParam); 
} 
return 0; 

}

EDIT:

_wndInstance является экземпляром класса MainWindow я написал. Часть заголовка MainWindow:

private: 
HWND _wndHwnd; 

public: 
HWND GetWndHWND(); 

MainWindow касты:

 HWND MainWindow::GetWndHWND() 
    { 
     return _wndHwnd; 
    } 

_wndHwnd устанавливается в закрытом методе, который создает окно:

_wndHwnd = CreateWindowEx(
    WS_EX_CLIENTEDGE, 
    g_szClassName, 
    "\"Xbox controller on WINDOWS\" Manager", 
    WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX, // no maximize box 
    CW_USEDEFAULT, CW_USEDEFAULT, 450, 370, 
    NULL, NULL, hinstance, NULL); 
if (_wndHwnd == NULL) 
{ 
    MessageBox(NULL, "Window Creation Failed!", "Error!", 
     MB_ICONEXCLAMATION | MB_OK); 
    return; 
} 

ShowWindow(_wndHwnd, nCmdShow); 
UpdateWindow(_wndHwnd); 
+1

Что такое код, который устанавливает значение, возвращаемое 'GetWndHWND()'? – andlabs

+0

Я отредактировал его в сообщении. Я также использую VS 2013 с компилятором по умолчанию. –

+0

Сделайте MCVE и опубликуйте это вместе с понятным описанием проблемы –

ответ

1

WM_CREATE посылается перед тем CreateWindowEx() возвращается, и таким образом, прежде чем ваше назначение произойдет. Вам необходимо будет перестроить ваш код, чтобы HWND использовался только после того, как он назначен _wndHwnd.

Если вам не нужно ничего делать между WM_CREATE и началом цикла сообщений, вы можете просто отказаться от обработчика WM_CREATE. Это зависит от того, как ваш код будет работать в будущем.

Но более безопасный подход будет назначать _wndHwnd в вашем WM_CREATE обработчик (или даже WM_NCCREATE), так как он у вас имеется в качестве параметра вашей оконной процедуре hwnd, и он будет обрабатывать другие сообщения, посылаемые между созданием окна и переменное присвоение. Вы можете даже пройти _wndInstance в качестве последнего параметра до CreateWindowEx() и получить к нему доступ от WM_CREATE; см. this.

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