Nightshade2 |
Отправлено: 15 Декабря, 2016 - 11:55:12
|
Наблюдатель
Покинул форум
Сообщений всего: 35
Дата рег-ции: Нояб. 2016
Репутация: 1
|
Пытаюсь отправить сочетание клавиш неактивному окну
Нашел код... как говорят рабочий...
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]));
Такая конструкция не работает. Похоже что-то не так пишу. |
|
|
Kibor |
Отправлено: 15 Декабря, 2016 - 13:08:14
|
Эксперт
Покинул форум
Сообщений всего: 8217
Дата рег-ции: Март 2013
Откуда: Одесса
Репутация: 357
|
Nightshade2 пишет: AttachThreadInput и attach в киборе одно и тоже?
да
Nightshade2 пишет: Но логики and, or, xor нету. Этого сильно не хватает и при проверке разных условий. Приходится писать многоэтажные каскады if.
&& ||(для просмотра ссылки Вам необходимо авторизоваться) |
|
|
Kibor |
Отправлено: 15 Декабря, 2016 - 19:14:18
|
Эксперт
Покинул форум
Сообщений всего: 8217
Дата рег-ции: Март 2013
Откуда: Одесса
Репутация: 357
|
Nightshade2 пишет: С помощью Spy++ обнаружил, что Кибор напрочь игнорирует lparam
в функции sendkey
там есть 30 бит - была ли нажата кнопка до этого. Так вот при отправке wm_keyup этот бит должен взводиться, чтобы избегать двойного нажатия клавиши. Но кибор этого не делает.
sendkey эмуляция PostMessage. Функционал тот же. Читайте про PostMessage(....._KEYDOWN, ....., .....);
Nightshade2 пишет: На этой странице как раз нет упоминания этой логики.
Серьезно?
Цитата с(для просмотра ссылки Вам необходимо авторизоваться) Цитата: Можно сравнивать несколько условий сразу разделив их && (и) || (или):
if (5==6 && str=="бла"+str1 && (c-6>8 || ch=='a'))//выполнить код этот |
|
|
Kibor |
Отправлено: 15 Декабря, 2016 - 23:27:34
|
Эксперт
Покинул форум
Сообщений всего: 8217
Дата рег-ции: Март 2013
Откуда: Одесса
Репутация: 357
|
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, статус которого мы изменили программно.
Функция работает.
А как и где ее применять это виднее вам. |
|
|
|