Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как включить верхний регистр в чужом процессе ? [D7, Win2k, WinXP]


Страницы:   1 2 3 4

ANB ©   (2005-08-29 14:39:00) 

Чтобы напечатать строго большую или маленькую букву независимо от текущего состояния. Попробовал вот так - не помогает. :

 // Установим регистр
 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);
- всегда печатает маленькими. Пробовал вместо FF - 1, никакого эффекта.


ANB   (2005-09-02 16:51:00) [1]


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


alpet   (2005-09-02 16:20:00) [2]

Весьма работоспособен и след. код. Надо только символы в верхнем регистре передавать. Паузу я обычно ставлю в 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:15:00) [3]


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


ANB   (2005-09-02 16:01:00) [4]


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


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


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


ANB   (2005-09-02 15:59:00) [6]


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

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


alpet   (2005-09-02 15:55:00) [7]

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

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


alpet   (2005-09-02 15:49:00) [8]

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

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


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


ANB   (2005-09-02 15:03:00) [9]


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


ANB   (2005-09-02 14:50:00) [10]

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


ANB   (2005-09-02 14:47:00) [11]


> 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] лежит буква.


alpet   (2005-09-02 13:14:00) [12]

Попробуй обойтись без 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 12:29:00) [13]


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


ANB   (2005-09-02 12:04:00) [14]


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


alpet   (2005-09-02 11:39:00) [15]

[62] ANB ©   (02.09.05 11:12)

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


ANB   (2005-09-02 11:12:00) [16]


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


alpet   (2005-09-02 10:25:00) [17]

[59] ANB ©   (02.09.05 09:52)

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


ANB   (2005-09-02 09:54:00) [18]


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

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


ANB   (2005-09-02 09:52:00) [19]


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


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

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


Страницы:   1 2 3 4

Наверх

Титульная страница Поиск, карта сайта Написать письмо