Alternativas a la anotación dinámica
Hay otras maneras de proporcionar compatibilidad personalizada con IAccessible para los elementos de la interfaz de usuario y, en algunos casos, son la solución correcta. Antes de la anotación dinámica, estas técnicas alternativas eran las únicas opciones disponibles para los desarrolladores. Incluyen la implementación de todas las técnicas de programación y la interfaz IAccessible .
Implementar toda la interfaz IAccessible
Una técnica alternativa es implementar toda la interfaz IAccessible . Este enfoque suele ser necesario para controles personalizados o elementos de interfaz de usuario radicalmente diferentes; sin embargo, los costos de desarrollo y pruebas son lo suficientemente significativos como para evitarse a menos que sea realmente necesario. Si el objetivo es modificar una sola propiedad, el costo es difícil de justificar.
Técnicas de programación
Otra opción es usar técnicas de subclases y ajuste para modificar la información que se expone para una propiedad específica. Esta es la técnica que la anotación dinámica está pensada para reemplazar. Para invalidar una sola propiedad mediante la subclases y el ajuste, el desarrollador debe realizar los pasos siguientes:
- Subclase el HWND del objeto IAccessible .
- Intercepte el mensaje de WM_GETOBJECT para el valor IParam/OBJID correcto.
- Reenvíe el mensaje WM_GETOBJECT a la clase base mediante la función callWndProc callback. Si se devuelve cero, llame a CreateStdAccessibleObject; De lo contrario, llame a LresultFromObject en el valor devuelto para obtener el puntero de interfaz IAccessible nativo del control.
- Cree una clase contenedora, que implementa IAccessible y encapsula el puntero de interfaz IAccessible devuelto del paso anterior. Esta clase contenedora envía todos los métodos y propiedades al puntero de interfaz IAccessible original, excepto aquellos que se van a invalidar. Esto implica escribir código de reenvío para todas las 21 propiedades y métodos de la interfaz IAccessible , independientemente de cuántos se invaliden realmente.
Además, los desarrolladores deben comprobar las condiciones siguientes:
- El método o la propiedad invalidados solo deben controlar los identificadores secundarios necesarios y reenviar todos los demás al puntero de interfaz IAccessible original.
- El ajuste también debe reenviar interfaces IEnumVARIANT e IOleWindow solo si el objeto original los admite.
- El recuento de referencias debe controlarse correctamente, especialmente si se admiten otras interfaces.
- Los valores devueltos de IDispatch deben controlarse correctamente, especialmente con el método ITypeInfo::Invoke, al que se debe llamar con un puntero de interfaz a la interfaz contenedora, no a un puntero a la interfaz IAccessible original.
Estas técnicas requieren una cantidad considerable de trabajo, incluso si solo se deben invalidar una o dos propiedades. La mayoría del código resultante está relacionado con la subclases y el ajuste, y solo una pequeña fracción proporciona realmente la información invalidada.
Sin embargo, hay escenarios en los que se necesitan estas técnicas. Por ejemplo, si va a realizar cambios estructurales para crear un elemento de interfaz de usuario de marcador de posición, debe usar estas técnicas en lugar de anotación dinámica.
Corregir nombres derivados de etiquetas
Algunos controles comunes de Microsoft Win32, como el control de cuadro de edición, casi siempre se usan con una etiqueta (una entrada LTEXT en el archivo de recursos) o un cuadro de grupo (GROUPBOX en el archivo de recursos). Microsoft Active Accessibility deriva automáticamente la propiedad name del control de su etiqueta. Para estos controles, se omite el texto de la ventana (que se muestra en Microsoft Visual Studio como la propiedad Name o ID), ya que normalmente se genera automáticamente y rara vez es muy descriptivo; por ejemplo, "IDC_EDIT1".
Si la interfaz de usuario de la aplicación no está diseñada correctamente, es posible que Microsoft Active Accessibility no pueda establecer el nombre correctamente. Para asociarse a un control, el cuadro de etiqueta o grupo debe colocarse inmediatamente antes del control dinámico en el orden de tabulación.
El orden de tabulación se puede cambiar mediante la herramienta de Visual Studio (en el menú Formato cuando el editor de recursos está abierto) o editando directamente el archivo de recursos.
En el ejemplo siguiente se muestra la descripción de un archivo de recursos de un cuadro de diálogo que contiene dos cuadros de edición etiquetados.
IDD_INPUTNAME DIALOGEX 22, 17, 312, 118
STYLE DS_SETFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
CAPTION "Enter your name"
FONT 8, "System", 0, 0, 0x0
BEGIN
DEFPUSHBUTTON "OK",IDOK,179,35,30,11,WS_GROUP
LTEXT "First Name:",IDC_STATIC,8,16,43,8
LTEXT "Last Name:",IDC_STATIC,8,33,43,8
EDITTEXT IDC_EDITFIRSTNAME,53,15,120,12,ES_AUTOHSCROLL
EDITTEXT IDC_EDITLASTNAME,53,34,120,12,ES_AUTOHSCROLL
END
En este ejemplo, las etiquetas y los controles no aparecen en el orden de tabulación correcto. Como resultado, La accesibilidad activa de Microsoft asigna el nombre "Apellidos" al cuadro de edición de nombre y ningún nombre en absoluto al cuadro de edición de apellidos.
En el ejemplo siguiente se muestra la lista de recursos correcta. Tenga en cuenta también que las teclas de método abreviado se han designado en las etiquetas.
IDD_INPUTNAME DIALOGEX 22, 17, 312, 118
STYLE DS_SETFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
CAPTION "Enter your name"
FONT 8, "System", 0, 0, 0x0
BEGIN
LTEXT "&First Name:",IDC_STATIC,8,16,43,8
EDITTEXT IDC_EDITFIRSTNAME,53,15,120,12,ES_AUTOHSCROLL
LTEXT "&Last Name:",IDC_STATIC,8,33,43,8
EDITTEXT IDC_EDITLASTNAME,53,34,120,12,ES_AUTOHSCROLL
DEFPUSHBUTTON "OK",IDOK,179,35,30,11,WS_GROUP
END
Cuando los controles tienen etiquetas complementarias, como para valores mínimos y máximos en una barra de seguimiento, estas etiquetas deben colocarse después del control en el orden de tabulación. La etiqueta principal del control debe aparecer inmediatamente antes del propio control.
Asignar nombres a controles sin etiquetas
No siempre es posible o deseable tener una etiqueta visible para cada control. Sin embargo, todavía puede proporcionar un nombre para el control agregando una etiqueta invisible. Como siempre, la etiqueta invisible debe preceder inmediatamente al control en el orden de tabulación.
Si usa el Editor de recursos en Microsoft Visual Studio .NET, puede establecer la propiedad Visible en False. Para que la etiqueta sea invisible al editar el archivo de recursos (.rc), agregue NOT WS_VISIBLE o a la parte de estilo del control de etiqueta, como se muestra en el ejemplo siguiente.
LTEXT "&FullName:",IDC_STATIC,111,23,44,8,NOT WS_VISIBLE
Tenga en cuenta que cualquier tecla de método abreviado designada funciona aunque la etiqueta sea invisible.