自定义消息框自动消失

时间:2018-08-23 12:29:40

标签: c++ winapi mfc

我需要在现有的MFC应用程序中添加一个自定义消息框,如果用户未按“确定”,该消息框将在几秒钟后消失。

该怎么做?

我对MFC基本熟悉,但对c ++很好。

2 个答案:

答案 0 :(得分:5)

无需使用TaskDialogIndirect()编写自定义对话框即可完成此操作。

基本步骤

  1. 设置TASKDIALOGCONFIG::dwFlags中的TDF_CALLBACK_TIMER位。这将大约每200毫秒调用一次回调(如果指定)。
  2. callback function分配给TASKDIALOGCONFIG::pfCallback
  3. 当使用TDN_TIMER通知代码调用回调时,请将通过wParam传递给回调的经过时间与所需的超时值进行比较。要关闭对话框,请向其发送TDM_CLICK_BUTTON消息。

您可以看中并显示进度条(TDF_SHOW_PROGRESS_BAR),也可以只显示您在计时器回调中更新的倒计时文本。参见Task Dialog Messages

示例

这里是使用纯Windows API的示例。 MFC具有CTaskDialog类,但是我认为,如果答案不太依赖MFC,它将更有用。对于非MFC用户,只需更改对tc.hInstancetc.hwndParent的分配。

TASKDIALOGCONFIG tc{ sizeof(tc) };
tc.hInstance = AfxGetInstanceHandle();
tc.hwndParent = GetSafeHwnd();  // assuming you call this from a dialog member function
tc.dwFlags = TDF_CALLBACK_TIMER | TDF_SIZE_TO_CONTENT;
tc.dwCommonButtons = TDCBF_OK_BUTTON;
tc.pszWindowTitle = L"Task dialog with timeout";
tc.pszContent = L"This dialog will close after 5 seconds!";

DWORD timeout = 5000;  // milliseconds
tc.lpCallbackData = reinterpret_cast<LONG_PTR>( &timeout );

// Assign a lambda function as callback.
tc.pfCallback = []( HWND hwnd, UINT uNotification, WPARAM wParam, LPARAM lParam, LONG_PTR dwRefData )
{
    if( uNotification == TDN_TIMER )
    {
        DWORD* pTimeout = reinterpret_cast<DWORD*>( dwRefData );  // = tc.lpCallbackData
        DWORD timeElapsed = static_cast<DWORD>( wParam );
        if( *pTimeout && timeElapsed >= *pTimeout )
        {
            *pTimeout = 0; // Make sure we don't send the button message multiple times.
            SendMessage( hwnd, TDM_CLICK_BUTTON, IDOK, 0 );
        }
    }
    return S_OK;
};

::TaskDialogIndirect( &tc, nullptr, nullptr, nullptr );

答案 1 :(得分:3)

最简单的方法,如果您只希望消息框超时,请使用user32.dll中的下一个未公开的api:

extern "C"
WINUSERAPI int WINAPI MessageBoxTimeoutW(IN HWND hWnd, 
                            IN PCWSTR lpText, IN PCWSTR lpCaption, 
                            IN UINT uType, IN WORD wLanguageId, IN DWORD dwMilliseconds);

我们需要的所有内容-将此声明添加到 c ++ 代码中并与 user32.lib 链接,但这通常是默认情况下执行的。在此调用之后,它像往常一样MessageBoxW,带有2个附加参数。最后一个简单的视图-以毫秒为单位的平局。

例如:

MessageBoxTimeoutW(HWND_DESKTOP, L"Text", 
    L"Caption", MB_ICONINFORMATION|MB_YESNO, 0, 4000);

请注意,MessageBoxW只需调用MessageBoxTimeoutW即可:

int MessageBoxW(
  HWND    hWnd,
  LPCTSTR lpText,
  LPCTSTR lpCaption,
  UINT    uType
)
{
    return MessageBoxTimeoutW(hWnd, lpText, lpCaption, uType, 0, INFINITE);
}

所以前4个参数和返回值类似MessageBoxW api中。如果消息框被超时关闭-返回IDTIMEOUT(在 winuser.h 中声明),但使用MB_OK(单个 OK 按钮)除外-总是返回IDOK