Что нового

Как сделать, чтобы хоткеи работали только при активном GUI - новое решение

Suppir

Продвинутый
Сообщения
967
Репутация
62
Привет!

AutoIt по умолчанию перехватывает все хоткеи, идущие с клавиатуры. Если вы хотите сделать так, чтобы хоткеи работали только когда активно ваше приложение, можно воспользоваться GUISetAccelerators. Но я предлагаю другое, более простое решение:

Код:
GUICreate("Пример")
GUISetState()

AdlibRegister("_isActive")

while 1
	Sleep(100)
WEnd	


Func _isActive()
	If WinActive("Пример") Then
		HotKeySet("q", "_SayHello")
	Else
		HotKeySet("q")
	EndIf
EndFunc


Func _SayHello()
	TrayTip("", "Hello world!", 1)
	sleep (1000)
	TrayTip("", "", 0)
EndFunc



В этом примере если приложение активно, то работает хоткей "q" (выскакивает надпись в трее). А если приложение не активно, то хоткеи перестают перехватываться AutoIt'ом - а значит, другие программы работают без проблем!

Смысл идеи:
с помощью функции AdlibRegister через определенные промежутки времени проверяем активно ли приложение. Если оно активно, то устанавливаем хоткеи. А если приложение не активно, то снимаем хоткеи. Проверено - работает :smile:
 

SyDr

Сидра
Сообщения
651
Репутация
158
1) Функция вызывается раз в 250 мс. Если была вызвана функция и тут же произошла потеря фокуса, то хоткей действует ещё почти четверть секунды.
2) А если в системе есть ещё окна с таким же заголовком?
 
Автор
S

Suppir

Продвинутый
Сообщения
967
Репутация
62
SyDr

1. После того как пользователь развернет или развернет наш GUI, вряд ли он успеет в течение 0,25 секунды нажать на хоткей. Разве что он чемпион по квейку :smile:
2. Заголовок нужно делать достаточно уникальным. Например: MyProg, v.0.1 beta :smile: Вряд ли будут еще такие программы.

Самое главное, что этот способ очень простой, не требует прописывания акселераторов (т.е. эту функцию легко переносить из программы в программу).
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Suppir сказал(а):
Самое главное, что этот способ очень простой...

Ты это серьезно? Зачем усложнять себе жизнь? Если честно, то более "странного" решения я еще не видел. Акселераторы именно для этого и были придуманы, вопрос только в том, как их лучше использовать. А HotKeySet() не будет работать, если в другом скрипте уже назначены те же горячие клавиши. Для подобных задач я советую всегда использовать акселераторы.

Код:
Dim $HK[12][2] = [['{F1}'], ['{F2}'], ['{F3}'], ['{F4}'], ['{F5}'], ['{F6}'], ['{F7}'], ['{F8}'], ['{F9}'], ['{F11}'], ['{F11}'], ['{F12}']]

GUICreate('MyGUI')
For $i = 0 To UBound($HK) - 1
	$HK[$i][1] = GUICtrlCreateDummy()
Next
GUISetAccelerators($HK)
GUISetState()

While 1
	$Msg = GUIGetMsg()
	Switch $Msg
		Case -3
			ExitLoop
		Case $HK[0][1] To $HK[UBound($HK) - 1][1]
			ConsoleWrite(($Msg - $HK[0][1]) & @CR)
	EndSwitch
WEnd


А еще это можно сделать с помощью HotKey.au3 библиотеки.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
Для этого обычно используется WM_ACTIVATE:

Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

$hMainGUI = GUICreate('WM_ACTIVATE Demo', 330, 185)

$nExit_Button = GUICtrlCreateButton('Exit', 330 - 100 - 10, 130 + 10 + 10, 100, 23)

GUIRegisterMsg($WM_ACTIVATE, 'WM_ACTIVATE')
GUISetState(@SW_SHOW, $hMainGUI)

While 1
	Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE, $nExit_Button
			Exit
	EndSwitch
WEnd

Func _SayHello()
	TrayTip("", "Hello world!", 1)
	sleep(1000)
	TrayTip("", "", 0)
EndFunc

Func WM_ACTIVATE($hWnd, $Msg, $wParam, $lParam)
	Local $iWinWinActive = Int(Hex($wParam))
	
	If $iWinWinActive = 1 Then
		HotKeySet("q", "_SayHello")
	Else
		HotKeySet("q")
	EndIf
EndFunc



Добавлено:
Сообщение автоматически объединено:

Suppir [?]
Заголовок нужно делать достаточно уникальным. Например: MyProg, v.0.1 beta
Вообще то GUICreate возвращает hWnd, т.н дескриптор окна, это и есть уникальный идентификатор окна.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Немного смутила следующая запись:

Код:
$iWinWinActive = Int(Hex($wParam))


Нужно так:

Код:
Func WM_ACTIVATE($hWnd, $iMsg, $wParam, $lParam)
	If BitAND($wParam, 0xFFFF) Then
		HotKeySet("q", "_SayHello")
	Else
		HotKeySet("q")
	EndIf
EndFunc   ;==>WM_ACTIVATE


:whistle:
 
Верх