![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как включить верхний регистр в чужом процессе ? [D7, Win2k, WinXP]
ANB © (2005-08-29 14:39:00)Чтобы напечатать строго большую или маленькую букву независимо от текущего состояния. Попробовал вот так - не помогает. :
- всегда печатает маленькими. Пробовал вместо FF - 1, никакого эффекта.
// Установим регистр
ThreadFrom := GetCurrentThreadId;
ThreadTo := GetWindowThreadProcessId(hWindow, nil);
AttachThreadInput(ThreadFrom, ThreadTo, True);
GetKeyBoardState(KeyBoardState);
KeyBoardState[VK_CAPITAL] := 0;
if (bUpper) then begin
KeyBoardState[VK_SHIFT] := $FF;
KeyBoardState[VK_LSHIFT] := $FF;
end else begin
KeyBoardState[VK_SHIFT] := $FF;
KeyBoardState[VK_LSHIFT] := $FF;
end;
SetKeyBoardState(KeyBoardState);
// Эмулируем нажатие клавиши
keybd_event(dwVK, bScanCode, dwFlags, 0);
AttachThreadInput(ThreadFrom, ThreadTo, False);
Наиль (2005-09-02 01:18:00) [21]Тема очень интересная. Хотя я ни когда на работал с клавиатурой на прямую решил попробывать включить/выключить лампочку капслока. За час испытаний получил такой код:
keybd_event(VK_CAPITAL,0,0,0);
keybd_event(VK_CAPITAL,0,KEYEVENTF_KEYUP,0);
меняет состояние капслока на противоположное.
А поповоду комбинации, допустим Ctrl+A, на форуме писали:
Нажать (Эмулировать) Ctrl
Нажать А
Отпустить А
Отпустить Ctrl
либо через keybd_event (для активной программы), либо через PostMessage (для определённой программы).
Извините, если сообщение не в тему.
alpet (2005-09-01 18:25:00) [22]ANB © (01.09.05 17:57) [55]
Дело не в аттаче, а синхронизации ввода, и его обработки потоком Magic'a.
ks [VK_CONTROL] := $80;
SetKeyboardState(ks);
PostMessage (...VK_HOME);
Sleep (200); // Magic must handle Ctrl-Home combination
ks [VK_CONTROL] := $00;
SetKeyboardState(ks);
ANB (2005-09-01 17:57:00) [23]
> alpet © (01.09.05 17:50) [53]
> begin...end © (01.09.05 17:53) [54]
Я неправильно атач использую или так вообще работать не будет и нужно внедряться ?
begin...end (2005-09-01 17:53:00) [24]> ANB © (01.09.05 17:48) [52]
> вообще то я перевел это, что он лампочки на этих кнопках
> включать не умеет.
Правильно перевели.
> Можно как нибудь заставить его в другом процессе работать ?
Я бы попробовал внедриться.
> alpet © (01.09.05 17:50) [53]
> Не нажмет, это программно не реализуемо (в смысле физическое
> нажатие).
А что, прямо-таки непонятно было, о чём я говорил?
> Функция может установить состояние этой клавиши для вызвавшего
> потока
И я об этом же. Поэтому непонятно, чем поведение SetKeyboardState в смысле установки состояния CAPS LOCK отличается от случаев с другими клавишами.
alpet (2005-09-01 17:50:00) [25]begin...end © (01.09.05 17:45) [51]
Не нажмет, это программно не реализуемо (в смысле физическое нажатие). Функция может установить состояние этой клавиши для вызвавшего потока (и потоков подключенных к вводу, с помощью AttachThread). Светодиод CAPS от этого не загорится. В этом отношении глобальное состояние Caps будет неизменным.
ANB (2005-09-01 17:48:00) [26]
> begin...end © (01.09.05 17:45) [51]
- вообще то я перевел это, что он лампочки на этих кнопках включать не умеет. А вверху - что только для текущего процесса. Можно как нибудь заставить его в другом процессе работать ?
begin...end (2005-09-01 17:45:00) [27]> alpet © (01.09.05 17:41) [50]
В смысле? SetKeyboardState нажмёт CAPS LOCK в текущем процессе. Так же как и любую другую клавишу.
alpet (2005-09-01 17:41:00) [28]begin...end © (01.09.05 17:40) [48]
Ай ☺. Опять ошибки на внимательность?
alpet (2005-09-01 17:40:00) [29]ANB © (01.09.05 17:36) [47]
попробуй. Если правда программа реагирует только на PostMessage (а такое очень даже может быть) - между вызовами SetKeyboardState надо давать ей отработать поступившие сообщения (самое простое - через Sleep). Поскольку PostMessage отправит сообщения в очередь потока сразу, а обработаются они скорее всего после завершения работы твоего кода (включая все вызовы SetKeyboardState).
begin...end (2005-09-01 17:40:00) [30]> alpet © (01.09.05 17:30) [46]
> Кроме этого - он не изменяет состояния клавиш, общего для
> всей системы (типа *Lock).
Ой.
ANB (2005-09-01 17:36:00) [31]
> alpet © (01.09.05 17:30) [46]
- то есть через attach может проканать ? Чего то у меня не получилось. Я код уже писал выше.
alpet (2005-09-01 17:30:00) [32]Ограничения SetKeyboardState:
Changes made to this table do not affect keyboard input to any other thread.
...
Because the SetKeyboardState function alters the input state of the calling thread and not the global input state of the system, an application cannot use SetKeyboardState to set the NUM LOCK, CAPS LOCK, or SCROLL LOCK (or the Japanese KANA) indicator lights on the keyboard.
...
Т.е. он не приведет к изменениям клавирного ввода, в другом потоке. Для этого и вызвается AttachInput. Кроме этого - он не изменяет состояния клавиш, общего для всей системы (типа *Lock).
ANB (2005-09-01 17:21:00) [33]
> alpet © (01.09.05 17:17) [44]
- так у меня и было все раньше на SendMessage. Блокнот и делфовые приложения все это ели (кроме комбинаций). Только Magic не ел. Заменил на Post - заел. SetKeyboardState будет работать только в моем процессе :((( Я уже в SDK смотрел и в MSDN. Хотя, может неправильно перевел . . .
alpet (2005-09-01 17:17:00) [34]ANB © (01.09.05 17:11) [43]
Можно и SendMessage - на notepad действует (см. [42]). Главное что при этом почему-то работает и SetKeyboardState, и соответственно можно ведь любую комбинацию сделать.
ANB (2005-09-01 17:11:00) [35]
> alpet © (01.09.05 16:29) [40]
Заработало ! Надо было чилдовому окну посылать сообщения постом. Остались комбинации. Но они у меня не только в Magic, пока вообще нигде не работают, только через keybd_event. Не подскажешь, куда рыть ? Я попробовал нажать и CHAR - ничего не получилось. Но я не пытался отпускать. Ща попробую.
alpet (2005-09-01 17:05:00) [36]А вот такой код, успешно перемещает курсор в начало текста в блокноте:
var h, hm, tid, ctid: THandle;
ks: TKeyboardstate;
begin
hm := GetForegroundWindow;
ctid := GetCurrentThreadId ();
tid := GetWindowThreadProcessId (hm);
if tid <> ctid then AttachThreadInput (ctid, tid, true);
h := GetFocus;
fillchar (ks, sizeof (TKeyboardState), 0);
ks [VK_CONTROL] := $80;
SetKeyboardState (ks);
SendMessage (h, WM_KEYDOWN, VK_HOME, 0);
SendMessage (h, WM_KEYUP, VK_HOME, 0);
ks [VK_CONTROL] := $00;
SetKeyboardState (ks);
if tid <> ctid then AttachThreadInput (ctid, tid, false);
end;
ANB (2005-09-01 16:30:00) [37]
> alpet © (01.09.05 16:29) [40]
- это на форме. Ща над Magic поиздеваюсь.
alpet (2005-09-01 16:29:00) [38]допустим на форме есть несколько кнопок и таймер 100мс.
вот код таймера который будет перемещать фокус по кнопкам:
procedure Tmform.Timer1Timer(Sender: TObject);
begin
PostMessage (Handle, WM_KEYDOWN, VK_TAB, 0);
PostMessage (Handle, WM_KEYUP, VK_TAB, 0);
end;
Использование WM_CHAR при этом ничего не делает.
ANB (2005-09-01 12:25:00) [39]Так, ест теперь через сообщения обычные кнопки, стрелки, Enter, Esc. Не ест сочетания кнопок и Tab.
ANB (2005-09-01 11:50:00) [40]Не, Ctrl туда не загоняется. Только Alt. Да хрен с ним. У меня редко это используется. Главное - в эдитах печатает. Кстати, как Tab правильно сэмулировать ? Чего то я его поломал.