Главная »Статьи »Ёпрст — корректор текста: как это сделано
Ёпрст — корректор текста: как это сделано

В книге Ревича Ю.В. "Нестандартные приемы программирования на Delphi" описывается процесс создания программы-корректора текста, набранного в неправильной раскладке клавиатуры, т.е. русского текста случайно набранного английскими буквами или английского текста набранного русскими буквами. Идея программы проста: она должна скопировать выделенный текст в буфер обмена, загрузить его, определить язык, исправить текст, заменить его в буфере обмена и вставить на место выделенного. В книге пошагово описывается этот процесс. Основную трудность представляет кодировка русского языка в WindoswXP. Предложенные в книге варианты решения этой проблемы хорошо работают со многими приложениями, но к сожалению с MS Word проблема остается. Выложенные в Интернет готовые программы по разным причинам мне не подошли, поэтому возникла идея доработать код Ревича Ю.В., для обеспечения корректной работы с MS Word.

Суть идеи заключается в том, что перед попыткой послать приложению команды на копирование текста в буфер обмена проводится проверка (по имени класса окна) не MS Word-ли это. И если это так, то делается попытка подключиться к нему через механизм OLE. Далее извлечение и замена текста выполняются методами OLE Automation. Кроме решения проблемы с кодировкой русского языка, этот способ позволяет сохранить содержимое буфера обмена. Если же имя класса окна не соответствует имени класса окна MS Word, то работа проводится через буфер обмена.

Полный текст процедуры обработки приведен ниже, а исходный код программы в конце статьи.

procedure RecodeProc;
var
  n: Integer;
  EdtHandle: HWnd;
  pCapText, pClsName: PChar;
  CapText, ClsName: String;
  s: String;
begin
  WndHandle:= GetForegroundWindow;        // Хендл вызывающего окна

  n:= GetWindowTextLength(WndHandle) + 1; // Выделяем буферы для текста
  pCapText:= StrAlloc(n);
  pClsName:= StrAlloc(255);

  GetWindowText(WndHandle, pCapText, n);  // Считываем  текст заголовка окна
  GetClassName(WndHandle, pClsName, 255); // Считываем название класса окна

  CapText:= StrPas(pCapText);
  ClsName:= StrPas(pClsName);

  StrDispose(pCapText);
  StrDispose(pClsName);

  if AnsiCompareText('OpusApp', ClsName) = 0 then // если это MSWord
  begin
    WordApp:= GetActiveOleObject('Word.Application');
    if not VarIsEmpty(WordApp) then
    begin
      s:= WordApp.ActiveDocument.ActiveWindow.Selection.Text; // Взять из текст MSWord
      Translate(s);
      WordApp.ActiveDocument.ActiveWindow.Selection.Text:= s; // Вернуть текст в MSWord
      WordApp:= Unassigned;
    end;
  end else // это не MSWord
  begin
    EdtHandle:= GetTopWindow(WndHandle);

    keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), 0, 0);
    keybd_event(Ord('C'), MapVirtualKey(Ord('C'), 0), 0, 0);
    keybd_event(Ord('C'), MapVirtualKey(Ord('C'), 0), KEYEVENTF_KEYUP, 0);
    keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), KEYEVENTF_KEYUP, 0);
    SendMessage(EdtHandle, WM_COMMAND, $00010043, $00000000); // Ускоритель
    
    // Задержка, чтобы приложение закрыло буфер обмена
    Sleep(50); // Постоянная задержка
    while not OpenClipboard(FHandle) do Sleep(5); // Задержка, пока буфер не откроется
    CloseClipboard;                               // Закрыть открытый нами буфер
    // Взять строку из буфера
    s:= Clipboard.AsText;
    // Перекодировать
    Translate(s);
    // Вернуть обратно в буфер
    Clipboard.Open;
    Clipboard.AsText:= s;
    Clipboard.Close;
    
    // Вставить вместо выделенного
    keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), 0, 0);
    keybd_event(Ord('V'), MapVirtualKey(Ord('V'), 0), 0, 0);
    keybd_event(Ord('V'), MapVirtualKey(Ord('V'), 0), KEYEVENTF_KEYUP, 0);
    keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), KEYEVENTF_KEYUP, 0);
    SendMessage(EdtHandle, WM_COMMAND, $00010043, $00000000); // Ускоритель
  end;
end;

К статье прилагаются файлы с исходным кодом на Delphi.


Внимание! Запрещается воспроизведение данной статьи или ее части без согласования с автором. Если вы желаете разместить эту статью на своем сайте или издать в печатном виде, свяжитесь с автором.
Автор статьи: Вершинин И.В.

 
Используются технологии uCoz