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を返しました]エラーが発生する人の参考になれば幸いです。
スポンサーリンク
最後までご覧いただき、ありがとうございます。