Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2005.11.06;
Скачать: [xml.tar.bz2];

Вниз

Как включить верхний регистр в чужом процессе ?   Найти похожие ветки 

 
alpet ©   (2005-09-01 16:29) [40]

допустим на форме есть несколько кнопок и таймер 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 16:30) [41]


> alpet ©   (01.09.05 16:29) [40]
- это на форме. Ща над Magic поиздеваюсь.


 
alpet ©   (2005-09-01 17:05) [42]

А вот такой код, успешно перемещает курсор в начало текста в блокноте:

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 17:11) [43]


> alpet ©   (01.09.05 16:29) [40]

Заработало ! Надо было чилдовому окну посылать сообщения постом. Остались комбинации. Но они у меня не только в Magic, пока вообще нигде не работают, только через keybd_event. Не подскажешь, куда рыть ? Я попробовал нажать и CHAR - ничего не получилось. Но я не пытался отпускать. Ща попробую.


 
alpet ©   (2005-09-01 17:17) [44]

ANB ©   (01.09.05 17:11) [43]

Можно и SendMessage - на notepad действует (см. [42]). Главное что при этом почему-то работает и SetKeyboardState, и соответственно можно ведь любую комбинацию сделать.


 
ANB ©   (2005-09-01 17:21) [45]


> alpet ©   (01.09.05 17:17) [44]
- так у меня и было все раньше на SendMessage. Блокнот и делфовые приложения все это ели (кроме комбинаций). Только Magic не ел. Заменил на Post - заел. SetKeyboardState будет работать только в моем процессе :((( Я уже в SDK смотрел и в MSDN. Хотя, может неправильно перевел . . .


 
alpet ©   (2005-09-01 17:30) [46]

Ограничения 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:36) [47]


> alpet ©   (01.09.05 17:30) [46]

- то есть через attach может проканать ? Чего то у меня не получилось. Я код уже писал выше.


 
begin...end ©   (2005-09-01 17:40) [48]

> alpet ©   (01.09.05 17:30) [46]

> Кроме этого - он не изменяет состояния клавиш, общего для
> всей системы (типа *Lock).

Ой.


 
alpet ©   (2005-09-01 17:40) [49]

ANB ©   (01.09.05 17:36) [47]

попробуй. Если правда программа реагирует только на PostMessage (а такое очень даже может быть) - между вызовами SetKeyboardState надо давать ей отработать поступившие сообщения (самое простое - через Sleep). Поскольку PostMessage отправит сообщения в очередь потока сразу, а обработаются они скорее всего после завершения работы твоего кода (включая все вызовы SetKeyboardState).


 
alpet ©   (2005-09-01 17:41) [50]

begin...end ©   (01.09.05 17:40) [48]

Ай &#9786;. Опять ошибки на внимательность?


 
begin...end ©   (2005-09-01 17:45) [51]

> alpet ©   (01.09.05 17:41) [50]

В смысле? SetKeyboardState нажмёт CAPS LOCK в текущем процессе. Так же как и любую другую клавишу.


 
ANB ©   (2005-09-01 17:48) [52]


> begin...end ©   (01.09.05 17:45) [51]
- вообще то я перевел это, что он лампочки на этих кнопках включать не умеет. А вверху - что только для текущего процесса. Можно как нибудь заставить его в другом процессе работать ?


 
alpet ©   (2005-09-01 17:50) [53]

begin...end ©   (01.09.05 17:45) [51]
Не нажмет, это программно не реализуемо (в смысле физическое нажатие). Функция может установить состояние этой клавиши для вызвавшего потока (и потоков подключенных к вводу, с помощью AttachThread). Светодиод CAPS от этого не загорится. В этом отношении глобальное состояние Caps будет неизменным.


 
begin...end ©   (2005-09-01 17:53) [54]

> ANB ©   (01.09.05 17:48) [52]

> вообще то я перевел это, что он лампочки на этих кнопках
> включать не умеет.

Правильно перевели.

> Можно как нибудь заставить его в другом процессе работать ?

Я бы попробовал внедриться.

> alpet ©   (01.09.05 17:50) [53]

> Не нажмет, это программно не реализуемо (в смысле физическое
> нажатие).

А что, прямо-таки непонятно было, о чём я говорил?

> Функция может установить состояние этой клавиши для вызвавшего
> потока

И я об этом же. Поэтому непонятно, чем поведение SetKeyboardState в смысле установки состояния CAPS LOCK отличается от случаев с другими клавишами.


 
ANB ©   (2005-09-01 17:57) [55]


> alpet ©   (01.09.05 17:50) [53]


> begin...end ©   (01.09.05 17:53) [54]

Я неправильно атач использую или так вообще работать не будет и нужно внедряться ?


 
alpet ©   (2005-09-01 18:25) [56]

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);


 
Наиль ©   (2005-09-02 01:18) [57]

Тема очень интересная. Хотя я ни когда на работал с клавиатурой на прямую решил попробывать включить/выключить лампочку капслока. За час испытаний получил такой код:
keybd_event(VK_CAPITAL,0,0,0);
keybd_event(VK_CAPITAL,0,KEYEVENTF_KEYUP,0);

меняет состояние капслока на противоположное.
А поповоду комбинации, допустим Ctrl+A, на форуме писали:
Нажать (Эмулировать) Ctrl
Нажать А
Отпустить А
Отпустить Ctrl

либо через keybd_event (для активной программы), либо через PostMessage (для определённой программы).

Извините, если сообщение не в тему.


 
Наиль ©   (2005-09-02 01:26) [58]

Я так давно читаю эту ветку, что забыл про что спрашивается.
Похоже, что мой ответ в тему, а Ctrl+A лишнее.


 
ANB ©   (2005-09-02 09:52) [59]


> alpet ©   (01.09.05 18:25) [56]
- и будет работать без атача ?
Нажатая кнопка обозначается $80 ? 1 - не подходит ?


 
ANB ©   (2005-09-02 09:54) [60]


> Наиль ©   (02.09.05 01:18) [57]

1. через keybd_event у меня и так уже все работает.
2. через PostMessage пока не получается (но твой вариант не работает - я уже писал)
3. для многих приложений работает и SendMessage


 
alpet ©   (2005-09-02 10:25) [61]

[59] ANB ©   (02.09.05 09:52)

AttachThreadInput необходим, как же без него будет работать SetKeyboardState


 
ANB ©   (2005-09-02 11:12) [62]


> alpet ©   (02.09.05 10:25) [61]
- я его правильно пытался делать ?


 
alpet ©   (2005-09-02 11:39) [63]

[62] ANB ©   (02.09.05 11:12)

почти. вместо $FF  надо использовать $81 или $80. При этом старший бит соответствует состоянию клавиши - нажата/не нажата, а младший - состояние в предыдущий раз (т.е. скорее используется для GetKeyboardState).


 
ANB ©   (2005-09-02 12:04) [64]


> alpet ©   (02.09.05 11:39) [63]
- УРРРРЯЯЯЯЯ !!! Со слипами и SetKeyboardState (с атачем) все работает.


 
ANB ©   (2005-09-02 12:29) [65]


> alpet ©   (02.09.05 11:39) [63]
- спасибо.


 
alpet ©   (2005-09-02 13:14) [66]

Попробуй обойтись без Sleep:

begin
hm := GetForegroundWindow;
ctid := GetCurrentThreadId ();
tid := GetWindowThreadProcessId (hm, pid);
if tid <> ctid then AttachThreadInput (ctid, tid, true);
hProcess := OpenProcess (SYNCHRONIZE, false, pid);
h := GetFocus;
GetKeyboardState (ks);
ks [VK_CONTROL] := $81;
SetKeyboardState (ks);
PostMessage (h, WM_KEYDOWN, VK_HOME, 0);
PostMessage (h, WM_KEYUP, VK_HOME, 0);
if hProcess <> 0 then WaitForInputIdle (hProcess, 500)
 else sleep (500);
ks [VK_CONTROL] := $00;
SetKeyboardState (ks);
if tid <> ctid then AttachThreadInput (ctid, tid, false);
CloseHandle (hProcess);
end;

Для большей оптимизации hProcess можно получать при запуске программы, например если запускать magic через CreateProcess.


 
ANB ©   (2005-09-02 14:47) [67]


> alpet ©   (02.09.05 13:14) [66]
- клевая идея. Сейчас попробую. У меня еще одна бяка. Посылаю через WM_Char русские буквы, а приезжают крякозябры. Через keybd_event я переключаю раскладку и все работает. А здесь не хочет. Регистр сохраняется. Английские буквы тоже нормально приезжают.
Виртуальный код пытался генерить 2-мя способами :
1. dwVK := VkKeyScanEx(sKey[1], KBD); // KBD - раскладка
2. dwVK := ord(sKey[1]);
В sKey[1] лежит буква.


 
ANB ©   (2005-09-02 14:50) [68]

Перепроверил - первый вариант даже регистр не сохраняет.


 
ANB ©   (2005-09-02 15:03) [69]


> alpet ©   (02.09.05 13:14) [66]
- не, перестало работать. Поставил Sleep обратно. Черт с ним, не критично. Пока закоментарил ожидание.


 
alpet ©   (2005-09-02 15:49) [70]

Перед отправкой русских букв надо действительно переключать расскладку, но можно обойтись без keybd_event:

PostMessage (hWnd, WM_INPUTLANGCHANGEREQUEST, 0, $419); // switch to ru
PostMessage (hWnd, WM_INPUTLANGCHANGEREQUEST, 0, $409); // switch to eng


Насчет WaitForInputIdle - какой результат функция возвращает? Если ошибку попробуй процесс открывать PROCESS_ALL_ACCESS.


 
alpet ©   (2005-09-02 15:55) [71]

По поводу регистра:

ks [VK_SHIFT] := $81;
SetKeyboardState (ks);
PostMessage (hWnd, WM_CHAR, Ord ("A"), 0);
Sleep (500);
ks [VK_SHIFT] := $00;
SetKeyboardState (ks);
PostMessage (hWnd, WM_CHAR, Ord ("b"), 0);
Sleep (500);


 
ANB ©   (2005-09-02 15:59) [72]


> alpet ©   (02.09.05 15:49) [70]
- так я ее переключал. Короче, спасло вот это :

SendMessage(hWindow, WM_INPUTLANGCHANGE, $CC, KBD);
Причем KBD можно любую передавать. Главное - $CC - на языке включить и везде печататает и по русски и по английски.


 
ANB ©   (2005-09-02 16:00) [73]


> alpet ©   (02.09.05 15:55) [71]
- да работает уже все ! И регистр и язык и через сообщения и через эмуляцию. Немного с бубном поплясали и готово.


 
ANB ©   (2005-09-02 16:01) [74]


> alpet ©   (02.09.05 15:55) [71]
- спасибо. Я еще пошаманю с паузой по твоему совету и могу выложить готовый код, может кому надо.


 
ANB ©   (2005-09-02 16:15) [75]


> alpet ©   (02.09.05 15:49) [70]
- точно, ошибка верталась. Написал PROCESS_ALL_ACCESS и все заработало.


 
alpet ©   (2005-09-02 16:20) [76]

Весьма работоспособен и след. код. Надо только символы в верхнем регистре передавать. Паузу я обычно ставлю в 5 - хватает как правило для notepad.

d := 5;
ks [vk_shift] := ks [vk_shift] or $80;
SetKeyboardState (ks);
PostMessage (h, WM_KEYDOWN, Ord ("A"), 0);
Sleep (d);
ks [vk_shift] := ks [vk_shift] and $7F;
SetKeyboardState (ks);
Sleep (d);
PostMessage (h, WM_KEYDOWN, Ord ("Q"), 0);
Sleep (d);

Если вставить в обработчик таймера, печатае: "AqAqAqAq"


 
ANB ©   (2005-09-02 16:51) [77]


> alpet ©   (02.09.05 16:20) [76]
Все замечательно работает без пауз и в нормальном регистре, если передавать WM_CHAR. Ну и язык теперь тоже нормально. Спасибо за помощь.



Страницы: 1 2 вся ветка

Форум: "WinAPI";
Текущий архив: 2005.11.06;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.61 MB
Время: 0.039 c
2-1129168891
lmz
2005-10-13 06:01
2005.11.06
Округлени числа бухгалтерским методом


2-1129409232
Денис
2005-10-16 00:47
2005.11.06
Как сделать ping всех доступных FTP и сохранить в файл?


14-1128411337
dr Tr0jan
2005-10-04 11:35
2005.11.06
Измерение сопротивления с помощью осциллографа


6-1122384608
Almaz
2005-07-26 17:30
2005.11.06
Синхронизация доступа к сокету


3-1127899468
Аноним
2005-09-28 13:24
2005.11.06
Структура БД





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский