我需要在现有的MFC应用程序中添加一个自定义消息框,如果用户未按“确定”,该消息框将在几秒钟后消失。
该怎么做?
我对MFC基本熟悉,但对c ++很好。
答案 0 :(得分:5)
无需使用TaskDialogIndirect()
编写自定义对话框即可完成此操作。
TASKDIALOGCONFIG::dwFlags
中的TDF_CALLBACK_TIMER
位。这将大约每200毫秒调用一次回调(如果指定)。TASKDIALOGCONFIG::pfCallback
。TDN_TIMER
通知代码调用回调时,请将通过wParam
传递给回调的经过时间与所需的超时值进行比较。要关闭对话框,请向其发送TDM_CLICK_BUTTON
消息。您可以看中并显示进度条(TDF_SHOW_PROGRESS_BAR
),也可以只显示您在计时器回调中更新的倒计时文本。参见Task Dialog Messages。
这里是使用纯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 );
答案 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
。