【问题标题】:C++: cleanup actions in response to Windows logoffC++:响应 Windows 注销的清理操作
【发布时间】:2014-12-23 22:19:54
【问题描述】:

我想捕捉 Windows 注销事件,以便进行一些清理工作。我的WindowProc 看起来像这样:

switch (uMsg){
case WM_ENDSESSION:
case WM_DESTROY:
    PostQuitMessage(0);
    return 0;
// other messages
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);

WinMain 中的消息循环如下所示:

for(;;){
    bool bTerminate = false;
    while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){
        if(msg.message == WM_QUIT){
            bTerminate = true;
        }
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    if(bTerminate){
        break;
    }
    // do other stuff
    Sleep(10);
}
FILE * fout;
fopen_s(&fout, "C:\\success.txt", "w"); // simulating cleanup actions
fclose(fout);
ExitProcess(0);

预期的机制是WindowProc 执行PostQuitMessage,导致主消息循环接收WM_QUIT,打破循环并将程序发送到清理。当我退出程序(因此发送WM_DESTROY)时,程序会创建success.txt,但是当程序运行并且我注销(发送WM_ENDSESSION)时,它不会。

我也看过WM_QUERYENDSESSION,但MSDN 说“每个应用程序在收到此消息后应立即返回TRUEFALSE,并推迟任何清理操作,直到它收到WM_ENDSESSION 消息。 "

【问题讨论】:

    标签: c++ windows logoff


    【解决方案1】:

    WM_ENDSESSION 处理实际上并没有让您的应用程序有机会退出消息循环。您应该假设系统在发送WM_ENDSESSION 消息后调用了 TerminateProcess。

    因此,您的应用程序需要执行的任何清理工作都应在从窗口过程返回之前完成。

    【讨论】:

    • 也就是说清理代码应该在从窗口过程返回之前调用?
    • @HarryJohnston 这是我的理解,是的。
    【解决方案2】:

    在 Windows UI 应用程序中,您可以使用: LRESULT CMainDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
    { if(message == WM_ENDSESSION) { if(lParam == ENDSESSION_LOGOFF) { /*Handle event*/ } } return CDialogEx::WindowProc(message, wParam, lParam); }
    您可以从this msdn link获得更多帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-18
      • 1970-01-01
      • 1970-01-01
      • 2017-02-02
      相关资源
      最近更新 更多