螢幕助讀程式和硬體系統按鈕

朗讀程式等螢幕助讀程式必須能夠辨識並處理硬體系統按鈕事件,並將事件狀態傳達給使用者。 在某些情況下,螢幕助讀程式可能需要專門處理這些硬體按鈕事件,而不讓它們反昇至其他處理常式。

從 Windows 10 版本 2004 開始,UWP 應用程式能以與其他硬體按鈕相同的方式,接聽並處理 Fn 硬體系統按鈕事件。 以往,此系統按鈕僅充當其他硬體按鈕所回報之事件和狀態的修飾元。

注意事項

是否支援 Fn 按鈕取決於 OEM 廠商,功能可能包括:切換/鎖定開啟或關閉的功能 (而非按住不放的按鍵組合),以及對應的鎖定指示燈 (對盲人或視力障礙人士可能沒有幫助)。

Fn 按鈕事件會透過 Windows.UI.Input 命名空間中的新 SystemButtonEventController 類別公開。 SystemButtonEventController 物件支援下列事件:

重要事項

如果這些事件已由優先順序較高的處理常式處理,則 SystemButtonEventController 無法接收這些事件。

範例

以下範例將會示範如何根據 DispatcherQueue 建立 SystemButtonEventController,並處理此物件支援的四種事件。

按下 Fn 按鈕時,通常會引發多個支援的事件。 舉例來說,按下 Surface 鍵盤上的 Fn 按鈕會同時引發 SystemFunctionButtonPressed、SystemFunctionLockChanged 和 SystemFunctionLockIndicatorChanged。

  1. 在第一個程式碼片段中,我們僅加入所需的命名空間,並指定了一些全域物件,包括用來管理 SystemButtonEventController 執行緒的 DispatcherQueueDispatcherQueueController 物件。

    然後,我們指定了註冊 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. 第三個程式碼片段包含 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 類別