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.
--------