How to intercept pen and touch inputs on windows.

Having problems with building or using CEF's C/C++ APIs? This forum is here to help. Please do not post bug reports or feature requests here.

How to intercept pen and touch inputs on windows.

Postby lwttai » Tue Jul 07, 2020 10:08 pm

Recently, I want to intercept the user inputs(mouse, pen, touch inputs) on the CEF window.
What I doing now is, hook the WndProc in the child window(class name: Chrome_WidgetWin_0) of the browser window(via CefBrowserHost->GetWindowHandle()) when CefLifeSpanHandler::OnAfterCreated. But this not working well, all the input message just sent when mousebutton is down, otherwise message are sent to child window(class name: Chrome_RenderWidgetHostHWND) of which window I hooked WndProc.
I try also hook the real window(Chrome_RenderWidgetHostHWND) which receive user inputs message. But I don't get a right timing for that. When OnAfterCreated, that windows is not created yet. When WM_PARENTNOTIFY with WM_CREATE on Chrome_WidgetWin_0, the real window is not valid and can't hook the WndProc by ::SetWindowPtrLong yet.
Is there any notification about the Chrome_RenderWidgetHostHWND created? Or any suggestion about getting pen or touch inputs with othre ways?

Code: Select all
window tree:
+-"My app"QWidget
     +-"BrowserWindow"CefBrowserWindow
          +-""Chrome_WidgetWin_0                           // witch I current hooked
              +-"Chrome Legacy Window"Chrome_RenderWidgetHostHWND // witch I try to hooked but without a proper timing
              +-""Intermediate D3D Window
lwttai
Techie
 
Posts: 22
Joined: Mon Oct 14, 2019 12:18 am

Re: How to intercept pen and touch inputs on windows.

Postby Czarek » Tue Jul 07, 2020 10:52 pm

Maintainer of the CEF Python, PHP Desktop and CEF C API projects. I'm available for contract work, see my resume.
User avatar
Czarek
Virtuoso
 
Posts: 1869
Joined: Sun Nov 06, 2011 2:12 am

Re: How to intercept pen and touch inputs on windows.

Postby lwttai » Wed Jul 08, 2020 1:13 am

Both subclass and a hook is great. But both of them require a HWND for the target window. Is there any notification or callback from CEF when the Chrome_RenderWidgetHostHWND create as soon as possible?
lwttai
Techie
 
Posts: 22
Joined: Mon Oct 14, 2019 12:18 am

Re: How to intercept pen and touch inputs on windows.

Postby Czarek » Wed Jul 08, 2020 3:39 am

See CefLifeSpanHandler::OnAfterCreated callback.
Maintainer of the CEF Python, PHP Desktop and CEF C API projects. I'm available for contract work, see my resume.
User avatar
Czarek
Virtuoso
 
Posts: 1869
Joined: Sun Nov 06, 2011 2:12 am

Re: How to intercept pen and touch inputs on windows.

Postby lwttai » Wed Jul 08, 2020 5:30 am

I already hook the WinProc in CefLifeSpanHandler::OnAfterCreated callback. But only CefBrowserWindow and Chrome_WidgetWin_0 is created at this timing. The Chrome_RenderWidgetHostHWND window witch receive pen window messages is create after this callback.
lwttai
Techie
 
Posts: 22
Joined: Mon Oct 14, 2019 12:18 am

Re: How to intercept pen and touch inputs on windows.

Postby ndesktop » Wed Jul 08, 2020 6:48 am

You need a CBT hook and intercept HCBT_CREATEWND to catch the creation moment. It should be enough to lookup the window class to match L"Chrome_RenderWidgetHostHWND".
From there you can subclass it, or store the HWND and use another hook to process WM_TOUCH (I'm no expert in touch, but I hear CallWndProc hook is not the best type, but mouse LL hook is - take this with caution).
ndesktop
Expert
 
Posts: 403
Joined: Thu Dec 03, 2015 10:10 am

Re: How to intercept pen and touch inputs on windows.

Postby lwttai » Mon Jul 13, 2020 3:04 am

CBT hook seems too heavy for this~ :D
This is my solution.
1. Hook WndProc of Chrome_WidgetWin_0 in CefLifeSpanHandler::OnAfterCreated
2. Subclass Chrome_RenderWidgetHostHWND in WM_PARENTNOTIFY of Chrome_WidgetWin_0.
Code: Select all
// CefLifeSpanHandler::OnAfterCreated
MyHandler::OnAfterCreated()
{
  ...
  HWND browserWin = m_browser->GetHost()->GetWindowHandle();
  m_chromeWidgetWin = ::GetWindow(browserWin, GW_CHILD);
  m_chromeWidgetWinProc = ::SetWindowLongPtrW(m_chromeWidgetWin, GWL_WNDPROC, ChromWidgtWinHook);
  ...
}

MyHandler::subclassRenderWin(HWND hwnd)
{
  ::SetWindowSubclass(hwnd, ChromeRenderWidgetSubClassProc, kChromeRenderWidgetSubclassId, (DWORD_PTR)this);
}

LRESULT __stdcall ChromeWidgetWinHook(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
  ...
  if (message == WM_PARENTNOTIFY && LOWORD(wparam) == WM_CREATE)
  {
    // At this moment, ::SetWindowLongPtrW return INVALID_WINDOW_HANDLE but ::SetWindowSubclass works well
    if (isRenderWin(lparam))
      getHandlerByWinId(hwnd)->subclassRenderWin(lparam);
  }
  ...
}

LRESULT __stdcall ChromeRenderWidgetSubClassProc(
  HWND hWnd, UINT uMsg, WPARAM wParam,
  LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
  if (uIdSubclass == kChromeRenderWidgetSubclassId)
  {
    // do whatever you want
    ...
  }
  return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}

lwttai
Techie
 
Posts: 22
Joined: Mon Oct 14, 2019 12:18 am


Return to Support Forum

Who is online

Users browsing this forum: Google [Bot] and 36 guests