mef-t
Осваивающий
- Сообщения
- 306
- Репутация
- 30
AutoIt: 3.3.8.1
Версия: 0.1.1.3
Категория: Автоматизация, Вспомогательные функции, Строки, Буфер обмена, Разное
Описание: Данная программа позволяет конвертировать выделенный текст или последнее слово (расположенное слева от указателя) из символов одной раскладки клавиатуры в другую.
Преимущества перед аналогами:
Рождение идеи:
Код:
Файл: keyboard switcher
Снимок: N/A
История версий:
Источник: autoit-script.ru
Автор: mef-t
Отдельное спасибо:
Yashied - позаимствовал код для переключения раскладки после конвертации из программы http://autoit-script.ru/index.php/topic,2212.0.html
firex - помог с копированием буфера обмена, содержащего растровый рисунок и список файлов
InnI - ткнул носом в темы с проблемой залипания клавиш
ViSiToR a.k.a CreatoR - программа a.k.a SwitchIt; за основу была взята данная программа, но со временем многое переделалось, на текущий момент в приведенном коде осталось мало общего и исходным
Первостепенные доработки:
P.S.: Буду рад Вашим комментариям, критике, предложениям и отзывам.
Версия: 0.1.1.3
Категория: Автоматизация, Вспомогательные функции, Строки, Буфер обмена, Разное
Описание: Данная программа позволяет конвертировать выделенный текст или последнее слово (расположенное слева от указателя) из символов одной раскладки клавиатуры в другую.
Программа по горячей клавише "Ctrl + `" конвертирует заранее выделенный тест из русского языка в английский или обратно в случае ошибочно выбранной раскладки. Программа по горячей клавише "Break" конвертирует слово слева от курсора. После конвертации происходит смена раскладки. Перед конвертацией копируется содержимое буфера обмена. Затем выделенный текст помещается в буфер обмена, от туда считывается, преобразуется и затем через буфер обмена заменяет исходный. После конвертации возвращается исходное содержимое буфера обмена
Преимущества перед аналогами:
Программы, сразу считывающие выделенный текст, будут хорошо работать только в том случае, если им сделать поддержку всех возможных элементов редактирования, например "Scintilla", используемый в SciTE.
Программы, считывающие текст из буфера обмена (на примере SwitchIt) упускают то, что содержимое в буфере обмена может быть не только текстом. В этом случае, любое не текстовое содержимое теряется после применения программы
На текущий момент "keyboard switcher" так же сохраняет растровые изображения и списки файлов. В будущем и другие типы содержимого.
Программы, считывающие текст из буфера обмена (на примере SwitchIt) упускают то, что содержимое в буфере обмена может быть не только текстом. В этом случае, любое не текстовое содержимое теряется после применения программы
На текущий момент "keyboard switcher" так же сохраняет растровые изображения и списки файлов. В будущем и другие типы содержимого.
Рождение идеи:
Изначально пользовался Punto Switcher. На текущий момент он установлен дома. Но при доработке программы сменю. Из Punto мне требуется всего навсего конвертация текста с одной раскладки в другую и, очень редко, смена заглавных и прописных символов, при этом строго по моему усмотрению, а не по усмотрению программы. На текущей работе строгая политика безопасности. Лицензия Punto Switcher не позволяет использовать программу в коммерческих целях, а ее использование на работе как раз попадает под данный пункт. После недолгих страданий от навязавшейся привычки решил восполнить утрату и реализовать недостающий функции своими силами.
Код:
Код:
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=ico\ico2.ico
#AutoIt3Wrapper_Outfile=keyboard switcher.exe
#AutoIt3Wrapper_Compression=4
#AutoIt3Wrapper_Res_Comment=Программа для переключения раскладки клавиатуры
#AutoIt3Wrapper_Res_Description=Смена раскладки
#AutoIt3Wrapper_Res_Fileversion=0.1.1.3
#AutoIt3Wrapper_Res_Fileversion_AutoIncrement=y
#AutoIt3Wrapper_Res_LegalCopyright=@mef-t
#AutoIt3Wrapper_Tidy_Stop_OnError=n
#AutoIt3Wrapper_AU3Check_Stop_OnWarning=n
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <ModernMenuRaw.au3>
#include <Clipboard.au3>
#include <WinAPI.au3>
#include <WinAPIEx.au3>
#include <Misc.au3>
Const $tagDROPFILES = "dword pFiles; long ptX; long ptY; bool fNC; bool fWide; "
#NoTrayIcon
Opt("GUIOnEventMode", 1)
Opt("TrayMenuMode", 7)
_SetFlashTimeOut(250)
$nTrayIcon = _TrayIconCreate("keyboard switcher", "ico\ico2.ico")
_TrayCreateContextMenu() ; контекстное меню иконки в трее
$bUseAdvTrayMenu = False
$nExit = _TrayCreateItem('Выход')
GUICtrlSetOnEvent($nExit, "_exit")
_TrayIconSetState()
$kKeySelectConvert = '^`'
$kKeyLastConvert = '{PAUSE}'
_HotKeyDisabled()
While 1
Sleep(200)
WEnd
Func _exit()
Exit
EndFunc
Func _Key_Switche()
_HotKeyDisabled(False)
_bClip(@HotKeyPressed)
_HotKeyDisabled()
EndFunc
Func _HotKeyDisabled($bType = True)
If $bType Then
HotKeySet($kKeySelectConvert, '_Key_Switche') ; конвертирование выделенного текста
;~ HotKeySet('^ё', '_Key_Switche') ; конвертирование выделенного текста
HotKeySet($kKeyLastConvert, '_Key_Switche') ; конвертирование последнего слова
;~ HotKeySet('{ESC}', '_exit') ; выход из скрипта по ESC
Else
HotKeySet($kKeySelectConvert) ; конвертирование выделенного текста
;~ HotKeySet('^ё') ; конвертирование выделенного текста
HotKeySet($kKeyLastConvert) ; конвертирование последнего слова
;~ HotKeySet('{ESC}') ; выход из скрипта по ESC
EndIf
EndFunc
Func _bClip($Key)
Select
Case _ClipBoard_IsFormatAvailable($CF_TEXT) Or _ClipBoard_IsFormatAvailable($CF_OEMTEXT) Or _ClipBoard_IsFormatAvailable($CF_UNICODETEXT)
$hText = ClipGet()
ClipPut("")
; =====================================
ConvertProc($Key)
; =====================================
ClipPut("")
ClipPut($hText)
Case _ClipBoard_IsFormatAvailable($CF_BITMAP)
_ClipBoard_Open(0)
$hBitmap = _ClipBoard_GetDataEx($CF_BITMAP)
$hBitmap = _WinAPI_CopyImage( $hBitmap, 0, 0, 0, BitOr( 0x0008, 0x0004 ))
_ClipBoard_Empty()
_ClipBoard_Close()
; =====================================
ConvertProc($Key)
; =====================================
_ClipBoard_Open(0)
_ClipBoard_Empty()
_ClipBoard_SetDataEx($hBitmap, $CF_BITMAP)
_ClipBoard_Close()
Case _ClipBoard_IsFormatAvailable($CF_HDROP)
_ClipBoard_Open(0)
$pDROPFILES = _ClipBoard_GetDataEx( $CF_HDROP )
$tDROPFILES = DllStructCreate( $tagDROPFILES, $pDROPFILES )
$pFiles = DllStructGetData( $tDROPFILES, "pFiles" )
$ptX = DllStructGetData( $tDROPFILES, "ptX" )
$ptY = DllStructGetData( $tDROPFILES, "ptY" )
$fNC = DllStructGetData( $tDROPFILES, "fNC" )
$fWide = DllStructGetData( $tDROPFILES, "fWide" )
Local $aFileList[999] = [0], $pCurFile = $pDROPFILES + $pFiles
While True
$tFILELIST = DllStructCreate( "wchar[260]", $pCurFile )
$sCurFile = DllStructGetData( $tFILELIST, 1 )
$iCurFileLen = StringLen( $sCurFile )
If $iCurFileLen Then
$aFileList[0] += 1
$aFileList[$aFileList[0]] = $sCurFile
;~ ConsoleWrite( $sCurFile & @CRLF )
; *
$pCurFile += ( $iCurFileLen * 2 ) + 0x02
Else
ExitLoop
EndIf
WEnd
_ClipBoard_Empty()
_ClipBoard_Close()
; =====================================
ConvertProc($Key)
; =====================================
_ClipBoard_Open(0)
_ClipBoard_Empty()
$iUnicodeArray_TotalLen = 0x01
$sUnicodeArray_TagStrings = ""
$sUnicodeArray_TagStrings = ""
For $Idx = 1 To $aFileList[0] Step 1
$iLen = StringLen( $aFileList[$Idx] )
$iUnicodeArray_TotalLen += ( $iLen * 2 ) + 0x01
$sUnicodeArray_TagStrings &= "wchar[" & $iLen & "]; byte[1]; "
Next
$sUnicodeArray_TagStrings &= "byte[1];"
; ---
$hMemory = _MemGlobalAlloc( $pFiles + $iUnicodeArray_TotalLen, $GHND )
If $hMemory <> 0 Then
$hLock = _MemGlobalLock($hMemory)
If $hLock <> 0 Then
$tDROPFILES = DllStructCreate( $tagDROPFILES & $sUnicodeArray_TagStrings, $hLock )
DllStructSetData( $tDROPFILES, "pFiles", $pFiles )
DllStructSetData( $tDROPFILES, "ptX", $ptX )
DllStructSetData( $tDROPFILES, "ptY", $ptY )
DllStructSetData( $tDROPFILES, "fNC", $fNC )
DllStructSetData( $tDROPFILES, "fWide", $fWide )
For $Idx = 1 To $aFileList[0] Step 1
DllStructSetData( $tDROPFILES, 6 + ( ( $Idx - 1 ) * 2 ), $aFileList[$Idx] )
Next
_MemGlobalUnlock( $hMemory )
_ClipBoard_SetDataEx( $hMemory, $CF_HDROP )
EndIf
EndIf
_ClipBoard_Close()
Case _ClipBoard_CountFormats() = 0
_ClipBoard_Open(0)
_ClipBoard_Empty()
_ClipBoard_Close()
; =====================================
ConvertProc($Key)
; =====================================
Case Else
MsgBox(64, 'Ошибка', 'Буфер обмена скопировать не удалось')
EndSelect
EndFunc
Func ConvertProc($Key)
if $Key = $kKeyLastConvert Then
_SendEx("^+{LEFT}")
EndIf
_SendEx("^{INS}")
Local $SelectedText = ClipGet()
If $SelectedText = "" Then
Return
EndIf
Local $NewClip = ConvertText($SelectedText)
ClipPut($NewClip)
_SendEx("+{INS}")
Local $hWnd = WinGetHandle('[ACTIVE]')
If Not $hWnd Then
Return
EndIf
If Not StringInStr(_WinAPI_GetClassName($hWnd), 'AutoIt') Then
_WinAPI_SetKeyboardLayout(_GetOwnerWindow($hWnd), 0, 0x0002)
Else
_AutoItSetKeyboardLayout($hWnd)
EndIf
EndFunc
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
;If $Mode = 0 Then Russian language used
;If $Mode = 1 Then English language used
;If $Mode = -1 Then String Inverted
Func ConvertText($Text, $Mode=-1)
Local $AnsiStr = "ёйцукенгшщзхъфывапролджэячсмитьбю.,/№;%:?ХЪБЮЖЁ" & '"Э'
Local $AsciiStr = "`qwertyuiop[]asdfghjkl;'zxcvbnm,./?|#$%^&{}<>:~" & '@"'
Local $sCharStr = $AnsiStr & $AsciiStr
Local $iLenChars = StringLen($sCharStr)
Local $sCharStrUP = StringRegExp ($sCharStr, "[А-ЯЁ]" , 3)
$sCharStrUP = _ArrayToString($sCharStrUP, "")
$sTextR = StringLower($Text)
$sTextR = StringRegExpReplace ($sTextR, "[^a-zа-яё\x22-\x27\x2c\x2e\x2f\x3a-\x3c\x3e-\x40\x5b\x5d\x5e\x60\x7b-\x7e]", "" )
Local $iSearch = (StringIsASCII($sTextR) * (-2)) + 1
For $i = 1 To StringLen($Text)
Local $StringIsUpper = 0, $iNewChar = '', $sChar = '', $iPosition = 0, $iNewCharPosition = 0 ; обновление переменных
$sChar = StringMid($Text, $i, 1) ; извлечение исмвола из переводимой строки
If StringIsUpper($sChar) And StringInStr($sCharStrUP, $sChar, 1) = 0 Then
$StringIsUpper = 1
EndIf
$iRegistr = $StringIsUpper*-1+1
$iPosition = StringInStr($sCharStr, $sChar, $iRegistr, $iSearch)
If $iPosition > 0 Then
$iNewCharPosition = $iPosition + ($iLenChars / 2)
If $iNewCharPosition > $iLenChars Then $iNewCharPosition -= $iLenChars
$iNewChar = StringMid($sCharStr, $iNewCharPosition, 1)
If $StringIsUpper = 1 Then $iNewChar = StringUpper($iNewChar)
$Text = StringReplace($Text, $i, $iNewChar)
EndIf
Next
Return $Text
EndFunc
;~ --------------------------------------------------------------------------------------
Func _AutoItSetKeyboardLayout($hWnd)
Local $List = _WinAPI_EnumProcessWindows(WinGetProcess($hWnd), 0)
If Not IsArray($List) Then
Return SetError(1, 0, 0)
EndIf
For $i = 1 To $List[0][0]
If (Not BitAND(WinGetState($List[$i][0]), 2)) And (StringInStr($List[$i][1], 'AutoIt')) Then
_WinAPI_SetKeyboardLayout($List[$i][0], 0, 0x0002)
EndIf
Next
EndFunc ;==>_AutoItSetKeyboardLayout
Func _GetOwnerWindow($hWnd)
Local $hOwner = _WinAPI_GetAncestor($hWnd, 3)
If _WinAPI_GetClassName($hOwner) = 'Shell_TrayWnd' Then
Return $hWnd
EndIf
Return $hOwner
EndFunc ;==>_GetOwnerWindow
Func _ArrayToString(Const ByRef $avArray, $sDelim = "|", $iStart = 0, $iEnd = 0)
If Not IsArray($avArray) Then Return SetError(1, 0, "")
If UBound($avArray, 0) <> 1 Then Return SetError(3, 0, "")
Local $sResult, $iUBound = UBound($avArray) - 1
; Bounds checking
If $iEnd < 1 Or $iEnd > $iUBound Then $iEnd = $iUBound
If $iStart < 0 Then $iStart = 0
If $iStart > $iEnd Then Return SetError(2, 0, "")
; Combine
For $i = $iStart To $iEnd
$sResult &= $avArray[$i] & $sDelim
Next
Return StringTrimRight($sResult, StringLen($sDelim))
EndFunc ;==>_ArrayToString
Файл: keyboard switcher
Снимок: N/A
История версий:
0.1.1.3 - * Первый релиз (трей с отдельным меню, конвертация раскладки, копирование памяти с текстом, растровым изображением и файлами)
Источник: autoit-script.ru
Автор: mef-t
Отдельное спасибо:
Yashied - позаимствовал код для переключения раскладки после конвертации из программы http://autoit-script.ru/index.php/topic,2212.0.html
firex - помог с копированием буфера обмена, содержащего растровый рисунок и список файлов
InnI - ткнул носом в темы с проблемой залипания клавиш
ViSiToR a.k.a CreatoR - программа a.k.a SwitchIt; за основу была взята данная программа, но со временем многое переделалось, на текущий момент в приведенном коде осталось мало общего и исходным
Первостепенные доработки:
- исправить редактирование последнего слова, не всегда верно определяется
- добавить сохранение буфера обмена для видео, аудио потоков и других типов соддержимого
- добавить конвертацию из маленький в большие символы и обратно
P.S.: Буду рад Вашим комментариям, критике, предложениям и отзывам.