Что нового

Установка горячих клавиш с использованием только символов

dimid

Новичок
Сообщения
20
Репутация
0
Доброго дня!

Нужно установить горячую (или коомбинацию, хотя лучше одну) клавишу. Программа висит в памяти, по горячей клавише делает некое действие и спокойно висит дальше (бесконечный цикл со слип (несколько секунд)).

Проблема:
1. обойтись нужно без задействования клавиш навроде ctrl, shift, f7, alt и прочих несимвольных
2. если поставить некую горячую клавишу Р, то во время печати юзер ее может нажать нечаянно и вызовет функцию когда не надо.

Идеи:
1. Клавишу нужно удерживать долгое время (секунд 10, например)
2. Сделать коомбинацию клавиш которые вряд ли нажмет по очереди случайно

Подскажите как лучше сделать. Заранее спасибо.
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
dimid
По поводу идей:
http://forum.script-coding.com/viewtopic.php?id=1205

Например, вариант с нахождением курсора мыши в определенном месте не подойдет?
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
dimid [?]
Подскажите как лучше сделать
Посмотрите пример для функции
Код:
_WinAPI_SetWindowsHookEx()
В примере при нажатии определённых сочетаний клавиш (Jon, AutoIt) происходит определённое действие (появляется ToolTip).
А "долгое нажатие" можно рассматривать, как повтор одного символа определённое количество раз.
 
Автор
D

dimid

Новичок
Сообщения
20
Репутация
0
1. С курсором нельзя к сожалению:
- банальное ClipCursor
- его отключение
- нечаянное помещение в ту область

2. С хуком тоже нельзя
- они могут быть сняты
- переназначены
- хуки могут быть перехвачены и наш обработчик не получит управление

У меня получилось вот так. Не знаю насколько корректно это, но потестил - вроде работает без ложных срабатываний и нагрузки на систему тоже не заметил. Как такой вариант?
Код:
#include <WinAPI.au3>
myfunc ()

Func myfunc ()
   
Local $st1, $st2, $st3
while 1
Sleep (1000)
$st1 = _WinAPI_GetAsyncKeyState(0x51) ; q
If Abs ($st1) > 1 Then
   $st2 = _WinAPI_GetAsyncKeyState(0x50) ; p 
   If Abs ($st2) > 1 Then
	  $st3 = _WinAPI_GetAsyncKeyState(0x58) ; x
	  If Abs ($st3) > 1 Then
		 ; ###
		 ; тут полезная нагрузка по сочетанию qpx
		 MsgBox (64, "OK", "Была зажата коомбинация QPX")
		 ; ###
			
		 
	  EndIf
   EndIf
EndIf

WEnd

EndFunc
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
dimid [?]
хуки могут быть перехвачены
Теоретически если хуки перехватываются, вы не сможете печатать. Хуки перехватывают событие, но не поглащают его, хотя могут это сделать. Может я не всё понимаю, но это то что я понимаю сейчас.
Есть ещё _IsPressed, но она нугружает процессор. Кстати, _IsPressed использует GetAsyncKeyState то есть ваш вариант с _WinAPI_GetAsyncKeyState.
 
Автор
D

dimid

Новичок
Сообщения
20
Репутация
0
Если интересно то примерно так про хуки:
1. обработчик хука сам решает что делать с принимаемыми данными - т.е вполне может не давать печатать, или подменять данные, или конспектировать (кейлоггер)
2. хуки можно снять, переназначить или не передать управление в цепочке событий
3. хук можно не только на клаву поставить, но и на мышь, например...

А вот подвопрос на интерес: если отрубили клаву или заблокировали ввод, то как можно мышью подать уникальный сигнал?
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
dimid [?]
вполне может не давать печатать, или подменять данные
и даже может выключить компьютер и не дать ему вообще загружаться, если мы говорим о стороннем приложении. Надеюсь мы не впадаем в крайности, вы же не пишете вирус, который хочет получить полный контроль над пользователем и не дать себя как то деактивировать. Если хук не даёт печатать это уже вирус.

хуки можно снять, переназначить или не передать управление в цепочке событий
а ещё можно убить процесс и удалить вашу программу.

3. хук можно не только на клаву поставить, но и на мышь, например...
например... это вопрос или ответ?
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
dimid [?]
1. С курсором нельзя
2. С хуком тоже нельзя
Тогда и _WinAPI_GetAsyncKeyState() нельзя, т.к. её можно перекрыть тем же хуком.

вряд ли нажмет по очереди случайно
В вашем примере клавиши должны быть нажаты одновременно, а не по очереди.

во время печати юзер ее может нажать нечаянно
В вашем примере нужно зажать 3 клавиши и держать их около секунды. Если это делать во время печати, то после "полезной" работы функции нужно проделать "бесполезную" работу по удалению из текста "qqqqpppppxxxxxxxxxxxxxx". Или этим будет заниматься ваша функция?
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
dimid [?]
Если интересно то примерно так про хуки:
Если интересно, то вот хорошая статья по хукам, когда-то читал, когда переводил справку по этим функциям.
Про то что я сказал
Может я не всё понимаю
имелось ввиду, что я не слышал, чтобы сторонние программы переназначали/удаляли хуки. Они на сколько я знаю встают в цепочку обработки хуков и как правило без надобности не должны поглащать его, то есть получил, обработал свои действия в своей программе, передал на выход, чтобы другие обработчики смогли обработать для своих программ. Это при всех равных условиях, то есть я не имею ввиду вирусы, которые делают так как им нужно, а не пользователю.
 
Автор
D

dimid

Новичок
Сообщения
20
Репутация
0
Именно так. Это вспомогательный модуль кое куда для борьбы с малварью. Они делают с хуками именно то, что я сказал. Что можно, а что нельзя делать с ними представлением кое-какое имею.

Моя функция работает по нажатию одновременно трех клавиш - именно такая задумка и есть - т.е юзер не сможет НЕЧАЯННО это сделать.

_WinAPI_GetAsyncKeyState() нельзя, т.к. её можно перекрыть тем же хуком.
о таких зловредах я не слышал. к слову: у нормальных антивирусов эта функция (и ее сестра) похукана в ядре как противодействие кейлоггерам. На максимальных настройках - будет алерт о подозрении на кейлогг.

имелось ввиду, что я не слышал, чтобы сторонние программы переназначали/удаляли хуки.
а я понял, что вы в хуках плохо разбираетесь и в двух словах решил объяснить :smile:
зловреды очень активно снимают/ставят/перехватывают данный вид хуков.

Если это делать во время печати, то после "полезной" работы функции нужно проделать "бесполезную" работу по удалению из текста "qqqqpppppxxxxxxxxxxxxxx".
такое будет если юзер зажмет эти три клавиши находясь в текстовом редакторе. Но - такого не будет - первое, а второе - юзать что-то кроме печатных символов нельзя по вышеозначенным причинам, потому с таким смешным возможным последствием придется мириться.
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
dimid [?]
о таких зловредах я не слышал
Код:
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <StructureConstants.au3>

OnAutoItExitRegister("Cleanup")

$hStub_KeyProc = DllCallbackRegister("_KeyProc", "long", "int;wparam;lparam")
$hmod = _WinAPI_GetModuleHandle(0)
$hHook = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, DllCallbackGetPtr($hStub_KeyProc), $hmod)

While 1
  Sleep(1000)
  $st1 = _WinAPI_GetAsyncKeyState(0x51) ; q
  If Abs ($st1) > 1 Then
     $st2 = _WinAPI_GetAsyncKeyState(0x50) ; p
     If Abs ($st2) > 1 Then
        $st3 = _WinAPI_GetAsyncKeyState(0x58) ; x
        If Abs ($st3) > 1 Then
           ; ###
           ; тут полезная нагрузка по сочетанию qpx
           MsgBox (64, "OK", "Была зажата коомбинация QPX")
           ; ###
        EndIf
     EndIf
  EndIf
WEnd

Func _KeyProc($nCode, $wParam, $lParam)
    Local $tKEYHOOKS
    $tKEYHOOKS = DllStructCreate($tagKBDLLHOOKSTRUCT, $lParam)
    If $nCode < 0 Then
        Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
    EndIf
    If $wParam = $WM_KEYDOWN Then
        If DllStructGetData($tKEYHOOKS, "vkCode") = 0x51 Then
          ControlSend("", "", "", "q")
          Return -1
        EndIf
    EndIf
    Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
EndFunc   ;==>_KeyProc

Func Cleanup()
    _WinAPI_UnhookWindowsHookEx($hHook)
    DllCallbackFree($hStub_KeyProc)
EndFunc   ;==>Cleanup
 
Автор
D

dimid

Новичок
Сообщения
20
Репутация
0
Товарищ, мы говорим об ITW-зловредах. Понятно, что накодить можно что угодно. Пример: CureIt имеет при запуске некую самозащиту в виду того, что малварь с ним борется. AVZ не имеет самозащиты в виду того, что малварь с ним борется больше детектируя его по имени файла/окна - с этим борятся юзая полиморфный переименованный avz.
Итого имеем: не можем юзать в нашем модуле непечатные клавиши, т.к малварь частенько их рубает, не можем юзать хук, т.к тоже не факт, что мы получим управление. А вот делать в цикле опрос состояния клавиш мы вполне можем, т.к малвари, которая ставит перехват на эту функцию и мешает считывать состояния клавиш как-то не встречалось ;)

Потому мой вопрос такой? Вполне ли имеет право на существование то, что я накодил или есть более изящный метод?
 
Верх