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