这可以在不必使用编写自定义对话框的情况下完成TaskDialogIndirect().
TDF_CALLBACK_TIMER位TASKDIALOGCONFIG::dwFlags.这将大约每200毫秒调用一次回调(如果指定).TASKDIALOGCONFIG::pfCallback.TDN_TIMER通知代码调用回调时,将传递给回调的经过时间wParam与所需的超时值进行比较.要关闭对话框,请向其发送TDM_CLICK_BUTTON消息.您可以想象并显示进度条(TDF_SHOW_PROGRESS_BAR)或只显示您在计时器回调中更新的倒计时文本.请参阅任务对话框消息.
以下是使用普通Windows API的示例.MFC有这个CTaskDialog类,但我认为如果它不依赖于MFC,这个答案会更有用.对于非MFC的用户中,只有分配到tc.hInstance和tc.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)
最简单的方法,如果您只想要带有超时的消息框,请使用 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