Winapi 窗口将不响应消息

Winapi 窗口将不响应消息,winapi,visual-c++,Winapi,Visual C++,像往常一样,我遇到了一个非常奇怪的问题 事实上,我不太确定问题到底是什么,但我确定症状是什么。 应用程序正在接收消息、处理消息和调用API,但除了在某些看似异常的情况下,这些都是徒劳的 我在试着抓住一个按键,逃生键。当应用程序收到它时,它调用PostQuitMessage(),并在稍后完成处理(清理)。 问题是,当调用PostQuitMessage()时,什么也不会发生。 窗口仍然在那里,我假设API失败了(但它返回void,所以我不知道),因为我在Spy++上没有看到任何引用WM\u QUIT

像往常一样,我遇到了一个非常奇怪的问题

事实上,我不太确定问题到底是什么,但我确定症状是什么。 应用程序正在接收消息、处理消息和调用API,但除了在某些看似异常的情况下,这些都是徒劳的

我在试着抓住一个按键,逃生键。当应用程序收到它时,它调用
PostQuitMessage()
,并在稍后完成处理(清理)。 问题是,当调用
PostQuitMessage()
时,什么也不会发生。 窗口仍然在那里,我假设API失败了(但它返回void,所以我不知道),因为我在Spy++上没有看到任何引用
WM\u QUIT
WM\u CLOSE
或类似内容的内容

导致窗口关闭的因素包括单击关闭按钮[x]或从非客户端区域或标题栏拖动窗口,然后按escape。只需单击窗口“alt tabbing?”即可打开窗口,而我能想到的一切都不允许窗口响应,尽管消息正在处理中

我将在下面发布相关代码。如果任何人有任何要求、建议或解决方案,欢迎!谢谢你抽出时间,祝你今天愉快

这是窗口程序;它的地址存储在
GWLP_USERDATA
中,存储方式与本文描述的方法类似。我以前在其他应用程序中使用过这个,但从未遇到过这个问题,收到的句柄是有效的——函数就是不起作用

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);
        }
}
以及
wWinMain()
主体的一部分

std::unique_ptr insureoneinstance(新的ApplicationMutex);
/*
*如果实例不是第一个,则返回API的返回值
*尝试查找窗口后,设置ForeGroundWindow。
*/
如果(!ensureOnInstance->IsInstanceFirst(L“SDV”)){
(setforegroundindow(FindWindow(nullptr,L“SDV”));
返回1;
}
/*
*创建并显示我们的主窗口;初始化帧。
*/
std::unique_ptr MainWin(新的主窗口());
MainWin->SwitchState(简介);
MainWin->CreateWindowWithUserFormat();
ShowWindow(MainWin->Window(),SW_SHOWNORMAL);
SetActiveWindow(MainWin->Window());
设置焦点(MainWin->Window());
断言(MainWin->Window()!=nullptr);
std::unique_ptr SDV(新应用程序引擎(MainWin->Window(),
此实例、CmdLine、CmdShow));
SDV->Initialize();
消息;
int Res=1;
而(Res=GetMessage(&Message,MainWin->Window(),0,0)>0){
翻译消息(和消息);
DispatchMessage(&Message);
}
如果(Res==-1){
返回GetLastError();
}

再次感谢您的时间。

在您的
GetMessage
通话中,您只处理
MainWin->Window()
的消息,但
PostQuitMessage
会发布一条未绑定到任何特定窗口的线程消息。因此,您的
GetMessage
将永远无法检索它。应该为第二个参数而不是窗口句柄传递NULL


(此外,由于运算符优先级的原因,您有一个逻辑错误-
Res
将仅为1或0,而不是-1,尽管这与您的问题无关)。

GetMessage
调用中,您只处理
MainWin->Window()的消息,但是
PostQuitMessage
发布一条未绑定到任何特定窗口的线程消息。因此,您的
GetMessage
将永远无法检索它。应该为第二个参数而不是窗口句柄传递NULL



(此外,由于运算符优先级,您有一个逻辑错误-
Res
将仅为1或0,而不是-1,尽管这不是您的问题的原因)。

正如我所说,我不太确定这里的相关代码是什么,如果有人需要更多的代码,我很乐意发布。你在用这个互斥体做什么?它是一个命名互斥体的抽象;它确保只有一个应用程序实例在运行。我看到了一些错误,但是没有一个可以解释你的行为,可能隐藏的代码中还有更多:1)你忘记了开关中的
break
语句,因此你实际上在任何按键上都会发布退出消息。2)
while
中的条件遗漏了一些括号:它应该是
((Res=GetMessage(…)>0)
。返回是否会使break语句无效?正如我所说,我不太确定这里的相关代码是什么,如果有人需要更多的代码,我很乐意发布。你在用这个互斥体做什么?它是一个命名互斥体的抽象;它确保只有一个应用程序实例在运行。我看到了一些错误,但是没有一个可以解释你的行为,可能隐藏的代码中还有更多:1)你忘记了开关中的
break
语句,因此你实际上在任何按键上都会发布退出消息。2)
while
中的条件遗漏了一些括号:它应该是
((Res=GetMessage(…)>0)
。返回不是使break语句无效吗?谢谢!它起作用了。你是救命恩人,你!但这并不能解释为什么拖动窗口会导致这种行为(或者我看不到)。我的意思是,我可以理解为什么
[x]
绑定到窗口,但我不明白为什么只有在不单击并拖动窗口的情况下才会发生这种情况。再次阅读该评论,我仍然不清楚。让我引用我的帖子:“从非客户端区域或标题栏拖动窗口,然后按escape[关闭窗口]”,我的问题是为什么?你是说拖动时按escape,还是先拖动然后按escape?只需先拖动然后按escape。抱歉耽搁了,顺便说一句。老实说,我不知道为什么会这样-对我来说似乎很奇怪。谢谢!它起作用了。你是救命恩人,你!但这并不能解释为什么拖动窗口会导致这种行为(或者我看不到)
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();
    }