Подскажите, пожалуйста, как научить программу отлавливать факт нажатия кнопок клавиатуры в окне другого приложения?
В общем нужно что-то типа клавиатурного шпиона написать...
работа с клавиатурой, C#, MSVS08 |
1. Пользуйтесь тегами кода. - [code] ... [/code]
2. Точно указывайте язык, название и версию компилятора (интерпретатора).
3. Название темы должно быть информативным.
В описании темы указываем язык!!!
Наладить общение поможет, если вы подпишитесь по почте на новые темы в этом форуме.
работа с клавиатурой, C#, MSVS08 |
Unknown |
Сообщение
#1
|
Пионер Группа: Пользователи Сообщений: 104 Пол: Мужской Реальное имя: Евгений Репутация: 0 |
Подскажите, пожалуйста, как научить программу отлавливать факт нажатия кнопок клавиатуры в окне другого приложения?
В общем нужно что-то типа клавиатурного шпиона написать... -------------------- go ask Alice
|
volvo |
Сообщение
#2
|
Гость |
Глобальный хук на клавиатуру?
Вот тут есть пример на C#: Processing Global Mouse and Keyboard Hooks in C# |
Unknown |
Сообщение
#3
|
Пионер Группа: Пользователи Сообщений: 104 Пол: Мужской Реальное имя: Евгений Репутация: 0 |
Спасибо! Теперь другой вопрос: как в окно другого приложения (например, Word'а) записать какой-то текст, который был отловлен моей программой?
-------------------- go ask Alice
|
volvo |
Сообщение
#4
|
Гость |
А оно тебе надо писать это в окно Word-а? Создать DOC-файл и открыть его Word-ом будет недостаточно?
|
Unknown |
Сообщение
#5
|
Пионер Группа: Пользователи Сообщений: 104 Пол: Мужской Реальное имя: Евгений Репутация: 0 |
да, мне это нужно
Мне нужно написать прогу наподобие PuntoSwitcher. -------------------- go ask Alice
|
volvo |
Сообщение
#6
|
Гость |
Ну, тогда смотри, как работать с Word-ом: Word Automation, больше помочь ничем не могу, .NET - это не мое
|
Unknown |
Сообщение
#7
|
Пионер Группа: Пользователи Сообщений: 104 Пол: Мужской Реальное имя: Евгений Репутация: 0 |
Word - это я просто в качестве примера привел. А вообще мне нужно: отловить ввод текста, определить последнее окно, в котором клавиши нажимались, стереть введенный текст и заменить транслитированным.
Сейчас я хочу узнать, как обратиться к окну другого приложения. Или хотя бы как это правильно сформулировать, чтобы поискать можно было. Я правильно понимаю, что мне нужен хэндл окна? еще нужно определить текстовое поле на этом окне... В общем, если кто подскажет, будет здорово -------------------- go ask Alice
|
Unknown |
Сообщение
#8
|
Пионер Группа: Пользователи Сообщений: 104 Пол: Мужской Реальное имя: Евгений Репутация: 0 |
определять хэндл окна по его названию научился - findwindow, но это не совсем то, что нужно...
-------------------- go ask Alice
|
volvo |
Сообщение
#9
|
Гость |
Цитата Я правильно понимаю, что мне нужен хэндл окна? еще нужно определить текстовое поле на этом окне... Ты правильно понимаешь... На WinAPI это делается через FindWindow/FindWindowEx, в Шарпе - насколько я знаю - через вызов этих же функций с использованием механизма pInvoke. Последнее окно - это то, которое имеет фокус ввода? API-шная GetFocus Function тебе поможет (вызывать - через тот же pInvoke)... Вот и все собственно... |
Unknown |
Сообщение
#10
|
Пионер Группа: Пользователи Сообщений: 104 Пол: Мужской Реальное имя: Евгений Репутация: 0 |
Вот спасибо! оказывается есть полно полезных функций!
-------------------- go ask Alice
|
Unknown |
Сообщение
#11
|
Пионер Группа: Пользователи Сообщений: 104 Пол: Мужской Реальное имя: Евгений Репутация: 0 |
Гмм... GetFocus все время возвращает 0... в чем может быть дело?
Код if (winH != GetFocus()) { buf = new List<int>(); winH = GetFocus(); } buf.Add(e.KeyValue); textBox1.Text += e.KeyCode; Добавлено через 18 мин. Вроде бы GetForegroundWindow - то, что нужно! ) -------------------- go ask Alice
|
volvo |
Сообщение
#12
|
Гость |
Ну и чего ты творишь? Я ж тебе дал ссылку на MSDN, там явно сказано:
Цитата Return Value The return value is the handle to the window with the keyboard focus. If the calling thread's message queue does not have an associated window with the keyboard focus, the return value is NULL. ... Use the GetForegroundWindow function to retrieve the handle to the window with which the user is currently working. You can associate your thread's message queue with the windows owned by another thread by using the AttachThreadInput function. Вот так это приблизительно делается на WinAPI: // Получаем хэндл активного приложенияВозможно, .NET позволяет сделать это же самое и проще... |
Unknown |
Сообщение
#13
|
Пионер Группа: Пользователи Сообщений: 104 Пол: Мужской Реальное имя: Евгений Репутация: 0 |
спасибо, попробовал сделать по шагам - споткнулся на GetFocus - возвращает ноль.
winH = GetForegroundWindow(); В чем может быть дело? Пробовал сделать по-другому: через SendKeys.Send, но возникла проблема с раскладками - чтобы вывести транслитированный текст с помощью Send, нужно сменить раскладку в окне активного приложения - никак не могу разобраться, как это сделать! for (int i = 0; i < buf.Count; i++) Но, видимо, LoadKeyboardLayout меняет раскладку только в моей программе... пробовал подключиться к потоку другого приложения - не помогло. Обойтись без раскладок, в принципе, можно - используя SendMessage: SendMessage(txtbox, WM_SETFOCUS, nul, nul); Но тут надо определить хэндл поля ввода txtbox. txtbox = FindWindowEx(winH, IntPtr.Zero, "Edit", null); Это работает для NotePad'а, а универсальный способ есть? -------------------- go ask Alice
|
volvo |
Сообщение
#14
|
Гость |
Цитата попробовал сделать по шагам - споткнулся на GetFocus - возвращает ноль. Хм... Надо будет установить себе хотя бы SharpDevelop, посмотреть, что творится в C#, потому как приведенный мной код в C++ отрабатывает прекрасно, GetFocus получает дескриптор активного контрола, и посылка в него, скажем,::SendMessage(hWndOfFocused, WM_SETTEXT, 0,(long int)"Just a test\0");, приводит к появлению этого текста в чужом приложении... НО!!! Не везде, естественно. Универсального способа нет и вряд ли он будет, потому что это сработает только тогда, когда контрол является оконным, то есть, если у него вообще есть HWND. А если нет? А если чужое приложение рисует на канве (как это делал ICQ, например, в форме быстрого ответа. Не знаю, может сейчас уже изменили, и там тоже используются оконные компоненты?), что тогда делать будешь? Кстати, еще один способ (опять же, только для оконных контролов) - получить активное приложение через GetForegroundWindow, а потом пройтись по каждому из его дочерних окон, то есть, перебрать все суб-контролы этого приложения (удобно делается через EnumChildWindows), для каждого получать GetWindowInfo, и проверять в полученной структуре поле dwWindowStatus. Если оно == WS_ACTIVECAPTION, значит, нашел контрол, на котором фокус ввода. |
volvo |
Сообщение
#15
|
Гость |
Update: ответ на вопрос
Цитата GetFocus - возвращает ноль. <...> В чем может быть дело? WinForms FAQ - "// Note that if the focused Control is not a .Net control, then this will return null." |
Гость |
Сообщение
#16
|
Гость |
Цитата WinForms FAQ - "// Note that if the focused Control is not a .Net control, then this will return null." т.е., к примеру, поле мемо программы, написанной в билдере, я не смогу определить как выделенное? |
volvo |
Сообщение
#17
|
Гость |
Установил себе наконец-то SharpDevelop, написал так:
void getActControl(IntPtr myWnd), ни в случае активного NotePad-а, ни в случае активного Word-а не получаю нулей в myFocused... |
Unknown |
Сообщение
#18
|
Пионер Группа: Пользователи Сообщений: 104 Пол: Мужской Реальное имя: Евгений Репутация: 0 |
Если я не ошибаюсь, я пробовал на ICQ...
Спасибо за помощь, программу написал - с помощью SendKeys ) -------------------- go ask Alice
|
Текстовая версия | 26.04.2024 7:36 |