Reputation: 1057
As usual I'm experiencing a very strange problem.
In fact, I'm not so sure what the problem actually is, but I am sure what the symptoms are. The application is receiving messages, handling the messages, and calling APIs, but to no avail, except in some exceptional-seeming circumstances.
I'm trying to catch a keypress, the escape key. When the application receives it, it calls PostQuitMessage()
and finishes processing (cleanup) later.
The problem is that when PostQuitMessage()
is called, nothing happens.
The window is still sitting there, and I assume the API fails (but it returns void, so I can't tell) because I see nothing on Spy++ that refers to WM_QUIT
, WM_CLOSE
or the like.
The things that result in the window's closure include clicking the close button [x] or dragging the window from the non-client area or title bar, and than pressing escape. Simply clicking the window, "alt-tabbing?" to the window, and everything I else can think of does not allow the window to respond, although the messages are being processed.
I'll post relevant code below. If anyone has any requests, suggestions, or solutions, they are welcome! Thank you for your time and have a good day.
This is the window procedure; it's address is stored in GWLP_USERDATA
in a similar manner to the method described in this article. I've used this before in other apps and have never encountered this problem, The handle received is valid -- the function just doesn't work!?
LONG_PTR MainWindow::HandleMessage(UINT Message,
WPARAM WParam, LPARAM LParam) {
switch(CurrentState) {
case Introduction:
return HandleIntroMessage(Message, WParam, LParam);
default:
return DefWindowProc(Window(), Message, WParam, LParam);
}
}
LONG_PTR MainWindow::HandleIntroMessage(UINT Message,
WPARAM WParam, LPARAM LParam) {
switch(Message) {
case WM_KEYDOWN:
switch (WParam) {
case VK_ESCAPE:
PostQuitMessage(0);
return false;
}
case WM_DESTROY:
PostQuitMessage(0);
default:
return DefWindowProc(Window(), Message, WParam, LParam);
}
}
And part of the body of wWinMain()
.
std::unique_ptr<ApplicationMutex> EnsureOneInstance(new ApplicationMutex);
/*
* If the instance is not first, return with the return value of the API
* SetForegroundWindow after trying to find the window.
*/
if(!EnsureOneInstance->IsInstanceFirst(L"SDV") ) {
(SetForegroundWindow(FindWindow(nullptr, L"SDV") ) );
return 1;
}
/*
* Create and show our main window; initialize the frame.
*/
std::unique_ptr<MainWindow> MainWin(new MainWindow() );
MainWin->SwitchState(Introduction);
MainWin->CreateWindowWithUserFormat();
ShowWindow(MainWin->Window(), SW_SHOWNORMAL);
SetActiveWindow(MainWin->Window() );
SetFocus(MainWin->Window() );
assert(MainWin->Window() != nullptr);
std::unique_ptr<ApplicationEngine> SDV(new ApplicationEngine(MainWin->Window(),
ThisInstance, CmdLine, CmdShow) );
SDV->Initialize();
MSG Message;
int Res = 1;
while(Res = GetMessage(&Message, MainWin->Window(), 0, 0) > 0) {
TranslateMessage(&Message);
DispatchMessage(&Message);
}
if(Res == -1) {
return GetLastError();
}
Thank you again for your time.
Upvotes: 2
Views: 230
Reputation: 37202
In your GetMessage
call you're only processing messages for MainWin->Window()
, but PostQuitMessage
posts a thread message that isn't bound to any particular window. Therefore your GetMessage
will never retrieve it. You should pass NULL for the second parameter instead of the window handle.
(Additionally, you have a logic error because of operator precedence - Res
will only ever be 1 or 0, not -1, although this isn't responsible for your problem).
Upvotes: 4