interface ICoreWebView2ExperimentalCompositionController

Note

This reference is no longer being maintained. For the latest API reference, see WebView2 API Reference.

Note

This an experimental API that is shipped with our prerelease SDK. See WebView2 release notes.

interface ICoreWebView2ExperimentalCompositionController
  : public IUnknown

This interface is an extension of the ICoreWebView2Controller interface to support visual hosting.

Summary

Members Descriptions
add_CursorChanged Add an event handler for the CursorChanged event.
CreateCoreWebView2PointerInfoFromPointerId A helper function to convert a pointerId received from the system into an ICoreWebView2ExperimentalPointerInfo.
get_Cursor The current cursor that WebView thinks it should be.
get_RootVisualTarget The RootVisualTarget is a visual in the hosting app's visual tree.
get_UIAProvider Returns the UI Automation Provider for the WebView.
put_RootVisualTarget Set the RootVisualTarget property.
remove_CursorChanged Remove an event handler previously added with add_CursorChanged.
SendMouseInput If eventKind is COREWEBVIEW2_MOUSE_EVENT_KIND_HORIZONTAL_WHEEL or COREWEBVIEW2_MOUSE_EVENT_KIND_WHEEL, then mouseData specifies the amount of wheel movement.
SendPointerInput SendPointerInput accepts touch or pen pointer input of types defined in COREWEBVIEW2_POINTER_EVENT_KIND.
COREWEBVIEW2_BOUNDS_MODE Mode for how the Bounds property is interpreted in relation to the RasterizationScale property.
COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND Kind of cross origin resource access allowed for host resources during download.
COREWEBVIEW2_MATRIX_4X4 Matrix that represents a 3D transform.
COREWEBVIEW2_MOUSE_EVENT_KIND Mouse event type used by SendMouseInput to convey the type of mouse event being sent to WebView.
COREWEBVIEW2_MOUSE_EVENT_VIRTUAL_KEYS Mouse event virtual keys associated with a COREWEBVIEW2_MOUSE_EVENT_KIND for SendMouseInput.
COREWEBVIEW2_POINTER_EVENT_KIND Pointer event type used by SendPointerInput to convey the type of pointer event being sent to WebView.

An object implementing the ICoreWebView2ExperimentalCompositionController interface will also implement ICoreWebView2Controller. Callers are expected to use ICoreWebView2Controller for resizing, visibility, focus, and so on, and then use ICoreWebView2ExperimentalCompositionController to connect to a composition tree and provide input meant for the WebView.

Members

add_CursorChanged

Add an event handler for the CursorChanged event.

public HRESULT add_CursorChanged(ICoreWebView2ExperimentalCursorChangedEventHandler * eventHandler, EventRegistrationToken * token)

The event is raised when WebView thinks the cursor should be changed. For example, when the mouse cursor is currently the default cursor but is then moved over text, it may try to change to the IBeam cursor.

It is expected for the developer to send COREWEBVIEW2_MOUSE_EVENT_KIND_LEAVE messages (in addition to COREWEBVIEW2_MOUSE_EVENT_KIND_MOVE messages) through the SendMouseInput API. This is to ensure that the mouse is actually within the WebView that sends out CursorChanged events.

        // Register a handler for the CursorChanged event.
        CHECK_FAILURE(m_compositionController->add_CursorChanged(
            Callback<ICoreWebView2ExperimentalCursorChangedEventHandler>(
                [this](ICoreWebView2ExperimentalCompositionController* sender, IUnknown* args)
                    -> HRESULT {
                    HRESULT hr = S_OK;
                    HCURSOR cursor;
                    if (!m_useCursorId)
                    {
                        CHECK_FAILURE(sender->get_Cursor(&cursor));
                    }
                    else
                    {
                        UINT32 cursorId;
                        wil::com_ptr<ICoreWebView2ExperimentalCompositionController2> compositionController2 =
                            m_controller.query<ICoreWebView2ExperimentalCompositionController2>();
                        CHECK_FAILURE(compositionController2->get_SystemCursorId(&cursorId));
                        cursor = ::LoadCursor(nullptr, MAKEINTRESOURCE(cursorId));
                        if (cursor == nullptr)
                        {
                            hr = HRESULT_FROM_WIN32(GetLastError());
                        }
                    }

                    if (SUCCEEDED(hr))
                    {
                        SetClassLongPtr(
                            m_appWindow->GetMainWindow(), GCLP_HCURSOR, (LONG_PTR)cursor);
                    }
                    return hr;
                })
                .Get(),
            &m_cursorChangedToken));

CreateCoreWebView2PointerInfoFromPointerId

A helper function to convert a pointerId received from the system into an ICoreWebView2ExperimentalPointerInfo.

public HRESULT CreateCoreWebView2PointerInfoFromPointerId(UINT pointerId, HWND parentWindow, struct COREWEBVIEW2_MATRIX_4X4 transform, ICoreWebView2ExperimentalPointerInfo ** pointerInfo)

parentWindow is the HWND that contains the WebView. This can be any HWND in the hwnd tree that contains the WebView. The COREWEBVIEW2_MATRIX_4X4 is the transform from that HWND to the WebView. The returned ICoreWebView2ExperimentalPointerInfo is used in SendPointerInfo. The pointer type must be either pen or touch or the function will fail.

get_Cursor

The current cursor that WebView thinks it should be.

public HRESULT get_Cursor(HCURSOR * cursor)

The cursor should be set in WM_SETCURSOR through ::SetCursor or set on the corresponding parent/ancestor HWND of the WebView through ::SetClassLongPtr. The HCURSOR can be freed so CopyCursor/DestroyCursor is recommended to keep your own copy if you are doing more than immediately setting the cursor.

get_RootVisualTarget

The RootVisualTarget is a visual in the hosting app's visual tree.

public HRESULT get_RootVisualTarget(IUnknown ** target)

This visual is where the WebView will connect its visual tree. The app uses this visual to position the WebView within the app. The app still needs to use the Bounds property to size the WebView. The RootVisualTarget property can be an IDCompositionVisual or a Windows::UI::Composition::ContainerVisual. WebView will connect its visual tree to the provided visual before returning from the property setter. The app needs to commit on its device setting the RootVisualTarget property. The RootVisualTarget property supports being set to nullptr to disconnect the WebView from the app's visual tree.

            // Set the host app visual that the WebView will connect its visual
            // tree to.
            BuildDCompTreeUsingVisual();
            if (m_isDcompTargetMode)
            {
                if (!m_dcompTarget)
                {
                    m_dcompTarget = Make<DCompTargetImpl>(this);
                }
                CHECK_FAILURE(
                    m_compositionController->put_RootVisualTarget(m_dcompTarget.get()));
            }
            else
            {
                CHECK_FAILURE(
                    m_compositionController->put_RootVisualTarget(m_dcompWebViewVisual.get()));
            }
            CHECK_FAILURE(m_dcompDevice->Commit());
// Create host app visual that the WebView will connect to.
//   - Create a IDCompositionTarget for the host window
//   - Create a visual and set that as the IDCompositionTarget's root
//   - Create another visual and add that to the IDCompositionTarget's root.
//     This visual will be the visual root for the WebView.
void ViewComponent::BuildDCompTreeUsingVisual()
{
    CHECK_FAILURE_BOOL(m_dcompDevice != nullptr);

    if (m_dcompWebViewVisual == nullptr)
    {
        CHECK_FAILURE(m_dcompDevice->CreateTargetForHwnd(
            m_appWindow->GetMainWindow(), TRUE, &m_dcompHwndTarget));
        CHECK_FAILURE(m_dcompDevice->CreateVisual(&m_dcompRootVisual));
        CHECK_FAILURE(m_dcompHwndTarget->SetRoot(m_dcompRootVisual.get()));
        CHECK_FAILURE(m_dcompDevice->CreateVisual(&m_dcompWebViewVisual));
        CHECK_FAILURE(m_dcompRootVisual->AddVisual(m_dcompWebViewVisual.get(), TRUE, nullptr));
    }
}

get_UIAProvider

Returns the UI Automation Provider for the WebView.

public HRESULT get_UIAProvider(IUnknown ** provider)

put_RootVisualTarget

Set the RootVisualTarget property.

public HRESULT put_RootVisualTarget(IUnknown * target)

remove_CursorChanged

Remove an event handler previously added with add_CursorChanged.

public HRESULT remove_CursorChanged(EventRegistrationToken token)

SendMouseInput

If eventKind is COREWEBVIEW2_MOUSE_EVENT_KIND_HORIZONTAL_WHEEL or COREWEBVIEW2_MOUSE_EVENT_KIND_WHEEL, then mouseData specifies the amount of wheel movement.

public HRESULT SendMouseInput(COREWEBVIEW2_MOUSE_EVENT_KIND eventKind, COREWEBVIEW2_MOUSE_EVENT_VIRTUAL_KEYS virtualKeys, UINT32 mouseData, POINT point)

A positive value indicates that the wheel was rotated forward, away from the user; a negative value indicates that the wheel was rotated backward, toward the user. One wheel click is defined as WHEEL_DELTA, which is 120. If eventKind is COREWEBVIEW2_MOUSE_EVENT_KIND_X_BUTTON_DOUBLE_CLICK COREWEBVIEW2_MOUSE_EVENT_KIND_X_BUTTON_DOWN, or COREWEBVIEW2_MOUSE_EVENT_KIND_X_BUTTON_UP, then mouseData specifies which X buttons were pressed or released. This value should be 1 if the first X button is pressed/released and 2 if the second X button is pressed/released. If eventKind is COREWEBVIEW2_MOUSE_EVENT_KIND_LEAVE, then virtualKeys, mouseData, and point should all be zero. If eventKind is any other value, then mouseData should be zero. Point is expected to be in the client coordinate space of the WebView. To track mouse events that start in the WebView and can potentially move outside of the WebView and host application, calling SetCapture and ReleaseCapture is recommended. To dismiss hover popups, it is also recommended to send COREWEBVIEW2_MOUSE_EVENT_KIND_LEAVE messages.

bool ViewComponent::OnMouseMessage(UINT message, WPARAM wParam, LPARAM lParam)
{
    // Manually relay mouse messages to the WebView
    if (m_dcompDevice || m_wincompCompositor)
    {
        POINT point;
        POINTSTOPOINT(point, lParam);
        if (message == WM_MOUSEWHEEL || message == WM_MOUSEHWHEEL)
        {
            // Mouse wheel messages are delivered in screen coordinates.
            // SendMouseInput expects client coordinates for the WebView, so convert
            // the point from screen to client.
            ::ScreenToClient(m_appWindow->GetMainWindow(), &point);
        }
        // Send the message to the WebView if the mouse location is inside the
        // bounds of the WebView, if the message is telling the WebView the
        // mouse has left the client area, or if we are currently capturing
        // mouse events.
        bool isMouseInWebView = PtInRect(&m_webViewBounds, point);
        if (isMouseInWebView || message == WM_MOUSELEAVE || m_isCapturingMouse)
        {
            DWORD mouseData = 0;
            switch (message)
            {
            case WM_MOUSEWHEEL:
            case WM_MOUSEHWHEEL:
                mouseData = GET_WHEEL_DELTA_WPARAM(wParam);
                break;
            case WM_XBUTTONDBLCLK:
            case WM_XBUTTONDOWN:
            case WM_XBUTTONUP:
                mouseData = GET_XBUTTON_WPARAM(wParam);
                break;
            case WM_MOUSEMOVE:
                if (!m_isTrackingMouse)
                {
                    // WebView needs to know when the mouse leaves the client area
                    // so that it can dismiss hover popups. TrackMouseEvent will
                    // provide a notification when the mouse leaves the client area.
                    TrackMouseEvents(TME_LEAVE);
                    m_isTrackingMouse = true;
                }
                break;
            case WM_MOUSELEAVE:
                m_isTrackingMouse = false;
                break;
            }

            // We need to capture the mouse in case the user drags the
            // mouse outside of the window bounds and we still need to send
            // mouse messages to the WebView process. This is useful for
            // scenarios like dragging the scroll bar or panning a map.
            // This is very similar to the Pointer Message case where a
            // press started inside of the WebView.
            if (message == WM_LBUTTONDOWN || message == WM_MBUTTONDOWN ||
                message == WM_RBUTTONDOWN || message == WM_XBUTTONDOWN)
            {
                if (isMouseInWebView && ::GetCapture() != m_appWindow->GetMainWindow())
                {
                    m_isCapturingMouse = true;
                    ::SetCapture(m_appWindow->GetMainWindow());
                }
            }
            else if (message == WM_LBUTTONUP || message == WM_MBUTTONUP ||
                message == WM_RBUTTONUP || message == WM_XBUTTONUP)
            {
                if (::GetCapture() == m_appWindow->GetMainWindow())
                {
                    m_isCapturingMouse = false;
                    ::ReleaseCapture();
                }
            }

            // Adjust the point from app client coordinates to webview client coordinates.
            // WM_MOUSELEAVE messages don't have a point, so don't adjust the point.
            if (message != WM_MOUSELEAVE)
            {
                point.x -= m_webViewBounds.left;
                point.y -= m_webViewBounds.top;
            }

            CHECK_FAILURE(m_compositionController->SendMouseInput(
                static_cast<COREWEBVIEW2_MOUSE_EVENT_KIND>(message),
                static_cast<COREWEBVIEW2_MOUSE_EVENT_VIRTUAL_KEYS>(GET_KEYSTATE_WPARAM(wParam)),
                mouseData, point));
            return true;
        }
        else if (message == WM_MOUSEMOVE && m_isTrackingMouse)
        {
            // When the mouse moves outside of the WebView, but still inside the app
            // turn off mouse tracking and send the WebView a leave event.
            m_isTrackingMouse = false;
            TrackMouseEvents(TME_LEAVE | TME_CANCEL);
            OnMouseMessage(WM_MOUSELEAVE, 0, 0);
        }
    }
    return false;
}

SendPointerInput

SendPointerInput accepts touch or pen pointer input of types defined in COREWEBVIEW2_POINTER_EVENT_KIND.

public HRESULT SendPointerInput(COREWEBVIEW2_POINTER_EVENT_KIND eventKind, ICoreWebView2ExperimentalPointerInfo * pointerInfo)

Any pointer input from the system must be converted into an ICoreWebView2ExperimentalPointerInfo first.

COREWEBVIEW2_BOUNDS_MODE

Mode for how the Bounds property is interpreted in relation to the RasterizationScale property.

enum COREWEBVIEW2_BOUNDS_MODE

Values Descriptions
COREWEBVIEW2_BOUNDS_MODE_USE_RAW_PIXELS Bounds property represents raw pixels. Physical size of Webview is not impacted by RasterizationScale.
COREWEBVIEW2_BOUNDS_MODE_USE_RASTERIZATION_SCALE Bounds property represents logicl pixels and the RasterizationScale property is used to get the physical size of the WebView.

COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND

Kind of cross origin resource access allowed for host resources during download.

enum COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND

Values Descriptions
COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND_DENY All cross origin resource access is denied, including normal sub resource access as src of a script or image element.
COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND_ALLOW All cross origin resource access is allowed, including accesses that are subject to Cross-Origin Resource Sharing(CORS) check.
COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND_DENY_CORS Cross origin resource access is allowed for normal sub resource access like as src of a script or image element, while any access that subjects to CORS check will be denied.

Note that other normal access checks like same origin DOM access check and Content Security Policy still apply. The following table illustrates the host resource cross origin access according to access context and COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND. Cross Origin Access Context |DENY |ALLOW |DENY_CORS --------- | --------- | --------- | --------- From DOM like src of img, script or iframe element |Deny |Allow |Allow From Script like Fetch or XMLHttpRequest |Deny |Allow |Deny

COREWEBVIEW2_MATRIX_4X4

Matrix that represents a 3D transform.

typedef COREWEBVIEW2_MATRIX_4X4

This transform is used to calculate correct coordinates when calling CreateCoreWebView2PointerInfoFromPointerId. This is equivalent to a D2D1_MATRIX_4X4_F

COREWEBVIEW2_MOUSE_EVENT_KIND

Mouse event type used by SendMouseInput to convey the type of mouse event being sent to WebView.

enum COREWEBVIEW2_MOUSE_EVENT_KIND

Values Descriptions
COREWEBVIEW2_MOUSE_EVENT_KIND_HORIZONTAL_WHEEL Mouse horizontal wheel scroll event, WM_MOUSEHWHEEL.
COREWEBVIEW2_MOUSE_EVENT_KIND_LEFT_BUTTON_DOUBLE_CLICK Left button double click mouse event, WM_LBUTTONDBLCLK.
COREWEBVIEW2_MOUSE_EVENT_KIND_LEFT_BUTTON_DOWN Left button down mouse event, WM_LBUTTONDOWN.
COREWEBVIEW2_MOUSE_EVENT_KIND_LEFT_BUTTON_UP Left button up mouse event, WM_LBUTTONUP.
COREWEBVIEW2_MOUSE_EVENT_KIND_LEAVE Mouse leave event, WM_MOUSELEAVE.
COREWEBVIEW2_MOUSE_EVENT_KIND_MIDDLE_BUTTON_DOUBLE_CLICK Middle button double click mouse event, WM_MBUTTONDBLCLK.
COREWEBVIEW2_MOUSE_EVENT_KIND_MIDDLE_BUTTON_DOWN Middle button down mouse event, WM_MBUTTONDOWN.
COREWEBVIEW2_MOUSE_EVENT_KIND_MIDDLE_BUTTON_UP Middle button up mouse event, WM_MBUTTONUP.
COREWEBVIEW2_MOUSE_EVENT_KIND_MOVE Mouse move event, WM_MOUSEMOVE.
COREWEBVIEW2_MOUSE_EVENT_KIND_RIGHT_BUTTON_DOUBLE_CLICK Right button double click mouse event, WM_RBUTTONDBLCLK.
COREWEBVIEW2_MOUSE_EVENT_KIND_RIGHT_BUTTON_DOWN Right button down mouse event, WM_RBUTTONDOWN.
COREWEBVIEW2_MOUSE_EVENT_KIND_RIGHT_BUTTON_UP Right button up mouse event, WM_RBUTTONUP.
COREWEBVIEW2_MOUSE_EVENT_KIND_WHEEL Mouse wheel scroll event, WM_MOUSEWHEEL.
COREWEBVIEW2_MOUSE_EVENT_KIND_X_BUTTON_DOUBLE_CLICK First or second X button double click mouse event, WM_XBUTTONDBLCLK.
COREWEBVIEW2_MOUSE_EVENT_KIND_X_BUTTON_DOWN First or second X button down mouse event, WM_XBUTTONDOWN.
COREWEBVIEW2_MOUSE_EVENT_KIND_X_BUTTON_UP First or second X button up mouse event, WM_XBUTTONUP.

The values of this enum align with the matching WM_* window messages.

COREWEBVIEW2_MOUSE_EVENT_VIRTUAL_KEYS

Mouse event virtual keys associated with a COREWEBVIEW2_MOUSE_EVENT_KIND for SendMouseInput.

enum COREWEBVIEW2_MOUSE_EVENT_VIRTUAL_KEYS

Values Descriptions
COREWEBVIEW2_MOUSE_EVENT_VIRTUAL_KEYS_NONE No additional keys pressed.
COREWEBVIEW2_MOUSE_EVENT_VIRTUAL_KEYS_LEFT_BUTTON Left mouse button is down, MK_LBUTTON.
COREWEBVIEW2_MOUSE_EVENT_VIRTUAL_KEYS_RIGHT_BUTTON Right mouse button is down, MK_RBUTTON.
COREWEBVIEW2_MOUSE_EVENT_VIRTUAL_KEYS_SHIFT SHIFT key is down, MK_SHIFT.
COREWEBVIEW2_MOUSE_EVENT_VIRTUAL_KEYS_CONTROL CTRL key is down, MK_CONTROL.
COREWEBVIEW2_MOUSE_EVENT_VIRTUAL_KEYS_MIDDLE_BUTTON Middle mouse button is down, MK_MBUTTON.
COREWEBVIEW2_MOUSE_EVENT_VIRTUAL_KEYS_X_BUTTON1 First X button is down, MK_XBUTTON1.
COREWEBVIEW2_MOUSE_EVENT_VIRTUAL_KEYS_X_BUTTON2 Second X button is down, MK_XBUTTON2.

These values can be combined into a bit flag if more than one virtual key is pressed for the event. The values of this enum align with the matching MK_* mouse keys.

COREWEBVIEW2_POINTER_EVENT_KIND

Pointer event type used by SendPointerInput to convey the type of pointer event being sent to WebView.

enum COREWEBVIEW2_POINTER_EVENT_KIND

Values Descriptions
COREWEBVIEW2_POINTER_EVENT_KIND_ACTIVATE Corresponds to WM_POINTERACTIVATE.
COREWEBVIEW2_POINTER_EVENT_KIND_DOWN Corresponds to WM_POINTERDOWN.
COREWEBVIEW2_POINTER_EVENT_KIND_ENTER Corresponds to WM_POINTERENTER.
COREWEBVIEW2_POINTER_EVENT_KIND_LEAVE Corresponds to WM_POINTERLEAVE.
COREWEBVIEW2_POINTER_EVENT_KIND_UP Corresponds to WM_POINTERUP.
COREWEBVIEW2_POINTER_EVENT_KIND_UPDATE Corresponds to WM_POINTERUPDATE.

The values of this enum align with the matching WM_POINTER* window messages.