What is the code for

This is for using the systems MessageBox (no extra dialog creation needed). After a
time with no user-response the dialog is automatically closed. An optional text showing
the time left to interact is provided. It's also a replacement for MSDN Q181934 (doesn't work)

Basics

Before calling MessageBox, a timer is installed. In the timer's
callback-procedure the message-text from the box is replaced (optional).

When the box should be closed, a WM_COMMAND is posted to the
MessageBox Window.

Timer-Callback

I decided to collect all the information corresponding to the MessageBox
(title, Message, Flags ...) in a class. Then there is the problem that only a
static timer-callback-procedure can be installed with the SetTimer()-function:
one can not access the class-members (as it is static).

To solve this problem, I inserted a Map to store the classes corresponding to
a timer-id:

Sample

History

5.11.2000 posted to Code Project
14.11.2000 bugfixes for NT4
05.02.2001 bug reported when created with MBYES: defbutton then
is IDCANCEL
05.02.2001 global function went to class-scope

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

Comments and Discussions

I created a MFC-AppWizard exe project(Dialog-based) and added the files "timedmsgbox.cpp" and "timedmsgbox.h" to it,then changed the afximpl.h path as: #include "C:\\Program Files\\Microsoft Visual Studio\\VC98\\MFC\\SRC\\afximpl.h" My computer's OS is WindowsXP sp2Compiling tool is VC6The compiling result is the followingHow can I solve this problem?

I am very new to this windows programming. I working as a co-op. I have to implement a project, where the msg box is coming if the user is inputting something it does the work accordingly, which its doing currently. But the window should disappear after 15 seconds, if the user is not inputting anything. Can someone, Please explain this to me in layman's term how to implement this. The given example is good but somewhat confusing. Your help will be highly appreciated.

I was glad to see this class and glad that someone had done a nice job on it. However, like everything, I needed something a little bit beyond what was provided - namely modeless operation with a more general interface (than was used in the multi-threaded example of the demo project).

I made the following changes:

//timedmsgbox.h UINT ShowMessageBoxThreaded(void);

//Internal function to show the messagebox from a thread. static UINT ThreadedMessageBoxShow(LPVOID pParam); //in "Protected"

//timedmsgbox.cpp (Changed implementation on the destructor)CDlgTimedMessageBox::~CDlgTimedMessageBox(){ //Force the timer to stop if using a threaded show and the CDlgTimedMessageBox instance is // being destroyed before the timer has timed out or the user has clicked the button. CDlgTimedMessageBox::m_sectMap.Lock(); { ::KillTimer(NULL, m_idTimer); m_idTimer = 0; CDlgTimedMessageBox::m_mapTimerIdToClassMe.RemoveKey((void*)m_idTimer); } CDlgTimedMessageBox::m_sectMap.Unlock();

I converted the source so it runs under Windows CE 3.0 But one problem. The messagebox timer doesn't count down. :(It always says 5 seconds.. and when never closes the box before I tap close with the pen.

In Win CE 3.0 is GetDesktopWindow() not available for API, only for CWin.Please replace in function:void CDlgTimedMessageBox::GetWindowHandles(void)... the line:hWnd = ::GetWindow(::GetDesktopWindow(), GW_CHILD);... with line:hWnd = ::GetWindow((HWND) CWnd::GetDesktopWindow(), GW_CHILD);

Now, the counters in the MessageBoxes count down, but only on the pocket pc and not on emulation (WCE x86em), because you get a wrong hWnd with the replaced line.

Fantastic piece of work However, I've decided to test the code out for memory leaks. And to my surprise, THERE WAS It puzzles me why the code will experiece that when it DOESN'T consist of any 'new' nor 'delete' in it, though the leak ain't severe.

One leak which I saw when reviewing the code was that the m_idTimer was being reset to zero prior to calling CMapPtrToPtr::RemoveKey to remove the mapping from the m_mapTimerIdToClassMe list. So a very small amount being left in the m_mapTimerIdToClassMe list due to that.

This is a *real* newbie question ( , but how do you set the message box to be always on top. I want it to notify me from a program running in the background, but the message doesn't appear when the app is minimized.

It can be found in afximpl.h which is located at XXX\VC98\MFC\SRCJust include the file in:- the file that does not compile (#include <../SRC/afximpl.h>)- precompiled header stdafx.h (#include <../SRC/afximpl.h>)- or in in you general DevStudio includes (full path)Markus Loibl

I love the class, but never like having global methods. Rather than using ::TimedMessageBox or creating the class & making the ShowMessageBox() call, I added a method to the class that is exactly like ::TimedMessageBox(), but is static....presto -- we have class scope AND the ability to use a single line of code to create the message box.

You wouldn't happen to have something like this message box class that would display a message until the class object is destroyed or a method is called?? I'd done this with dialogs, but want something that doesn't rely on any resources and is auto-sizing like the message box is.

>>destroyed or a method is called:In the code, when the last timer is finished, then it happens:// done with the boxm_bStoppedByTimer = TRUE;::PostMessage(m_hMsgBox, WM_COMMAND, (WPARAM) m_DefaultReturn, (LPARAM) m_hDefaultButton);

I think you can do this also from a function. But first you have to check if the handles are ok: Do this with GetWindowHandles().The members are protected, so derive your own class and insert a function doing this.