より良いエンジニアを目指して

1日1つ。良くなる!上手くなる!

WPF上でManaged DirectXを動かす

昔作ったManagedDirectXのアプリケーションをWPFに移植したい。

Managed DirectXは、もう古の技術なのですが。

とはいえ、以下の記事を参考にさせていただきました。

blogs.wankuma.com

WPFアプリケーションを作成します。

Managed DirectX関連のdllを参照に追加します。

WindowsFormsHostを利用するため、WindowsFormsIntegrationを参照に追加します。

f:id:rimever:20210221151005p:plain

WinFormsのカスタムコントロール(ユーザーコントロールでも可能)を追加して、その中でManaged DirectXを呼び出します。

app.configを以下のように修正します。これがないと、うんともすんとも言わずに動かないので注意です。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <startup useLegacyV2RuntimeActivationPolicy="true">
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/>
    </startup>
    <runtime>
        <!-- AppContextSwitchOverrides value attribute is in the form of 'key1=true|false;key2=true|false  -->
        <AppContextSwitchOverrides value="Switch.UseLegacyAccessibilityFeatures=false;Switch.UseLegacyAccessibilityFeatures.2=false;Switch.UseLegacyAccessibilityFeatures.3=false" />
    </runtime>
</configuration>

では、実行です。

f:id:rimever:20210221151520p:plain
この例外は続行してOK

KeyBoardはどのように取得するか

Managed DirectXでキーボード状態を取得するためのKeyboardDeviceを生成する際にはWinFormsのコントロールを指定します。

これは、なので単純にカスタムコントロールを指定するのはNGです。親コントロール、つまりFormの必要があります。

d.sunnyone.org

上記の記事を参考にさせていただきました。これはWPFのWindowのハンドルを渡すことで対応します。

            // キーボードデバイスの作成
            IntPtr hwd = new WindowInteropHelper(this).Handle;
            _keyboardDevice = new Device(SystemGuid.Keyboard);

            // 協調レベルの設定
            _keyboardDevice.SetCooperativeLevel(hwd,
                CooperativeLevelFlags.NonExclusive | CooperativeLevelFlags.Background);
            // キャプチャするデバイスを取得
            _keyboardDevice.Acquire();

f:id:rimever:20210223094027p:plain

余談ですが、MouseDeviceも同様にできます。Manage DirectXのマウス位置は移動量なので、そんなに使い勝手は良くありませんね。

昔の自分どうしていたかなと思ったら、コントロールのマウス座標取得APIを使ってました。

成果物

github.com