Esta página proporciona un conjunto de notas para introducirse al mundo de las llamadas COM que hace NVDA con Microsoft Word.
Para comenzar
- Abre Microsoft Word (con el contenido que desees explorar).
- Pulsa NVDA+ctrl+z para abrir la consola Python
- Accede a un objeto TextInfo: tInfo = focus.makeTextInfo(«caret»)
Comprueba el tamaño del rango actual:
tInfo._rangeObj.start
tInfo._rangeObj.end
Puedes modificar estas posiciones y ver el texto que hay en el rango con tInfo._rangeObj.text.
Exploración de la interfaz
Usar la referencia del modelo de objetos VBA de Microsoft Word es útil para saber qué hay disponible. Visita https://msdn.microsoft.com/EN-US/library/office/ff837519.aspx (si este enlace se rompe, o tienes problemas para llegar a la información, intenta buscar «Microsoft Word range object» y sube un nivel en la jerarquía de la documentación). El modelo de objeto del que hablamos está disponible también en la consola Python, en tInfo._rangeObj. Esto te permite cosas como obtener el número de hipervínculos en el rango, ver el texto para uno de ellos, y su dirección:
tInfo._rangeObj.hyperlinks.count
tInfo._rangeObj.hyperlinks.item(1).range.text
tInfo._rangeObj.hyperlinks.item(1).address
Cómo obtener los identificadores de propiedades y métodos
Al mirar winword.cpp, te darás cuenta de que hay llamadas a _com_dispatch_raw_method y _com_dispatch_raw_propget que se apoyan en definiciones disponibles en la parte superior del archivo, tales como #define wdDISPID_RANGE_START 3. Es importante tener la capacidad de acceder a estos valores. Esto puede hacerse consultando al objeto com el identificador asociado a un nombre:
idisp = tInfo._rangeObj._comobj
idisp.GetIDsOfNames(‘hyperlinks’)
debería mostrar: [156]
_com_dispatch_raw_method y _com_dispatch_raw_propget
NVDA usa estas funciones para llamar a los métodos y propiedades que hemos visto más arriba.
¡Es muy difícil encontrar documentación para ellas!
A continuación se muestra una corta descripción de estas funciones (adaptada de la información en un foro: http://www.progtown.com/topic94739-function-comdispatchmethod.html).
// Obtener propiedades del objeto
HRESULT __ cdecl _com_dispatch_raw_propget(IDispatch * pDisp, DISPID dispid, VARTYPE vt, void * pResult);
// Llamar a un método del objeto
HRESULT __ cdecl _com_dispatch_raw_method (IDispatch * pDisp, DISPID dispid, WORD w, VARTYPE vt, void * pResult, const wchar_t * szFormat…);
// Donde:
pDisp – IDispatch del objeto del método. Este parece ser el objeto en el que quieres hacer la llamada u obtener una propiedad.
dispid – El DISPID del método a llamar. El id del método a llamar, tal y como lo devuelve GetIDsOfNames().
w – DISPATCH_METHOD o DISPATCH_PROPERTYGET.
vt – el tipo a devolver. Debe ser un tipo variant (uno de los siguientes: VT_I4, VT_DISPATCH, VT_BSTR, VT_BOOL, VT_EMPTY, VT_R4. Mira debajo).
pResult – Puntero con la ubicación de memoria donde se guardará el valor devuelto. El tipo debe coincidir con el especificado en el parámetro anterior.
SzFormat – Cadena donde cada byte representa el tipo variant de cada argumento pasado al método en la llamada.
… – variables con argumentos. Los argumentos que se pasan al método según se ha especificado en el parámetro anterior.
Parámetro w
Al recuperar el valor de range.Information usa DISPATCH_PROPERTYGET
parámetro vt
- VT_I4 – pasa una dirección a un entero en pResult (4 bytes)
- VT_DISPATCH – pasa un puntero IDispatchPtr como pResult. Devuelve un tipo de datos complejo, que puede consultarse más adelante.
- VT_BSTR – algún tipo de cadena. Pasa en pResult la dirección a un tipo BST
- VT_BOOL – tipo booleano.
- VT_EMPTY – ¡sin argumento!
- VT_R4 – Número real (de coma flotante). (4 bytes)
Valores conocidos para el parámetro SzFormat
- L»\x0003″ – un entero
- L»\x0003\x0003 – dos enteros
- L»\x0009″ – IDispatchPtr
- Los siguientes valores se han encontrado inspeccionando: https://github.com/svn2github/FDM/blob/master/shdocvw.tli
- L»\x400c – VARIANT *
- L»\x400b – VARIANT_BOOL *
- L»\x000b – VARIANT_BOOL
- L»\x0008 – BSTR
- L»\x4009 – IDispatch * *
- L»\x4003 – LONG *
Para asegurarte de los tipos que necesita una función, puedes buscarla en los archivos *.tlh y *.tli que se crean a través del proceso documentado en el mensaje del commit: e2aa0cc0d2d (en la rama: experiment_useCompiledMSWordInterface).