You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C++/WinRT/UWP项目中从CoreWindow获取ICoreWindowInterop

Getting HWND and HINSTANCE for DirectInput in a C++/WinRT UWP Project

Hey there, let's get this sorted out for you—getting the right HWND and HINSTANCE is key to making DirectInput recognize your joystick in a UWP app, and I know the COM interop part can feel confusing when coming from traditional Win32 or dealing with C++/WinRT's unique model.

First, forget GetTopMostWindow—UWP uses a different window model

UWP apps don't expose their windows through old Win32 top-level window functions like that. You need to use the ICoreWindowInterop interface to bridge the C++/WinRT CoreWindow type to the HWND you need. And don't worry about CComPtr—C++/WinRT has its own smart pointer, winrt::com_ptr, that plays nicely with its types.

Step-by-Step Implementation

1. Include the necessary headers

Add these to your source file (likely App.cpp):

#include <windows.ui.core.interop.h>
#include <winrt/Windows.UI.Core.h>
#include <dinput.h> // For DirectInput types

Don't forget to link against dinput8.lib in your project settings (under Linker > Input > Additional Dependencies).

2. Convert CoreWindow to ICoreWindowInterop in App::OnLaunched

Here's how to get the interop interface, extract the HWND, and grab a valid HINSTANCE:

void App::OnLaunched(LaunchActivatedEventArgs const& e)
{
    // Keep your existing window setup code (like creating the root Frame)
    Frame rootFrame = Window::Current().Content().as<Frame>();
    if (rootFrame == nullptr)
    {
        rootFrame = Frame();
        rootFrame.NavigationFailed({ this, &App::OnNavigationFailed });
        Window::Current().Content(rootFrame);
    }

    if (e.PrelaunchActivated() == false)
    {
        if (rootFrame.Content() == nullptr)
        {
            rootFrame.Navigate(xaml_typename<YourAppName::MainPage>(), e.Arguments());
        }
        Window::Current().Activate();
    }

    // --- Start of DirectInput setup code ---
    // Get the current CoreWindow
    winrt::Windows::UI::Core::CoreWindow coreWindow = Window::Current().CoreWindow();

    // Get the underlying IUnknown pointer from the CoreWindow wrapper
    winrt::com_ptr<ICoreWindowInterop> coreWindowInterop;
    winrt::check_hresult(
        winrt::get_unknown(coreWindow)->QueryInterface(
            winrt::guid_of<ICoreWindowInterop>(),
            reinterpret_cast<void**>(coreWindowInterop.put())
        )
    );

    // Extract the HWND
    HWND hwnd = nullptr;
    winrt::check_hresult(coreWindowInterop->get_WindowHandle(&hwnd));

    // Get a valid HINSTANCE for your UWP app
    HINSTANCE hInstance = GetModuleHandleW(nullptr);

    // Now initialize DirectInput with these values
    LPDIRECTINPUT8 di = nullptr;
    winrt::check_hresult(
        DirectInput8Create(
            hInstance,
            DIRECTINPUT_VERSION,
            IID_IDirectInput8,
            reinterpret_cast<void**>(&di),
            nullptr
        )
    );

    // Set the correct cooperative level (critical for joystick enumeration)
    winrt::check_hresult(
        di->SetCooperativeLevel(
            hwnd,
            DISCL_EXCLUSIVE | DISCL_FOREGROUND // Adjust to DISCL_NONEXCLUSIVE if needed
        )
    );

    // Now you can enumerate joysticks as usual!
    // ... your joystick enumeration code here ...
}

Key Notes to Avoid Headaches

  • Use winrt::check_hresult: This macro throws an exception if a COM call fails, making it way easier to debug issues instead of silently ignoring errors.
  • UI Thread Only: Run this code on the UI thread—OnLaunched is already on the UI thread, so this is safe. If you need to access the HWND later from a background thread, marshal back to the UI thread first.
  • Add Game Controller Capability: Enable this in your Package.appxmanifest otherwise your app won't have permission to access joystick devices:
    <Capabilities>
        <DeviceCapability Name="gameController" />
    </Capabilities>
    

Why this works

C++/WinRT types like CoreWindow are wrappers around COM objects. winrt::get_unknown retrieves the underlying IUnknown* from the wrapper, which we use to query the ICoreWindowInterop interface. This interface gives us direct access to the HWND UWP uses under the hood—something DirectInput needs to properly associate with input devices (including joysticks).

内容的提问来源于stack exchange,提问作者SebKun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:10:10