WM_TOUCH is not immediately sent with touch down event - windows-7

I am working with a touch screen and using Windows 7 built in drivers (as it never prompted me to install any). it works fine, except for one small issue. When I touch the screen, it will not send the WM_LBUTTONDOWN until I move my finger off the screen. It appears to do this to determine if I intend to hold down to emulate WM_RBUTTONDOWN or not. (Also, I tried to disable the hold down emulate gesture, but it never disables in practice.)
So I thought I would just receive the WM_TOUCH messages. And I found that WM_TOUCH (0x240) is also not sent to my window until I move my finger off the screen. I sort of thought that defeats the purpose of WM_TOUCH altogether.
Both before and after registering to receive WM_TOUCH messages, I received three messages immediately upon touching the screen:
1. Send: 0x02CC (undocumented tablet messages)
2. Post: 0x011B (undocumented)
3. Send: 0x011A (WM_GESTURENOTIFY)
0x011A is WM_GESTURENOTIFY, which my code is to respond to (perhaps I am not responding correctly?). I reply with a standard response (using sample code from MS) to receive full notifications.
Another thing, I began getting WM_TOUCH when I register for touch messages, but I continue to get the WM_GESTURENOTIFY message as well. According to the MS documentation, once I register to get WM_TOUCH, I no longer get gesture messages.
If anyone can tell me how to get WM_TOUCH messages immediately (e.g. when I am getting the WM_GESTURENOTIFY messages), and not after I let my finger up off the touch scree, I would appreciate it much.

Check out this tutorial on touch events:
http://msdn.microsoft.com/en-us/gg464991
What you want to use is the RegisterTouchWindow function, as such:
RegisterTouchWindow(handle, 0);
Windows will now send WM_TOUCH messages instead of WM_GESTURE messages to your window. Keep in mind that you will have to compile against Windows SDK version 7.0 or newer for this to work.

I almost got the same issue and solved it by using :
RegisterTouchWindow( hWnd, TWF_WANTPALM );

Related

SetWindowsHookEx(WH_SHELL, ...): What is the meaning of event HSHELL_WINDOWREPLACED?

If I register a hook via SetWindowsHookEx(WH_SHELL, ShellProc, ...), what is the meaning of event HSHELL_WINDOWREPLACED? (My Google-fu fails me. I have searched high and low!)
Win32 Docs:
SetWindowsHookEx(): https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowshookexw
ShellProc (callback): https://learn.microsoft.com/en-us/windows/win32/winmsg/shellproc
The offical docs read: A top-level window is being replaced. Weirdly, they also say: Windows 2000: Not supported. Does that mean only supported before or after Win2K?
I created a test driver to watch a Microsoft Windows session, but I was never able to trigger this mysterious event.
I also found a similar event here:
RegisterShellHookWindow: https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registershellhookwindow
... that says:
HSHELL_WINDOWREPLACING: A handle to the window replacing the top-level window.
HSHELL_WINDOWREPLACED: A handle to the window being replaced.
Related:
How can I be notified when a new window is created on Win32?
Why HSHELL_WINDOWDESTROYED, HSHELL_WINDOWCREATED?
In this instance, the term "replace" refers to the occasions when a window stops responding to messages ("hangs") and, after a certain period, Windows hides it and replaces it on-screen with a faded-out copy (called a "ghost window").
Windows does this so that, even when the app is not processing messages, the user can interact with the ghost window to move it around and try to close it.
The wParam value is the handle of the hung window (the one being replaced) and the lParam value is the handle of the ghost window (its replacement).
If the window starts responding again, the notification is sent again, with the window handles swapped around.

No mousewheel events when using touchpad

I'm having troubles retrieving mousewheel events when my program is running on my laptop and when I'm scrolling using the touchpad.
I was initially using DirectInput to catch input events, but I've read here and there that DirectInput wasn't able to handle scroll events sent by touchpads.
I did some extra researchs and fell on this old topic: C++ DirectInput Mouse Scroll Wheel with a Laptop Touchpad
So i've tried to use a PeekEvent loop to catch my mouse inputs. Everything wen fine when using a real mouse, but when I switched to my laptop, ta-da: no WM_MOUSEWHEEL events received. (And this guy predicted it )
I don't receive any WM_VSCROLL or WM_GESTURE event either.
Additionnaly I've made another program based on wxWidgets and in this case, the mouse wheel events are propery catched by the application. I've parsed the source code to see how wxWidgets retrieve windows events and, except if I'm missing something, it seems to be the exact same code as mine.
Is there some kind of voodoo magic trick to catch mouse wheel events generated by a touchpad?
I can provide more informations about my code if needed.
Thanks
EDIT:
I did some extra debug to find what's going on:
First, I was wrong saying I don't catch WM_MOUSEWHEEL event at all. In fact, in the WindowProc Callback I actually receive wheel events.
However, the PeekMessage call doesn't return any event.
I could eventually change the way I collect mouse events to do it directly in the WindowProc callback, but I'll need to do some weird stuff just to handle something that should be working the same way using both a real mouse or a touchpad.

Message received when Window gets activated

I'm trying to pause a DirectX game when the windows loses focus, but the messages seem to be inconsistent.
When using windows mode WM_SETFOCUS and WM_KILLFOCUS messages are received and everything works fine, but these messages are not received when using full screen mode. WM_NCACTIVATE is received when using full screen mode and it works fine, but in window mode is not received when the application is minimized from the taskbar. WM_ACTIVATEAPP also is not received in several cases.
Is there any consistent way of handling the gain/lose focus problem? I want to use only one message that is received in both full screen and window mode.
You should use WM_ACTIVATE for that.

WM_POWERBROADCAST handler for CMainDlg in ATL app not invoked

I have an ATL app where I want to handle WM_POWERBROADCAST. I have a CMainDlg (CAxDialogImpl) in whose MSG_MAP I defined the handler.
BEGIN_MSG_MAP(CMainDlg)
...
MESSAGE_HANDLER(WM_POWERBROADCAST, OnPowerChange)
...
END_MSG_MAP()
However, the handler isn't invoked when I do things that should invoke it, for instance change power settings or put the machine to sleep.
Any ideas about what might be going on, and how to fix this? Does CMainDlg not get notified of power events, for some reason?
I suspect your dialog not being a top level window (WS_POPUP styled).
Just tested with a WTL AppWizard non modal dialog app that WM_POWERBROADCAST is received (without any registration) on AC plugged/unplugged.
Did you register to receive the power events?
To add to answers above, you might want to use Spy++ tool to make sure the messages of interest are posted to your application in first place. You will also see which windows they are posted to, and if it is your window where you are waiting for this message.

Receive screensaver notification

I want to receive a notification in my C++ application when a screensaver is about to start. I tried listening to WM_SYSCOMMAND messages with wParam == SC_SCREENSAVE which some people think should do the trick.
That didn't work. Spy++ even showed that my window didn't receive any WM_SYSCOMMAND message. Interesting thing is when I turned off the monitor I did receive the message with wParam == SC_MONITORPOWER. Am I understanding it wrong? Or did I just miss something?
Edit: For testing I used the default windows screensaver (the one with windows logo).
It appears that I will receive the SC_SCREENSAVE message only when my window has focus. The way around this is to set global hook. That would require me to put the callback function in a separate DLL and there is also this scary message about hooks slowing down the system so I decided to drop the idea of responding to screensaver start.
This is a relatively complex task (although it would be nice if it were easy).
Some of these tests you'll find online only work if your window is in focus. If it's running in the background it may not receive such messages.
Other tests rely on a screensaver program running (check the currently set screensaver, and then watch the process list to see if it's active) but don't work if you go into powersave mode, or if your screensaver is a black screen (ie, no program, just monitor off).
I don't believe there's an ideal way to do this. You might want to go back to the beginning and think more carefully about why you need to detect this state, and what you are trying to accomplish. You might need a different solution.
Probably my answer comes too late.
The MSDN handles screensavers under "Legacy".
On a notebook they waste battery and on a PC they are also useless.
It is better to turn the monitor off than letting it show a screensaver.
As you don't explain exactly what you want to do I don't know if you really need the notification BEFORE the saver starts or if it is enough to get notified when it already has just started.
In the latter case it is easy.
Write a thread that periodically checks:
BOOL b_SaverRunning;
SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, &b_SaverRunning, 0);

Resources