Botones del sistema de hardware y lectores de pantalla
Los lectores de pantalla, como Narrador, deben ser capaces de reconocer y controlar eventos de botón del sistema de hardware y comunicar su estado a los usuarios. En algunos casos, es posible que el lector de pantalla tenga que controlar estos eventos de botón de hardware exclusivamente y no dejar que se propagan a otros controladores.
A partir de la versión 2004 de Windows 10, las aplicaciones para UWP pueden escuchar y controlar los eventos de botón del sistema de hardware Fn de la misma manera que otros botones de hardware. Anteriormente, este botón del sistema solo actuaba como un modificador para cómo otros botones de hardware notificaron sus eventos y estado.
Nota:
La compatibilidad con botones Fn es específica del OEM y puede incluir características como la capacidad de activar o desactivar (frente a una combinación de teclas de pulsación y suspensión), junto con una luz indicadora de bloqueo correspondiente (que puede no ser útil para los usuarios ciegos o con discapacidades visuales).
Los eventos de botón Fn se exponen a través de una nueva clase SystemButtonEventController en el espacio de nombres Windows.UI.Input . El objeto SystemButtonEventController admite los siguientes eventos:
- SystemFunctionButtonPressed
- SystemFunctionButtonReleased
- SystemFunctionLockChanged
- SystemFunctionLockIndicatorChanged
Importante
SystemButtonEventController no puede recibir estos eventos si ya han sido controlados por un controlador de prioridad más alta.
Ejemplos
En los ejemplos siguientes, se muestra cómo crear un SystemButtonEventController basado en DispatcherQueue y controlar los cuatro eventos admitidos por este objeto.
Es habitual que se activen más de uno de los eventos admitidos cuando se presiona el botón Fn. Por ejemplo, al presionar el botón Fn en un teclado Surface se activa SystemFunctionButtonPressed, SystemFunctionLockChanged y SystemFunctionLockIndicatorChanged al mismo tiempo.
En este primer fragmento de código, simplemente se incluyen los espacios de nombres necesarios y se especifican algunos objetos globales, incluidos los objetos DispatcherQueue y DispatcherQueueController para administrar el subproceso SystemButtonEventController .
A continuación, especificamos los tokens de evento devueltos al registrar los delegados de control de eventos 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;
También especificamos un token de evento para el evento SystemFunctionLockIndicatorChanged junto con una bool para indicar si la aplicación está en "Modo de aprendizaje" (donde el usuario simplemente intenta explorar el teclado sin realizar ninguna función).
winrt::event_token _fnLockIndicatorToken; bool _isLearningMode = false;
Este tercer fragmento de código incluye los delegados del controlador de eventos correspondientes para cada evento admitido por el objeto SystemButtonEventController .
Cada controlador de eventos anuncia el evento que se ha producido. Además, el controlador FunctionLockIndicatorChanged también controla si la aplicación está en modo "Learning" (
_isLearningMode
= true), lo que impide que el evento se propaga a otros controladores y permita al usuario explorar las características del teclado sin realizar realmente la acción.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); }); }