具有超时的MessageBox或从另一个线程关闭MessageBox

Pat*_*ick 5 c++ windows winapi

如果我的应用程序崩溃,我使用ExceptionFilter来捕获崩溃,执行一些最终操作,然后向用户显示应用程序崩溃的消息框.

因为应用程序已经崩溃,所以我可以(或者我不敢)做很多事情,因为如果我做得太多,执行的代码可能会访问损坏的内存并再次崩溃.我目前无法做的一些事情(或者我不敢做)是关闭网络连接,Oracle数据库会话,......

问题是,如果应用程序崩溃,并且用户在MessageBox打开时外出吃午餐,则由于打开数据库会话,其他用户可能会被阻止.因此,我想:

  • 具有超时的MessageBox.问题是你不能用标准的MessageBox Win32 API函数做这个,我不想为它做一个特定的对话框(因为我想在崩溃后最小化执行的逻辑)
  • 或者从另一个线程关闭MessageBox的可能性(另一个线程可以提供超时逻辑).

我是否忽略了Win32 API中的某些内容,是否有可能让MessageBox超时?

或者从另一个线程关闭一个打开的MessageBox的正确方法是什么(如何获取MessageBox句柄,如何关闭它,......)?

Ale*_* K. 6

虽然我同意产生一个新的过程以显示即发即弃对话框可能是最好的,但是FWIW实际上是在XP及以上版本中从user32导出的超时消息框功能; MessageBoxTimeout(如用的东西WShell.Popup())


Sim*_*mon 5

快速复制/粘贴解决方案:

int DU_MessageBoxTimeout(HWND hWnd, const WCHAR* sText, const WCHAR* sCaption, UINT uType, DWORD dwMilliseconds)
{
    // Displays a message box, and dismisses it after the specified timeout.
    typedef int(__stdcall *MSGBOXWAPI)(IN HWND hWnd, IN LPCWSTR lpText, IN LPCWSTR lpCaption, IN UINT uType, IN WORD wLanguageId, IN DWORD dwMilliseconds);

    int iResult;

    HMODULE hUser32 = LoadLibraryA("user32.dll");
    if (hUser32)
    {
        auto MessageBoxTimeoutW = (MSGBOXWAPI)GetProcAddress(hUser32, "MessageBoxTimeoutW");

        iResult = MessageBoxTimeoutW(hWnd, sText, sCaption, uType, 0, dwMilliseconds);

        FreeLibrary(hUser32);
    }
    else
        iResult = MessageBox(hWnd, sText, sCaption, uType);         // oups, fallback to the standard function!

    return iResult;
}
Run Code Online (Sandbox Code Playgroud)