I've tried using RegisterPointerInputTarget (Win32 API) to capture all PT_TOUCH messages, but my app behaves exactly as if the function was never called. I've followed all advice I could find: the app has uiAccess=true, is signed, and is installed to C:\Program Files. The windows is created as a child of HWND_MESSAGE and the RegisterPointerInputTarget returns 1. However, my WndProc is not receiving any WM_POINTER messages at all. If I instead create a normal window, my WndProc receives WM_POINTER messages as expected, only when I'm pointing over the window.
Below is the code of my program. Note that the calls to InitializeTouchInjection, ShowWindow, UpdateWindow and AccSetRunningUtilityState should be unnecessary, I've just been trying everything I've seen in any example I could find.
I'm using a Wacom Intuos, tried both with the pen and with the fingers.
#include "pch.h"
#include <iostream>
#include <Windows.h>
#include "oleacc.h"
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_NCPOINTERUP:
case WM_NCPOINTERDOWN:
case WM_NCPOINTERUPDATE:
case WM_TOUCH:
case WM_POINTERDOWN:
case WM_POINTERUP:
case WM_POINTERUPDATE:
{
std::cout << "TOUCH MESSAGE " << message << " WPARAM " << wParam << " LPARAM " << lParam << std::endl;
break;
}
}
std::cout << "SOME MESSAGE " << message << " HWND " << hWnd << " WPARAM " << wParam << " LPARAM " << lParam << std::endl;
return DefWindowProc(hWnd, message, wParam, lParam);
}
int main()
{
//InitializeTouchInjection(10, TOUCH_FEEDBACK_NONE);
LPCSTR className = "TouchHookWindow";
HINSTANCE hInstance = GetModuleHandle(NULL);
WNDCLASS wc;
memset(&wc, 0, sizeof(wc));
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
//wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
//wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
//wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpszClassName = className;
if (!RegisterClass(&wc))
{
std::cout << "Failed to register window class!\n";
return -1;
}
DWORD dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
DWORD dwStyle = WS_OVERLAPPEDWINDOW;
//DWORD dwExStyle = WS_EX_NOACTIVATE;// | WS_EX_TRANSPARENT;
//DWORD dwStyle = WS_OVERLAPPEDWINDOW;
RECT rc;
rc.left = 0;
rc.top = 0;
rc.right = 100;
rc.bottom = 100;
AdjustWindowRectEx(&rc, dwStyle, FALSE, dwExStyle);
//HWND hWnd = CreateWindowEx(dwExStyle, className, "Touch Hook", dwStyle, 0, 0, rc.right-rc.left, rc.bottom-rc.top, NULL, NULL, hInstance, NULL);
HWND hWnd = CreateWindowEx(0, className, "TouchHook", 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, hInstance, NULL);
//HWND hWnd = CreateWindowEx(dwExStyle, className, "TouchHook", dwStyle, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_MESSAGE, NULL, hInstance, NULL);
//HWND hWnd = CreateWindowEx(dwExStyle, className, "TouchHook", dwStyle, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
std::cout << "Failed to create window!\n";
return -1;
}
//ShowWindow(hWnd, SW_SHOW);
//UpdateWindow(hWnd);
//SetForegroundWindow(hWnd);
//SetFocus(hWnd);
{
BOOL result = RegisterTouchWindow(hWnd, 0);
std::cout << "RegisterTouchWindow result " << result << std::endl;
}
{
BOOL result = RegisterPointerInputTarget(hWnd, PT_TOUCH);
std::cout << "RegisterPointerInputTarget result " << result << std::endl;
}
{
//HRESULT hr = AccSetRunningUtilityState(hWnd, ANRUS_TOUCH_MODIFICATION_ACTIVE, ANRUS_TOUCH_MODIFICATION_ACTIVE);
//std::cout << "AccSetRunningUtilityState " << (FAILED(hr) ? "FAILED" : "SUCCESS") << std::endl;
}
{
MSG msg;
BOOL result;
while (result = GetMessage(&msg, NULL, 0,0) != 0)
{
if (result != -1)
{
if (msg.message == WM_QUIT)
{
break;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
}
return 0;
}