Using the Windows SetTimer() function - winapi

I am getting confused with the SetTimer() function.
SetTimer() takes three parameters:
SetTimer(1,2000,Timerflow);
However I've seen another version of SetTimer that takes four parameters:
SetTimer(NULL,1,2000,Timerflow);
What is the difference between these two functions?
I know SetTimer() Three parameters. But when I try the four parameter SetTimer() function, I get the error:
error C2660: 'SetTimer' : function does not take 4 parameters
So what is the main difference and what causes this error?

The 4-parameter version is the plain Win32 API version, and the first parameter is a window handle.
The 3-parameter version is a member of MFC's CWnd class, and works with the window handle of the CWnd instance for which you call it.
If you need to call the 4-parameter Win32 API from within a method of a CWnd-derived object, do this:
::SetTimer(NULL, 1, 2000, Timerflow);

The only Windows API called SetTimer takes four parameters. Presumably the other one is part of MFC or some other framework, and the first parameter is implied by the object you call it on. For example:
CWnd * w = .... // get window somehow
w->SetTimer(1,2000,Timerflow);

If you use SetTimer to create a timer in GUI classes such as the MFC's CWnd, you can use the 3-parameter form:
UINT SetTimer(
UINT nIDEvent, // timer identifier
UINT uElapse, // time-out value
TIMERPROC lpTimerFunc // address of timer procedure
);
But if you use it in non-GUI classes, you have to use the 4-parameter form. The first parameter is to specify which GUI component will respond for the timer event. This version of the function is called from Win32 API.
eUINT SetTimer(
HWND hWnd, // handle of window for timer messages
UINT nIDEvent, // timer identifier
UINT uElapse, // time-out value
TIMERPROC lpTimerFunc // address of timer procedure
);
It is very simple, isn't it?

According to MSDN: https://msdn.microsoft.com/en-us/library/windows/desktop/ms644906(v=vs.85).aspx, the first and last parameters are optional. Therefore, you can have a SetTimer call with even 2 parameters (not recommended however). The error is most likely from an incorrect cast (needs a uint_ptr, you give an hwnd, for example)

Related

Where are the rest of the TMessage missing params?

The VCL TMessage class provides the Message, WParam and LParam members, but a window message has more members:
typedef struct tagMSG {
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt;
DWORD lPrivate;
} MSG, *PMSG, *NPMSG, *LPMSG;
Where are the hwnd, time, pt and lPrivate members? I'm in specially need of the time parameter.
Is there a way to access the original message that TMessage is constructed from (or any other means to get the time parameter)?
I'm handling my messages in TComponent::WndProc(Winapi::Messages::TMessage &Message).
Where are the hwnd, time, pt and lPrivate members?
There aren't any such members in TMessage.
MSG is the structure that the Win32 API uses in a message loop to retrieve messages from a message queue, via the GetMessage() and PeekMessage() functions, prior to dispatching them to window procedures via DispatchMessage(). The time, pt, and lPrivate values are not delivered to a window procedure, however a window procedure can retrieve the time and pt values via the GetMessageTime() and GetMessagePos() functions, respectively (the lPrivate value is not accessible).
TMessage is the structure that the VCL uses in window procedures that are created by the RTL's MakeObjectInstance() function. This function allows classes, like the VCL's TWinControl and TTimer, to use non-static virtual WndProc() methods as Win32 window procedures.
In a standard Win32 window procedure, there are only 4 parameters available - hWnd, uMsg, wParam and lParam. An RTL-based window procedure ignores the hWnd (as it already knows exactly which object method to call), copies the uMsg, wParam and lParam values into a TMessage, calls the target WndProc() method passing it the TMessage, and then returns the TMessage::Result value back to the OS.
I'm in specially need of the time parameter. Is there a way to access the original message that TMessage is constructed from (or any other means to get the time parameter)?
If the message comes from the message queue of the thread that is calling your WndProc(), you can use the Win32 API GetMessageTime() function. Or, you can use the Win32 API SetWindowsHookEx() function to install a WH_GETMESSAGE hook into the thread's message queue.
If your component's WndProc() is called in the main UI thread specifically, you can alternatively use the VCL's TApplication::OnMessage or TApplicationEvents::OnMessage events, which receive a copy of the original MSG structure. Your component can use a private TApplicationEvents object to hook the OnMessage event.
However, a window procedure can receive both queued messages and non-queued messages, so if the message does not come from the calling thread's message queue at all, then there is simply no time (or pt) value available to retrieve for it, as non-queued messages do not go through the MSG structure to begin with.
I'm handling my messages in TComponent::WndProc(Winapi::Messages::TMessage &Message).
TComponent does not have a WndProc() method. Perhaps you are thinking of TWinControl::WndProc() instead?

SetWindowsHookEx for current thread returns null

I have an issue trying to get a keyboard hook for the current thread.
Firstly, I needed to get keyboard input for all threads, so I used :
hHook = SetWindowsHookEx(WH_KEYBOARD_LL, mKeyboardProc, GetModuleHandle(NULL), 0);
This works fine, but when I try to set the dwThreadId parameter (the last one) to GetCurrentThreadId(), SetWindowsHookEx returns NULL.
What could be the problem ?
Thanks.
WH_KEYBOARD_LL is a global hook, as stated in the documentation. That means that you must pass 0 for the thread ID parameter.
You could have diagnosed this yourself had you called GetLastError, as described by the documentation. This would have returned error code ERROR_GLOBAL_ONLY_HOOK, This hook procedure can only be set globally.

Get event's in X11

I am using Canon SDK to get the events from the camera. In the SDK, we register a callback function, which is called when a particular event occurs. I have built a Java wrapper, which communicates with the SDK.
But when the event is triggered, my window doesn't get the event directly. Infact on windows, this is how I get the event and dispatch it to myself:
private static final User32 lib = User32.INSTANCE;
boolean hasMessage = lib.PeekMessage( msg, null, 0, 0, 1 ); // peek and remove
if( hasMessage ){
lib.TranslateMessage( msg );
lib.DispatchMessage( msg ); //message gets dispatched and hence the callback function is called
}
Basically one peeps if the window has received an event or not and then proceeds. On Mac, one can do it using Cocoa by having a NSApplication and WindowServer sends events if any.
I am looking for similar alternative using X11. Any sample code/link will suffice.
PS: This a follow up question to this.
I suppose you are looking for XPeekEvent. The Xlib is very well documented and the manpage for XNextEvent(3) says:
The XPeekEvent function returns the first event from the event queue,
but it does not remove the event from the queue. If the queue is
empty, XPeekEvent flushes the output buffer and blocks until an event
is received. It then copies the event into the client-supplied XEvent
structure without removing it from the event queue.
Example code for displaying a basic Xwindow and a main event loop for handling events can be found (for example) on wikibooks.

How to Use Timers in Windows

What are the various ways that a timer can be set up using the Windows API. What are the pros and cons of each method?
I'm using MS DevStudio's C++.
There are two timer related functions on the Windows system: SetTimer and KillTimer (I know, the names are odd - CreateTimer and DestroyTimer would be more sensible, as in CreateWindow and DestroyWindow, but that is what is available).
SetTimer can function in one of two modes: the timer event can trigger a user defined callback or it can post a message to a window. The format of this function is:
timer_id = SetTimer (window, event_id, interval, callback);
To use a callback:
timer_id = SetTimer (NULL, NULL, interval_in_milliseconds, callback);
To get a WM_TIMER message to a window:
timer_id = SetTimer (window, event_id, interval_in_milliseconds, NULL);
In both cases, the calling thread needs to have a message queue as both variants issue a WM_TIMER message, the default handler calls the callback function.
Depending on the OS you're using the value of interval has upper and lower bounds. See the API documentation for more details.
To release the timer after you're finished with it do the following if you provided a window handle:
KillTimer (window, event_id); // event_id is important!
and if you used a callback:
KillTimer (NULL, timer_id);
A single window can have many timers associated with it, use a different event_id for each timer. Reusing an event_id stops the first instance of the timer without posting the WM_TIMER message.
Pros: fairly easy to use.
Cons: latency between interval end and processing of WM_TIMER message, resolution is large, requires a message processing loop.
Another method for handling timers is to use waitable timer objects. These don't require any message processing, don't use WM_TIMER or callbacks. As such, they're a bit more complex. Understanding the Windows event system will be helpful.
There are three types of timer objects: manual-reset, synchronisation and periodic; and there are four functions for handling the timer objects: CreateWaitableTimer, SetWaitableTimer, CancelWaitableTimer and CloseHandle (there is a fifth, OpenWaitableTimer but that is unlikely to useful to many people). There are also a set of functions required for notification of when a timer expires: WaitForSingleObject, MsgWaitForSingleObject, WaitForMultipleObjects and MsgWaitForMultipleObjects being the most useful.
The usual method for using these timers is:
CreateWaitableTimer (...)
SetWaitableTimer (...)
WaitForSingleObject (...)
CloseHandle (...)
Compare this to SetTimer - the only way to know if a timer has expired is to poll it, either in a loop or with an infinte timeout (i.e. suspend the thread until the timer elapses).
Pros: very flexible, no need to have a message queue.
Cons: hard to use
Usually, look at the API you are going to use, for example MFC, Qt or GTK; they all have timer classes.
If you're not going to use a GUI API, I personally like boost::timer (www.boost.org)
For high resolution timers, use queryperformancecounter

How to correctly use SetWindowsHookEx & CallNextHookEx

I can correctly setup up a windows hook, but I get confused by the line in MSDN that says "Calling the CallNextHookEx function to chain to the next hook procedure is optional, but it is highly recommended; otherwise, other applications that have installed hooks will not receive hook notifications and may behave incorrectly as a result. You should call CallNextHookEx unless you absolutely need to prevent the notification from being seen by other applications.".
I want to be a good programming citizen and call the next hook. But, my hook procedure looks like this:
LRESULT CALLBACK CBTProc(int code, WPARAM wp, LPARAM lp)
{
if (code != HCBT_CREATEWND)
{
// What do I do here? It's not the event I requested so how do I pass it on?
return 0;
}
// It's the code we want (create window)
CallNextHookEx(...);
...
}
So, what happens in the hook procedure if the code isn't the one I'm interested in? How do I call the next hook?
Edit: The main problem is that a HHOOK is returned from the SetWindowsHookEx, and that needs to be passed to the CallNextHookEx function.
Update: It seems the hook parameter is ignored on the NT platforms:
http://msdn.microsoft.com/en-us/library/ms644974.aspx
http://www.klenotic.com/pl/null_hhook/
According to the docs, the proper thing to do is pass the arguments you received directly to CallNextHookEx, exactly as you received them. You should also call CallNextHookEx regardless of whether you decided to handle the hook message.
According to MSDN, the first parameter to CallNextHookEx is ignored on on NT/XP/2003, and for older Win95-based operating systems it should be the HHOOK you received when you registered your hook with SetWindowsHookEx. The docs don't specify a value for Windows 2000, but since it's part of the NT family, a reasonable guess is that it's ignored there as well.
Given all that, a good way to code the method for NT-family operating systems might be this:
LRESULT CALLBACK CBTProc( int code, WPARAM wp, LPARAM lp )
{
if( code == HCBT_CREATEWND )
ProcessCreateWnd( wp, lp );
return CallNextHookEx( 0, code, wp, lp );
}
void ProcessCreateWnd( WPARAM wp, LPARAM lp )
{
// my code here
}
This makes sure that you always call the hook at the end of your processing, and makes it hard to accidentally add a return that will bypass CallNextHookEx.

Resources