WM_Copy, wm_gettext и wm_keydown не работают?

Проблема: мне нужно получить выделенный текст из окна приложения Windows (не моей программы). Я делаю свою работу в Delphi XE, и программное обеспечение, к которому я пытаюсь получить доступ, представляет собой клудж, созданный за последние 15 лет с помощью C, C++, VB и кто знает, чего еще. У меня нет исходного кода. Поле редактирования (памятка в формате RTF), которое я пытаюсь прочитать, относится к классу «Ter32Class». Когда я использую wm_copy, ничего не попадает в буфер обмена. когда я использую wm_gettext, ничего. Когда я использую команды wm_keydown (для имитации Ctrl-Ins или Ctrl-C ) Ничего не произошло. Обратите внимание, что я могу заставить все эти альтернативы работать в wordpad, блокноте и FireFox, но не в этом приложении (или, кстати, в OpenOffice, но это не проблема). Единственный способ, которым я смог программно получить текст из этого поля, — это использовать автогорячую клавишу с простой командой «send ^c». Пока это работает, это неэлегантно. ПОМОЩЬ?!?

Дополнительная информация: Иерархия окон: Ter32Class является дочерним элементом OI_Mdi, который является дочерним элементом MDIClient, который является дочерним элементом OI_Window. Я углубляюсь, чтобы получить соответствующий дескриптор, поскольку он будет реагировать на команду вставки.

Я использую Delphi XE, но мне бы понравилось любое решение на C++ или VB, если ни у одного гуру Delphi XE нет ответа.


person b-p    schedule 12.08.2011    source источник
comment
Я предполагаю, что AutoHotKey использует SendInput, чтобы правильно подделать ввод. Возможно, это один из тех случаев, когда отправки команд WM_KEYDOWN недостаточно. Возможно, вам придется сделать то же самое.   -  person David Heffernan    schedule 12.08.2011


Ответы (1)


С форума по быстрым макросам

Одно из окон, с которым мне нужно поговорить, относится к классу Ter32Class, который, по-видимому, является TE Edit Control, редактором, который не наследуется от стандартного элемента управления RichText.

и

Опубликованный метод общения с этим элементом управления - через его DLL.

поэтому, если что-то не изменилось (сообщение 2006 года), похоже, вам нужно будет использовать его dll для получения текста.

От Sub Systems (веб-сайт управления TE Edit)

Функции интерфейса приложения

GetTerBuffer: получение текста окна
HANDLE GetTerBuffer(hWnd, size)

person Lieven Keersmaekers    schedule 12.08.2011
comment
@David - я никогда не использовал этот компонент, но, поскольку вам необходимо передавать hWnd каждой функции, я предположил, что не имеет значения, какому процессу принадлежит окно. - person Lieven Keersmaekers; 12.08.2011
comment
Некоторые возможные опасения. В этом коде могут использоваться некоторые глобальные переменные. С отдельным процессом у вас есть два их экземпляра. Что, если бы у вас была версия DLL, отличная от целевого приложения, в которой были определены другие структуры данных. Наконец, многие функции Windows API, которые получают дескрипторы окон, работают только при вызове из потока этого окна (то есть того, который его создал). Windows имеет привязку к потоку - это обычная фраза для описания этого. - person David Heffernan; 12.08.2011
comment
@David - Действительные опасения, но поскольку OP только пытается прочитать текст, глобальные переменные не должны быть проблемой. Я не знал, что дескрипторы окон доступны только создавшему их потоку, спасибо. Я оставлю ответ открытым на некоторое время, прежде чем удалить его. ОП, попробуй, не повредит. - person Lieven Keersmaekers; 12.08.2011
comment
Я не знаю точно, что это не сработает, просто есть некоторые сомнения. - person David Heffernan; 12.08.2011
comment
Это обнадеживает, и я попробую все вышеперечисленное. Большое спасибо, и я обновлю, когда у меня будут результаты. - person b-p; 13.08.2011
comment
Обновление: я признаюсь, что еще не пробовал API, но... Я просмотрел дополнительные параметры для отправки текста и обнаружил, что работают следующие: ` keybd_event(VK_CONTROL, 0, 0, 0); keybd_event(ord('C'), 0, 0, 0); keybd_event(ord('C'), 0, KEYEVENTF_KEYUP, 0); keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0); ` - person b-p; 13.08.2011
comment
Мне не удалось заставить sendinput работать - я знаю, что один из них выйдет из строя, если уровень UIPI неадекватен, но я не знаю, почему это не удалось (код ошибки не был указан). - person b-p; 13.08.2011
comment
@Lieven: я попробовал dll. Получение hwnd элемента управления TE Edit было тривиальным, как и настройка доступа к dll, но... Я столкнулся со странной проблемой. ter32.dll имеет некоторые зависимости, некоторые из которых являются взаимными - не слишком уверен в том, чтобы обойти это с помощью динамической загрузки dll. Например, для этого требуется x.dll, для которого требуется y.dll. y.dll требует x.dll. y.dll не загружается, потому что не загружена x.dll (которая не загружается, потому что y.dll не загружена). Конечный результат: ter32.dll не загружается. Я понимаю, что это ответвляется от исходного вопроса. Мне сделать новый пост? - person b-p; 14.08.2011
comment
@b-p - извините за задержку, но да, было бы лучше сделать это новым постом. Мне было бы интересно увидеть решение этой проблемы. - person Lieven Keersmaekers; 14.08.2011
comment
@lieven - готово. см. этот пост здесь - person b-p; 19.08.2011
comment
keybd_event точно сработает, если вы все сделаете правильно. Это просто не может не сработать. Вы дали другому приложению фокус ввода? - person David Heffernan; 19.08.2011
comment
@David - keybd_event работает, но ... Я просто ненавижу использовать для этого буфер обмена. Было бы более аккуратно использовать getsel, gettext, setsel и т. д., и это расстраивает, если вы не можете этого сделать. Я должен учитывать задержки (это работает только с адекватной задержкой) - person b-p; 20.08.2011