Кибор » Кибор - Интегрированная среда разработки ботов » Вопросы и решение проблем » Отправка сочетаний клавиш в окно

Страниц (3): [1] 2 3 »
 

1. Nightshade2 - 15 Декабря, 2016 - 03:55:12 - перейти к сообщению
Пытаюсь отправить сочетание клавиш неактивному окну
Нашел код... как говорят рабочий...
CODE:

//С аккселераторами, которые с клавишами-модификаторами, дополнительная фишка -
//посылки PostMessage недостаточно, нужно еще дополнительно обновить "keyboard
// input-state table" в нужном потоке.
//Вот такой код может сработать (закомментарены те части, без которых генерация
// аккселератора тоже произойдет).
HWND h = ::FindWindow(NULL, L"Безымянный - Блокнот");
if (h != NULL)
{
HWND child = ::FindWindowEx(h,NULL,"Edit", NULL);

UINT lparam_Ctrl1 = ::MapVirtualKey(VK_CONTROL, 0) << 16 | 1 ;
UINT lparam_A1 = ::MapVirtualKey((int)'A', 0) << 16 | 1 ;

UINT lparam_A2 = 1 << 31 | 1 << 30 | ::MapVirtualKey((int)'A', 0) << 16 | 1 ;
UINT lparam_Ctrl2 = 1 << 31 | 1 << 30 | ::MapVirtualKey(VK_CONTROL, 0) << 16 | 1 ;

DWORD pid;
DWORD tid = GetWindowThreadProcessId(child, &pid);
HANDLE hProc = OpenProcess(PROCESS_QUERY_INFORMATION | SYNCHRONIZE, FALSE, pid);
//Ctrl + A

AttachThreadInput(GetCurrentThreadId(), tid, TRUE);

LRESULT pl1_Ctrl = ::PostMessage(child, WM_KEYDOWN, VK_CONTROL, lparam_Ctrl1 );
WaitForInputIdle(hProc, INFINITE);

BYTE state[256];
GetKeyboardState(state);
state[VK_CONTROL] = 0x80;
SetKeyboardState(state);

LRESULT pl1_A = ::PostMessage(child, WM_KEYDOWN, (int)'A', lparam_A1 );
WaitForInputIdle(hProc, INFINITE);
/*
GetKeyboardState(state);
state['A'] = 0x80;
SetKeyboardState(state);
*/

LRESULT pl2_A = ::PostMessage(child, WM_KEYUP, (int)'A', lparam_A2);
WaitForInputIdle(hProc, INFINITE);
/*
GetKeyboardState(state);
state['A'] = 0x0;
SetKeyboardState(state);
*/

LRESULT pl2_Ctrl = ::PostMessage(child, WM_KEYUP, VK_CONTROL, lparam_Ctrl2);
WaitForInputIdle(hProc, INFINITE);
/*
GetKeyboardState(state);
state[VK_CONTROL] = 0x0;
SetKeyboardState(state);
*/

AttachThreadInput(GetCurrentThreadId(), tid, FALSE);

}

Возникло несколько вопросов.
AttachThreadInput и attach в киборе одно и тоже?
Как мне вызвать SetKeyboardState(state); ?
Как написать 1 << 31 | 1 << 30
1<<31 я могу посчитать в калькуляторе и забить константами.
Но логики and, or, xor нету. Этого сильно не хватает и при проверке разных условий. Приходится писать многоэтажные каскады if.
(Добавление)
char state[256];
state[84]=128;
external(INT, "SetKeyboardState", "SetKeyboardState", "User32.dll"Подмигивание;
SetKeyboardState(address(#state[0]));
Такая конструкция не работает. Похоже что-то не так пишу.
2. Kibor - 15 Декабря, 2016 - 05:08:14 - перейти к сообщению
 Nightshade2 пишет:
AttachThreadInput и attach в киборе одно и тоже?

да
 Nightshade2 пишет:
Но логики and, or, xor нету. Этого сильно не хватает и при проверке разных условий. Приходится писать многоэтажные каскады if.

&& ||(для просмотра ссылки Вам необходимо авторизоваться)
3. Nightshade2 - 15 Декабря, 2016 - 06:10:51 - перейти к сообщению
[quote=Kibor]&& ||(для просмотра ссылки Вам необходимо авторизоваться) /quote]
На этой странице как раз нет упоминания этой логики.
И еще... С помощью Spy++ обнаружил, что Кибор напрочь игнорирует lparam
в функции sendkey
там есть 30 бит - была ли нажата кнопка до этого. Так вот при отправке wm_keyup этот бит должен взводиться, чтобы избегать двойного нажатия клавиши. Но кибор этого не делает.


30 The previous key state. The value is 1 if the key is down before the message is sent,
or it is zero if the key is up.
(Добавление)
Нормальное нажатие кнопки:
<000109> 000207DA P WM_KEYDOWN nVirtKey:'F' cRepeat:1 ScanCode:21 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<000110> 000207DA P WM_CHAR chCharCode:'224' (224) cRepeat:1 ScanCode:21 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<000111> 000207DA P WM_KEYUP nVirtKey:'F' cRepeat:1 ScanCode:21 fExtended:0 fAltDown:0 fRepeat:1 fUp:1

Нажатие через sendkey:
<000229> 000207DA P WM_KEYDOWN nVirtKey:'T' cRepeat:0 ScanCode:00 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<000230> 000207DA P WM_KEYUP nVirtKey:'T' cRepeat:0 ScanCode:00 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<000231> 000207DA P WM_CHAR chCharCode:'229' (229) cRepeat:0 ScanCode:00 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<000232> 000207DA P WM_CHAR chCharCode:'229' (229) cRepeat:0 ScanCode:00 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
4. Kibor - 15 Декабря, 2016 - 11:14:18 - перейти к сообщению
 Nightshade2 пишет:
С помощью Spy++ обнаружил, что Кибор напрочь игнорирует lparam
в функции sendkey
там есть 30 бит - была ли нажата кнопка до этого. Так вот при отправке wm_keyup этот бит должен взводиться, чтобы избегать двойного нажатия клавиши. Но кибор этого не делает.

sendkey эмуляция PostMessage. Функционал тот же. Читайте про PostMessage(....._KEYDOWN, ....., .....);

 Nightshade2 пишет:
На этой странице как раз нет упоминания этой логики.

Серьезно?
Цитата с(для просмотра ссылки Вам необходимо авторизоваться)
 Цитата:
Можно сравнивать несколько условий сразу разделив их && (и) || (или):
if (5==6 && str=="бла"+str1 && (c-6>8 || ch=='a'))//выполнить код этот
5. Nightshade2 - 15 Декабря, 2016 - 12:35:40 - перейти к сообщению
sendkey так же отправляет WM_KEYUP, причем криво отправляет
6. Kibor - 15 Декабря, 2016 - 13:14:39 - перейти к сообщению
естественно..
потому что PostMessage не отправляет нажатие отпускание нажатие, а только клик.
7. Nightshade2 - 15 Декабря, 2016 - 13:34:34 - перейти к сообщению
Все он отправляет. И нажатие и отпускание.
Просто в киборе отсутствует код заполнения lparam
UINT lparam_A2 = 1 << 31 | 1 << 30 | ::MapVirtualKey((int)'A', 0) << 16 | 1 ;
1 << 31 | 1 << 30 | Как раз и говорит приложению, что мы отжимаем кнопку.
8. Kibor - 15 Декабря, 2016 - 13:54:34 - перейти к сообщению
Это я не знаю.
По поводу MapVirtualKey
external(INT, "MapVirtualKey", "MapVirtualKeyA", "User32.dll");
9. Nightshade2 - 15 Декабря, 2016 - 14:21:15 - перейти к сообщению
GetKeyboardState(state);
state['A'] = 0x0;
SetKeyboardState(state); - вот это не пойму как вызвать.
10. Kibor - 15 Декабря, 2016 - 15:27:34 - перейти к сообщению
 Nightshade2 пишет:
SetKeyboardState(state); - вот это не пойму как вызвать.


 Цитата:
external(INT, "SetKeyboardState", "SetKeyboardState", "User32.dll" );
char state[256];
for (int n=0; n<256; n++)state[n]=0;
state[20]=1;//Типа нажат CapsLock
//messagebox (SetKeyboardState(address(#state[0])));//возвращает не 0
SetKeyboardState(address(#state[0]));
//Теперь при НЕ нажатом CapsLock в редакторе Кибор будет печатать ЗАГЛАВНЫЕ буквы.
//И наоборот при АКТИВНОМ CapsLock в редакторе Кибор будет печатать мелкие буквы.


Вставить этот код в Кибор.
Отключить CapsLock. Напечатать в Кибор ниже кода текст. Убедиться что текст пишет мелкими буквами.
Запустить скрипт. После отработки скрипта не включая CapsLock опять в редакторе Кибор напечатать текст. Текст будет печатать ЗАГЛАВНЫМИ буквами. При включение CapsLock наоборот мелкими. То есть в Кибор CapsLock будет реагировать наоборот, так как код 20 это код CapsLock, статус которого мы изменили программно.
Функция работает.
А как и где ее применять это виднее вам.

Powered by ExBB FM 1.0 Final