Что нового

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

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 705
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 UDF (оффициальный форум)
Автор: Yashied


Примечания:

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

Yashied

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

:smile:
 

gregaz

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

SECTOR

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

Yashied

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

Yashied

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

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 166
Репутация
2 331
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 705
@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 166
Репутация
2 331
Yashied [?]
Для удобства.

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

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

Redline

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

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 166
Репутация
2 331
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 705
CreatoR сказал(а):
Да, в таком (нативном) виде это действительно может упростить многим жизнь. OK, будет время, добавлю эту возможность.



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

OffTopic:

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

:whistle:
 

CreatoR

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

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

Yashied

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

OffTopic:

CreatoR сказал(а):
Это сокращение от «Горячие клавиши».
Ааа, а я то уж подумал, что это...

:smile:
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 166
Репутация
2 331
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 705
Эта библиотека была написана специально для HotKey UDF, что-то вроде бонуса. Зачем ее использовать в GUISetAccelerators()? В любом случае, написать функцию конвертации не проблема.
 

CreatoR

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

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

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