Search code examples
visual-c++mfcactivexwebview2

WebView2 based ActiveX control and intercepting WM_LBUTTONDBLCLK


I've got a legacy VS2008 application that requires WebView2 integration, the older IE implementation is no longer viable. To accomplish this I've created and ActiveX control that wraps up the WebView2 API in VS2019. The parent VS2008 CDialog supports multiple instances of this ActiveX control in a grid via CreateControl(). InvokeHelper() is used for simple URL and visibility commands.

All works and functions as expected. However, I need to intercept a double mouse click message to toggle full screen for the ActiveX control over which it was performed.

Problem being I just don't seem to be able to intercept this message. The ActiveX control appears to intercept the WM_LBUTTONDBLCLK message first and simply dismiss it.

Any advice on how to intercept this message would be more than greatly appreciated.


Solution

  • The following based on Poul's sugguestion formed the basis of an acceptable solution.

    1. From your OnCreateCoreWebView2ControllerCompleted(...) handler add ICoreWebView2::AddSCriptToExecuteOnDocumentCreated(lpszJavacode,...)

    2. The following javascript worked for me

      //  Individually 'click' and 'dblclick' handlers work, but together the
      //  'click' handler pre-dominates.  For this reason some timer based
      //  processing needs to be introduced.
      //  https://simplernerd.com/js-double-click/
      LPCTSTR lpszJavacode =
      L"let numClicks = 0;"
      L"const handleClick = () => {"
      L"    numClicks++;"
      L"    if (numClicks === 1) {"
      L"        singleClickTimer = setTimeout(() => {"
      L"            numClicks = 0;"
      L"            window.chrome.webview.postMessage('click');"
      L"        }, 400);"
      L"    } else if (numClicks === 2) {"
      L"        clearTimeout(singleClickTimer);"
      L"        numClicks = 0;"
      L"        window.chrome.webview.postMessage('dblclick');"
      L"    }"
      L"};"
      L"document.addEventListener('click', handleClick);";
      
    3. Set up a receiver for when above javascript produces a result ICoreWebView2::add_WebMessageReceived ( ... )

    4. In the above received callback fetch the Json message

      LPWSTR pwStr;
      args -> get_WebMessageAsJson( &pwStr );
      CString receivedMessage = pwStr
      

      Then search for 'dblclick' and 'click' in received web message receivedMessage.Find(L"dblclick") and (L"click")

    5. Post appropriate WM_LBUTTONDBLCLK or WM_LBUTTONUP message back to COleControl derived parent. This is assumed to be acting as a container for the WebView2 objects

    6. Upon receipt of WM_LBUTTONDBLCLK or WM_LBUTTONUP messages fire back to ActiveX container using COleControl::FireDblClick() and FireClick() respectively.

    7. Create an EVENTSINK_MAP in the ActiveX control container and add handlers DISPID_CLICK and DISPIB_DBLCLK. From those containers post WM_LBUTTONDBLCLK back into the message loop. WM__LBUTTONDOWN and WM_LBUTTONUP were posted for single button click.

    8. Solution was somewhat unexpected for legacy MFC programmer but works just fine and has opened the door for integrating WebView2 into pre-VS2015 apps.