суббота, 1 августа 2009 г.

Как получить текст под курсором (указателем мыши)

Это перевод How to retrieve text under the cursor (mouse pointer). Автор: Реймонд Чен.

Microsoft Active Accessibility - это технология, которая предоставляет информацию об объектах на экране для вспомогательных средств, таких как читалки экранов (screen readers). Но это не означает, что только читалки экранов могут использовать её.

Вот программа, которая показывает использование Active Accessibility на самом зачаточном уровне: чтение текста. В Active Accessibility есть намного больше всего, чем только чтение текста. Вы можете перемещаться по объектам на экране, читать различные свойства, даже ссылаться на команды по ним - и всё это программно.

Создайте новое приложение, положите на форму метку и таймер, и напишите такой обработчик OnTimer:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  RecalcText;
  Label1.Caption := g_pszText;
end;
Конечно же, самая интересная часть заключена в процедуре RecalcText, которая получает текст под курсором мыши:
  private
    { Private declarations }
    g_pszText: String;
    g_pt: TPoint;
    procedure RecalcText;
  end;

...

uses
  OleAcc;

function AccessibleObjectFromPoint(ptScreen: TPoint; out ppacc: IAccessible; out pvarChild: Variant): HRESULT; stdcall; external 'oleacc.dll';

procedure TForm1.RecalcText;
var
  pt: TPoint;
  pacc: IAccessible;
  vtChild: Variant;
  bsName, bsValue: WideString;
begin
  if GetCursorPos(pt) and ((pt.x <> g_pt.x) or (pt.y <> g_pt.y)) then
  begin
    g_pt := pt;
    if (SUCCEEDED(AccessibleObjectFromPoint(pt, pacc, vtChild))) then
    try
      bsName := '';
      bsValue := '';
      pacc.get_accName(vtChild, bsName);
      pacc.get_accValue(vtChild, bsValue);
      g_pszText := 'Name: ' + bsName + #13#10'Value: ' + bsValue;
    finally
      VarClear(vtChild);
      pacc := nil;
    end;
  end;
end;
Давайте посмотрим на эту функцию. Мы начинаем с того, что берём позицию мышиного курсора и смотрим: изменился ли он с последнего раза. Если да - тогда мы просим функцию AccessibleObjectFromPoint найти нам объект по этим координатам и вернуть экземпляр IAccessible плюс идентификатор потомка (child). Эти два кусочка информации и представляют объект под курсором.

В итоге всё сводится к простому запросу имени (get_accName) и значения (get_accValue) объекта и показе их на форме.

Для получения дальнейшей информации о accessibility - почитайте сайт Сары Форд, в частности, сообщение What is Assistive Technology Compatibility.

Читать далее.

10 комментариев:

  1. Нельзя ли убрать номера строк и зеленую полоску из блоков кода? Очень уж неудобно копипастить :)

    ОтветитьУдалить
  2. Справа-вверху должна быть кнопенька копирования в буфер. Не видно?
    Мне самому не нравится, что не работает как надо по Ctrl + C, но красиво выстроенную нумерацию строк тоже охота иметь.

    ОтветитьУдалить
  3. Да, действительно кнопка есть. В фаерфоксе выдает диалог с кнопкой ОК, что все скопировано :)

    ОтветитьУдалить
  4. У меня в опере нет никакой кнопки, однако, текст выделяется и так, и так. Хочешь - с цифрами, хочешь - без. :)

    По теме: некоторые "тексты" недоступны. Например, перемещаю курсор над этой страничкой - все строки статьи определяются. А когда перемещаю его над кодом примера - Name и Value пусты.

    То же самое, например, если жму выпадающее меню, в опере. Пункт головного меню пишется, а в выпадающем - Name и Value пустые :(

    почему так? Не все объекты выдают своё имя и значение, функциями pacc.get_accName и pacc.get_accValue?

    ОтветитьУдалить
  5. >>> У меня в опере нет никакой кнопки, однако, текст выделяется и так, и так. Хочешь - с цифрами, хочешь - без. :)

    Как-бы прошёл год и плагин подсветки обновился.

    >>> почему так? Не все объекты выдают своё имя и значение, функциями pacc.get_accName и pacc.get_accValue?

    См. ссылку в посте: Читать далее.

    ОтветитьУдалить
  6. Не заметил ссылку :) спасибо!
    Получается, ничего не сделать, хреновастенько работает :( в программе, где это мне требуется тишина практически на всех контролах

    Lingvo 12й свои всплывающие подсказки выдаёт, похоже, абсолютно везде. Наверное, текст распознают. Придётся что-то подобное писать :(

    ОтветитьУдалить
  7. херня редкостная, а не перевод

    ОтветитьУдалить
  8. Зачем изуродовано из C в Делфи???

    ОтветитьУдалить

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку.

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.

Примечание. Отправлять комментарии могут только участники этого блога.