C# Еще один вариант вставки текста во внешнее приложение (вариант 2)
Я когда-то писал статью о передаче текста во внешнее приложение. Там использовалась функция PostMessageW, которая посимвольно передавала текст в окно содержащее фокус ввода. Сейчас я покажу второй вариант, который кардинально отличается от первого.
Для начала нам понадобиться помощник для работы с буфером обмена. Я взял код работы с буфером обмена отсюда. С помощью него, мы будем сохранять объект из буфера и после вставки возвращать его обратно.
В общем реализация выглядит так:
- окно, в которое необходимо передать текст, активно;
- вызывается наше приложение, вводится текст;
- закрываем окно, чтобы предыдущее приложение получило фокус ввода;
- во временную переменную сохраняем содержимое буфера обмена;
- в буфер обмена помещаем свой текст;
- эмулируем нажатие кнопок Ctrl+V;
- возвращаем содержимое буфера обмена из временной переменной.
Вот такая получается у нас схема. Пример к статье, содержит все необходимое для работы. А функция вставки выглядит следующим образом:
[DllImport("user32.dll")]
public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, int dwExtraInfo);
ReadOnlyCollection<DataClip> clipData;
private void pasteText(string text)
{
//закрываем текущее приложение
Close();
//копируем из буфера обмена в переменную
clipData = ClipboardHelper.GetClipboard();
//вставляем текст в буфер
Clipboard.SetDataObject(text, true);
//эмулируем нажатие Ctrl+V
keybd_event(VK_CONTROL, 0, 0, 0);
keybd_event((byte)'V', 0, 0, 0);
keybd_event((byte)'V', 0, WM_KEYUP, 0);
keybd_event(VK_CONTROL, 0, WM_KEYUP, 0);
//возвращаем объект обратно
ClipboardHelper.SetClipboard(clipData);
}
Для эмуляции нажатия кнопок используется функция keybd_event. В процессе тестирования она лучше работала, чем SendMessage.
Преимущества этого метода реализации:
- возможность передать приложению RTF-текст;
- передача текста независимо от того, можно ли получить дескриптор окна. Нам не нужно знать, где находится фокус ввода;
- должно работать во всех версиях Windows.
Заключение
Ниже вы можете скачать тестовый проект. И обязательно прочитайте как запускать.
Важно! Как запускать:
- создайте ярлык на рабочем столе на exe-файл проекта;
- в свойствах ярлыка назначьте горячие клавиши для запуска;
- поставьте курсор в какое-то поле ввода и нажмите заранее заданную комбинацию клавиш ярлыка;
- введите текст и нажмите вставить.
Скачать тестовый проект
Популярность: 25%
Если у вас возникли вопросы, вы можете оставить их в комментариях


Добрый день. А где можно взять коды клавиш. Если мне, например, нужно отправить нажатие клавиши tab, для передвижения фокуса между элементами управления формы. Спасибо
Все коды вы можете посмотреть здесь
Спасибо за ответ, никак не мог найти эту табл. А есть ли возожность передавать сообщения форме без передачи ей фокуса? я как понял не все. Например, используя PostMessage, нажатие таба я передаю без фокуса формы, а вот ввод текста в текст бокс не идет этим же способом. keybd_event, как я понял, работает только с фокусированной формой. Спасибо
keybd_event просто эмулирует нажатие клавиши. Какая форма активна он не смотрит (куда попадет, туда и попадет). PostMessage и SendMessage передают сообщение объекту зная его хэндл. Поэтому им все равно в фокусе форма или нет.
Вот такой пример:
[DllImport("user32.dll", SetLastError = false)]
public static extern IntPtr GetDlgItem(IntPtr hDlg, int nIDDlgItem);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern IntPtr SendMessage(HandleRef hWnd, uint Msg, IntPtr wParam, string lParam);
public const uint WM_SETTEXT = 0x000C;
private void InteropSetText(IntPtr iptrHWndDialog, int iControlID, string strTextToSet)
{
IntPtr iptrHWndControl = GetDlgItem(iptrHWndDialog, iControlID);
HandleRef hrefHWndTarget = new HandleRef(null, iptrHWndControl);
SendMessage(hrefHWndTarget, WM_SETTEXT, IntPtr.Zero, strTextToSet);
}
Спасибо чел. Тема раскрыта отлично.