Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Как сделать кастомизированные компоненты интерфейса доступными для программ чтения экрана в Delphi

Delphi , ОС и Железо , Монитор и Экран

Вопрос доступности приложений для пользователей с ограниченными возможностями зрения становится все более актуальным. Разработчики, использующие Delphi для создания пользовательских интерфейсов, часто сталкиваются с проблемой невидимости кастомизированных компонентов для программ чтения экрана. В данной статье мы рассмотрим, как можно решить эту проблему, используя примеры кода на Object Pascal (Delphi).

Описание проблемы

При разработке приложений на Delphi, использующих кастомизированные компоненты интерфейса, которые наследуются от TWinControl или TGraphicControl, может возникнуть ситуация, когда эти компоненты не распознаются программами чтения экрана, такими как NVDA. Это означает, что пользователи, зависимые от программ чтения экрана, не смогут взаимодействовать с вашим приложением в полной мере.

Подтвержденный ответ

Для того чтобы сделать кастомизированные компоненты видимыми для программ чтения экрана, необходимо реализовать один из доступных API (программных интерфейсов) для доступности. Программа NVDA поддерживает несколько таких API, включая Microsoft Active Accessibility (MSAA), также известный как IAccessible.

Пример реализации IAccessible

  1. Создайте новый интерфейс IAccessible для вашего компонента, который будет возвращать необходимую информацию о компоненте. Это может быть реализовано с помощью перехвата сообщений GetIDsOfNamedChild и get_accChild.
type
  TCustomAccessible = class(TWinControl, IAccessible)
  end;

interface

uses
  Winapi.Windows;

type
  IAccessible = interface(IUnknown)
    ['{79EAC9C0-BAF9-11CE-8C82-00AA004B8EFF}']
    function GetIDOfChild(windowHandle: THandle; var childIndex: Integer): HResult; stdcall;
    function GetIDsOfNamedChild(windowHandle: THandle; name: PChar; var idChild: Integer): HResult; stdcall;
    function AccHitTest(xLeft: Longint; yTop: Longint; var idChild: Integer; var childHit: TPoint; var chkFlags: Longint): HResult; stdcall;
    function GetAccParent(windowHandle: THandle; var parentID: Integer): HResult; stdcall;
    function GetAccChildCount(var childCount: Integer): HResult; stdcall;
    function GetAccName(variant child: OLEVariant; var nameBuf: OLEStr; var childNameLen: Longint; var dw: Longint): HResult; stdcall;
    function GetAccValue(variant child: OLEVariant; var pstrValue: OLEStr; var childValueLen: Longint; var dw: Longint): HResult; stdcall;
    function GetAccDescription(variant child: OLEVariant; var description: OLEStr; var descriptionLen: Longint; var dw: Longint): HResult; stdcall;
    function GetAccRole(variant child: OLEVariant; var varChildRole: Longint): HResult; stdcall;
    function GetAccState(variant child: OLEVariant; var varStateFlags: Longint): HResult; stdcall;
    function GetAccHelpTopic(variant child: OLEVariant; var pstrHelp: OLEStr; var dwHelpWinID: Longint): HResult; stdcall;
    function GetAccHelpFile(variant child: OLEVariant; var pszHelpFile: OLEStr): HResult; stdcall;
    function ElectronicTextSelection(windowHandle: THandle; var chkidSel: Integer): HResult; stdcall;
    function GetAccSelectionInfo(var pSelectionInfo: PAccSelection; var varChildrenSelected: Longint): HResult; stdcall;
    function AccLocation(fromChild: Integer; var xLeft: Longint; var yTop: Longint; var dw: Longint; var varPrserveScreen: Longint): HResult; stdcall;
    function GetAccPropValue(variant child: OLEVariant; var dispid: Integer; var pstrPropName: OLEStr; var pVarProp: OLEVariant; var dw: Longint): HResult; stdcall;
    function PutByName(variant child: OLEVariant; var name: OLEStr; var pvarNewVal: OLEVariant; var dw: Longint): HResult; stdcall;
    function PutByRefChild(variant child: OLEVariant; var refChild: OLEVariant; var pvarNewVal: OLEVariant; var dw: Longint): HResult; stdcall;
    function GetAccDefaultAction(variant child: OLEVariant; var pszDefaultAction: OLEStr; var varChildElemCount: Longint): HResult; stdcall;
    function AccDoDefaultAction(variant child: OLEVariant; dw: Longint): HResult; stdcall;
    function AccSelect(intwocan: Integer; var idChild: Integer; var varChildren: Array[0] of Integer): HResult; stdcall;
    property SupportsGetAsString: Boolean read GetSupportsGetAsString;
    function GetSupportsGetAsString: HResult; stdcall;
    function GetAccText(variant child: OLEVariant; var pstrTextBuf: OLEStr; var lReturn: Longint; var dwReasons: Longint; var pws: Longint): HResult; stdcall;
    function GetAccHelpTopicObj(var pvarHelpObj: OLEVariant): HResult; stdcall;
    function AccDoChar(winid, lKey: Longint): HResult; stdcall;
    function AccWindowThumbGetSize(var pSize: TSize): HResult; stdcall;
    function AccDoMenuCommandValue(menucmd: Longint): HResult; stdcall;
    function AccRoleFromName(name: OLEStr): Integer; stdcall;
    function AccValueFromString(value: OLEStr): Integer; stdcall;
    function AccStateFromSetOfId(ids: Longint): Longint; stdcall;
    function AccHelp Navigate(winid: Integer; dwNavDir: Integer): HResult; stdcall;
    function AccHitLike(winid, child: Integer; dwreasons: Longint): HResult; stdcall;
    function GetnaccDoclandmarkGetByType(winid: Integer; dwtype: Integer): Integer; stdcall;
    function GetnaccDoclandmarkPropertyByType(winid: Integer; dwtype: Integer; var pszwid: OLEStr): Integer; stdcall;
    function AccLocationFromPoint(xLeft: Longint; yTop: Longint; var ppt: TPoint; var id: Integer): HResult; stdcall;
    function AccNavigate(winid, dwidChild: Integer; dwNavDir: Integer): HResult; stdcall;
    function AccValueFromPropertyName(var pszwid: OLEStr): Integer; stdcall;
    function AccHitTestLeftOf(winid, child: Integer): Integer; stdcall;
    function AccHitTestRightOf(winid, child: Integer): Integer; stdcall;
    function AccHitTestTopOf(winid, child: Integer): Integer; stdcall;
    function AccHitTestBottomOf(winid, child: Integer): Integer; stdcall;
    function AccHitTestNearestObj(winid, xLeft: Longint; yTop: Longint): Integer; stdcall;
    function AccHitList(winid, winidstart: Integer; dwIDListflags: Integer; var pwinidlist: Integer): Integer; stdcall;
    function AccLocationOf(winid, child: Integer): Integer; stdcall;
  end;

implementation

// В данном примере необходимо реализовать логику для каждого из методов интерфейса IAccessible
// Например, для получения имени компонента можно перегрузить метод GetAccName следующим образом:
function TCustomAccessible.GetAccName(var child: OLEVariant; var nameBuf: OLEStr; var childNameLen: Longint; var dw: Longint): HResult;
begin
  Result := S_OK; // Успешный результат
  // Здесь должна быть логика для заполнения строки nameBuf именем компонента
end;

end.
  1. Не забудьте зарегистрировать ваш компонент в операционной системе, чтобы он был доступен для программ чтения экрана.

Альтернативные API

Помимо MSAA, существуют и другие API, такие как IAccessible2, Java Access Bridge, UI Automation. Выбор конкретного API зависит от требований вашего приложения и целевой платформы.

Заключение

Следуя этим шагам, вы сможете сделать ваши кастомизированные компоненты видимыми для программ чтения экрана, таких как NVDA, и улучшить доступность вашего приложения для пользователей с ограниченными возможностями зрения.

Создано по материалам из источника по ссылке.

Вопрос касается создания доступных для чтения экрана кастомизированных компонентов интерфейса в среде разработки Delphi.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Монитор и Экран ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-07-12 16:41:13/0.008404016494751/1