Link to home
Start Free TrialLog in
Avatar of hrasheed
hrasheed

asked on

Need Help with an OnTimer Function

i have an OnTimer function that checks for error messages and was just wondering what happens if the timer goes off and there is already a stack of functions to be executed.  Does it wait for the current one to finish, interrupt it, or add to the end of the queue?
ASKER CERTIFIED SOLUTION
Avatar of nietod
nietod

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of nietod
nietod

Note that even though you are having a timer call-back procedure called, the system is still message based.  Windows will send a WM_TIMER message to your window.  Then if the timer message is passed to the default wndow procedure, it will call the specified call-back procedure.  

continues

Note that there are (at least) 3 levels of priorities given to messages in the windows OS.

The WM_TIMER and WM_PAINT messages are given the lowest priorities.  (at least in their default uses).  In other words, all other messages that need to be handled are handled before these messages, noi matter how long they are
"waiting".  The reason for this is that they are not really placed in the message queue.  (At least not by the OS, a program could send them or post them in which case they would have higher priority).   Instead the GetMessage() (and other message functions) generate these messages only when the queue is empty and when the messages are needed (the timer has expired or the window has an update region).   Thus these messages never "stack up" in the queue.  This is important because they could potentially occur frequently and could A) cause the program to spend all of its time handling them repeatedly (which isn't necessary) and B) cause the queue to overflow (in win 95 and 98).

continues
Thus there is ordinarily no way to get a 2nd WM_TIMER message while processing a first one.  However, it could happen if durring the processing the 1st message, you get more messages.  i.e. if you start a 2nd message loop inside the processing of the 1st message.  This is unlikely, bit it might happen if you have a messagebox or modal dialog to show during the processing of the WM_TIMER event.    So this could happen, bit its under your control.  i..e. you would have to have code that allowed it to happen, in most cases it will never happen.
Avatar of hrasheed

ASKER

just to be sure, if say the program was handling a button click and the WM_TIMER comes in the middle, will the button click complete, or will the timer message be handled immediately
It depends on what you mean by "handling a button click".

If you mean handling the final message produced by the button click, i.e the WM_LBUTTONUP for example, then you will not get the notification durring the handling of that message.

If you mean durring the processing of the mouse button sequence, well then it depends.   That  sequence is a series of messages that begin with the mopuse button press and that track the movement of the mouse and ends when the mouse is released.   in between these messages, other messages may occur, like WM_TIMER.  So yes it _could_ occur durring the process.  Does that matter?

Note that on a standard button control, all these messages are handled privately and I don-t think that the WM_TIMER message will ever "make it to you" during this.  the same with mouse interaction in a menu and moving/sizing a window.  I may be wrong about that.  However many messages are "aborted" durring these operations and I suspect this could be one of them.

if you handle the mouse sequnce yourself however, then the message could occur.


Why do you ask?   What are you doing that this is a concern?
Avatar of Axter
>>it could happen if durring the processing the 1st >>message, you get more messages
>>in most cases it will never happen.

Actually, I've had this problem happen in a number of applications.
The method I used to insure the call back function doesn't get call during current call back, is to add a static bool variable to the function, and check if it is set.

Example:

void SomeCallbackFunction(....)
{
   static bool Busy = false; //initiate to false
   if (!Busy)
   {
    Busy = true;
   //.. Your function code here
   
    Busy = false;
   }
}
i am writing a dialog box which can handle mouse clicks and keyboard input.  This box also has an item which should occur roughly on a given interval.  However, handling the mouse clicks (the functions are mapped to BN_CLICKED)  is more important that handling the timer item.  It is important that the timer either not interrupt the code handling the mouse click or that the dialog box return control to the code handling the mouse click in the correct location if it does.
i am writing a dialog box which can handle mouse clicks and keyboard input.  This box also has an item which should occur roughly on a given interval.  However, handling the mouse clicks (the functions are mapped to BN_CLICKED)  is more important that handling the timer item.  It is important that the timer either not interrupt the code handling the mouse click or that the dialog box return control to the code handling the mouse click in the correct location if it does.
when the shown SomeCallbackFunction returns, will it go back to complete handling the message it was processing when the second message interrupted it?
>> Actually, I've had this problem happen in a number of applications.
This can only happend if you process messages during the WM_TIMER message.  That is unlikely, but possible.   However, messaget may be processed indirectly, like by opening a messagebox.  

>>  It is important that the timer
>> either not interrupt the code handling the
>> mouse click or that the dialog box return control to the
>> code handling the mouse click in the correct location if it does.
Well its always going to return control to the correct location.  There is no doubt about that.

The only way you can get a WM_TIMER message (and hence a call to your callback procedure) is when you (or code somewhere) calls GetMessage() or one of its alternatives.    So if in handling the the mouse, a private message loop is started--as is done by the default button procedure, then this private message loop will call GetMessage()  (or something similar) and it is possible that a WM_TIMER will occur and your callback will be called.  However, when this private message loop ends--like when the mouse button is release, then control will return to the location where the mouse processing started (somewhere inside a WM_LBUTTONDOWN handler, probalby inside the button's defautl window procedure.)    

 So program flow control will never bee "messed up" by this process.  However, you can have problems with rentrancy.  i..e if the WM_TIMER handler (includign the callback procedure, in your case) is not rentrant, this can be a problem.  So you need to look at what the handler does to make sure it is safely rentrant.  Things that might not be rentrant might be using unprotected global resources, like say using a global bitmap, opening a specific file, using a global data structure.  That sort of thing.   If you are doing anythign that makes the code non rentrant, then you need to protect against it.   Axter showed one technique for this, Its a good simple one.  there are others depending on your circumstances.  Like if you are in a multi-threaded environment, that is not a sufficient approach as you can have other reasons for rentrancy that it doesn't guard against.

>> when the shown SomeCallbackFunction returns, will it go back to
>> complete handling the message it was processing when the
>> second message interrupted it?
Absolutely!