How to Get ICoreWindowInterop from CoreWindow

可紊 提交于 2021-02-08 11:37:57

问题


I have a C++/WinRT/UWP project. I need the HWND and HINSTANCE to be able to correctly initialize Direct Input, otherwise DirectInput manage only to enumerate the keyboard and mouse but not the joysticks.. don't ask me why, I even tried to get the TopMostWindow from the HInstance got with GetModule, it just return NULL when running from my C++/WinRT/UWP app, but works when running from a console app.

documentation https://docs.microsoft.com/en-us/windows/win32/api/corewindow/nn-corewindow-icorewindowinterop I have no idea how to cast my CoreWindow to ICoreWindowInterop. CComPtr is not availble and not usable in C++/WinRT, conflicts with IUnkwnown.

In the method App::OnLaunched(LaunchActivatedEventArgs const& e) I get the current window like this

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

Then I don't know how to get the ICoreWindowInterop from it. CoreWindow is a ICoreWindow , but I don't see any explanation in the Microsoft documentation :/

I tried casting and reinterpret casting without success ( compilation error ). I'm no COM/Windows expert, so I'm quite lost now.

Thanks for the help Cheers, Seb


回答1:


The ICoreWindowInterop is not immediately available from a CoreWindow. The interface is cloaked, and as such will not show up when using IInspectable's introspection. You'll have to drop down to raw COM and explicitly query for the interface.

Kenny Kerr has written an article years ago (Windows 8, where’d you put my HWND?!) that details the required steps. There's still a bit of work required to get this to compile in a C++/WinRT application.

First up, you'll have to declare the ICoreWindowInterop interface. The following will suffice:

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;
};

Next, we need an IUnknown interface pointer to the CoreWindow. There is pre-built functionality as the free function get_unknown. To get this to compile, you'll have to #include <Unknwn.h> before including any C++/WinRT headers.

Once all that is in place, you can easily get the HWND given a CoreWindow instance:

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;
}

There seems to be evidence that reaching down to the HWND will fail Microsoft Store certification. If that is an issue, you'll have to find a different solution.




回答2:


From this document, it mentions how to get the HWND. First query for the ICoreWindowInterop interface by using CoreWindow and then call the get_WindowHandle virtual function to get your app’s HWND. I try to convert the code to c ++ / winrt, you can check it.

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));


来源:https://stackoverflow.com/questions/59526810/how-to-get-icorewindowinterop-from-corewindow

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!