Программный интерфейс JFW

(Или как работает библиотека JFWAPI)
Дата публикации:2006
Поделиться в Twitter Поделиться в F******k Поделиться в VKontakte Поделиться в Telegram Поделиться в Mastodon

В основу этой статьи положены материалы и исходные коды, любезно предоставленные Sergey SFeLi.

Внимание! Исходные коды программ и сопутствующая информация представлены как есть и могут быть использованы желающими на свой страх и риск. Никаких гарантий (в том числе того, что приводимая информация является безопасной и не содержит ошибок) не предоставляется.

Основные принципы

Разработчиками программы экранного доступа JAWS предусмотрен программный интерфейс (API), позволяющий взаимодействовать приложениям напрямую с JAWS без посредства скриптов. Этот программный интерфейс содержит весьма узкий набор возможностей, тем не менее позволяющих программистам улучшить доступность своих приложений для работы под JAWS. Известная библиотека jfwapi.dll использует возможности этого интерфейса, однако не всегда программист заинтересован "таскать" за собой эту dll, а даже наоборот - хотел бы включить функции для работы с JAWS в свое приложение. Кроме того, ряд версий библиотеки jfwapi.dll содержат ошибки (например, не работает функция JFWStopSpeech), что тоже не добавляет плюсов этой библиотеки.

Рассмотрим, как реализован программный интерфейс JAWS. Окно JAWS обрабатывает ряд вспомогательных сообщений, благодаря чему внешнее приложение может управлять работой JAWS, посылая ему соответствующее сообщение при помощи системных функций SendMessage или PostMessage. Некоторые из этих сообщений описаны ниже. Имена сообщений выбраны в известной степени произвольно, но главное - это числовой код сообщений и назначение их параметров.

Для того чтобы через JAWS озвучить строку текста, необходимо функцией SendMessage передать окну JAWS системное сообщение WM_COPYDATA, в котором параметр wParam может принимать следующие значения:

  • WM_JFW_SAYNOWAIT = 0x041b - Озвучить указанный текст, прервав озвучивание текущего фрагмента текста .
  • WM_JFW_SAYSTRING = 0x041a - Озвучить указанный текст, без прерывания озвучивания текущего фрагмента текста.

Параметр lParam должен содержать указатель на структуру COPYDATASTRUCT, которая должна содержать озвучиваемую строку текста.

Ниже приведен список сообщений, обрабатываемых окном JAWS. В списке также дано краткое описание сообщений и их параметров. Все сообщения посылаются при помощи функции PostMessage.

  • WM_JFW_STOPSPEECH = 0x0419 - Прерывает речевой вывод.
    Параметры: wParam = 0, lParam = 0.
    Возвращаемое значение: игнорируется.
  • WM_JFW_RUNSCRIPT = 0x0439 - Выполнить скрипт или функцию из файлов сценариев JAWS.
    Параметры: wParam = 0 для выполнения скрипта, =1 для выполнения функции. lParam - должен содержать идентификатор атома из глобальной таблицы атомов. Этот атом должен хранить имя функции или скрипта.
    Возвращаемое значение: игнорируется.
  • WM_JFW_ENABLE = 0x044a - Предположительно отключает/включает озвучивание текстовой информации, получаемой от драйвера видеоперехвата.
    Параметры: wParam(BOOL) =1 - отключить озвучивание текста, полученного от драйвера видеоперехвата. = 0 - включить. lParam = 0.
    Возвращаемое значение: игнорируется.
  • WM_JFW_DISABLE = 0x044b - Предположительно блокирует работу JAWS.
    Параметры: wParam =0, lParam =0.
    Возвращаемое значение: игнорируется.

Исходные коды функций

Исходный код функций, реализующих отправку этих сообщений, достаточно прозрачен и не требует особых пояснений. Ссылка на архив с исходниками находится в соответстсвующем разделе. Далее приводится текст трех файлов:

  • jfwmsg.h - заголовочный файл с определением кодов сообщений.
  • jfwapi.h - заголовочный файл с объявлением функций.
  • jfwapi.c - исходный код на C.
/* --- Файл jfwms.h --- */
#ifndef _JFWMSG_H_
#defined _JFWMSG_H_
#define WM_JFW_STOPSPEECH 0x0419#define WM_JFW_SAYSTRING 0x041a
#define WM_JFW_SAYNOWAIT 0x041b
#define WM_JFW_RUNSCRIPT 0x0439
#define WM_JFW_ENABLE 0x044a
#define WM_JFW_DISABLE 0x044b
#endif
/* --- Файл jfwapi.h --- */
#ifndef _JFWAPI_H_
#define _JFWAPI_H_
extern BOOL WINAPI JFWDisable(void);
extern BOOL WINAPI JFWEnable(BOOL bNoDDIHooks);
extern BOOL WINAPI JFWFindWindow(HWND * hWnd);
extern BOOL WINAPI JFWRunFunction(LPCSTR szName);
extern BOOL WINAPI JFWRunScript(LPCSTR szName);
extern BOOL WINAPI JFWSayString(LPSTR szStringToSpeak, BOOL bInterrupt);
extern BOOL WINAPI JFWStopSpeech(void);
#endif
/* --- Файл jfwapi.c --- */
#include 
#include 
#include "jfwapi.h"
#include "jfwmsg.h"
BOOL WINAPI JFWDisable(void) {
 HWND hWnd;
 if (JFWFindWindow(&hWnd)) {
 PostMessage(hWnd, WM_JFW_DISABLE, 0, 0);
 return TRUE;
 } else {
 return FALSE;
 }
}
BOOL WINAPI JFWEnable(BOOL bNoDDIHooks) {
 HWND hWnd;
 if (JFWFindWindow(&hWnd)) {
 PostMessage(hWnd, WM_JFW_ENABLE, bNoDDIHooks, 0);
 return TRUE;
 } else {
 return FALSE;
 }
}
BOOL WINAPI JFWFindWindow(HWND * hWnd) {
 return ((*hWnd = FindWindow("JFW", NULL)) != NULL);
}
BOOL WINAPI JFWRunFunction(LPCSTR szName) {
 HWND hWnd;
 if (JFWFindWindow(&hWnd)) {
 PostMessage(hWnd, WM_JFW_RUNSCRIPT, TRUE, GlobalAddAtom(szName));
 return TRUE;
 } else {
 return FALSE;
 }
}
BOOL WINAPI JFWRunScript(LPCSTR szName) {
 HWND hWnd;
 if (JFWFindWindow(&hWnd)) {
 PostMessage(hWnd, WM_JFW_RUNSCRIPT, FALSE, GlobalAddAtom(szName));
 return TRUE;
 } else {
 return FALSE;
 }
}
BOOL WINAPI JFWSayString(LPSTR szStringToSpeak, BOOL bInterrupt) {
 HWND hWnd;
 COPYDATASTRUCT cds;
 if (!JFWFindWindow(&hWnd)) return FALSE;
 cds.dwData = 0;
 cds.cbData = strlen(szStringToSpeak) + 1;
 cds.lpData = (PVOID) szStringToSpeak;
 return SendMessage(hWnd, WM_COPYDATA, (bInterrupt) ?
 WM_JFW_SAYNOWAIT : WM_JFW_SAYSTRING, (LPARAM) &cds);
}
BOOL WINAPI JFWStopSpeech(void) {
 HWND hWnd;
 if (JFWFindWindow(&hWnd)) {
 PostMessage(hWnd, WM_JFW_STOPSPEECH, 0, 0);
 return TRUE;
 } else {
 return FALSE;
 }
}


Распространение материалов сайта означает, что распространитель принял условия лицензионного соглашения.
Идея и реализация: © Владимир Довыденков и Анатолий Камынин,  2004-2024