single.php

C# WinUI3 のKeyDownイベントで[CoreWindow.GetForCurrentThreadがnullを返しました]が表示される場合の対処法

C# WinUI 3アプリを作っていく途中で、調べたことを忘録的に投稿します。今回はWinUI3プロジェクトで、[CoreWindow.GetForCurrentThread().GetKeyState]を利用してキーの状態を取得する際に[CoreWindow.GetForCurrentThreadがnullを返しました]が表示される場合の対処法です。

[修飾キー]の検出

WinUI3のアプリでキーボードショートカットなどを作る場合に[KeyDown]イベントで処理を行います。

例えばキーボードの[Ctrl]キーを押した際に処理をしたい場合には、次のコードで押されたキーの種類を判別できます。

private void Grid_KeyDown(object sender, KeyRoutedEventArgs e)
{
  switch (e.Key)
  {
    case Windows.System.VirtualKey.Control:
      Message.Text = "Ctrl";
      break;
  }
}

実行した画面でキーボードの[Ctrl]キーを押すと、キーが検出できます。

しかし、[Ctrl]や[Shift]キーなどの押したまま、他キーとの組み合わせを検出できません。

公式の[キーボード イベント]にサンプルコードが記載されています。

private static bool IsCtrlKeyPressed()
{
    var ctrlState = CoreWindow.GetForCurrentThread().GetKeyState(VirtualKey.Control);
    return (ctrlState & CoreVirtualKeyStates.Down) == CoreVirtualKeyStates.Down;
}

このコードを実行すると、次のエラーが表示され動作してくれません。

[System.NullReferenceException: ‘Object reference not set to an instance of an object.’ Windows.UI.Core.CoreWindow.GetForCurrentThread(…) が null を返しました。]

調べてみると[CoreWindow.GetForCurrentThread()]は常にNULLを返すようになってしまったようです。

[InputKeyboardSource]アセンブリに、それっぽいメソッドがあったので代用してみたら使えました。

private static bool IsCtrlKeyPressed()
{
  var ctrlState = InputKeyboardSource.GetKeyStateForCurrentThread(Windows.System.VirtualKey.Control);
  return (ctrlState & CoreVirtualKeyStates.Down) == CoreVirtualKeyStates.Down;
}

[KeyDown]イベントも[Ctrl]との組み合わせを検出できるように変更します。

private void Grid_KeyDown(object sender, KeyRoutedEventArgs e)
{
    string downKey = "";
    if(IsCtrlKeyPressed() == true)
    {
        downKey = "Ctrl ";
        switch (e.Key)
        {
            case Windows.System.VirtualKey.A:
                downKey += "+ A";
                break;
        }
        Message.Text = downKey;
        return;
    }

    switch (e.Key)
    {
        case Windows.System.VirtualKey.Control:
            downKey = "Ctrl";
            break;

        case Windows.System.VirtualKey.A:
            downKey += "A";
            break;
    }

    Message.Text = downKey;
}

実行すると、こんな感じで[Ctrl]と[A]キー組み合わせが検出できました。

まとめ

今回はWinUI3プロジェクトで、[CoreWindow.GetForCurrentThread().GetKeyState]を利用してキーの状態を取得する際に[CoreWindow.GetForCurrentThreadがnullを返しました]が表示される場合の対処法について紹介しました。

公式の[キーボード イベント]に記載されていたサンプルコードでエラーになって焦りましたが、別アセンブリに代替えできるメソッドが用意されていました。

WinUI 3アプリの[KeyDown]イベントで[CoreWindow.GetForCurrentThreadがnullを返しました]エラーが発生する人の参考になれば幸いです。

スポンサーリンク

最後までご覧いただき、ありがとうございます。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です