{"id":105529,"date":"2021-08-06T07:00:00","date_gmt":"2021-08-06T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=105529"},"modified":"2021-08-06T07:33:38","modified_gmt":"2021-08-06T14:33:38","slug":"20210806-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20210806-00\/?p=105529","title":{"rendered":"Using Windows Runtime interop methods from C++\/WinRT: Some helper functions"},"content":{"rendered":"<p>Last time, <a title=\"An example of using Windows Runtime interop methods from C++\/WinRT: RequestTokenForWindowAsync\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20210805-00\/?p=105520\"> we saw how to combine various pieces of C++\/WinRT in order to call a Windows Runtime interop interface and capture the result as a C++\/WinRT object<\/a>.<\/p>\n<p>There is some redundancy in the pattern, since you have to name the interface twice: Once to obtain it from the factory, and again to name the member function.<\/p>\n<p>A little helper function will save some typing:<\/p>\n<pre>template&lt;\r\n    typename Result,\r\n    typename WinRTType,\r\n    typename InteropInterface,\r\n    typename... InteropArgs,\r\n    typename... Args&gt;\r\nauto capture_interop(\r\n    HRESULT (STDMETHODCALLTYPE InteropInterface::*method)(InteropArgs...),\r\n    Args&amp;&amp;... args)\r\n{\r\n    return winrt::capture&lt;Result&gt;(\r\n        winrt::get_activation_factory&lt;WinRTType, InteropInterface&gt;(),\r\n        method, std::forward&lt;Args&gt;(args)...);\r\n}\r\n<\/pre>\n<p>Our example last time then simplifies to<\/p>\n<pre>capture_interop&lt;\r\n    winrt::IAsyncOperation&lt;winrt::WebTokenRequestResult&gt;,\r\n    winrt::WebAuthenticationCoreManager&gt;(\r\n    &amp;::IWebAuthenticationCoreManagerInterop::RequestTokenForWindowAsync,\r\n    window,\r\n    static_cast&lt;::IInspectable*&gt;(winrt::get_abi(request)));\r\n<\/pre>\n<p>There is a corresponding pattern for interop interfaces on instance objects.<\/p>\n<pre>template&lt;\r\n    typename Result,\r\n    typename InteropInterface,\r\n    typename... InteropArgs,\r\n    typename... Args&gt;\r\nauto capture_interop(\r\n    winrt::IUnknown const&amp; o,\r\n    HRESULT (STDMETHODCALLTYPE InteropInterface::*method)(InteropArgs...),\r\n    Args&amp;&amp;... args)\r\n{\r\n    return winrt::capture&lt;Result&gt;(\r\n        o.as&lt;InteropInterface&gt;(), method, std::forward&lt;Args&gt;(args)...);\r\n}\r\n<\/pre>\n<p>Usage for this would be something like<\/p>\n<pre>winrt::UserActivity activity = ...;\r\n\r\nauto session = capture_interop&lt;winrt::UserActivitySession&gt;(\r\n    activity, &amp;::IUserActivityInterop::CreateSessionForWindow, window);\r\n<\/pre>\n<p>These helper functions are part of the <a href=\"https:\/\/github.com\/microsoft\/wil\"> Windows Implementation Library<\/a>, documented here: <a href=\"https:\/\/github.com\/microsoft\/wil\/wiki\/WIL-and-C---WinRT-together#capture_interop\"> <code>capture_interop<\/code><\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Getting the interface, and the capturing from it.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-105529","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Getting the interface, and the capturing from it.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/105529","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=105529"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/105529\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=105529"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=105529"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=105529"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}