Как надежно вызывать действия копирования / вставки в буфер обмена в других приложениях, не мешая входной очереди - PullRequest
0 голосов
/ 07 декабря 2010

Некоторое время назад я написал простое приложение, которое окружает выделенный текст в любом поле ввода в любом приложении некоторыми символами Unicode, когда пользователь нажимает некоторую горячую клавишу.По сути, логика приложения следующая:

  • Зарегистрировать глобальную горячую клавишу.
  • Горячая клавиша сработала, теперь установите монитор буфера обмена и вызовите копию буфера обмена, чтобы увидеть, был ли выбран какой-либо текст.
  • Если буфер обмена изменился и теперь содержит текст, окружите указанный текст символами, а затем вызовите вставку буфера обмена, поэтому поле ввода будет обновлено с измененным текстом.

Проблема в том, что я не могу получитьКопировать / вставить функциональность из других приложений надежным способом.То, что я пытался датировать:

  1. Если я отправляю WM_COPY / WM_PASTE, это чаще игнорируется, чем нет, в зависимости от приложения.
  2. Если я использую SendInput, keybd_event или любой другойМешать с клавиатуры, чтобы нажимать / отжимать обычные горячие клавиши буфера обмена, он часто будет манипулировать нажатыми пользователем клавишами: копирование / вставка использует управление или сдвиг, которые также довольно популярны для всех общих горячих клавиш во всех приложениях, включая мое приложение.
  3. Если я использую Journal Hook для непосредственного ввода сообщений клавиатуры в системную очередь ввода, иногда это будет работать нормально, а иногда возникают странные сбои.Кроме того, другие приложения могут использовать JournalHook для себя, и это плохо испортит мое приложение.Не говоря уже о том, что политики безопасности по умолчанию затрудняют использование журнала.
  4. Я пытался получить / установить текст в полях ввода с помощью автоматизации пользовательского интерфейса Windows вместо магии буфера обмена, но это редко работает.

Итак, если вы знаете другие способы заставить другие приложения надежно использовать функции копирования / вставки или даже можете разработать совершенно другой подход, я был бы очень признателен, если бы вы сказали мне:)

Ответы [ 2 ]

0 голосов
/ 01 февраля 2011

О, кажется, я мог найти только более или менее надежный способ вызвать копирование-вставку без SendInput или перехвата журнала, но я должен с этим справиться :-) Так что вот, если кто-то найдет это полезным:

  1. Запоминание и сброс модификаторов клавиатуры с помощью AttachThreadInput (yourAppThreadId, targetAppThreadId) + SetKeyboardState (keyStateWithoutKeyboardModifiers).
  2. Установить модификатор клавиши Ctrl через SetKeyboardState (keyStateWithControl) для сочетания клавиш Ctrl + C / V.
  3. Затем PostMessage для сфокусированного дескриптора управления с сообщением WM_KEYDOWN для клавиши C или V, независимо от того, хотите ли вы скопировать или вставить его.
  4. Вызовите Thread.CurrentThread.Join (20), чтобы позволить другому приложению обрабатывать сообщения - и это самый запаздывающий момент во всей сделке, поскольку я не смог найти надежный способ узнать, когда у другого приложения будет пустая очередь сообщений.
  5. Восстановление запомненных клавиатурных модификаторов.

Кроме того, каждый раз, когда вы выполняете SetKeyboardState, впоследствии вызываете SetForegroundWindow (focusControlHandle) и SetFocus (focusControlHandle).

0 голосов
/ 07 декабря 2010

Я думаю, что ваш подход не так уж плох, может быть, вы можете начать с WM_DRAWCLIPBOARD, чтобы вы могли отслеживать буфер обмена. Хороший пример кода можно найти здесь .
Далее я бы взглянул на Класс SendKeys - Внимание: Flush, Buffer и т. Д. Используйте это для отправки Ctrl + C / V вместо сообщения Windows! Вы должны получить уведомление от вашего монитора, если он работал.
Теперь я бы использовал класс Cliboard для манипулирования данными и их вставки обратно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...