Skip to content

Commit

Permalink
Merge pull request #4599 from MicrosoftEdge/api-specs-com-conversion
Browse files Browse the repository at this point in the history
API Review: Interop between COM and WinRT
  • Loading branch information
david-risney committed Jun 12, 2024
2 parents 977d00b + 817bb8b commit 4d9bcfb
Showing 1 changed file with 89 additions and 1 deletion.
90 changes: 89 additions & 1 deletion specs/CoreWebView2.CreateFromCOMObject.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,14 @@ To help implement this for Unity, we are adding a new static factory function on
class that will allow it to wrap an existing ICoreWebView2 COM object, instead of creating a new
one.

To round out the more general scenario of interoperating between libraries written in different
languages, we add the ability to convert a CoreWebView2 to and from .NET and COM, as well as
to and from WinRT and COM.

# Examples
## CoreWebView2.CreateFromComICoreWebView2

## COM to .NET

```c#
public class MyWebView2Control
{
Expand Down Expand Up @@ -47,8 +53,52 @@ public class MyWebView2Control
}
```

## WinRT to COM

```c++
winrt::com_ptr<ICoreWebView2> GetComICoreWebView2FromCoreWebView2(
winrt::Microsoft::Web::WebView2::Core::CoreWebView2 coreWebView2WinRT)
{
// Get the COM interop interface from the WinRT CoreWebView2.
auto interop = coreWebView2WinRT.as<ICoreWebView2Interop2>();

// Get the COM ICoreWebView2 object from the COM interop interface.
winrt::com_ptr<ICoreWebView2> coreWebView2Com;
winrt::check_hresult(interop->GetComICoreWebView2(coreWebView2Com.put()));

return coreWebView2Com;
}
```
## COM to WinRT
```c++
winrt::Microsoft::Web::WebView2::Core::CoreWebView2 CreateCoreWebView2FromComICoreWebView2(
winrt::com_ptr<ICoreWebView2> coreWebView2Com)
{
auto factory = winrt::get_activation_factory<
winrt::Microsoft::Web::WebView2::Core::CoreWebView2>();
// Get the COM interop interface from the WinRT factory.
auto interop = factory.try_as<ICoreWebView2ActivationFactoryInterop>();
// Get the WinRT CoreWebView2 object from the COM interop interface as
// its ABI interface.
winrt::com_ptr<IUnknown> coreWebView2WinRTAsIUnknown;
winrt::check_hresult(interop->CreateFromComICoreWebView2(
coreWebView2Com.get(), coreWebView2WinRTAsIUnknown.put()));
// Convert from the WinRT CoreWebView2 object API interface to C++/WinRT type
return coreWebView2WinRTAsIUnknown.as<
winrt::Microsoft::Web::WebView2::Core::CoreWebView2>();
}
```


# API Details

## .NET API

```c#
namespace Microsoft.Web.WebView2.Core
{
Expand All @@ -64,10 +114,48 @@ namespace Microsoft.Web.WebView2.Core
/// <exception cref="ArgumentNullException">Thrown when the provided COM pointer is null.</exception>
/// <exception cref="InvalidComObjectException">Thrown when the value is not an ICoreWebView2 COM object and cannot be wrapped.</exception>
public static CoreWebView2 CreateFromComICoreWebView2(IntPtr value);

/// <summary>
/// Returns the existing COM ICoreWebView2 object underlying this .NET CoreWebView2 object.
/// This allows interacting with the WebView2 control using COM APIs,
/// even if the control was originally created using .NET.
/// </summary>
/// <returns>Pointer to a COM object that implements the ICoreWebView2 COM interface.</returns>
public IntPtr GetComICoreWebView2();
}
}
```

## WinRT COM Interop API

```c# (but really COM IDL)
/// Interop interface for the CoreWebView2 WinRT object to allow WinRT end
/// developers to be able to use COM interfaces as parameters for some methods.
/// This interface is implemented by the Microsoft.Web.WebView2.Core.CoreWebView2
/// runtime class.
[uuid(B151AD7C-CFB0-4ECF-B9B2-AFCA868581A6), object, pointer_default(unique)]
interface ICoreWebView2Interop2 : IUnknown {
/// Get a COM ICoreWebView2 interface corresponding to this WinRT CoreWebView2
/// object.
HRESULT GetComICoreWebView2([out, retval] ICoreWebView2** coreWebView2);
}

/// Interop interface for the CoreWebView2 WinRT activation factory object to allow
/// WinRT end developers to be able to use COM interfaces as parameters for some
/// methods.
/// This interface is implemented by the Microsoft.Web.WebView2.Core.CoreWebView2
/// activation factory runtime class.
[uuid(BABBED43-D40E-40CF-B106-8ED65FAE2E7C), object, pointer_default(unique)]
interface ICoreWebView2ActivationFactoryInterop : IUnknown {
/// Creates a CoreWebView2 WinRT object that wraps an existing COM ICoreWebView2 object.
/// This allows interacting with the WebView2 control using WinRT,
/// even if the control was originally created using COM.
HRESULT CreateFromComICoreWebView2([in] ICoreWebView2* coreWebView2Com,
[out, retval] IUnknown** coreWebView2WinRt);
}

```

# Appendix
We have a couple of other options to accomplish this, including moving the "CreateFromComICoreWebView2" function to the
CoreWebView2Controller class instead. CoreWebView2Controller could then be used to get the CoreWebView2 through
Expand Down

0 comments on commit 4d9bcfb

Please sign in to comment.