Что нового

Создание элементов HotKey Input для GUI

Yashied

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

Категория: Мышь и клавиатура, Элементы GUI

Описание: Создает и обеспечивает работу с элементами HotKey Input (визуальная установка горячих клавиш).

Синтаксис и параметры:
Основные функции:

_GUICtrlCreateHotKeyInput
_GUICtrlDeleteHotKeyInput
_GUICtrlReadHotKeyInput
_GUICtrlSetHotKeyInput
_GUICtrlReleaseHotKeyInput

Дополнительные функции:

_KeyLock
_KeyUnlock
_KeyLoadName
_KeyToStr


[box title=_GUICtrlCreateHotKeyInput]

Создает элемент HotKey Input для GUI.

Синтаксис вызова:

Код:
_GUICtrlCreateHotKeyInput ( $iKey, $iLeft, $iTop [, $iWidth [, $iHeight [, $iStyle [, $iExStyle [, $sSeparator]]]]] )


Параметры:

$iKey

16-битный код горячей клавиши, который состоит из младшего (VK - Virtual Key) и старшего (CK - Command Key) байтов. Значения битов для этих байтов показаны ниже.

0-7Определяет код горячей клавиши из таблицы Virtual-Key Codes. Коды клавиш мыши (0x01 - 0x06) и вспомогательных клавиш (0x11, 0x12 и т.д) не поддерживаются.
8Задает клавишу SHIFT.
9Задает клавишу CTRL.
10Задает клавишу ALT.
11Задает клавишу WIN.
12-15Не используются и должны быть установлены в нулевое значение.

Вы можете использовать функцию BitOR() для объединения VK- и CK-значений. Код клавиши не может состоять только из одного(их) CK-значения. Так же, не допускается использование более одного VK-значения. Функция не делает различий между левыми и правыми вспомогательными клавишами. Например, нельзя назначить горячую клавишу с использованием только левой клавиши CTRL. Это так же будет работать и для правой клавиши. Этот параметр идентичен аналогичному параметру из HotKey библиотеки.

$iLeft, $iTop, $iWidth, $iHeight, $iStyle, $iExStyle

Эти параметры идентичны параметрам для функии GUICtrlCreateInput().

$sSeparator (Опционально)

Строка символов для разделения имен клавиш при отображении в элементе HotKey Input. По умолчанию - "-".

Возвращаемое значение:

Функция возвращает идентификатор (controlID) созданного элемента HotKey Input, аналогично другим GUICtrlCreate... функциям. В случае ошибки возвращает 0.

Примечания:

  • Для уничтожения элемента HotKey Input используйте только функцию _GUICtrlDeleteHotKeyInput(). Не используйте GUICtrlDelete().
  • HotKey Input не будет работать в выключенном состоянии - $GUI_DISABLE.
  • Перед вызовом GUIDelete() рекомендуется уничтожить при помощи функции _GUICtrlReleaseHotKeyInput() все созданные ранее элементы HotKey Input.
[/box]

[box title=_GUICtrlDeleteHotKeyInput]

Уничтожает элемент HotKey Input.

Синтаксис вызова:

Код:
_GUICtrlDeleteHotKeyInput ( $controlID )


Параметры:

$controlID

Идентификатор (controlID) уничтожаемого элемента HotKey Input, возвращенный функцией _GUICtrlCreateHotKeyInput().

Возвращаемое значение:

При успешном завершении функция возвращает 1, в случае ошибки - 0.

Примечания:

  • Для уничтожения элемента HotKey Input используйте только эту функцию. Не используйте GUICtrlDelete().
  • Если элемент HotKey Input является последним из созданных, то хук автоматически будет удален из цепочки хуков после его уничтожения.
  • Для уничтожения всех ранее созданных элементов HotKey Input используйте функцию _GUICtrlReleaseHotKeyInput().
[/box]

[box title=_GUICtrlReadHotKeyInput]

Считывает 16-битный код горячей клавиши из элемента HotKey Input.

Синтаксис вызова:

Код:
_GUICtrlReadHotKeyInput ( $controlID )


Параметры:

$controlID

Идентификатор (controlID) элемента HotKey Input, возвращенный функцией _GUICtrlCreateHotKeyInput(), из которого необходимо считать код горячей клавиши.

Возвращаемое значение:

Функция возвращает 16-битный код горячей клавиши (см. _GUICtrlCreateHotKeyInput()), установленный в поле элемента HotKey Input. В случае ошибки или отсутствия установленной горячей клавиши возвращает 0.

Примечания:

  • Для получения строкового значения горячей клавиши используйте функцию _KeyToStr().
[/box]

[box title=_GUICtrlSetHotKeyInput]

Устанавливает 16-битный код горячей клавиши в элемент HotKey Input.

Синтаксис вызова:

Код:
_GUICtrlSetHotKeyInput ( $controlID, $iKey )


Параметры:

$controlID

Идентификатор (controlID) элемента HotKey Input, возвращенный функцией _GUICtrlCreateHotKeyInput(), в который необходимо установить заданную горячую клавишу.

$iKey

16-битный код устанавливаемой горячей клавиши (см. _GUICtrlCreateHotKeyInput()). Если значение этого параметра равно нулю, то элемент HotKey Input будет очищен.

Возвращаемое значение:

При успешном завершении функция возвращает 1, в случае ошибки - 0.

Примечания:

Нет.
[/box]

[box title=_GUICtrlReleaseHotKeyInput]

Уничтожает все элементы HotKey Input, созданные ранее при помощи функции _GUICtrlCreateHotKeyInput() и удаляет хук из цепочки хуков.

Синтаксис вызова:

Код:
_GUICtrlReleaseHotKeyInput (  )


Параметры:

Нет.

Возвращаемое значение:

При успешном завершении функция возвращает 1, в случае ошибки - 0.

Примечания:

Нет.
[/box]

[box title=_KeyLock]

Блокирует использование указанной горячей клавиши для всех элементов HotKey Input.

Синтаксис вызова:

Код:
_KeyLock ( $iKey )


Параметры:

$iKey

16-битный код горячей клавиши (см. _GUICtrlCreateHotKeyInput()), которая должна быть заблокирована.

Возвращаемое значение:

Нет.

Примечания:

  • Функция является независимой и может быть вызвана в любое время.
  • Функция блокирует горячие клавиши только для элементов HotKey Input. Более того, после блокировки, эти горячие клавиши будут доступны для других приложений. Например, если заблокировать ALT-TAB (0x0409), то эта комбинация будет работать так же, как и раньше, в то время когда элементы HotKey Input находятся в фокусе.
  • Функция блокирует комбинацию клавиш (горячую клавишу), а не отдельную клавишу. Таким образом нельзя заблокировать, например клавишу F5, остается возможность использовать эту клавишу в сочетании с системными клавишами - CTRL, ALT и т.д. Для этой цели используйте функцию _KeyLoadName().
  • С помощью этой функции можно заблокировать сколько угодно комбинаций клавиш, но не более одной за один вызов функции.
  • Для снятия блокировки используйте функцию _KeyUnlock().
[/box]

[box title=_KeyUnlock]

Разблокирует указанную горячую клавишу, заблокированную ранее функцией _KeyLock(), для всех элементов HotKey Input.

Синтаксис вызова:

Код:
_KeyUnlock ( $iKey )


Параметры:

$iKey

16-битный код горячей клавиши (см. _GUICtrlCreateHotKeyInput()), заблокированной ранее с помощью функции _KeyLock(), которая должна быть разблокирована.

Возвращаемое значение:

Нет.

Примечания:

  • Функция является независимой и может быть вызвана в любое время.
  • С помощью этой функции можно разблокировать сколько угодно, заблокированных ранее комбинаций клавиш, но не более одной за один вызов функции.
  • Для блокировки используйте функцию _KeyLock().
[/box]

[box title=_KeyLoadName]

Загружает названия клавиш, которые будут отображаться во всех элементах HotKey Input.

Синтаксис вызова:

Код:
_KeyLoadName ( $aKeyName )


Параметры:

$aKeyName

Одномерный массив из 256 строк, содержащих названия клавиш с кодами, соответствующими индексам в массиве. Эти названия будут отображаться в поле для всех элементов HotKey Input. Например:

Код:
Dim $aKeyName[256]

$aKeyName[0x00] = "None"
$aKeyName[0x01] = ""
$aKeyName[0x02] = ""
$aKeyName[0x03] = ""
$aKeyName[0x04] = ""
$aKeyName[0x05] = ""
$aKeyName[0x06] = ""
$aKeyName[0x07] = ""
$aKeyName[0x08] = "Backspace"
$aKeyName[0x09] = "Tab"
...
$aKeyName[0xFF] = ""

Элемент массива с нулевым индексом содержит название, которое будет отображаться в поле HotKey Input при отсутствии установленной горячей клавиши (может быть пустым - ""). Названия для клавиш мыши (0x01 - 0x06) не используются и должны быть пустыми. Коды для необходимых клавиш можно узнать из таблицы Virtual-Key Codes. Если имя клавиши не определено (пустая строка), то эта клавиша будет исключена для использования в любых комбинациях в элементах HotKey Input. Таким образом можно ограничивать допустимый набор разрешенных для использования клавиш. По умолчанию загружается массив $VK, находящийся в файле vkArray.au3. Этот файл является составной частью библиотеки HotKeyInput.

Возвращаемое значение:

При успешном завершении функция возвращает 1, в случае ошибки - 0 и устанавливает значение @error в 1.

Примечания:

  • Если длина массива отличается от 256, то он не будет загружен и функция возвратит ошибку.
  • Помимо глобальной блокировки, с помощью этой функции можно переименовывать названия клавиш, например Shift в SHIFT и т.д.
  • Названия для клавиш CTRL, ALT, SHIFT и WIN с кодами (0xA2, 0xA3), (0xA4, 0xA5), (0xA0, 0xA1) и (0x5B, 0x5C) соответственно должны быть одинаковые (см. vkArray.au3). Коды 0x10, 0x11 и 0x12 не поддерживаются.
[/box]

[box title=_KeyToStr]

Преобразует 16-битный код горячей клавиши в строку, содержащую комбинацию из названий клавиш и разделителей.

Синтаксис вызова:

Код:
_KeyToStr ( $iKey [, $sSeparator] )


Параметры:

$iKey

16-битный код горячей клавиши (см. _GUICtrlCreateHotKeyInput()) для преобразования.

$sSeparator

Строка символов для разделения имен клавиш при отображении в элементе HotKey Input. По умолчанию - "-".

Возвращаемое значение:

Функция возвращает строку, состоящую из названий клавиш и разделителей, например "None", "Win-F" или "Alt-Shift-D". В случае ошибки (клавиша не определена) - "".

Примечания:

  • Возвращаемая этой функцией строка предназначена только для визуального представления горячей клавиши и не может быть использована в качестве параметра для функции HotKeySet().
  • Для переименования названий клавиш используйте функцию _KeyLoadName().
[/box]

Пример:
Код:
#Include <GUIConstantsEx.au3>
#Include <HotKeyInput.au3>

Global $Form, $ButtonOk, $HotkeyInput1, $HotkeyInput2, $GUIMsg

$Form = GUICreate('Test', 300, 160)
GUISetFont(8.5, 400, 0, 'Tahoma', $Form)

$HotkeyInput1 = _GUICtrlCreateHotKeyInput(0, 56, 55, 230, 20)
$HotkeyInput2 = _GUICtrlCreateHotKeyInput(0, 56, 89, 230, 20)

_KeyLock(0x062E) ; Lock CTRL-ALT-DEL for Hotkey Input control, but not for Windows

GUICtrlCreateLabel('Hotkey1:', 10, 58, 44, 14)
GUICtrlCreateLabel('Hotkey2:', 10, 92, 44, 14)
GUICtrlCreateLabel('Click on Input box and hold a combination of keys.' & @CR & 'Press OK to view the code.', 10, 10, 280, 28)
$ButtonOk = GUICtrlCreateButton('OK', 110, 124, 80, 23)
GUICtrlSetState(-1, BitOR($GUI_DEFBUTTON, $GUI_FOCUS))
GUISetState()

While 1
	$GUIMsg = GUIGetMsg()
	Select
		Case $GUIMsg = $GUI_EVENT_CLOSE
			Exit
		Case $GUIMsg = $ButtonOk
			$t = '   Hotkey1:  0x' & StringRight(Hex(_GUICtrlReadHotKeyInput($HotkeyInput1)), 4) & '  (' & GUICtrlRead($HotkeyInput1) & ')   ' & @CR & @CR & _
					'   Hotkey2:  0x' & StringRight(Hex(_GUICtrlReadHotKeyInput($HotkeyInput2)), 4) & '  (' & GUICtrlRead($HotkeyInput2) & ')   '
			MsgBox(0, 'Code', $t, 0, $Form)
	EndSelect
WEnd

Скриншот:

HotKeyInput.png

Источник: HotKeyInput UDF (оффициальный форум)
Автор: Yashied


Примечания:

  • Эта библиотека была разработана специально для поддержки библиотеки HotKey, но может быть использована и отдельно от нее.
  • Так как библиотека использует глобальный хук, то все ранее установленные в системе горячие клавиши не будут работать до тех пор, пока элемент HotKey Input находится в фокусе (собственно это и не нужно). Исключение составляют только те горячие клавиши, которые были заблокированы при помощи функции _KeyLock().
  • Библиотека не предназначена для работы со стандартной функцией HotKeySet(), но может быть легко модифицирована для этой цели. (см. функцию _KeyToStr() и этот материал).
  • Файл vkArray.au3 является составной частью данной библиотеки и должен находиться в той же директории, что и сама библиотека.
 
Автор
Yashied

Yashied

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

:smile:
 

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
[?]
Yashied сказал(а):
Обновил описание библиотеки
Классная работа и оформление.
Похоже на оформление и перевод потрачено времени и сил никак не меньше ,чем разработку :IL_AutoIt_1:
 

SECTOR

Продвинутый
Сообщения
399
Репутация
59
Как получить код понятно но не получается привязать горячую клавишу из этого кода! :'(
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Приведи пример, что именно не работает.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Yashied
Действительно не очень уж просто разобраться в установке клавиш.

Я чисто интуитивно догадался что соеденять нужно так:

Код:
0xA1A345


это отдельные 0xA1 (Shift), 0xA3 (Ctrl), и 0x45 (E).

BitOR тут не помагает.

Имхо, не помешало бы добавить поддержку строковых значений, чтобы юзер мог указать сразу: _GUICtrlCreateHotKeyInput("SHIFT + CTRL + E", 65, 50, 230, 20).
Ну и/или функцию для преобразования строкового значения в Hex (типа _StrToKey).


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

P.S
И как мне задать комбинацию «Win + Left»?

Код:
_GUICtrlCreateHotKeyInput(0x5B25, 75, 90, 220, 20, -1, -1, "+")


Выводит «Ctrl+Shift+Win+Left».
Upd: Вот так вроде нормально: 0x0825
А вот как вывести теперь «Ctrl + Win + Left»?
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
@CreatoR

Вы можете использовать функцию BitOR() для объединения VK- и CK-значений. Код клавиши не может состоять только из одного(их) CK-значения. Так же, не допускается использование более одного VK-значения. Функция не делает различий между левыми и правыми вспомогательными клавишами. Например, нельзя назначить горячую клавишу с использованием только левой клавиши CTRL. Это так же будет работать и для правой клавиши. Этот параметр идентичен аналогичному параметру из HotKey библиотеки.

Если честно, то я не понимаю в чем тут проблема. Я специально разделил системные и все остальные клавиши в разные константы - CK- и VK- (см. здесь).

Ответ на твой вопрос:

Код:
Global Const $CK_SHIFT = 0x0100
Global Const $CK_CONTROL = 0x0200
Global Const $CK_ALT = 0x0400
Global Const $CK_WIN = 0x0800

Global Const $VK_LEFT = 0x25

_GUICtrlSetHotKeyInput($HotkeyInput, BitOR($CK_CONTROL, $CK_WIN, $VK_LEFT))


Не путать $CK_... c $VK_...



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

CreatoR сказал(а):
Имхо, не помешало бы добавить поддержку строковых значений, чтобы юзер мог указать сразу...

А зачем? Эта библиотека предназначена специально для поддержки HotKey. Горячая клавиша задается всего одним числовым значением, причем в соответствии с MSDN. Зачем писать малополезную функцию для анализа строк? Если отказаться от HotKeySet() в пользу _HotKeyAssign(), то исходный код может уменьшится в разы, именно за счет использования числовых значений для задания горячих клавиш.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Yashied [?]
Для удобства.

Если отказаться от HotKeySet() в пользу _HotKeyAssign(), то исходный код может уменьшится в разы, именно за счет использования числовых значений для задания горячих клавиш.
Согласен, но AutoIt тем и лучше для новичков (чем тот же C), что на нём удобнее и легче писать код, а структура таких значений параметров немного ставит под вопрос данный факт (простота использования).

Мне лично будет не трудно перейти на такой лад, а вот для новичков сомневаюсь, хотя могу ошибаться, народ сегодня у нас смышлённый попадается :Typing:
 

Redline

AutoIT Гуру
Сообщения
506
Репутация
375
Новая версия AutoIt ругается на Opt('OnExitFunc', )
мона обновлять UDF :smile:
Global $OnHotKeyInputExit = OnAutoItExitRegister('OnHotKeyInputExit')
Global $OnHotKeyExit = OnAutoItExitRegister('OnHotKeyExit')
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Yashied [?]
Сильный аргумент
Без шуток, очень сильный!

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

Вот написал функцию _StrToKey:

Код:
Func _StrToKey($sStr, $sSeparator = '-')
	Local Const $CK_SHIFT = 0x0100, $CK_CONTROL = 0x0200, $CK_ALT = 0x0400, $CK_WIN = 0x0800
	Local $iRet = ''
	
	If StringInStr($sStr, 'Ctrl') Then $iRet = BitOR($iRet, $CK_CONTROL)
	If StringInStr($sStr, 'Shift') Then $iRet = BitOR($iRet, $CK_SHIFT)
	If StringInStr($sStr, 'Alt') Then $iRet = BitOR($iRet, $CK_ALT)
	If StringInStr($sStr, 'Win') Then $iRet = BitOR($iRet, $CK_WIN)
	
	$sStr = StringRegExpReplace($sStr, '(?i)(Ctrl|Shift|Alt|Win)', '')
	$sStr = StringReplace($sStr, $sSeparator, '')
	
	$iRet = BitOR($iRet, "0x" & Hex(Asc(StringUpper($sStr)), 2))
	
	Return $iRet
EndFunc


Возможно её стоит добавить в библиотеку, а в начале функции _GUICtrlCreateHotKeyInput добавить:

Код:
If IsString($iKey) Then
		$iKey = _StrToKey($iKey, $sSeparator)
	EndIf


тогда можно будет намного проще указывать горячую клавишу:
Код:
$HotkeyInput1 = _GUICtrlCreateHotKeyInput("Ctrl+Shift+K", 56, 55, 230, 20, -1, -1, "+")
 
Автор
Yashied

Yashied

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

Да, в таком (нативном) виде это действительно может упростить многим жизнь. OK, будет время, добавлю эту возможность.



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

OffTopic:

CreatoR сказал(а):
где используются много г.клавиш...

И что это такие за Г. клавиши?

:whistle:
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Yashied [?]
будет время, добавлю эту возможность
У меня там в функции ошибка, пока идей нет как поправить... вобщем конвертация одиночной клавиши не всегда задаёт правильное Hex-значение, например хоткей «Ctrl + Shift + ~», тильда превращается в результате в «F15» :smile:

OffTopic:
что это такие за Г. клавиши?
Это сокращение от «Горячие клавиши».
 
Автор
Yashied

Yashied

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

Ну так нужно сделать просто таблицу (массив) соответствий.

OffTopic:

CreatoR сказал(а):
Это сокращение от «Горячие клавиши».

Ааа, а я то уж подумал, что это...

:smile:
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Yashied [?]
нужно сделать просто таблицу (массив) соответствий
А я просто использовал ту что в vkArray.au3, вот что получилось:

Код:
Func _StrToKey($sStr, $sSeparator = '-')
	Local Const $CK_SHIFT = 0x0100, $CK_CONTROL = 0x0200, $CK_ALT = 0x0400, $CK_WIN = 0x0800
	Local $iRet = ''
	
	If StringInStr($sStr, 'Ctrl') Then $iRet = BitOR($iRet, $CK_CONTROL)
	If StringInStr($sStr, 'Shift') Then $iRet = BitOR($iRet, $CK_SHIFT)
	If StringInStr($sStr, 'Alt') Then $iRet = BitOR($iRet, $CK_ALT)
	If StringInStr($sStr, 'Win') Then $iRet = BitOR($iRet, $CK_WIN)
	
	$sStr = StringRegExpReplace($sStr, '(?i)(Ctrl|Shift|Alt|Win)(' & $sSeparator & ')?', '')
	
	For $i = 1 To UBound($VK)-1
		If $VK[$i] = $sStr Then
			$iRet = BitOR($iRet, "0x" & Hex($i, 2))
			ExitLoop
		EndIf
	Next
	
	Return $iRet
EndFunc



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

Да и ещё, дл совместимости желательно добавить эту поддержку и в _GUICtrlSetHotKeyInput:

Код:
Func _GUICtrlSetHotKeyInput($iCtrlID, $iKey)
	Local $i
	
	If BitAND($iKey, 0x00FF) = 0 Then $iKey = 0
	
	For $i = 1 To $hkId[0][0]
		If $iCtrlID = $hkId[$i][0] Then
			$hkId[0][1] = 1
			
			If Not IsString($iKey) Then
				$iKey = _KeyToStr($iKey, $hkId[$i][3])
			EndIf
			
			If Not GUICtrlSetData($hkId[$i][0], $iKey) Then
				$hkId[0][1] = 1
				Return 0
			EndIf
			
			$hkId[$i][2] = $iKey
			$hkId[0][1] = 0
			
			Return 1
		EndIf
	Next
	
	Return 0
EndFunc
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Эта библиотека была написана специально для HotKey UDF, что-то вроде бонуса. Зачем ее использовать в GUISetAccelerators()? В любом случае, написать функцию конвертации не проблема.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Yashied [?]
Зачем ее использовать в GUISetAccelerators()?
Как зачем, у меня есть элементы GUI, и мне нужно позволить задавать для них HotKey :smile:.
Что тогда посоветуешь использовать?

написать функцию конвертации не проблема.
Я уже вроде написал (см. выше), и ты говорил что добавишь возможность указывать строковое значение, прошло уже 2 года :whistle:.

OffTopic:
Вот время летит...
 
Верх