-1

I don't really get how to use HWND in c++. I want to press a button and it should start a thread with a code running. But I never receive the command for button click in an other callback. So I did some debugging and it seems like that _wndInstance->GetWndHWND() returns something not valid. The method returns a private field which has it stored.

If you look a case WM_CREATE, the window content added will not show up with _wndInstance->GetWndHWND(). But if I just use hwnd from the parameters, it does work. But how is that possible if my first test-check validates that they are the same??

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 is an instance of a mainwindow class I wrote. Part of mainWindow header:

private:
HWND _wndHwnd;

public:
HWND GetWndHWND();

MainWindow cpp:

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

_wndHwnd is set in a private method which creates the window:

_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 Answers1

0

WM_CREATE is sent before CreateWindowEx() returns, and thus before your assignment happens. You will need to restructure your code so that the HWND is only used after it is assigned to _wndHwnd.

If you don't need to do anything between WM_CREATE and the beginning of the message loop, you can just drop your WM_CREATE handler. That depends on how your code will work in the future.

But a safer approach would be to assign _wndHwnd in your WM_CREATE handler (or even WM_NCCREATE), since you have it available as the hwnd parameter to your window procedure, and it would handle other messages sent between the window creation and the variable assignment. You can even pass _wndInstance as the last parameter to CreateWindowEx() and access it from WM_CREATE; see this for details.

andlabs
  • 11,290
  • 1
  • 31
  • 52