読者です 読者をやめる 読者になる 読者になる

しっぽを追いかけて

ぐるぐるしながら考えています

Unity と猫の話題が中心   掲載内容は個人の私見であり、所属組織の見解ではありません

Windows ストアアプリの操作用ショートカットキーの実装場所

複数画面のある Windows ストアアプリのプロジェクトテンプレートを作成すると、[Alt+←] や [Alt+→] のショートカットキーでブラウザの戻る・進むのような画面遷移を行うことができます

実はこれは Windows ランタイムの中で制御しているのではなく、自動生成される NavigationHelper の中の下記に記載されています

/// <summary>
/// このページがアクティブで、ウィンドウ全体を使用する場合、Alt キーの組み合わせなどのシステム キーを含む、
/// キーボード操作で呼び出されます。ページがフォーカスされていないときでも、
/// ページ間のキーボード ナビゲーションの検出に使用されます。
/// </summary>
/// <param name="sender">イベントをトリガーしたインスタンス。</param>
/// <param name="e">イベントが発生する条件を説明するイベント データ。</param>
private void CoreDispatcher_AcceleratorKeyActivated(CoreDispatcher sender,
    AcceleratorKeyEventArgs e)
{
    var virtualKey = e.VirtualKey;

    // 左方向キーや右方向キー、または専用に設定した前に戻るキーや次に進むキーを押した場合のみ、
    // 詳細を調査します
    if ((e.EventType == CoreAcceleratorKeyEventType.SystemKeyDown ||
        e.EventType == CoreAcceleratorKeyEventType.KeyDown) &&
        (virtualKey == VirtualKey.Left || virtualKey == VirtualKey.Right ||
        (int)virtualKey == 166 || (int)virtualKey == 167))
    {
        var coreWindow = Window.Current.CoreWindow;
        var downState = CoreVirtualKeyStates.Down;
        bool menuKey = (coreWindow.GetKeyState(VirtualKey.Menu) & downState) == downState;
        bool controlKey = (coreWindow.GetKeyState(VirtualKey.Control) & downState) == downState;
        bool shiftKey = (coreWindow.GetKeyState(VirtualKey.Shift) & downState) == downState;
        bool noModifiers = !menuKey && !controlKey && !shiftKey;
        bool onlyAlt = menuKey && !controlKey && !shiftKey;

        if (((int)virtualKey == 166 && noModifiers) ||
            (virtualKey == VirtualKey.Left && onlyAlt))
        {
            // 前に戻るキーまたは Alt キーを押しながら左方向キーを押すと前に戻ります
            e.Handled = true;
            this.GoBackCommand.Execute(null);
        }
        else if (((int)virtualKey == 167 && noModifiers) ||
            (virtualKey == VirtualKey.Right && onlyAlt))
        {
            // 次に進むキーまたは Alt キーを押しながら右方向キーを押すと次に進みます
            e.Handled = true;
            this.GoForwardCommand.Execute(null);
        }
    }
}

というわけでアプリ側で [Alt+←] や [Alt+→] の動作可否を制御できるわけです

この動作可否は意外と重要で、標準の MessageDialog ではなく自前で何かモーダルダイアログを表示するような場合、このショートカットキーの動作を無効化しておかないと裏で画面遷移ができてしまうという大参事が起きるからです;

モーダルダイアログについては他にも TAB キーによるフォーカス移動が裏でできるなど気を付ける点があり実装上の配慮が必要なちょっと面倒なところがあります