スクリーン リーダーとハードウェア システムのボタン

ナレーターなどのスクリーン リーダーには、ハードウェア システム ボタンのイベントを認識して処理し、その状態をユーザーに伝える機能が必要です。 場合によっては、スクリーン リーダーでこれらのハードウェア ボタン イベントを排他的に処理し、他のハンドラーにバブルアップさせないようにする必要があります。

Windows 10 バージョン 2004 以降、UWP アプリケーションでは、他のハードウェア ボタンと同様に Fn ハードウェア システム ボタンのイベントをリッスンして処理できるようになりました。 以前は、このシステム ボタンは、他のハードウェア ボタンからイベントと状態を報告する際の修飾子としてのみ機能していました。

Note

Fn ボタンのサポートは OEM 固有であり、(押し続けるキーの組み合わせに対して) オンまたはロックを切り替える機能や、対応するロック インジケーター ライト (視覚障碍のあるユーザーには役に立たない可能性があります) などの機能を含めることができます。

Fn ボタンのイベントは、Windows.UI.Input 名前空間内の新しい SystemButtonEventController クラスを介して公開されます。 SystemButtonEventController オブジェクトは、次のイベントをサポートしています。

重要

SystemButtonEventController は、これらのイベントがより優先度の高いハンドラーによって既に処理されている場合、これらのイベントを受け取ることができません。

次の例では、DispatcherQueue に基づいて SystemButtonEventController を作成し、このオブジェクトがサポートする 4 つのイベントを処理する方法を示しています。

Fn ボタンが押されると、サポートされている複数のイベントが発生するのが一般的です。 たとえば、Surface のキーボードで Fn ボタンを押すと、SystemFunctionButtonPressed、SystemFunctionLockChanged、SystemFunctionLockIndicatorChanged が同時に発生します。

  1. この最初のスニペットでは、必要な名前空間を含め、DispatcherQueueDispatcherQueueController の各オブジェクトを含むいくつかのグローバル オブジェクトを指定し、SystemButtonEventController スレッドを管理しています。

    次に、SystemButtonEventController イベント処理デリゲートの登録時に返されるイベント トークンを指定します。

    namespace winrt
    {
        using namespace Windows::System;
        using namespace Windows::UI::Input;
    }
    
    ...
    
    // Declare related members
    winrt::DispatcherQueueController _queueController;
    winrt::DispatcherQueue _queue;
    winrt::SystemButtonEventController _controller;
    winrt::event_token _fnKeyDownToken;
    winrt::event_token _fnKeyUpToken;
    winrt::event_token _fnLockToken;
    
  2. また、SystemFunctionLockIndicatorChanged イベントのイベント トークンと、アプリケーションが "学習モード" (ユーザーが何かの機能を実行せず、単にキーボードを調べようとしている場合) であるかどうかを示すブール値を指定します。

    winrt::event_token _fnLockIndicatorToken;
    bool _isLearningMode = false;
    
  3. この 3 つ目のスニペットには、SystemButtonEventController オブジェクトがサポートする各イベントに対応するイベント ハンドラー デリゲートが含まれています。

    各イベント ハンドラーから、発生したイベントが通知されます。 また、FunctionLockIndicatorChanged ハンドラーによって、アプリが "学習" モード (_isLearningMode = true) かどうかも制御します。こうすることで、イベントが他のハンドラーにバブルするのを防ぎ、ユーザーは実際にアクションを実行せずにキーボードの機能を試すことができます。

    void SetupSystemButtonEventController()
    {
        // Create dispatcher queue controller and dispatcher queue
        _queueController = winrt::DispatcherQueueController::CreateOnDedicatedThread();
        _queue = _queueController.DispatcherQueue();
    
        // Create controller based on new created dispatcher queue
        _controller = winrt::SystemButtonEventController::CreateForDispatcherQueue(_queue);
    
        // Add Event Handler for each different event
        _fnKeyDownToken = _controller->FunctionButtonPressed(
            [](const winrt::SystemButtonEventController& /*sender*/, const winrt:: FunctionButtonEventArgs& args)
            {
                // Mock function to read the sentence "Fn button is pressed"
                PronounceFunctionButtonPressedMock();
                // Set Handled as true means this event is consumed by this controller
                // no more targets will receive this event
                args.Handled(true);
            });
    
            _fnKeyUpToken = _controller->FunctionButtonReleased(
                [](const winrt::SystemButtonEventController& /*sender*/, const winrt:: FunctionButtonEventArgs& args)
                {
                    // Mock function to read the sentence "Fn button is up"
                    PronounceFunctionButtonReleasedMock();
                    // Set Handled as true means this event is consumed by this controller
                    // no more targets will receive this event
                    args.Handled(true);
                });
    
        _fnLockToken = _controller->FunctionLockChanged(
            [](const winrt::SystemButtonEventController& /*sender*/, const winrt:: FunctionLockChangedEventArgs& args)
            {
                // Mock function to read the sentence "Fn shift is locked/unlocked"
                PronounceFunctionLockMock(args.IsLocked());
                // Set Handled as true means this event is consumed by this controller
                // no more targets will receive this event
                args.Handled(true);
            });
    
        _fnLockIndicatorToken = _controller->FunctionLockIndicatorChanged(
            [](const winrt::SystemButtonEventController& /*sender*/, const winrt:: FunctionLockIndicatorChangedEventArgs& args)
            {
                // Mock function to read the sentence "Fn lock indicator is on/off"
                PronounceFunctionLockIndicatorMock(args.IsIndicatorOn());
                // In learning mode, the user is exploring the keyboard. They expect the program
                // to announce what the key they just pressed WOULD HAVE DONE, without actually
                // doing it. Therefore, handle the event when in learning mode so the key is ignored
                // by the system.
                args.Handled(_isLearningMode);
            });
    }
    

こちらもご覧ください

SystemButtonEventController クラス