How to create timer in WinApi (C++)?
Call the SetTimer function. This allows you to specify a callback function, or to have Windows post you a WM_TIMER message.
You cannot not know this if you write GUI code. Which makes it likely you want to use CreateTimerQueueTimer().
SetTimer. A window handle is needed, and the timer will not be delivered if you aren't pumping messages.
A Good Example for CreateTimerQueueTimer : Here
Another is HERE
call the setTimer() Function. Suppose I called
SetTimer(hWnd,POST_CBIT_TIMER,500,NULL);
Call back function is
UINT nIdEvent ;//global member variable
case WM_TIMER:
if(nIDEvent == POST_CBIT_TIMER)
{
KillTimer(hParent,POST_CBIT_TIMER);
}
break;
Related
The usual WinAPI message loop looks something like this:
MSG msg;
while (GetMessage(&msg, hwnd, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
Is it allowed not to call DispatchMessage() but to handle the message on your own? If not, how could I nicely approach this behavior while avoiding global variables and thread problems?
Edit:
I basically want to use my own callback function, which hasn't the WndProc signature. But I can't think of a way to call that function out of a WndProc without using static or global variables.
[Which would require locking, which I think isn't the best thing you can do with a callback function which probably gets called very frequently.]
Thanks for your help.
Is it allowed not to call DispatchMessage() but to handle the message on your own? If not, how could I nicely approach this behavior while avoiding global variables and thread problems?
If you are planning to use multiple threads in your GUI then each thread that creates a window will need to manage it's own message queue.
From this page: http://msdn.microsoft.com/en-us/library/ms810439.aspx
Changes to the Message Loop
Applications with multiple threads must include a message loop in each
thread that creates a window. The message loop and window procedure
for a window must be processed by the thread that created the window.
If the message loop does not reside in the same thread that created
the window, the DispatchMessage function will not get messages for the
window. As a result, the window will appear but won't show activation
and won't repaint, be moved, receive mouse messages, or generally work
as you expect it to.
You can react to a message there, but you still need/want to call DispatchMessage and actually handle the message in your normal wndproc. I'd be happy to say more about avoiding globals and/or threading problems, but it's hard to comment without more details about what you want to avoid.
Yes, you can handle the message yourself, if you wish. I usually set the result field to 0, but Windows only make use of this field for a few messages.
I have an external application that calls my application and is supposed to end it when the job is done. The log from this external application claims it uses WM_CLOSE on my app.
How can I intercept the WM_CLOSE message in my application to do some cleanup operations? I tried at_exit() and wrapping it in a class, but I think I have the wrong approach.
The official solution for console applications is HandlerRoutine, a callback set by SetConsoleCtrlHandler. Windows will call your handler with a CTRL_CLOSE_EVENT argument in case of a WM_CLOSE exit.
When you're using a class method with SetConsoleCtrlHandler, it must be a static method - Windows won't provide you with a this pointer.
You could just handle WM_CLOSE in your message loop to do whatever cleanup is necessary, or even abort the close (by returning 1 instead of 0). See e.g. this: http://cboard.cprogramming.com/windows-programming/141438-handling-wm_close-wm_destroy.html#post1056273
Edit: for console applications, this may be of interest: http://support.microsoft.com/kb/178893
You must create hidden window using winapi, and handle WM_CLOSE message in its message loop. Is your app using any gui elements?
The easiest way I think is to call PeekMessage from time to time.
BOOL IsCloseEventReceived()
{
MSG msg;
return PeekMessage(&msg, NULL, WM_CLOSE, WM_CLOSE, PM_NOREMOVE);
}
This function should work to check if a WM_CLOSE message has been posted. It's not blocking, and you'll need to call it on a regular basis.
I might be wrong, but I think you don't need a hidden window to handle messages, a message queue is attached to your process the first time you call a messages-related function, like PeekMessage. However if you receive a WM_CLOSE message prior to your first call of this function it might be lost.
I am developing MFC Dialog based application in Visual Studio 2008. I want to use timer that start on start of the application and continue to run and calls a function that performs my task? How can I do this?
Thanks
Just use SetTimer method, and pass two arguments: Timer ID (any number), and the timeout in milliseconds. Then write up OnTimer implementation, and an entry ON_WM_TIMER inside BEGIN_MESSAGE_MAP...END_MESSAGE_MAP.
CWnd::SetTimer takes 3 parameters, but only 2 are required. Pass third argument as NULL.
CWnd::OnTimer
_AFXWIN_INLINE UINT_PTR CWnd::SetTimer(UINT_PTR nIDEvent, UINT nElapse,
void (CALLBACK* lpfnTimer)(HWND, UINT, UINT_PTR, DWORD))
You may want to do something like
UINT_PTR myTimer = SetTimer (1, 1000, null); // one event every 1000 ms = 1 s
and react to the ON_TIMER event in your window's event handler:
void CMyView::OnTimer (UINT_PTR nIdEvent)
{
if (nIdEvent == 1)
// handle timer event
}
Alternatively you can pass a pointer to a function handling the timer events. Keeping the handle to the timer allows you to turn it off using KillTimer() in case you have to.
If you want to get the basic idea of using Timers, kindly have a look at this link and go through the step by step procedure on working with timers. After this, you should be able to use timers easily in your application whenever you want.
Link: http://www.functionx.com/visualc/controls/timer.htm
Hope this helps.
Cheers.
I'm writing some code that id like to be able to work with any window, such as a window created through the windows API, MFC, wxWidgets, etc.
The problem is that for some things I need to use the same thread that created the window, which in many cases is just sat in a message loop.
My first thought was to post a callback message to the window, which would then call a function in my code when it recieves the message using one of the params and a function pointer of some sorts. However there doesnt seem to be a standard windows message to do this, and I cant create my own message since I dont control the windows code, so cant add the needed code to the message handler to implement the callback...
Is there some other way to get the thread that created the window to enter my function?
EDIT:
John Z sugessted that I hooked the windows messages. If I do that is there some way to get "ids" for custom messages without the risk of conflicting with any custom messages the window already has?
eg I might do
WM_CALLBACK = WM_APP+1
But if the window I'm hooking has already done something with WM_APP+1 I'm gonna run into problems.
EDIT2:
just found RegisterWindowMessage :)
If you are in the same process as the window you can hook its messages by subclassing it. Check out http://msdn.microsoft.com/en-us/library/ms633570(VS.85).aspx
The key API is SetWindowLong.
// Subclass the edit control.
wpOrigEditProc = (WNDPROC) SetWindowLong(hwndEdit, GWL_WNDPROC, (LONG)EditSubclassProc);
// Remove the subclass from the edit control.
SetWindowLong(hwndEdit, GWL_WNDPROC, (LONG)wpOrigEditProc);
Alternatively to subclassing, you can use SetTimer to call a function in the window thread.
VOID CALLBACK Function(
HWND hwnd,
UINT uMsg,
UINT_PTR idEvent,
DWORD dwTime
)
{
// stuff
}
SetTimer(hWnd, event, 0, Function);
Can someone please point me to the easiest way to have a timer in a Win32 service?
I suppose I could create a dummy window for this purpose or have a second thread do tick counts, but what's best? Is there a more elegant way?
Thanks in advance.
You can use Timer Queues (http://msdn.microsoft.com/en-us/library/ms686796.aspx). They don't require an HWND.
Instead of using UI timers (even though you can use the NULL window handle as shown by Mr. 1800-INFO) you can use kernel waitable timer objects. See CreateWaitableTimer in the API docs. These can then be waited-on using WaitForSingleObject or WaitForMultipleObjects, etc, which is especially useful if that's already how your service waits for external events.
If it's not clear from that first link, the SetWaitableTimer function can associate a completion routine (user callback) with the timer. Remember to use the ...Ex versions of WaitForMultipleObjects (etc.) so that the thread is in an "alertable" state.
You can send your main thread WM_TIMER messages. The lParam for the message is the address of a callback function, or you can leave it NULL and handle it yourself in your message pump.
In this example, we are sending the timer to the thread message pump, there is no requirement to have a window associated with the timer.
UINT timer;
VOID CALLBACK Timer(HWND hwnd,
UINT uMsg,
UINT_PTR idEvent,
DWORD dwTime
)
{
KillTimer(0, timer);
}
timer=SetTimer(0, // window handle
0, // id of the timer message, leave 0 in this case
10000, // millis
Timer // callback
);
// pump messages
while (GetMessage) etc...
The Timer callback will be called by DispatchMessage. This question reminded me of the recent ONT.
You can use SetTimer to set the timer, then catch the WM_TIMER message in your message loop.
Example:
// Set a timer to expire in 10 seconds
SetTimer(hwnd,IDT_TIMER1, 10000,(TIMERPROC) NULL);
... then in message loop:
switch (wParam)
{
case IDT_TIMER1:
// Boom goes the dynamite
You can also decleare a function of type TIMERPROC and have that be called when the timer expires, if you don't want to do the message loop handling.
In one of your comments you said that "...the service is processing stuff in other threads, I just need to check the status of a few files every second."
Polling is not an optimal way of checking file status, and will adversely affect system performance. While there are (sometimes) problems doing this over networks, you should check out http://msdn.microsoft.com/en-us/library/aa364417(VS.85).aspx or http://msdn.microsoft.com/en-us/library/aa365261(VS.85).aspx for how to do it and http://blogs.msdn.com/oldnewthing/archive/2006/01/24/516808.aspx for why you should.
Are you just trying to "wake up" every now and then to do some work? You can always use Sleep().
Additionally, I typically have a thread that is in a while(1 == 1) loop with a sleep inside. There I can check for the shutdown request and other misc housekeeping. You could use that system to tickle an event or mutex for the worker thread in the app.