C# Вставка текста в «чужое» приложение. Вариант 1

И немного рекламы: Не знаете что подарить? Выбирайте сумки женские аксессуары женских и мужских коллекций.

Давно хотел написать программу, которая бы хранила заготовки и шаблоны текста, для быстрой вставки в другие приложения. Стандартными средствами .NET это сделать не удалось. В интернете тоже нет конкретной информации, которая бы четко и ясно ответила бы на этот вопрос. По крупицам собрав и разобрав различную информацию, опробовав кучу способов, я смог написать кое-что. Сегодня разберем приложение, которое будет вставлять определенный текст в «чужую» программу.

Реализация

Как я писал выше, одними возможностями .NET такой фокус сделать нельзя. Берем наши старые функции WINAPI. Нам понадобится 7 таких функций. Ниже они перечислены. Каждую описывать не буду. Ищите в MSDN.

using System.Runtime.InteropServices;
...
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern IntPtr GetFocus();

[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();

[DllImport("user32.dll")]
public static extern IntPtr SetForegroundWindow(IntPtr hWnd);

[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern bool PostMessage(IntPtr hWnd, int Msg, char wParam, int lParam);

[DllImport("user32")]
public static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach);

[DllImport("user32")]
public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

[DllImport("kernel32.dll", SetLastError = true)]
static extern uint GetCurrentThreadId();

Первое дело сделано — описали нужные функции.

Остально написать две функции. Обе важные, хоть и короткие. Первая получает дескриптор(хэндл) окна, в котором содержится фокус ввода.

void GetFocusedControl()
{
    IntPtr hFocus;
    IntPtr hFore;
    uint id = 0;
    //узнаем в каком окне находится фокус ввода
    hFore = GetForegroundWindow();
    //подключаемся к процессу
    AttachThreadInput(GetWindowThreadProcessId(hFore, out id), GetCurrentThreadId(), true);
    //получаем хэндл фокуса
    hFocus = GetFocus();
    //отключаемся от процесса
    AttachThreadInput(GetWindowThreadProcessId(hFore, out id), GetCurrentThreadId(), false);
    hControl = hFocus;
}

В переменной hControl содержится наш дескриптор окна, в которое мы будем вставлять текст.

Вторая функции принимает какой-то текст, разбирает его и посимвольно передает его в какое-то окно.

void pasteText(string text)
{
    try
    {
        //активизируем окно, которое имело фокус
        SetForegroundWindow(hControl);
        int WM_CHAR = 0x0102;
        //передаем ему текст посимвольно
        foreach (char ch in text)
        {
            PostMessage(hControl, WM_CHAR, ch, 1);
        }
    }
    catch (Exception error)
    {
        MessageBox.Show(error.Message);
    }
}

Перед передачей функцией SetForegroundWindow мы активизируем окно, в которое передаем текст.

Описаный выше способ передачи использует функцию PostMessage. У этого способа есть определенные минусы:
- нельзя передать форматированный-rtf текст;
- теоретически нельзя будет передать некоторым приложениям (каким, пока не знаю, но теоретически такое возможно);
- неизвестно, как будет работать в новых операционных системах Microsoft.

Из плюсов хочу отметить важную особенность — не используется буфер обмена (clipboard). То, что находится в буфере обмена не затрагивается.

Заключение

Как всегда, я представляю тестовый проект, чтобы вы могли посмотреть как это все работает.

Важно! Как запускать:
- создайте ярлык на рабочем столе на exe-файл проекта;
- в свойствах ярлыка назначьте горячие клавиши для запуска;
- поставьте курсор в какое-то поле ввода и нажмите заранее заданную комбинацию клавиш ярлыка;
- введите текст и нажмите вставить.

Все это необходимо, чтобы приложение до запуска получило дескриптор окна с фокусом. Иначе приложение получит само себя.

Тестовый проект

Популярность: 29%

Теги: , , ,

Если у вас возникли вопросы, вы можете оставить их в комментариях

Комментарии к статье

4 Ответов на “C# Вставка текста в «чужое» приложение. Вариант 1”

Оставить комментарий

(обязательно)

(обязательно)


 

MAXCACHE: 0.32MB/0.01675 sec