如何从CoreWindow获取ICoreWindowInterop

时间:2019-12-30 06:49:36

标签: uwp c++-winrt

我有一个C ++ / WinRT / UWP项目。 我需要HWND和HINSTANCE才能正确初始化Direct Input,否则DirectInput只能枚举键盘和鼠标,而不能枚举操纵杆。.不要问我为什么,我什至尝试从HInstance附带的TopMostWindow中获取。 GetModule,从我的C ++ / WinRT / UWP应用程序运行时,它只是返回NULL,而从控制台应用程序运行时,它可以工作。

文档https://docs.microsoft.com/en-us/windows/win32/api/corewindow/nn-corewindow-icorewindowinterop 我不知道如何将我的CoreWindow转换为ICoreWindowInterop。 CComPtr不可用,在C ++ / WinRT中不可用,与IUnkwnown冲突。

在App :: OnLaunched(LaunchActivatedEventArgs const&e)方法中 我得到这样的当前窗口

CoreWindow w = Window :: Current()。CoreWindow()。GetForCurrentThread();

然后,我不知道如何从中获取ICoreWindowInterop。 CoreWindow是ICoreWindow,但我在Microsoft文档中看不到任何解释:/

我尝试了转换并重新解释了转换,但均未成功(编译错误)。 我不是COM / Windows专家,所以现在我很迷路。

感谢您的帮助 干杯, 塞巴

2 个答案:

答案 0 :(得分:2)

CoreWindow不能立即提供ICoreWindowInterop。该接口是伪装的,因此在使用IInspectable进行内省时不会显示。您必须下拉至原始COM并显式查询接口。

肯尼·科尔(Kenny Kerr)多年前写了一篇文章(Windows 8, where’d you put my HWND?!),其中详细介绍了所需的步骤。要将此内容编译到C ++ / WinRT应用程序中,还需要做一些工作。

首先,您必须声明ICoreWindowInterop接口。满足以下条件:

struct
__declspec(uuid("45D64A29-A63E-4CB6-B498-5781D298CB4F"))
__declspec(novtable)
ICoreWindowInterop : public IUnknown
{
    virtual HRESULT STDMETHODCALLTYPE get_WindowHandle(HWND* hwnd) = 0;
    virtual HRESULT STDMETHODCALLTYPE put_MessageHandled(unsigned char value) = 0;
};

接下来,我们需要一个指向IUnknown的{​​{1}}接口指针。有一些预先构建的功能,如自由功能get_unknown。要使其编译,必须先CoreWindow,然后再包含任何C ++ / WinRT标头。

一切就绪后,您可以轻松获得给定#include <Unknwn.h>实例的HWND

CoreWindow

似乎有证据表明,降到HWND from_core_window(CoreWindow const& window) { winrt::com_ptr<ICoreWindowInterop> interop {}; winrt::check_hresult(winrt::get_unknown(window)->QueryInterface(interop.put())); HWND hwnd {}; winrt::check_hresult(interop->get_WindowHandle(&hwnd)); return hwnd; } fail Microsoft Store certification。如果这是一个问题,则必须找到其他解决方案。

答案 1 :(得分:0)

document开始,它提到了如何获得HWND。首先使用CoreWindow查询ICoreWindowInterop接口,然后调用get_WindowHandle虚拟函数以获取应用的HWND。我尝试将代码转换为c ++ / winrt,可以检查一下。

App.h

namespace XXXX
{
    MIDL_INTERFACE("45D64A29-A63E-4CB6-B498-5781D298CB4F")
        ICoreWindowInterop : public IUnknown
    {
    public:
        virtual HRESULT STDMETHODCALLTYPE get_WindowHandle(
            __RPC__deref_out_opt HWND * hwnd) = 0;

        virtual HRESULT STDMETHODCALLTYPE put_MessageHandled(
            boolean value) = 0;

    };

    struct App : AppT<App>
    {
        App();

        ......
    };
}

App.cpp

CoreWindow w = CoreWindow::GetForCurrentThread();
winrt::com_ptr<ICoreWindowInterop> interop;
winrt::check_hresult(winrt::get_unknown(w)->QueryInterface(interop.put()));

HWND hwnd;
winrt::check_hresult(interop->get_WindowHandle(&hwnd));