Что нового

[Автоматизация] Автозамена строк

StanleyTrace

Новичок
Сообщения
8
Репутация
0
Здравствуйте, я перехожу с AutoHotKey на AutoIt.
Вопрос: Как реализовать автозамену?
Например, аббревиатура "btw" должна автоматически замениться на "by the way", на AHK код выглядит так:

Код:
::btw::by the way

К моему сожалению, по русскому ману, по поиску форума и по гуглу я не нашёл тем "автозамена" в AutoIt.
 
Автор
S

StanleyTrace

Новичок
Сообщения
8
Репутация
0
Я так понимаю, это функция для обработки текста, помещаемого в переменную.

Как сделать, чтобы скрипт был постоянно запущен и отслеживал клавиатурные нажатия: когда будет введено "btw", он автоматически переписывал "btw" в "by the way"?
 

firex

AutoIT Гуру
Сообщения
943
Репутация
208
StanleyTrace [?]
Как сделать, чтобы скрипт был постоянно запущен и отслеживал клавиатурные нажатия: когда будет введено "btw", он автоматически переписывал "btw" в "by the way"?

http://autoit-script.ru/index.php/topic,16139.0.html
Код:
#include <WinAPI.au3>

Global $aHookRegister[2], $aCombinList[1][4]

Func CombinationRegister()
    $aHookRegister[0] = DllCallbackRegister('__hock_Proc', 'long', 'int;wparam;lparam')
    $aHookRegister[1] = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, DllCallbackGetPtr($aHookRegister[0]), _WinAPI_GetModuleHandle(''))
    If $aHookRegister[1] Then
        AdlibRegister('__compare_keys', 1)
        Return 1
    EndIf
    Return 0
EndFunc

Func CombinationUnregister()
    If $aHookRegister[1] Then
        _WinAPI_UnhookWindowsHookEx($aHookRegister[1])
    EndIf
    If $aHookRegister[0] Then
        DllCallbackFree($aHookRegister[0])
    EndIf
        AdlibUnRegister('__compare_keys')
EndFunc

Func AddCombinationEvent($aKeyList, $sProc)
    If IsArray($aKeyList) And UBound($aKeyList) And Not Ubound($aKeyList, 2) Then
        $aCombinList[0][0] += 1
        ReDim $aCombinList[$aCombinList[0][0] + 1][UBound($aCombinList, 2)]
        $aCombinList[$aCombinList[0][0]][0] = $aKeyList
        $aCombinList[$aCombinList[0][0]][1] = $sProc
        $aCombinList[$aCombinList[0][0]][2] = 0
        For $i = 0 To UBound($aKeyList) -1
            $aCombinList[$aCombinList[0][0]][3] += $aKeyList[$i]
        Next
        Return 1
    EndIf
    Return 0
EndFunc

Func __hock_Proc($nCode, $wParam, $lParam)
    Local $ttKeyHook, $aTemp

    $tKeyHook = DllStructCreate($tagKBDLLHOOKSTRUCT, $lParam)

    If ($wParam = 256) Then
        For $i = 1 To $aCombinList[0][0]
            If DllStructGetData($tKeyHook, 'vkCode') == 0x10 And DllStructGetData($tKeyHook, 'vkCode') == 0x14 Then
                ContinueLoop
            EndIf
            If __compare($aCombinList[$i][0], DllStructGetData($tKeyHook, 'vkCode')) Then
                $aCombinList[$i][2] += DllStructGetData($tKeyHook, 'vkCode')
            Else
                $aCombinList[$i][2] = 0
            EndIf
        Next
    EndIf

    Return _WinAPI_CallNextHookEx(0, $nCode, $wParam, $lParam)
EndFunc

Func __compare_keys()
    For $i = 1 To $aCombinList[0][0]
        If $aCombinList[$i][2] == $aCombinList[$i][3] Then
            Call($aCombinList[$i][1])
            $aCombinList[$i][2] = 0
        EndIf
    Next
EndFunc

Func __compare($aKeys, $vkCode)
    For $i = 0 To UBound($aKeys) -1
        If ($aKeys[$i] = $vkCode) Then
            Return 1
        EndIf
    Next
    Return 0
EndFunc
;                    b     t     w
Global $aBtw[3] = [0x42, 0x54, 0x57] ; Virtual-Key Codes - http://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx

If CombinationRegister() Then

    $hForm = GUICreate('', 400, 300)
    GUISetState( @SW_HIDE )

    AddCombinationEvent($aBtw, '__OnBtw')

    While 1
        Switch GUIGetMsg()
            Case -3
                CombinationUnregister()
                Exit
        EndSwitch
    Wend
EndIf

Func __OnBtw()
    Send( "{BS}{BS}{BS}by the way" )
EndFunc
 
Автор
S

StanleyTrace

Новичок
Сообщения
8
Репутация
0
Это что же, AutoHotKey настолько высокоуровневый язык, что там на всё про всё одна строчка кода?


• Если у меня таких сокращений пара десятков? Чтобы решить задачу меньшей кровью, нужно продублировать в коде последние три абзаца, добавив новые переменные и скорректировав vk-коды?


• Таким образом срабатывает не только на "btw", но и на "иец" (в другой раскладке). Плюс срабатывает даже при зажатом шифте.
Более показательный пример применения скрипта: два подряд вводимых знака дефис должны преобразоваться в одно длинное тире плюс пробел.
 

firex

AutoIT Гуру
Сообщения
943
Репутация
208
StanleyTrace [?]
Это что же, AutoHotKey настолько высокоуровневый язык, что там на всё про всё одна строчка кода?
Я не знаком с AutoHotKey, однако знаю, что он - ответвление Autoit (более узкоспециализированное в этом плане).

Немного модифицированный вариант:
Код:
#Include <WinAPI.au3>

Global $aHookRegister[2], $aCombinList[1][5]

; Virtual-Key Codes - http://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx

;					b		t		w
Global $aBtw[3] = [ 0x42, 0x54, 0x57 ]

If CombinationRegister() Then
    $hForm = GUICreate('', 400, 300)
    GUISetState( @SW_HIDE )
	#cs
		"" Любой
		"0407" Немецкий (стандартный)
		"0409" Английский (США)
		"040C" Французский (стандартный)
		"040D" Финский
		"0410" Итальянский
		"0415" Польский
		"0419" Русский
		"0422" Украинский
		"0423" Белорусский
		"0425" Эстонский
		"0426" Латвийский
		"0427" Литовский
	#ce
    AddCombinationEvent( $aBtw, '__OnBtw', "0409" )
    While 1
        Switch GUIGetMsg()
            Case -3
                CombinationUnregister()
                Exit
        EndSwitch
    Wend
EndIf

Func __OnBtw()
    Send( "{BS}{BS}{BS}by the way" )
EndFunc





; ---
Func CombinationRegister()
    $aHookRegister[0] = DllCallbackRegister('__hock_Proc', 'long', 'int;wparam;lparam')
    $aHookRegister[1] = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, DllCallbackGetPtr($aHookRegister[0]), _WinAPI_GetModuleHandle(''))
    If $aHookRegister[1] Then
        AdlibRegister('__compare_keys', 1)
        Return 1
    EndIf
    Return 0
EndFunc

Func CombinationUnregister()
    If $aHookRegister[1] Then
        _WinAPI_UnhookWindowsHookEx($aHookRegister[1])
    EndIf
    If $aHookRegister[0] Then
        DllCallbackFree($aHookRegister[0])
    EndIf
        AdlibUnRegister('__compare_keys')
EndFunc

Func AddCombinationEvent($aKeyList, $sProc, $sKeyboardLayout)
    If IsArray($aKeyList) And UBound($aKeyList) And Not Ubound($aKeyList, 2) Then
        $aCombinList[0][0] += 1
        ReDim $aCombinList[$aCombinList[0][0] + 1][UBound($aCombinList, 2)]
        $aCombinList[$aCombinList[0][0]][0] = $aKeyList
        $aCombinList[$aCombinList[0][0]][1] = $sProc
        $aCombinList[$aCombinList[0][0]][2] = 0
        For $i = 0 To UBound($aKeyList) -1
            $aCombinList[$aCombinList[0][0]][3] += $aKeyList[$i]
        Next
		$aCombinList[$aCombinList[0][0]][4] = $sKeyboardLayout
        Return 1
    EndIf
    Return 0
EndFunc

Func __hock_Proc($nCode, $wParam, $lParam)
    Local $ttKeyHook, $aTemp

    $tKeyHook = DllStructCreate($tagKBDLLHOOKSTRUCT, $lParam)

    If ($wParam = 256) Then
        For $i = 1 To $aCombinList[0][0]
            If DllStructGetData($tKeyHook, 'vkCode') == 0x10 And DllStructGetData($tKeyHook, 'vkCode') == 0x14 Then
                ContinueLoop
            EndIf
            If __compare($aCombinList[$i][0], DllStructGetData($tKeyHook, 'vkCode')) Then
                $aCombinList[$i][2] += DllStructGetData($tKeyHook, 'vkCode')
            Else
                $aCombinList[$i][2] = 0
            EndIf
        Next
    EndIf

    Return _WinAPI_CallNextHookEx(0, $nCode, $wParam, $lParam)
EndFunc

Func __compare_keys()
    For $i = 1 To $aCombinList[0][0]
        If $aCombinList[$i][2] == $aCombinList[$i][3] Then
			If $aCombinList[$i][4] And __GetKeyboardLayout( WinGetHandle( "[ACTIVE]" ) ) == $aCombinList[$i][4] Then _
				Call($aCombinList[$i][1])

			$aCombinList[$i][2] = 0
        EndIf
    Next
EndFunc

Func __compare($aKeys, $vkCode)
    For $i = 0 To UBound($aKeys) -1
        If ($aKeys[$i] = $vkCode) Then
            Return 1
        EndIf
    Next
    Return 0
EndFunc

Func __GetKeyboardLayout($hWnd)
    Local $aRet = DllCall("user32.dll", "long", "GetWindowThreadProcessId", "hwnd", $hWnd, "ptr", 0)
    $aRet = DllCall("user32.dll", "long", "GetKeyboardLayout", "long", $aRet[0])

    Return Hex($aRet[0], 4)
EndFunc
 
Автор
S

StanleyTrace

Новичок
Сообщения
8
Репутация
0
Спасибо, на вашем примере разобрался.
Для истории топика в качестве демонстрации добавления других сокращений добавил в ваш скрипт сокращение "etc":

Код:
#Include <WinAPI.au3>

Global $aHookRegister[2], $aCombinList[1][5]

; Virtual-Key Codes - http://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx
;                   b       t       w
Global $aBtw[3] = [ 0x42, 0x54, 0x57 ]

;                   e       t       c
Global $aEtc[3] = [ 0x45, 0x54, 0x43 ]



If CombinationRegister() Then
    $hForm = GUICreate('', 400, 300)
    GUISetState( @SW_HIDE )
    #cs
        "0407" Немецкий (стандартный)
        "0409" Английский (США)
        "040C" Французский (стандартный)
        "040D" Финский
        "0410" Итальянский
        "0415" Польский
        "0419" Русский
        "0422" Украинский
        "0423" Белорусский
        "0425" Эстонский
        "0426" Латвийский
        "0427" Литовский
    #ce
    AddCombinationEvent( $aBtw, '__OnBtw', "0409" )
	AddCombinationEvent( $aEtc, '__OnEtc', "0409" )
    While 1
        Switch GUIGetMsg()
            Case -3
                CombinationUnregister()
                Exit
        EndSwitch
    Wend
EndIf

Func __OnBtw()
    Send( "{BS}{BS}{BS}by the way" )
EndFunc
Func __OnEtc()
    Send( "{BS}{BS}{BS}et cetera" )
EndFunc




; ---
Func CombinationRegister()
    $aHookRegister[0] = DllCallbackRegister('__hock_Proc', 'long', 'int;wparam;lparam')
    $aHookRegister[1] = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, DllCallbackGetPtr($aHookRegister[0]), _WinAPI_GetModuleHandle(''))
    If $aHookRegister[1] Then
        AdlibRegister('__compare_keys', 1)
        Return 1
    EndIf
    Return 0
EndFunc

Func CombinationUnregister()
    If $aHookRegister[1] Then
        _WinAPI_UnhookWindowsHookEx($aHookRegister[1])
    EndIf
    If $aHookRegister[0] Then
        DllCallbackFree($aHookRegister[0])
    EndIf
        AdlibUnRegister('__compare_keys')
EndFunc

Func AddCombinationEvent($aKeyList, $sProc, $sKeyboardLayout)
    If IsArray($aKeyList) And UBound($aKeyList) And Not Ubound($aKeyList, 2) Then
        $aCombinList[0][0] += 1
        ReDim $aCombinList[$aCombinList[0][0] + 1][UBound($aCombinList, 2)]
        $aCombinList[$aCombinList[0][0]][0] = $aKeyList
        $aCombinList[$aCombinList[0][0]][1] = $sProc
        $aCombinList[$aCombinList[0][0]][2] = 0
        For $i = 0 To UBound($aKeyList) -1
            $aCombinList[$aCombinList[0][0]][3] += $aKeyList[$i]
        Next
        $aCombinList[$aCombinList[0][0]][4] = $sKeyboardLayout
        Return 1
    EndIf
    Return 0
EndFunc

Func __hock_Proc($nCode, $wParam, $lParam)
    Local $ttKeyHook, $aTemp

    $tKeyHook = DllStructCreate($tagKBDLLHOOKSTRUCT, $lParam)

    If ($wParam = 256) Then
        For $i = 1 To $aCombinList[0][0]
            If DllStructGetData($tKeyHook, 'vkCode') == 0x10 And DllStructGetData($tKeyHook, 'vkCode') == 0x14 Then
                ContinueLoop
            EndIf
            If __compare($aCombinList[$i][0], DllStructGetData($tKeyHook, 'vkCode')) Then
                $aCombinList[$i][2] += DllStructGetData($tKeyHook, 'vkCode')
            Else
                $aCombinList[$i][2] = 0
            EndIf
        Next
    EndIf

    Return _WinAPI_CallNextHookEx(0, $nCode, $wParam, $lParam)
EndFunc

Func __compare_keys()
    For $i = 1 To $aCombinList[0][0]
        If $aCombinList[$i][2] == $aCombinList[$i][3] Then
            If __GetKeyboardLayout( WinGetHandle( "[ACTIVE]" ) ) == $aCombinList[$i][4] Then _
                Call($aCombinList[$i][1])

            $aCombinList[$i][2] = 0
        EndIf
    Next
EndFunc

Func __compare($aKeys, $vkCode)
    For $i = 0 To UBound($aKeys) -1
        If ($aKeys[$i] = $vkCode) Then
            Return 1
        EndIf
    Next
    Return 0
EndFunc

Func __GetKeyboardLayout($hWnd)
    Local $aRet = DllCall("user32.dll", "long", "GetWindowThreadProcessId", "hwnd", $hWnd, "ptr", 0)
    $aRet = DllCall("user32.dll", "long", "GetKeyboardLayout", "long", $aRet[0])

    Return Hex($aRet[0], 4)
EndFunc
 
Верх