自定义消息框自动消失

Ron*_*Ron 2 c++ winapi mfc

我需要添加到现有的MFC应用程序,一个自定义消息框,如果用户没有按"确定",它将在几秒后消失.

怎么做?

我基本熟悉MFC,但是熟悉c ++.

zet*_*t42 5

这可以在不必使用编写自定义对话框的情况下完成TaskDialogIndirect().

基本步骤

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

您可以想象并显示进度条(TDF_SHOW_PROGRESS_BAR)或只显示您在计时器回调中更新的倒计时文本.请参阅任务对话框消息.

以下是使用普通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 );
Run Code Online (Sandbox Code Playgroud)

  • @RbMm由于它没有文档,可以在将来的任何时候删除它.过时,因为Task Dialog API更强大. (2认同)

RbM*_*bMm 5

最简单的方法,如果您只想要带有超时的消息框,请使用 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);
Run Code Online (Sandbox Code Playgroud)

我们需要的一切 - 将此声明添加到c++代码中并与user32.lib链接,但我们通常默认这样做。MessageBoxW在此之后,只需像往常一样使用 2 个附加参数进行调用即可。最后如何简单地查看 - 以毫秒为单位的 tiemout。

例如:

MessageBoxTimeoutW(HWND_DESKTOP, L"Text", 
    L"Caption", MB_ICONINFORMATION|MB_YESNO, 0, 4000);
Run Code Online (Sandbox Code Playgroud)

请注意,MessageBoxW只需调用MessageBoxTimeoutW

int MessageBoxW(
  HWND    hWnd,
  LPCTSTR lpText,
  LPCTSTR lpCaption,
  UINT    uType
)
{
    return MessageBoxTimeoutW(hWnd, lpText, lpCaption, uType, 0, INFINITE);
}
Run Code Online (Sandbox Code Playgroud)

所以前 4 个参数和返回值就像MessageBoxWapi 中一样。如果消息框因超时关闭 -返回(在winuser.hIDTIMEOUT中声明),除非使用(单个OK按钮) - 在这种情况下始终返回。MB_OKIDOK