Técnica de script para botones inaccesibles

 

Yo creía que el programa de duplicación de cedes clone cd tenía unos botones

que eran inaccesibles y, tras pedirle la versión 2.7 a un colega, me puse a

la tarea de realizar un script para intentar solucionar esta situación. Cual

no sería mi sorpresa cuando pido a un amigo que pruebe el script y éste me

cuenta que la versión del clone cd que actualmente está en la página del

fabricante:

 

http://www.elaboratebytes.com

 

es superior a la que me sirvió de referencia y, además, no tenía los

problemas de accesibilidad que motivaron que me tomara el trabajo de hacer

el script.

 

Aunque debo considerar el trabajo en vano, pues siempre se debe intentar

trabajar con las últimas versiones de un programa y, si encima son más

accesibles que las anteriores no merece la pena dedicar trabajo a un

software obsoleto y ya ampliamente superado por la propia empresa que lo

crea y distribuye.

 

NO obstante, adjunto el texto del script, no como fichero adjunto, sino como

parte de este mensaje, pues tiene una técnica que podría usarse en otros

scripts para acceder a botones que ni el cursor del pc ni el de jaws pueden

leer.

 

Primero dispongo el fichero leeme que muestra la teoría que sustenta el

trabajo práctico del script que va después.

 

Si no os gusta esto, borrad el mensaje y ya está.

 

Inicio del fichero leame:

Leeme del script de Clone Cd 2.7 para jaws 3.31 o superior.

 

Autor: Jose Luis Pérez,

con la colaboración de:

José Manuel Castell Gil.

Fecha: 27 de agosto de 2001.

 

Versión del script: 1.0 beta.

 

El programa clone cd no es especialmente inaccesible. Pero,

desafortunadamente, los botones más importantes que son los que se usan para

leer un cd, grabarlo o borrar un disco cdrw, son los que el jaws no lee de

ninguna manera. El script sólo hace esto, aunque la estrategia para

conseguirlo ha sido un tanto rebuscada.

 

Siempre que se pueda se ha de usar el cursor de jaws para acceder a un

elemento de una ventana e interactuar sobre él. El problema es que ni el

propio cursor de jaws detectaba estos elementos con los que no se podían

localizar de ningún modo. Para localizar los botones inaccesibles, he tenido

que contar con ayuda visual. Una vez situado el ratón de forma adecuada, uso

posteriormente las funciones del lenguaje de script de jaws para resituar el

ratón en la forma como la persona que ve lo situó y, también con las mismas

funciones habrá que simular un click con el botón izquierdo.

 

La resituación posterior del ratón merece alguna atención porque si se hace

simplemente en coordenadas absolutas, si la ventana del programa cambia de

posición en pantalla, lo cual es bastante frrecuente, obtendremos un

resultado fallido. La resituación hay que efectuarla teniendo como

referencia el borde izquierdo de la ventana en que estamos trabajando. Como

se trata de un cuadro de diálogo, la ventana es de tamaño fijo y sólo hay

que ocuparse del borde izquierdo y del límite inferior para resituar

correctamente el ratón y simular el click con el botón izquierdo.

 

En resumen, el script hace lo siguiente:

1. Averigua en qué cuadro de diálogo se está trabajando. Si son los cuatro

que tienen botones inaccesibles, el script se pone en marcha y en caso

contrario termina.

2. Se averigua en concreto en qué cuadro de diálogo se está trabajando.

Existe una función especializada en cada uno, aunque el código es igual en

todas ellas. Si se quisiera unificar el código la clase común de estos

cuadros de diálogo es TSettingsForm.

 

3. El script hace una búsqueda por si debajo de las pestañas del cuadro de

diálogo que se ha desplegado está la frase "Archivo imagen". Si es así, lo

indicará para  poner un botón más a la lista de botones no accesibles. Con

todo esto se usa la funcion del lenguaje de script de jaws para poner en

forma accesible, en forma de lista, todos los botones presentes en el cuadro

de diálogo, pero que el jaws no puede leer por sí mismo. El usuario

seleccionará el que desee y el script obrará en consecuencia.

 

4. Por último, se han incluido scripts para las teclas insert+h, insert+f1,

insert+q para responder como el usuario espera cuando las pulsa y se

encuentra con el clone cd cargado. Recuerde que sólo hay un script realmente

válido asociado a la pulsación de control+enter.

 

5. Si experimenta problemas con la funcionalidad del script debe observar lo

siguiente.

A veces hay versiones no registradas del clone cd que presentan como nombre

de la aplicación otro diferente a clonecd. Esto impide que el script se

ponga en marcha, pues según el procedimiento estándar de los scripts de

jaws, un archivo de script de una aplicación arranca siempre y cuando el

nombre del programa coincide con el del script. Si con el clone cd cargado

pulsa insert+q y el nombre de la aplicación no es clonecd, es señal

inequívoca de que hay algún problema con el programa y el script no es que

no funcione, sino es que ni se ha puesto en marcha.

 

Si por alguna causa cambia el título de los cuatro cuadros de diálogo que

despliegan las opciones del menú archivo, el script tampoco funcionará.

Simplemente, cambie las constantes titulo1 ... titulo4 por el valor adecuado

y todo volverá a funcionar como se espera.

 

Por último, respecto al nombre del archivo de imagen que clone cd utiliza,

en algunos ordenadores, jaws detecta un botón para abrir un cuadro de

diálogo para cambiar el nombre y ubicación de ese archivo. De hecho, en el

script editaelarchivo(), hay código para acceder a él. El problema es que en

algunos ordenadores esta técnica no funciona por lo que es mejor no

implementarla y sólo habrá de hacerse si se está completamente seguro de que

su ordenador sí detecta este botón.

 

Fin del fichero leeme.

 

Inicio del script:

 

; Scripts de jaws para clonecd versión 2.7

 

; version 1.0 en pruebas

 

; autor: jose luis perez con la colaboración

 

; jose Manuel Castell Gil

 

; fecha: agosto de 2001

 

; el programa es bastante accesible y lo único

 

; que se hace es acceder a unos botones que

 

; el jaws no puede leer por si mismo

 

; constantes de trabajo

 

const

 

mensaje = "botones no accesibles",

 

; titulo del cuadro de diálogo

 

item1 = "informacion lector|leer imagen|cancelar",

 

titulo1 = "Crear imagen desde el lector",

 

; item1 es la lista de opciones para presentar

 

; titulo1 es el nombre de la ventana que el

 

; script buscará para buscar después los botones

 

; que el jaws no puede leer correctamente

 

item2 = "informacion lector|grabar imagen|cancelar",

 

titulo2 = "Grabar imagen",

 

item3 = "informacion lector|copiar cd|cancelar",

 

titulo3 = "Copiar de lector a grabadora",

 

item4 = "informacion lector|borrar cd|cancelar",

 

titulo4 = "Borrar CD"

 

; se buscan cuatro ventanas con botones no accesibles

 

; porque el clone cd presenta cuatro ventanas con

 

; esta característica y quizá en futuras versiones

 

; cada una pueda tener características especiales,

 

; aunque en la versión actual no es así

 

Script botonesaccesibles ()

 

; este script se activa al pulsar control+enter

 

; recuerda que la pulsación de activación se

 

; cambia en el asistente de teclado de jaws

 

var

 

string NombreVentana,

 

string claseventana,

 

handle myhandle

 

let claseventana = GetWindowClass (getfocus ())

 

if claseventana == "TPageControl" then

 

let myhandle = (getparent (getfocus ()))

 

else

 

let myhandle = getparent(getparent (getparent (getparent (getfocus ()))))

 

endif

 

; obtiene el titulo de la ventana que realmente es

 

; un cuadro de diálogo que tiene los botones que

 

; no son accesibles y que nos interesa encontrar

 

; messagebox (GetWindowClass (myhandle))

 

; TSettingsForm es la clase de ventana

 

let Nombreventana = getwindowname (myhandle)

 

; saystring (nombreventana)

 

if NombreVentana == titulo1 then

 

opcion1(myhandle) ; primera opción

 

elif nombreventana == titulo2 then

 

opcion2 (myhandle) ; segunda opción

 

elif nombreventana == titulo3 then

 

opcion3 (myhandle) ; tercera opción

 

elif nombreventana == titulo4 then

 

opcion4 (myhandle) ; cuarta opción

 

else

 

return ; si el título de la ventana no corresponde

 

; a ninguna de las constantes el script termina

 

endif

 

; observe que el menú archivo tiene cinco opciones

 

; las cuatro primeras despliegan cada una un cuadro

 

; de diálogo cuyo titulo sera buscado por el script

 

; entre las cuatro constantes

 

EndScript

 

Void Function opcion1 (handle myhandle)

 

; la función toma como parámetro el manipulador o

 

; handle del cuadro de diálogo cuyos botones no

 

; accesibles pretendemos encontrar

 

var

 

int index,

 

string nombreventana,

 

string cadena

 

let nombreventana = getwindowname (myhandle)

 

let cadena = item1

 

if ArchivoImagen () == 1 then

 

let cadena = cadena + "|nombre de archivo"

 

endif

 

; si el cuadro de diálogo contiene el nombre del

 

; archivo imagen el script da la ocasión de

 

; poderlo averiguar, aunque no modificar

 

; pues se trata de un texto de sólo lectura

 

let index = DlgSelectItemInList (cadena, mensaje + nombreventana, 0)

 

if index == 1 then

 

informacionlector (myhandle) ; boton de la izquierda

 

elif index == 2 then

 

leerimagen (myhandle) ; boton del centro

 

elif index == 3 then

 

performscript cancelar () ; es el botón cancelar

 

; este botón sí que es accesible, porque aunque

 

; no se puede pulsar, el programa obedece

 

; perfectamente a la tecla escape

 

elif index == 4 then

 

performscript editaelarchivo ()

 

; el nombre del archivo de imagen se puede editar

 

; pero el programa no permite la modificación del

 

; cuadro de edición donde está dicho nombre

 

endif

 

EndFunction

 

Void Function opcion2 (handle myhandle)

 

; las funciones opcion2, 3 y 4 por ahora tienen

 

; la misma filosofía de funcionamiento que la

 

; funcion opcion1

 

var

 

int index,

 

string nombreventana,

 

string cadena

 

let nombreventana = getwindowname(myhandle)

 

let cadena = item2

 

if ArchivoImagen () == 1 then

 

let cadena = cadena + "|nombre de archivo"

 

endif

 

let index = DlgSelectItemInList (cadena, mensaje + nombreventana, 0)

 

if index == 1 then

 

informacionlector (myhandle)

 

elif index == 2 then

 

leerimagen (myhandle)

 

elif index == 3 then

 

performscript cancelar ()

 

elif index == 4 then

 

performscript editaelarchivo ()

 

endif

 

EndFunction

 

 

 

Void Function opcion3 (handle myhandle)

 

; como la funcion opcion1

 

var

 

int index,

 

string nombreventana,

 

string cadena

 

let nombreventana = getwindowname(myhandle)

 

let cadena = item3

 

if ArchivoImagen () == 1 then

 

let cadena = cadena + "|nombre de archivo"

 

endif

 

let index = DlgSelectItemInList (cadena, mensaje + nombreventana, 0)

 

if index == 1 then

 

informacionlector (myhandle)

 

elif index == 2 then

 

leerimagen (myhandle)

 

elif index == 3 then

 

performscript cancelar ()

 

elif index == 4 then

 

performscript editaelarchivo ()

 

endif

 

EndFunction

 

 

 

Void Function opcion4 (handle myhandle)

 

; como la funcion opcion1

 

var

 

int index,

 

string nombreventana,

 

string cadena

 

let nombreventana = getwindowname(myhandle)

 

let cadena = item4

 

if ArchivoImagen () == 1 then

 

let cadena = cadena + "|nombre de archivo"

 

endif

 

let index = DlgSelectItemInList (cadena, mensaje + nombreventana, 0)

 

if index == 1 then

 

informacionlector (myhandle)

 

elif index == 2 then

 

leerimagen (myhandle)

 

elif index == 3 then

 

performscript cancelar ()

 

elif index == 4 then

 

performscript editaelarchivo ()

 

endif

 

EndFunction

 

Int Function ArchivoImagen ()

 

; esta función busca la palabra "archivo imagen"

 

; justo debajo de los nombres de las pestañas

 

; del cuadro de diálogo y si esto es así,

 

; devuelve uno y cero en caso contrario

 

var

 

string cadena

 

savecursor ()

 

routejawstopc ()

 

jawscursor ()

 

jawspageup ()

 

jawshome ()

 

nextline ()

 

nextline ()

 

let cadena = getline ()

 

if cadena == "Archivo imagen" then

 

return 1

 

else

 

return 0

 

endif

 

EndFunction

 

Script editaelarchivo ()

 

; este script busca la palabra "archivo imagen"

 

; justo debajo de los nombres de las pestañas

 

; del cuadro de diálogo y si esto es así, hace

 

; click con el botón izquierdo del ratón en el

 

; principio de la siguiente línea, donde está

 

; el nombre del archivo de imagen. Se abre

 

; un cuadro de edición, pero éste es de sólo

 

; lectura con lo que no se puede modificar

 

; justo debajo hay un botón para cambiar el nombre y ubicación del archivo

 

var

 

string cadena

 

savecursor ()

 

routejawstopc ()

 

jawscursor ()

 

jawspageup ()

 

nextline ()

 

nextline ()

 

jawshome ()

 

let cadena = getline ()

 

if cadena != "Archivo imagen" then

 

return

 

endif

 

nextline ()

 

; nextline ()

 

; en pocos ordenadores si avanzamos el ratón a la siguiente línea

 

; vamos directamente al botón abrir archivo, pero a veces no funciona

 

jawshome ()

 

LeftMouseButton ()

 

pause ()

 

pccursor ()

 

EndScript

 

 

 

Void Function informacionlector (handle myhandle)

 

; esta función busca el boton no accesible

 

; situado a la izquierda del cuadro de diálogo

 

; y hace click sobre él con el botón izquierdo

 

; del ratón, sitúa el ratón usando como referencia

 

; constantes determinadas experimentalmente y el borde

 

; izquierdo y la parte inferior de la ventana

 

var

 

int TopX,

 

int TopY,

 

int bottomX,

 

int bottomY,

 

string NombreVentana

 

let topx = GetWindowleft (myhandle)

 

let topy = GetWindowTop (myhandle)

 

let bottomx = GetWindowright (myhandle)

 

let bottomy = GetWindowBottom (myhandle)

 

routejawstopc()

 

jawscursor ()

 

moveto (topx + 170, bottomy - 60)

 

pause ()

 

LeftMouseButton ()

 

pause ()

 

pccursor ()

 

EndFunction

 

Void Function leerImagen (handle myhandle)

 

; esta función busca el boton no accesible

 

; situado más a la derecha del cuadro de diálogo

 

; y hace click sobre él con el botón izquierdo

 

; del ratón, sitúa el ratón usando como referencia

 

; constantes determinadas experimentalmente y el borde

 

; izquierdo y la parte inferior de la ventana

 

var

 

int TopX,

 

int TopY,

 

int bottomX,

 

int bottomY,

 

string NombreVentana

 

let topx = GetWindowleft (myhandle)

 

let topy = GetWindowTop (myhandle)

 

let bottomx = GetWindowright (myhandle)

 

let bottomy = GetWindowBottom (myhandle)

 

routejawstopc()

 

jawscursor ()

 

moveto (topx + 220, bottomy - 60)

 

pause ()

 

LeftMouseButton ()

 

pause ()

 

pccursor ()

 

EndFunction

 

 

 

Script cancelar ()

 

; manda a la aplicación la tecla escape

 

{esc}

 

pause ()

 

EndScript

 

 

 

 

 

Script ayudasensitiva ()

 

if GetWindowClass (GetCurrentWindow ()) == "TMainForm" then

 

saystring ("ventana principal de clone cd")

 

else

 

PerformScript screensensitivehelp ()

 

endif

 

EndScript

 

Script hotkeyhelp ()

 

saystring ("use control+enter para acceder a los botones inaccesibles de las

cuatro opciones del menú archivo que despliegan cuadros de diálogo")

 

PerformScript HotKeyHelp()

 

EndScript

 

 

 

Script nombredeaplicacion ()

 

saystring ("el script para clone cd 2.7 está cargado")

 

saystring ("el nombre de la aplicación activa es ")

 

saystring (GetAppFileName ())

 

EndScript

 

Fin del script.

 

   --------  

 

 Volver al índice de taller