Главная »Статьи » |
В книге Ревича Ю.В. "Нестандартные приемы программирования на 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. Внимание! Запрещается воспроизведение
данной статьи или ее части без согласования с автором. Если вы желаете разместить
эту статью на своем сайте или издать в печатном виде, свяжитесь с автором. |