Что нового

HotKey - Установка горячих клавиш

Fever

Скриптер
Сообщения
308
Репутация
112
Крепыш сказал(а):
"клавиша нажата столько-то раз".

Код:
HotKeySet('d', '_count')
$i = 1

While 1
	Sleep(100)
WEnd

func _count()
	MsgBox(64, '', 'Кнопка нажата ' & $i & ' раз')
	$i = $i + 1
EndFunc

простой вариант :whistle:
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Или так
Код:
HotKeySet("{UP}", "UP")
HotKeySet("{DOWN}", "DOWN")
$i = 0
While 1
	Sleep(10)
WEnd
Func UP()
	Sleep(10)
	$i += 1
	Return $i
EndFunc   ;==>UP

Func DOWN()
	MsgBox(0, "", "С начала работы скрипта клавиша UP нажата " & $i & " раз", 3)
EndFunc   ;==>DOWN
 

Крепыш

Новичок
Сообщения
105
Репутация
2
Fever
madmasles

Не, не так. Имеется ввиду при нажатии клавиши несколько раз подряд (с интервалом не более 200 мс) выводится сообщение. Затем счётчик обнуляется, и отсчёт ведётся по-новой.
Но с HotKeySet я и сам могу. Типа так:
Код:
HotKeySet("{UP}", "UP") 
$i = 0 
While True 
  Sleep(10) 
WEnd 
Func UP() 
  $i += 1 
  Sleep(200) 
  If $i > 0 Then 
    ConsoleWrite('Нажата клавиша UP '&$i&' раз'&@CRLF) 
  EndIf 
  $i = 0 
EndFunc


Или вот (это, вроде, твой код, madmasles, с руборда):
Код:
HotKeySet("{UP}", "UP") 
$i = 0 
While 1 
    Sleep(10) 
    If $i > 0 Then 
        MsgBox(0, "", "Нажата клавиша UP " & $i & " раз", 3) 
        $i = 0 
    EndIf 
WEnd 
Func UP() 
    Sleep(200) ;пауза между нажатиями. 
    $i += 1 
    Return $i 
EndFunc   ;==>UP


Хотя второй вариант не подходит: сообщение должно выводиться в самой функции.

А вот с _HotKeyAssign не получается.
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Тормозить функции прерывания, даже Sleep'ом, плохой стиль программирования. Касаемо _HotKeyAssign(), она работает совершенно на другом принципе, в сравнении с HotKeySet(), здесь используется Hook со всеми его преимуществами и недостатками. Например можно назначить совершенно любую горячую клавишу (CTRL+ALT+DEL, F12, WIN+... и т.д.) или назначить клавишу, даже, если она была назначена другим приложением, при этом ваша программа получит наивысший приоритет. И многое другое, что нельзя осуществить с помощью HotKeySet().

Код:
#Include <HotKey.au3>

Global Const $VK_UP = 0x26

Global $Timer, $Count = 0, $Int = 0

_HotKeyAssign($VK_UP, 'UP')

While 1
	Sleep(10)
	If ($Count) And (TimerDiff($Timer) > 200) Then
		ConsoleWrite('Нажата клавиша UP ' & $Count & ' раз' & @CRLF)
		$Count = 0
	EndIf
WEnd

Func UP()
	$Timer = TimerInit()
	$Count += 1
EndFunc   ;==>UP
 

Крепыш

Новичок
Сообщения
105
Репутация
2
В самой функции UP() вывод сообщения можно как-нить реализовать?
 

Redline

AutoIT Гуру
Сообщения
506
Репутация
375
Нельзя ли добавить расширение для функции _HotKeyRelease, что бы была возможность удалять конкретный хоткей? Бывают ситуации с переназначение только одной горячей клавиши, и чтобы удалить старое ее сочетание нужно после _HotKeyRelease заново назначать _HotKeyAssign для всех сочетаний.
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Redline сказал(а):
Нельзя ли добавить расширение для функции _HotKeyRelease, что бы была возможность удалять конкретный хоткей? Бывают ситуации с переназначение только одной горячей клавиши, и чтобы удалить старое ее сочетание нужно после _HotKeyRelease заново назначать _HotKeyAssign для всех сочетаний.

Код:
_HotKeyAssign($iKey, "")


или просто

Код:
_HotKeyAssign($iKey)


Освобождает ранее установленную горячую клавишу $iKey. В принципе это написано в описании функции в первом посте.
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
Yashied

Код:
#include <HotKey.au3>
#include <vkConstants.au3>
;_HotKeyAssign(BitOR(0x0800, 0xA2), '_Stroka')
_HotKeyAssign(BitOR($CK_CONTROL, $CK_WIN), '_Stroka')

Почему это не работает? В Arum Switcher Win+Ctrl работает.


И ещё, в примере HotKeyInput.au3 в функции _GUICtrlCreateHotKeyInput хотелось бы использовать просмотр предыдущих горячих клавиш. Например, просто вставить их туда как текст-муляж или как реальные, ну чтобы было видно текущие и выбрать иные.


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

Что может неправильно быть в такой строке
Код:
For $i = 1 to 8
	If GUICtrlRead($HotkeyInput1) <> 'None' Then
	_HotKeyAssign('0x' & StringRight(Hex(_GUICtrlReadHotKeyInput(Eval('HotkeyInput' & $i))), 4), '_Mode'&$i)
		RegWrite("HKCU\Software\TextCorrection","Hotkey"&$i,"REG_SZ",GUICtrlRead(Eval('HotkeyInput' & $i)))
	EndIf
Next


Похоже ошибка, что это не числовая переменная
 
Автор
Yashied

Yashied

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

Yashied]Вы можете использовать функцию BitOR() для объединения VK- и CK-значений. [b]Код клавиши не может состоять только из одного(их) CK-значения.[/b] Так же сказал(а):
...в примере HotKeyInput.au3 в функции _GUICtrlCreateHotKeyInput хотелось бы использовать просмотр предыдущих горячих клавиш. Например, просто вставить их туда как текст-муляж или как реальные, ну чтобы было видно текущие и выбрать иные.

Ничего не понял.

AZJIO сказал(а):
Что может неправильно быть в такой строке...

Код:
$iKey = _GUICtrlReadHotKeyInput($CtrlID)
RegWrite('...', '...', 'REG_DWORD', $iKey)
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
Yashied
С RegWrite всё должно работать, я до неё ещё не дошёл.

Разгадал загадку, #Include <HotKey.au3> забыл добавить, добавил только #Include <HotKeyInput.au3>.
 
Автор
Yashied

Yashied

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

  • Пример нерабочий.
  • В функцию _HotKeyAssign() нужно передавать не строковое выражение, а числовое - код горячей клавиши. Кстати, именно его и возвращает функция _GUICtrlReadHotKeyInput().
  • Не нужно для элементов HotKey Input использовать GUICtrlRead(), для чтения введенной клавиши используй _GUICtrlReadHotKeyInput().
  • У тебя получился безбашенный код. Почему бы не использовать масивы? Здесь они сами напрашиваются.

Вообщем в пределах твоего кода нужно делать так:

Код:
For $i = 1 To 8
	$iKey = _GUICtrlReadHotKeyInput(Eval('HotkeyInput' & $i))
	MsgBox(0, "Сообщение", "0x" & Hex($iKey, 4))
	_HotKeyAssign($iKey, "_Mode" & $i)
	RegWrite("HKCU\Software\TextCorrection", "Hotkey" & $i, "REG_DWORD", $iKey)
Next
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
Yashied
Вот теперь заново всё переписывать, я уже в шестнадцатеричном виде сделал в ini. Массивы попробовал, не работает, может цифры можно загнать в массив, а я уж и элементы gui начал в массив загонять, в общем возвращаю и переделываю... отпишу потом.

HotkeyInput - это гуи элемент он вроде не работает в массиве, а iKey нет смысла добавлять в массив, так как от него нет толку, горячие клавиши генерируются и сохраняются в реальном времени и промежуточный массив хранить нет смысла.

Ctrl стал залипать, в чём причина? В скрипте используется _SendEx("^{INS}")
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
Для выделения текста, копирования и вставки. В "Arum Switcher" используется тот же метод, так как если смотреть в расширенном буфере, то видно восстановление буфера после операций вставки исправления текста.


Код:
;  @AZJIO 6.06.2010
; программа исправления текста набранного в неправильной раскладке клавиатуры
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_OutFile=TextCorrection.exe
;#AutoIt3Wrapper_icon=TextCorrection.ico
;#AutoIt3Wrapper_Compression=4
#AutoIt3Wrapper_UseUpx=n
#AutoIt3Wrapper_UseAnsi=y
#AutoIt3Wrapper_Res_Comment=-
#AutoIt3Wrapper_Res_Description=TextCorrection.exe
#AutoIt3Wrapper_Res_Fileversion=0.4.0.0
#AutoIt3Wrapper_Res_LegalCopyright=AZJIO
#AutoIt3Wrapper_Res_Language=1049
#AutoIt3Wrapper_Run_AU3Check=n
#AutoIt3Wrapper_Run_After=%autoitdir%\SciTE\ResHacker\ResHacker.exe -add "%out%", "%out%", %scriptdir%\TextCorrection1.ico, IconGroup, 1, 0
#AutoIt3Wrapper_Run_After=%autoitdir%\SciTE\ResHacker\ResHacker.exe -add "%out%", "%out%", %scriptdir%\TextCorrection3.ico, IconGroup, 3, 0
#AutoIt3Wrapper_Run_After=%autoitdir%\SciTE\ResHacker\ResHacker.exe -add "%out%", "%out%", %scriptdir%\TextCorrection4.ico, IconGroup, 4, 0
#AutoIt3Wrapper_Run_After=%autoitdir%\SciTE\ResHacker\ResHacker.exe -delete "%out%", "%out%", DIALOG, 1000,
#AutoIt3Wrapper_Run_After=%autoitdir%\SciTE\ResHacker\ResHacker.exe -delete "%out%", "%out%", ICON, 161,
#AutoIt3Wrapper_Run_After=%autoitdir%\SciTE\ResHacker\ResHacker.exe -delete "%out%", "%out%", ICON, 162,
#AutoIt3Wrapper_Run_After=%autoitdir%\SciTE\ResHacker\ResHacker.exe -delete "%out%", "%out%", ICON, 164,
#AutoIt3Wrapper_Run_After=%autoitdir%\SciTE\ResHacker\ResHacker.exe -delete "%out%", "%out%", ICON, 169,
#AutoIt3Wrapper_Run_After=%autoitdir%\SciTE\upx\upx.exe -7 --compress-icons=0 "%out%"
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

#Include <HotKeyInput.au3>
#Include <vkConstants.au3>
#Include <vkArray.au3>
#Include <HotKey.au3>
Opt("SendKeyDelay", 1)
Opt("SendKeyDownDelay", 1)
Opt("TrayMenuMode", 1)
Opt("TrayOnEventMode", 1)
_Singleton(" ") ; не запускать дважды
Global $Paused, $En, $Ru, $HotKey[9]
Global $Ini = @ScriptDir&'\TextCorrection.ini' ; путь к TextCorrection.ini

$EnDef = "`qwertyuiop[]asdfghjkl;'zxcvbnm,./~QWERTYUIOP{}ASDFGHJKL:""|ZXCVBNM<>?@#$^&"
$RuDef = "ёйцукенгшщзхъфывапролджэячсмитьбю.ЁЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭ/ЯЧСМИТЬБЮ,""№;:?"

;Проверка существования TextCorrection.ini
If Not FileExists($Ini) Then
	If MsgBox(4, "Выгодное предложение", "Первый старт, отсутствует TextCorrection.ini"&@CRLF&"создаём, иначе выход.") = "6" Then
		$iniopen = FileOpen($Ini,2)
		FileWrite($iniopen, '[General]' & @CRLF & _
		'Lang1=' & $EnDef  & @CRLF & _
		'Lang2=' & $RuDef & @CRLF & @CRLF & _
		'[HotKey]' & @CRLF & _
		'HotKey1=732' & @CRLF & _
		'HotKey2=734' & @CRLF & _
		'HotKey3=698' & @CRLF & _
		'HotKey4=703' & @CRLF & _
		'HotKey5=702' & @CRLF & _
		'HotKey6=731' & @CRLF & _
		'HotKey7=733' & @CRLF & _
		'HotKey8=539')
		FileClose($iniopen)
	Else
		Exit
	EndIf
EndIf

;читаем TextCorrection.ini
$En = IniRead ($Ini, "General", "Lang1", $EnDef )
$Ru = IniRead ($Ini, "General", "Lang2", $RuDef)
$aDef = StringSplit("732,734,698,703,702,731,733,539", ",")
For $i = 1 to 8
$HotKey[$i]=IniRead ($Ini, "HotKey", "HotKey"&$i, $aDef[$i] )
Next

TraySetIcon(@ScriptDir&"\TextCorrection.exe", 4)

$langdef = RegRead("HKCU\Keyboard Layout\Preload", "1") ; читаем язык по умолчанию
_HotKeySet()

$Suspend=TrayCreateItem("Приостановить")
TrayItemSetOnEvent(-1, "_Pause")

$Readme=TrayCreateItem("Readme")
TrayItemSetOnEvent(-1, "_Readme")

$About = TrayCreateItem("О программе")
TrayItemSetOnEvent(-1, "_About")

$GuiHotKey = TrayCreateItem("Горячие клавиши")
TrayItemSetOnEvent(-1, "_GuiHotKey")

$Quit = TrayCreateItem("Выход")
TrayItemSetOnEvent(-1, "_Mode8")

$L2=''
$hWnd=''

While 1
	Sleep(150)
	$WinList = WinList()
	For $i = 1 To $WinList[0][0]
		If $WinList[$i][0] <> "" And BitAND(WinGetState($WinList[$i][1]), 8) Then
			$hWnd = WinGetHandle($WinList[$i][1])
			ExitLoop
		EndIf
	Next
	$L1=_WinAPI_GetKeyboardLayout($hWnd)
	If $L1<>$L2 Then
		If $L1 = 1033 Then
			TraySetIcon(@ScriptDir&"\TextCorrection.exe", 3)
			$L2=1033
		Else
			TraySetIcon(@ScriptDir&"\TextCorrection.exe", 4)
			$L2=1049
		EndIf
	EndIf
WEnd

Func _Mode1()
	_Re("^+{LEFT}")
EndFunc   ;==>_Clovo

Func _Mode2()
	_Re("+{HOME}", 1)
EndFunc   ;==>_Stroka

Func _Mode3()
	_Re("+{HOME}", 5)
EndFunc   ;==>_space

Func _Mode4()
	_Re("^+{LEFT}", 1)
EndFunc   ;==>_Clovo1

Func _Mode5()
	_Re("^+{LEFT}", 4)
EndFunc   ;==>_Kras

Func _Mode6()
	_Re("^+{LEFT}", 2)
EndFunc   ;==>_Upper

Func _Mode7()
	_Re("^+{LEFT}", 3)
EndFunc   ;==>_Lower

Func _Mode8()
	Exit
EndFunc   ;==>_Quit

Func _Re($hk, $mode = 0)
	Local $Selected_Text, $New_Text, $Old_bufer, $aBykvText, $hWnd, $WinList, $Lang

	; определение активного окна и проверка раскладки клавиатуры
	$WinList = WinList()
	For $i = 1 To $WinList[0][0]
		If $WinList[$i][0] <> "" And BitAND(WinGetState($WinList[$i][1]), 8) Then
			$hWnd = WinGetHandle($WinList[$i][1])
			ExitLoop
		EndIf
	Next
	$Lang = _WinAPI_GetKeyboardLayout($hWnd) ; 1033 1049
	$setLang = ''

	$Old_bufer = ClipGet() ; для восстановления буфера
	;проверка выделенного текста, если не выделен, то выделяем
	Sleep(130)
	_SendEx("^{INS}")
	Sleep(30)
	$Selected_Text = ClipGet()
	Sleep(30)
	If $Selected_Text = $Old_bufer Then
		_SendEx($hk) ; выделяем текст
		Sleep(30)
		_SendEx("^{INS}") ; копируем текст
		Sleep(30)
		$Selected_Text = ClipGet()
		Sleep(30)
	EndIf
	If $Selected_Text = '' Then
		_SendEx($hk) ; выделяем текст
		Sleep(30)
		_SendEx("^{INS}") ; копируем текст
		Sleep(30)
		$Selected_Text = ClipGet()
		Sleep(30)
	EndIf
	$New_Text = ''

	If $mode = 5 Then ; исправление слова до пробела
		$aSelected_Text=StringRegExp($Selected_Text,'(^.*)( |\(|\)|\\|=|\+|%|!)(.*)$',3)
		If UBound($aSelected_Text)<2 Then
			$mode = 0
		Else
			$New_Text = $aSelected_Text[0]&$aSelected_Text[1]
			$Selected_Text = $aSelected_Text[2]
			$mode = 0
		EndIf
	EndIf
	
	$aBykvText = StringSplit($Selected_Text, "")

	; ищем справа-налево последний валидный символ в тексте, по которому можно определить язык
	$bykva = ''
	For $i = StringLen($Selected_Text) To 1 Step -1
		If StringInStr('ёйцукенгшщзхъфывапролджэячсмитьбюqwertyuiopasdfghjklzxcvbnm', StringMid($Selected_Text, $i, 1)) <> 0 Then
			$bykva = StringMid($Selected_Text, $i, 1)
			ExitLoop
		EndIf
	Next

	; установка языка, иначе по раскладке
	If $bykva<>'' Then
		If StringInStr("ёйцукенгшщзхъфывапролджэячсмитьбю", $bykva) <> 0 Then $Lang = '1049'
		If StringInStr("qwertyuiopasdfghjklzxcvbnm", $bykva) <> 0 Then $Lang = '1033'
	EndIf
	If $Lang = '' Then Return
	
	If $mode = 4 Then ; красная строка, режим перевода в верхний регистр первой буквы
		$bykva1 = ''
		$Selected_Text = StringLower($Selected_Text)
		For $i = 1 To StringLen($Selected_Text)
			If StringInStr('ёйцукенгшщзхъфывапролджэячсмитьбюqwertyuiopasdfghjklzxcvbnm', StringMid($Selected_Text, $i, 1)) <> 0 Then
				$New_Text = StringReplace($Selected_Text, $i, StringUpper(StringMid($Selected_Text, $i, 1)))
				ExitLoop
			EndIf
		Next
	EndIf

	If $mode = 3 Then ; режим перевода в нижний регистр, в том числе спес-символов
		$New_Text = StringLower($Selected_Text)
		If $Lang = '1033' Then
			$New_Text = StringReplace($New_Text, '@','2')
			$New_Text = StringReplace($New_Text, '#','3')
			$New_Text = StringReplace($New_Text, '$','4')
			$New_Text = StringReplace($New_Text, '^','6')
			$New_Text = StringReplace($New_Text, '&','7')
		EndIf

		If $Lang = '1049' Then
			$New_Text = StringReplace($New_Text, '"','2')
			$New_Text = StringReplace($New_Text, '№','3')
			$New_Text = StringReplace($New_Text, ';','4')
			$New_Text = StringReplace($New_Text, ':','6')
			$New_Text = StringReplace($New_Text, '?','7')
		EndIf
	EndIf

	If $mode = 2 Then ; режим перевода в верхний регистр, в том числе спес-символов
		$New_Text = StringUpper($Selected_Text)
		If $Lang = '1033' Then
			$New_Text = StringReplace($New_Text, '2','@')
			$New_Text = StringReplace($New_Text, '3','#')
			$New_Text = StringReplace($New_Text, '4','$')
			$New_Text = StringReplace($New_Text, '6','^')
			$New_Text = StringReplace($New_Text, '7','&')
		EndIf

		If $Lang = '1049' Then
			$New_Text = StringReplace($New_Text, '2','"')
			$New_Text = StringReplace($New_Text, '3','№')
			$New_Text = StringReplace($New_Text, '4',';')
			$New_Text = StringReplace($New_Text, '6',':')
			$New_Text = StringReplace($New_Text, '7','?')
		EndIf
	EndIf

	If $mode = 1 Then ; режим инвертирования
		;определяем язык
		; если русский, то меняем на англ.
		If $Lang = '1049' Then
			For $i = 1 To $aBykvText[0]
				$n = StringInStr($Ru, $aBykvText[$i], 1)
;===========================================================
; особое распознование в смешанном тексте для ;:? по левому символу
				If StringInStr(';:?', $aBykvText[$i]) Then
					$v=1		
					$bbb=0
					While $i-$v>0 And $bbb=0
						$bbb=StringInStr('ёйцукенгшщзхъфывапролджэячсмитьбюqwertyuiopasdfghjklzxcvbnm', $aBykvText[$i-$v])
						$v+=1
					WEnd
					If $bbb > 33 Then
						If $aBykvText[$i]=';' Then $New_Text &= 'ж'
						If $aBykvText[$i]=':' Then $New_Text &= 'Ж'
						If $aBykvText[$i]='?' Then $New_Text &= ','
						ContinueLoop
					EndIf
				EndIf
;===========================================================
				If $n = 0 Then
					$n = StringInStr($En, $aBykvText[$i], 1)
					If $n = 0 Then
						$New_Text &= $aBykvText[$i]
					Else
						$New_Text &= StringMid($Ru, $n, 1)
					EndIf
				Else
					$New_Text &= StringMid($En, $n, 1)
				EndIf
			Next
			$setLang = '1033'
		EndIf
		; если английский, то меняем на русс.
		If $Lang = '1033' Then
			For $i = 1 To $aBykvText[0]
				$n = StringInStr($En, $aBykvText[$i], 1)
;===========================================================
; особое распознование в смешанном тексте для ;:? по левому символу
				If StringInStr(';:?', $aBykvText[$i]) Then
					$v=1		
					$bbb=0
					While $i-$v>0 And $bbb=0
						$bbb=StringInStr('ёйцукенгшщзхъфывапролджэячсмитьбюqwertyuiopasdfghjklzxcvbnm', $aBykvText[$i-$v])
						$v+=1
					WEnd
					If $bbb <= 33 And $bbb>0 Then
						If $aBykvText[$i]=';' Then $New_Text &= '$'
						If $aBykvText[$i]=':' Then $New_Text &= '^'
						If $aBykvText[$i]='?' Then $New_Text &= '&'
						ContinueLoop
					EndIf
				EndIf
;===========================================================
				If $n = 0 Then
					$n = StringInStr($Ru, $aBykvText[$i], 1)
					If $n = 0 Then
						$New_Text &= $aBykvText[$i]
					Else
						$New_Text &= StringMid($En, $n, 1)
					EndIf
				Else
					$New_Text &= StringMid($Ru, $n, 1)
				EndIf
			Next
			$setLang = '1049'
		EndIf
	EndIf

	If $mode = 0 Then ; режим НЕ инвертирования
		;определяем язык
		; если русский, то меняем на англ.
		If $Lang = '1049' Then
			For $i = 1 To $aBykvText[0]
				$n = StringInStr($Ru, $aBykvText[$i], 1)
				If $n = 0 Then
					$New_Text &= $aBykvText[$i]
				Else
					$New_Text &= StringMid($En, $n, 1)
				EndIf
			Next
			$setLang = '1033'
		EndIf
		; если английский, то меняем на русс.
		If $Lang = '1033' Then
			For $i = 1 To $aBykvText[0]
				$n = StringInStr($En, $aBykvText[$i], 1)
				If $n = 0 Then
					$New_Text &= $aBykvText[$i]
				Else
					$New_Text &= StringMid($Ru, $n, 1)
				EndIf
			Next
			$setLang = '1049'
		EndIf
	EndIf

	If $New_Text <> '' Then
		ClipPut($New_Text) ; отправляем в буфер
		Sleep(10)
		Send("+{INS}") ; вставляем из буфера
	Else
		Send("{RIGHT}")
	EndIf
	ClipPut($Old_bufer) ; отправляем в буфер старый патерн
	If $setLang <> '' Then
		If $setLang = '1033' Then _SetKeyboardLayout("00000409", $hWnd)
		If $setLang = '1049' Then _SetKeyboardLayout("00000419", $hWnd)
	EndIf
EndFunc   ;==>_Re

Func _SendEx($sSend_Data)
	Local $hUser32DllOpen = DllOpen("User32.dll")
	While _IsPressed("10", $hUser32DllOpen) Or _IsPressed("11", $hUser32DllOpen) Or _IsPressed("12", $hUser32DllOpen)
		Sleep(10)
	WEnd
	Send($sSend_Data)
	DllClose($hUser32DllOpen)
EndFunc   ;==>_SendEx

; переключение раскладки клавиатуры
Func _SetKeyboardLayout($sLayoutID, $hWnd)
	Local $ret = DllCall("user32.dll", "long", "LoadKeyboardLayout", "str", $sLayoutID, "int", 0)
	DllCall("user32.dll", "int", "SendMessage", "hwnd", $hWnd, "int", 0x50, "int", 1, "int", $ret[0])
EndFunc   ;==>_SetKeyboardLayout

Func _WinAPI_GetKeyboardLayout($hWnd)

	Local $ret

	$ret = DllCall('user32.dll', 'long', 'GetWindowThreadProcessId', 'hwnd', $hWnd, 'ptr', 0)
	If (@error) Or (Not $ret[0]) Then
		Return SetError(1, 0, 0)
	EndIf
	$ret = DllCall('user32.dll', 'long', 'GetKeyboardLayout', 'long', $ret[0])
	If (@error) Or (Not $ret[0]) Then
		Return SetError(1, 0, 0)
	EndIf
	Return BitAND($ret[0], 0xFFFF)
EndFunc   ;==>_WinAPI_GetKeyboardLayout

Func _HotKeySet()
	For $i = 1 to 8
		_HotKeyAssign($HotKey[$i], '_Mode'&$i)
	Next
EndFunc

Func _GuiHotKey()
Opt("TrayIconHide", 1)
$Gui1 = GUICreate('Назначение горячих клавиш', 440, 250)
$f1=25
Dim $TL[9] = [9, _
'исправление слова инвертированием', _
'исправление строки инвертированием', _
'исправление слова до первого пробела', _
'исправление слова либо всё русское, либо английское', _
'красная строка, первая буква заглавная', _
'перевод в верхний регистр', _
'перевод в нижний регистр', _
'Выход']

For $i = 1 to 8
	Assign('Label' & $i, GUICtrlCreateLabel($TL[$i], 150,$f1*$i-10, 280, 17))
	Assign('HotkeyInput' & $i, _GUICtrlCreateHotKeyInput($HotKey[$i], 10, $f1*$i-12, 130, 20))
Next

_KeyLock(0x062E) ; запретить CTRL-ALT-DEL

$ButtonOk = GUICtrlCreateButton('Применить', 350, 225, 80, 23)
GUISetState(@SW_SHOW, $Gui1)
$msg = $Gui1
$msg111 = ''

While 1
	$msg = GUIGetMsg()
	Select
		Case $msg = $ButtonOk
			For $i = 1 to 8
				$iKey = _GUICtrlReadHotKeyInput(Eval('HotkeyInput' & $i))
				If $iKey <> 0 Then
					_HotKeyAssign(_GUICtrlReadHotKeyInput(Eval('HotkeyInput' & $i)), '_Mode'&$i)
					If $HotKey[$i]<>$iKey Then
						IniWrite($Ini, "HotKey", "HotKey"&$i, $iKey)
						$HotKey[$i] = $iKey
					EndIf
				EndIf
				;$msg111 &=_GUICtrlReadHotKeyInput(Eval('HotkeyInput' & $i))&@CRLF
			Next
				;ClipPut($msg111)
			GUIDelete($Gui1)
			Opt("TrayIconHide", 0)
			ExitLoop
		Case $msg = -3
			GUIDelete($Gui1)
			Opt("TrayIconHide", 0)
			ExitLoop
	EndSelect
WEnd
EndFunc

Func _Pause()
    $Paused = NOT $Paused
TraySetIcon(@ScriptDir&"\TextCorrection.exe", 1)
HotKeySet('{ESC}', "_Pause")
TrayItemSetText($Suspend,'Возобновление по Esc')
TrayItemSetState($Suspend,128)
TrayItemSetState($About,128)
TrayItemSetState($Quit,128)
TrayItemSetState($Readme,128)
TrayItemSetState($GuiHotKey,128)
    While $Paused
        Sleep(200)
    WEnd
TrayItemSetText($Suspend,'Приостановить')
TrayItemSetState($Suspend,64)
TrayItemSetState($About,64)
TrayItemSetState($Quit,64)
TrayItemSetState($Readme,64)
TrayItemSetState($GuiHotKey,64)
TraySetIcon(@ScriptDir&"\TextCorrection.exe", 4)
HotKeySet('{ESC}')
_HotKeySet()
EndFunc

Func _Readme()
Opt("TrayIconHide", 1)
MsgBox(0, 'Назначение программы', 'В скобках указана клавиша для английского языка' & @CRLF & @CRLF & _
'ESC - выход' & @CRLF & _
'Ctrl+\ исправление слова неинвертированием, либо всё на русском, либо всё на английском' & @CRLF & _
'Ctrl+ж (;) - исправление слова до первого пробела, неинвертированием' & @CRLF & _
'Ctrl+д (l) - исправление слова инвертированием' & @CRLF & _
'Ctrl+. (/) - исправление строки инвертированием' & @CRLF & _
'Ctrl+х ([) - перевод в верхний регистр' & @CRLF & _
'Ctrl+ъ (]) - перевод в нижний регистр' & @CRLF & _
'Ctrl+ю (.) - красная строка, первая буква заглавная.')
Opt("TrayIconHide", 0)
EndFunc


Func _About()
Opt("TrayIconHide", 1)
$font="Arial"
    $Gui1 = GUICreate("О программе", 270, 180, -1, -1, -1, 0x00000080)
	GUISetBkColor (0xf8c848)
	GUICtrlCreateLabel('Text Correction', 0, 20, 270, 23, 0x01)
	GUICtrlSetFont (-1,15, 600, -1, $font)
	GUICtrlSetColor(-1,0xa21a10)
	GUICtrlCreateLabel('исправление текста набранного в неправильной раскладке клавиатуры', 0, 49, 270, 46, 0x01)
	GUICtrlSetFont (-1,11, 600, -1, $font)
	GUISetFont (9, 600, -1, $font)
	GUICtrlSetColor(-1,0xa21a10)
	GUICtrlCreateLabel('Версия 0.4 от 6.06.2010', 55, 100, 210, 17)
	GUICtrlCreateLabel('Сайт:', 55, 115, 40, 17)
	$url=GUICtrlCreateLabel('http://azjio.ucoz.ru', 92, 115, 170, 17)
	GUICtrlSetCursor(-1, 0)
	GUICtrlSetColor(-1, 0x0000ff)
	GUICtrlCreateLabel('WebMoney: R939163939152', 55, 130, 210, 17)
	GUICtrlCreateLabel('Copyright AZJIO © 2010', 55, 145, 210, 17)
	GUISetState(@SW_SHOW, $Gui1)
$msg = $Gui1
	While 1
	  $msg = GUIGetMsg()
	  Select
		Case $msg = $url
			ShellExecute ('http://azjio.ucoz.ru')
		Case $msg = -3
			GUIDelete($Gui1)
			Opt("TrayIconHide", 0)
			ExitLoop
		EndSelect
    WEnd
EndFunc

; Misc.au3 - UDF

Func _IsPressed($sHexKey, $vDLL = 'user32.dll')
	Local $a_R = DllCall($vDLL, "short", "GetAsyncKeyState", "int", '0x' & $sHexKey)
	If @error Then Return SetError(@error, @extended, False)
	Return BitAND($a_R[0], 0x8000) <> 0
EndFunc

Func _Singleton($sOccurenceName, $iFlag = 0)
	Local Const $ERROR_ALREADY_EXISTS = 183
	Local Const $SECURITY_DESCRIPTOR_REVISION = 1
	Local $pSecurityAttributes = 0

	If BitAND($iFlag, 2) Then
		Local $tSecurityDescriptor = DllStructCreate("dword[5]")
		Local $pSecurityDescriptor = DllStructGetPtr($tSecurityDescriptor)
		Local $aRet = DllCall("advapi32.dll", "bool", "InitializeSecurityDescriptor", _
				"ptr", $pSecurityDescriptor, "dword", $SECURITY_DESCRIPTOR_REVISION)
		If @error Then Return SetError(@error, @extended, 0)
		If $aRet[0] Then
			$aRet = DllCall("advapi32.dll", "bool", "SetSecurityDescriptorDacl", _
					"ptr", $pSecurityDescriptor, "bool", 1, "ptr", 0, "bool", 0)
			If @error Then Return SetError(@error, @extended, 0)
			If $aRet[0] Then
				Local $structSecurityAttributes = DllStructCreate($tagSECURITY_ATTRIBUTES)
				DllStructSetData($structSecurityAttributes, 1, DllStructGetSize($structSecurityAttributes))
				DllStructSetData($structSecurityAttributes, 2, $pSecurityDescriptor)
				DllStructSetData($structSecurityAttributes, 3, 0)
				$pSecurityAttributes = DllStructGetPtr($structSecurityAttributes)
			EndIf
		EndIf
	EndIf

	Local $handle = DllCall("kernel32.dll", "handle", "CreateMutexW", "ptr", $pSecurityAttributes, "bool", 1, "wstr", $sOccurenceName)
	If @error Then Return SetError(@error, @extended, 0)
	Local $lastError = DllCall("kernel32.dll", "dword", "GetLastError")
	If @error Then Return SetError(@error, @extended, 0)
	If $lastError[0] = $ERROR_ALREADY_EXISTS Then
		If BitAND($iFlag, 1) Then
			Return SetError($lastError[0], $lastError[0], 0)
		Else
			Exit -1
		EndIf
	EndIf
	Return $handle[0]
EndFunc
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Если честно, то я мало понимаю что-либо в твоем коде, и Arum Switcher'а у меня нет. Я пользуюсь HotKey.au3 и HotKeyInput.au3 каждый день и уже не один год (XP, Vista и 7), и пока не замечал каких-либо "залипаний" и дугих необъяснимых глюков. Я уверен на 99%, что это связано с неправильным использованием этих библиотек. Приведи мне простой (небольшой) пример, где происходят залипания, я посмотрю. А пока можешь попробывать следующее:

Код:
Func _SendEx($sSend_Data)
	_HotKeyDisable(BitOR($HK_FLAG_NOERROR, $HK_FLAG_NOUNHOOK))
    Local $hUser32DllOpen = DllOpen("User32.dll")
    While _IsPressed("10", $hUser32DllOpen) Or _IsPressed("11", $hUser32DllOpen) Or _IsPressed("12", $hUser32DllOpen)
        Sleep(10)
    WEnd
    Send($sSend_Data)
    DllClose($hUser32DllOpen)
	_HotKeyEnable()
EndFunc   ;==>_SendEx
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
Yashied
Так может не было случая комбинирования? Сейчас вставил мессаги в вызываемые функции и не залипает, проверю ещё без _SendEx, хотя врят ли, потом попробую урезанный пример сделать. Предложенный тобой код проверил, также.

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

Кстати, отжимать приходится оба Ctrl.
Частично проблема решилась такой комбинацией, но работает через раз.

Код:
_SendEx("{LCTRL}")
_SendEx("{RCTRL}")



Вот пример с имитацией залипания.

Код:
#Include <HotKey.au3>

Global Const $VK_ESCAPE = 0x1B
Global Const $VK_F12 = 0x7B

; назначаем Ctrl+F12, после первого применения левый контрол зажат, так как с панели задач не разворачиваются приложения. После нажатия Ctrl всё нормализуется.
; для теста ставим текстовый курсор справа от текста, произойдёт выделение и копирование в буфер с выводом в мессагу.
_HotKeyAssign(BitOR($CK_CONTROL,$VK_F12), 'Message' )

; это типа выход "CTRL-ESC"
_HotKeyAssign(BitOR($CK_CONTROL, $VK_ESCAPE), 'Quit')

While 1
    Sleep(10)
WEnd


Func Message()
		Sleep(30)
	_SendEx("^+{LEFT}") ; выделяем текст
		Sleep(30)
	_SendEx("^{INS}") ; копируем текст
		Sleep(30)
    MsgBox(0, 'смотрим', ClipGet())
EndFunc   ;==>Message

Func Quit()
    Exit
EndFunc   ;==>Quit

Func _SendEx($sSend_Data)
	Local $hUser32DllOpen = DllOpen("User32.dll")
	While _IsPressed("10", $hUser32DllOpen) Or _IsPressed("11", $hUser32DllOpen) Or _IsPressed("12", $hUser32DllOpen)
		Sleep(10)
	WEnd
	Send($sSend_Data)
	DllClose($hUser32DllOpen)
EndFunc   ;==>_SendEx

Func _IsPressed($sHexKey, $vDLL = 'user32.dll')
	Local $a_R = DllCall($vDLL, "short", "GetAsyncKeyState", "int", '0x' & $sHexKey)
	If @error Then Return SetError(@error, @extended, False)
	Return BitAND($a_R[0], 0x8000) <> 0
EndFunc
 
Автор
Yashied

Yashied

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

Я не понял где у тебя залипания. У меня MsgBox(), не появляется до тех пор, пока не будет отжата клавиша Ctrl. Но так и должно быть, так как у тебя стоит цикл:

Код:
While _IsPressed("10", $hUser32DllOpen) Or _IsPressed("11", $hUser32DllOpen) Or _IsPressed("12", $hUser32DllOpen)
	Sleep(10)
WEnd
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
Yashied
Когда я не использовал HotKey.au3 у меня же такого эффекта не было. То есть для отжатия хватало Sleep(130), а теперь я руками отжимаю.
 
Автор
Yashied

Yashied

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



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

Не проще ли сделать так, у меня все прекрасно работает:

Код:
#Include <HotKey.au3>

Global Const $VK_ESCAPE = 0x1B
Global Const $VK_F12 = 0x7B

_HotKeyAssign(BitOR($CK_CONTROL, $VK_F12), 'Message')
_HotKeyAssign(BitOR($CK_CONTROL, $VK_ESCAPE), 'Quit')

While 1
	Sleep(1000)
WEnd

Func Message()
	ClipPut('')
	Send('^+{LEFT}')
	Sleep(30)
	Send('^{INS}')
	Sleep(30)
	MsgBox(0, '', ClipGet())
EndFunc   ;==>Message

Func Quit()
	Exit
EndFunc   ;==>Quit


Зачем вообще нужна _SendEx()?
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
Yashied
А у меня так не работает. Мессага вылетает, но при прокрутке колёсика мыши шрифт изменяется, значит контрол зажат.

Код:
Зачем вообще нужна _SendEx()?

Она каждые 10 милисекунд проверяет не нажаты ли клавиши Ctrl, Shift, Alt. И не продолжит пока клавиши не будут отжаты. Вот моя бывшая проблема
 
Верх