Получить активный текст окна (и отправить больше текста к нему) - PullRequest
12 голосов
/ 26 января 2009

Я создаю небольшую утилиту в C #, которая добавляет некоторый текст в активное текстовое поле при нажатии глобальной горячей клавиши, это тип функции автозаполнения. У меня работает глобальная горячая клавиша, но теперь я не знаю, как получить текущий текст в активном текстовом поле (если активным окном является текстовое поле, которое есть.) До сих пор я пробовал использовать

а. GetForegroundWindow, а затем используя этот дескриптор, вызывая GetWindowText. Это дало мне название окна активного окна, а не содержимое текстового поля.

б. GetActiveWindow и используя этот дескриптор для вызова GetWindowText. Это не дает мне никакого текста.

Вот пример того, что я сделал

[DllImport("user32.dll")]
private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
[ DllImport("user32.dll") ]
static extern int GetForegroundWindow();
[ DllImport("user32.dll") ]
static extern int GetWindowText(int hWnd, StringBuilder text, int count);   
[DllImport("user32.dll")]
static extern int GetActiveWindow();

public static void TestA() {
    int h = GetForegroundWindow();
    StringBuilder b = new StringBuilder();
    GetWindowText(h, b, 256);
    MessageBox.Show(b.ToString());
}

public static void TestB() {
    int h = GetActiveWindow();
    StringBuilder b = new StringBuilder();
    GetWindowText(h, b, 256);
    MessageBox.Show(b.ToString());
}

Итак, есть идеи, как этого добиться?

Изменить 28.01.2009: Итак, я узнал, как это сделать. Вот что я использовал:

using System;
using System.Text;
using System.Runtime.InteropServices;

public class Example
{
[DllImport("user32.dll")]
static extern int GetFocus();

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

[DllImport("kernel32.dll")]
static extern uint GetCurrentThreadId();

[DllImport("user32.dll")]
static extern uint GetWindowThreadProcessId(int hWnd, int ProcessId);    

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

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
static extern int SendMessage(int hWnd, int Msg, int wParam, StringBuilder lParam); 

const int WM_SETTEXT = 12;
const int WM_GETTEXT = 13;

public static void Main() 
{
    //Wait 5 seconds to give us a chance to give focus to some edit window,
    //notepad for example
    System.Threading.Thread.Sleep(5000);
    StringBuilder builder = new StringBuilder(500);

    int foregroundWindowHandle = GetForegroundWindow();
    uint remoteThreadId = GetWindowThreadProcessId(foregroundWindowHandle, 0);
    uint currentThreadId = GetCurrentThreadId();

    //AttachTrheadInput is needed so we can get the handle of a focused window in another app
    AttachThreadInput(remoteThreadId, currentThreadId, true);
    //Get the handle of a focused window
    int  focused = GetFocus();
    //Now detach since we got the focused handle
    AttachThreadInput(remoteThreadId, currentThreadId, false);

    //Get the text from the active window into the stringbuilder
    SendMessage(focused, WM_GETTEXT, builder.Capacity, builder);
    Console.WriteLine("Text in active window was " + builder);
    builder.Append(" Extra text");
    //Change the text in the active window
    SendMessage(focused, WM_SETTEXT, 0, builder);
    Console.ReadKey();
    }
}

Несколько замечаний по этому поводу. Пример ждет 5 секунд, прежде чем что-либо делать, что дает вам возможность сфокусироваться на каком-либо окне редактирования. В моем реальном приложении я использую горячую клавишу, чтобы вызвать это, но это только запутало бы этот пример. Кроме того, в производственном коде вы должны проверить возвращаемые значения вызовов win32, чтобы увидеть, были ли они успешными или нет.

Ответы [ 2 ]

1 голос
/ 04 февраля 2009

Пожалуйста, проверьте, что даже сообщение em_replacesel может не работать в другом процессе. Возможно, вам придется использовать WM_COPYDATA или вызвать оконную процедуру, как указано в URL,

http://www.microsoft.com/communities/newsgroups/en-us/default.aspx?dg=microsoft.public.smartphone.developer&tid=4e3a9289-9355-4af7-a5b9-84f1aa601441&cat=&lang=&cr=&sloc=en-us&p=1

1 голос
/ 26 января 2009

Целесообразно отправлять нажатия клавиш, если вы знаете активное окно и сфокусированное поле ввода. См. http://www.pinvoke.net/default.aspx/user32/keybd_event.html для API.

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