Новый вариант. Добавлено:
#NoEnv
#SingleInstance, force
SetBatchLines, -1
if !A_IsCompiled
{
if !FileExist(A_ScriptDir . "\Icons")
{
MsgBox, 4,, В директории скрипта отсутствует папка с иконками.`nЗагрузить с сервера?
IfMsgBox, Yes
{
FileCreateDir, % A_ScriptDir "\Icons"
TrayTip,, Идёт загрузка файлов с сервера`, подождите...
if !Ping("content.screencast.com")
{
MsgBox, 16, Ошибка!, Нет ответа от сервера.`nПроверьте соединение с интернетом!
ExitApp
}
PreUrl := "http://content.screencast.com/users/teadrinker/folders/icons/media/"
URLDownloadToFile, % PreUrl . "83188ad1-4a8a-491f-bf70-fb292e73c98c/Change.ico?downloadOnly=true" , Icons\Change.ico
URLDownloadToFile, % PreUrl . "57ced9ad-3ccc-4019-a9bd-6f86218f3dd9/Google.ico?downloadOnly=true" , Icons\Google.ico
URLDownloadToFile, % PreUrl . "4ed2cdc9-556f-4266-9b23-d8ec665c9b84/PlayPause.ico?downloadOnly=true", Icons\PlayPause.ico
URLDownloadToFile, % PreUrl . "869c4c44-5e3a-470c-bed4-c8d2bcee621d/Stop.ico?downloadOnly=true" , Icons\Stop.ico
URLDownloadToFile, % PreUrl . "0ac5a584-d28c-4ca7-aac8-a45631a2e3c3/Translate.ico?downloadOnly=true", Icons\Translate.ico
if !(FileExist("Icons\Change.ico") && FileExist("Icons\Google.ico") && FileExist("Icons\PlayPause.ico")
&& FileExist("Icons\Stop.ico") && FileExist("Icons\Translate.ico"))
{
TrayTip
MsgBox, Не удалось завершить загрузку.`nЗагрузите папку вручную из аттача к теме на форуме
,`nпоместите её в директорию скрипта и запустите скрипт снова.
ExitApp
}
else
{
Menu, Tray, Icon, % A_ScriptDir "\Icons\Google.ico"
TrayTip,, Загрузка успешно завершена!
Sleep, 1500
TrayTip
}
}
else
{
MsgBox, Загрузите папку вручную из аттача к теме на форуме
,`nпоместите её в директорию скрипта и запустите скрипт снова.
ExitApp
}
}
Menu, Tray, Icon, % A_ScriptDir "\Icons\Google.ico"
}
global MAX_URL_LENGTH := 2076, IMAGE_ICON := 1, WM_INPUTLANGCHANGEREQUEST := 0x50
, EVENT_SYSTEM_MOVESIZESTART := 0xA, EVENT_SYSTEM_MOVESIZEEND := 0xB
, GUIs := [], LangArray := {}, Player, Voice := [], ColorGui := "Default", MainTransText
, SIZING, Edit1HPos, Edit2HPos, Edit2YPos, Button2YPos, Button6YPos, Edit1FontSize, Edit2FontSize
, IsControlPos, GetControlPos, ScriptPID, GuiActive, SaveSize, AllowMultiWindow
, IniName := RegExReplace(A_ScriptName, "(.*\.).*", "$1ini")
Process, Exist
ScriptPID := ErrorLevel
InitLangArray()
Hotkey, IfWinActive
Hotkey, ~^vk43, HotkeyRun, Off
Hotkey, ~^Ins , HotkeyRun, Off
IniRead, Hotkey , % IniName, Hotkey , Hotkey , C
IniRead, ShowWindowOnStart , % IniName, Settings, ShowWindowOnStart , 0
IniRead, SaveSize , % IniName, Settings, SaveSize , 0
IniRead, AllowMultiWindow , % IniName, Settings, AllowMultiWindow , 0
IniRead, Edit1FontSize , % IniName, Location, Edit1FontSize , 8
IniRead, Edit2FontSize , % IniName, Location, Edit2FontSize , 8
if InStr(Hotkey, "C")
Hotkey, ~^vk43, On
if InStr(Hotkey, "Ins")
Hotkey, ~^Ins, On
Menu, Tray, NoStandard
Menu, Tray, Add, Открыть, Open
Menu, Tray, Default, Открыть
Menu, Tray, Add
Menu, Tray, Add, Показывать окно при запуске, ShowWindowOnStart
if ShowWindowOnStart
Menu, Tray, Check, Показывать окно при запуске
Menu, Tray, Add, Сохранять размеры окна, SaveSize
if SaveSize
Menu, Tray, Check, Сохранять размеры окна
Menu, Tray, Add, Разрешить много окон, AllowMultiWindow
if AllowMultiWindow
Menu, Tray, Check, Разрешить много окон
Menu, Tray, Add
Menu, Tray, Add, Использовать Ctrl+C+C, Hotkey
Menu, Tray, Add, Использовать Ctrl+Ins+Ins, Hotkey
if InStr(Hotkey, "C")
Menu, Tray, Check, Использовать Ctrl+C+C
if InStr(Hotkey, "Ins")
Menu, Tray, Check, Использовать Ctrl+Ins+Ins
Menu, Tray, Add
if !A_IsCompiled
{
Menu, Tray, Add, Edit, Edit
Menu, Tray, Add, Reload, Reload
Menu, Tray, Add
}
Menu, Tray, Add, Выход, ExitApp
HWINEVENTHOOK := SetWinEventHook(EVENT_SYSTEM_MOVESIZESTART, EVENT_SYSTEM_MOVESIZEEND, 0
, RegisterCallback("WinGetControlPos", "F"), 0, 0, 0)
OnExit, Exit
OnMessage(0x201, "WM_LBUTTONDOWN")
OnMessage(0x111, "WM_COMMAND")
OnMessage(0x214, "WM_SIZING")
ShowWindowOnStart ? ShowTranslation("", "", "en", "ru")
Return
Open:
if !WinExist("Google Translate ahk_pid" ScriptPID) || AllowMultiWindow
ShowTranslation("", "", "en", "ru")
return
ShowWindowOnStart:
AllowMultiWindow:
SaveSize:
Menu, Tray, ToggleCheck, % A_ThisMenuItem
%A_ThisLabel% := !%A_ThisLabel%
IniWrite, % %A_ThisLabel%, % IniName, Settings, %A_ThisLabel%
return
Edit:
Edit
return
Reload:
Reload
return
Hotkey:
Menu, Tray, ToggleCheck, % A_ThisMenuItem
if InStr(A_ThisMenuItem, "Ins")
Hotkey := InStr(Hotkey, "Ins") ? RegExReplace(Hotkey, "Ins") : Hotkey . "Ins"
if InStr(A_ThisMenuItem, "C+C")
Hotkey := InStr(Hotkey, "C") ? RegExReplace(Hotkey, "C") : Hotkey . "C"
Hotkey, ~^Ins, % InStr(Hotkey, "Ins") ? "On" : "Off"
Hotkey, ~^vk43, % InStr(Hotkey, "C") ? "On" : "Off"
IniWrite, % Hotkey, % IniName, Hotkey, Hotkey
return
HotkeyRun:
DoublePress()
return
Exit:
WinGet, List, List, % "Google Translate ahk_pid" ScriptPID
Loop % List
{
if (List%A_Index% = GUIs.1)
{
IniWriteSizeGui(GUIs.1), SaveSize ? IniWriteSizeEdit(GUIs.1)
break
}
}
DllCall("UnhookWinEvent", Ptr, HWINEVENTHOOK)
GUIs := LangArray := Voice := ""
ExitApp:
ExitApp
^!vk56::SendInput, {Raw}%MainTransText%
#If WinActive("Google Translate ahk_pid" ScriptPID)
Esc::WinClose, A
Enter::ControlClick, Button4, % "Google Translate ahk_pid" ScriptPID
#If WinActive("Google Translate ahk_pid" ScriptPID) && NN := GetEditFocus()
^WheelUp::
^WheelDown::
InStr(A_ThisHotkey, "Up") ? ++Edit%NN%FontSize : --Edit%NN%FontSize
Edit%NN%FontSize < 6 ? Edit%NN%FontSize := 6
Edit%NN%FontSize > 25 ? Edit%NN%FontSize := 25
ToolTip % "FontSize = " . Edit%NN%FontSize
Gui, % WinExist("A") . ":Default"
Gui, Font, % "q5 s" . Edit%NN%FontSize, Verdana
GuiControl, Font, Edit%NN%
SetTimer, IniWriteFontSize, -500
return
IniWriteFontSize:
ToolTip
IniWrite, %Edit1FontSize%, % IniName, Location, Edit1FontSize
IniWrite, %Edit2FontSize%, % IniName, Location, Edit2FontSize
return
DoublePress()
{
static pressed1 = 0
if pressed1 and A_TimeSincePriorHotkey <= 400 And Clipboard
{
pressed1 := 0
if (!(hwnd := WinExist("Google Translate ahk_pid" ScriptPID)) || AllowMultiWindow)
GuiActive := GetActiveWindow(), Translate(RegExReplace(Clipboard, "\R", "`r`n"))
else
TranslateInTheSameWindow(hwnd, Clipboard)
}
else
pressed1 := 1
}
Translate(Sourse, ByRef _from="", ByRef _to="", NewWindow = 1)
{
if !Ping("translate.google.com")
{
MsgBox, 16, Ошибка!, Нет ответа от сервера.`nПроверьте соединение с интернетом!
Return
}
if (_from = "" && _to = "")
{
cyr := RegExMatch(Sourse, "[А-Яа-я]")
from := cyr ? "ru" : "auto", to := cyr ? "en" : "ru"
}
else
from := _from, to := _to
PreUrl := "http://translate.google.com/translate_a/t?client=x&sl=" . from . "&tl=" . to . "&text="
Url := PreUrl . URIEncode(Sourse)
if StrLen(Url) > MAX_URL_LENGTH
{
if RegExMatch(Sourse, "[\.\?!\n]")
{
StartPos := 1
While StartPos := RegExMatch(Sourse, ".+?([\.\?!\r\n]+([ \t\r\n]*)|$)", Found, StartPos) + StrLen(Found)
{
Delimiter := Found2 ? Found2 : RegExReplace(Found, ".*(\s*)", "$1")
Text := RegExReplace(Found, "(.*)\s*", "$1")
Url := PreUrl . URIEncode(Text)
if StrLen(Url) > MAX_URL_LENGTH
{
If RegExMatch(Text, "[,;:—\r\n]")
{
PrevText := "", StartPos_ := 1
While StartPos_ := RegExMatch(Text, "(.+?)(([,;:—\.]+\s*)|$)", Found_, StartPos_) + StrLen(Found_)
{
txt := Found_1, dlmtr := Found_2
If StrLen(PreUrl . URIEncode(txt . dlmtr)) > MAX_URL_LENGTH
TransText .= GetTranslate(PreUrl . URIEncode(PrevText), from) . RegExReplace(PrevText, ".*(\s+)$", "$1")
. BreakdownByGaps(txt, PreUrl, from) . dlmtr, PrevText := ""
else If StrLen(PreUrl . URIEncode(txt . dlmtr . PrevText)) > MAX_URL_LENGTH
TransText .= GetTranslate(PreUrl . URIEncode(PrevText), from)
. RegExReplace(PrevText, ".*(\s+)$", "$1"), PrevText := txt . dlmtr
else
PrevText .= txt . dlmtr
}
TransText .= GetTranslate(PreUrl . URIEncode(PrevText), from)
}
else
TransText .= BreakdownByGaps(Text, PreUrl, ByRef from)
TransText .= Delimiter
}
else
TransText .= GetTranslate(Url, from) . Delimiter
}
}
else
TransText := BreakdownByGaps(Sourse, PreUrl, ByRef from)
}
else
TransText := GetTranslate(Url, from)
TransText := RegExReplace(TransText, " ``(.)", "$1" Chr(0x301)) ; обработка знака ударения
If NewWindow
ShowTranslation(Clipboard, TransText, from, to)
else
{
_from := from, _to := to
Return TransText
}
}
BreakdownByGaps(Text, PreUrl, ByRef from)
{
StartPos := 1
While StartPos := RegExMatch(Text, "(.+?)([ \t]+|$)", Found, StartPos) + StrLen(Found)
{
txt := Found1, dlmtr := Found2
If StrLen(PreUrl . URIEncode(txt . dlmtr)) > MAX_URL_LENGTH
TransText .= txt . dlmtr, PrevText := ""
else If StrLen(PreUrl . URIEncode(PrevText . txt . dlmtr)) > MAX_URL_LENGTH
TransText .= GetTranslate(PreUrl . URIEncode(PrevText), from)
. RegExReplace(PrevText, ".*(\s+)$", "$1"), PrevText := txt . dlmtr
else
PrevText .= txt . dlmtr
}
Return TransText .= GetTranslate(PreUrl . URIEncode(PrevText), from)
}
URIEncode(Str)
{
b_Format:=A_FormatInteger
SetFormat, IntegerFast, H
Loop, % StrPutVar(Str, Var, "UTF-8")
{
Ch:=NumGet(Var, A_Index-1, "UChar")
If Ch=0
Break
If (Ch>0x7f Or Ch<0x30 Or Ch=0x3d)
s.="%"((StrLen(c:=SubStr(Ch, 3))<2) ? "0"c:c)
else
s.=Chr(Ch)
}
SetFormat, IntegerFast, % b_Format
Return, s
}
GetTranslate(Url, byref from)
{
if !JsonTrans := UrlDownloadToVar(Url, "Opera/9.80 (Windows NT 6.1; U; ru) Presto/2.8.131 Version/11.10")
{
MsgBox, 16, Ошибка!, Нет ответа от сервера.`nПроверьте соединение с интернетом!
Return
}
oJSON := GetObjectFromJSON(JsonTrans)
Loop % oJSON.sentences.MaxIndex()
trans .= oJSON.sentences[A_Index].trans
MainTransText := FinishingText(trans)
if oJSON.HasKey("dict")
for k,v in oJSON.dict
for ky,val in v
{
if !(ky = "terms")
continue
dict .= "`n`n", i := 1
for key,value in val
{
if value ~= "i)(*UCP)^" trans "$"
continue
dict .= (i++ = 1 ? "" : "; ") . value
}
}
from := oJSON.src, oJSON := "", dict := Trim(dict, "`n")
Return FinishingText(trans . (dict ? "`n+`n" . dict : ""))
}
FinishingText(text)
{
if RegExMatch(text, "\\u\d\d\d\d")
{
StartPos := 1
While StartPos := RegExMatch(text, "\\u(\d\d\d\d)", Found, StartPos)
text := RegExReplace(text, "\Q" Found "\E", Chr("0x" Found1)), StartPos++
}
text := RegExReplace(text, "\\r\\n", "`r`n")
, text := RegExReplace(text, "\\(.)", "$1")
Return text
}
WM_LBUTTONDOWN()
{
PostMessage, WM_NCLBUTTONDOWN := 0xA1, HTCAPTION := 2
}
StrPutVar(string, ByRef var, encoding = "CP0")
{
; Ensure capacity.
VarSetCapacity( var, StrPut(string, encoding)
; StrPut returns char count, but VarSetCapacity needs bytes.
* ((encoding="utf-16"||encoding="cp1200") ? 2 : 1) )
; Copy or convert the string.
return StrPut(string, &var, encoding)
}
UrlDownloadToVar(URL, UserAgent = "", ProxyServer = "", UserName = "", Password = "")
{
WebRequest := ComObjCreate("WinHttp.WinHttpRequest.5.1")
ProxyServer ? WebRequest.SetProxy(HTTPREQUEST_PROXYSETTING_PROXY := 2, ProxyServer)
WebRequest.Open("GET", Url)
ProxyServer ? WebRequest.SetCredentials(UserName, Password, HTTPREQUEST_SETCREDENTIALS_FOR_PROXY := 1)
UserAgent ? WebRequest.Option(WinHttpRequestOption_UserAgentString := 0) := UserAgent
WebRequest.Send()
Text := WebRequest.ResponseText
WebRequest := ""
return Text
}
ShowTranslation(SourceText, TransText, from, to)
{
static PlayPause1, PlayPause2, Stop1, Stop2, hGui, Control, ExChange1, ExChange2, Source
, hIconPlayPause, hIconStop, hIconTranslate, hIconGoogle, hIconChange, Icons
, hButtPlayPause1, hButtPlayPause2, hButtStop1, hButtStop2, hButtTranslate, hButtChange1, hButtChange2
, BS_ICON := 0x40, WM_SETICON := 0x80, BM_SETIMAGE := 0xF7, ES_NOHIDESEL := 0x100
, WMSZ_TOP := 3, WMSZ_TOPLEFT := 4, WMSZ_TOPRIGHT := 5
Gui, New, +AlwaysOnTop +LastFound +Resize +hwndhGui +Owner +MinSize199x220 -MaximizeBox
Gui, Color, %ColorGui%
oSize := IniReadSizeEdit()
if (SaveSize && Edit1H := oSize.Edit1H)
Edit1W := oSize.Edit1W, Edit2H := oSize.Edit2H
Gui, Font, q5 s8, Verdana
Gui, Add, Text, % "x" (Edit1W > 310 ? 10 + (Edit1W - 310)//2 : 10) " y15", Исходный язык:
SourceLangNames := TargetLangNames := ""
For k,v In LangArray
SourceLangNames .= (A_Index = 1 ? "" : "|") . k . (v = from ? "|" : "")
, TargetLangNames .= (A_Index = 1 ? "" : "|") . k . (v = to ? "|" : "")
SourceLangNames := RegExReplace(SourceLangNames, "\|$", "||")
Gui, Add, DDL, % "x" (Edit1W > 310 ? 112 + (Edit1W - 310)//2 : 112) " yp-4 w182", % SourceLangNames
Gui, Add, Button, % "x" (Edit1W > 310 ? 297 + (Edit1W - 310)//2 : 297)
. " yp-1 w23 h23 " BS_ICON " hwndhButtChange1 gExchangeLang vExChange1"
Gui, Font, q5 s%Edit1FontSize%, Verdana
if !(SaveSize && Edit1H)
{
Gui, Add, Edit, x10 y+9 w310 Multi %ES_NOHIDESEL% vSource, % SourceText
GuiControlGet, Edit1, Pos
Edit1H < 45 ? Edit1H := 45
Edit1H > 250 ? Edit1H := 250
GuiControl, Move, Edit1, h%Edit1H%
}
else
Gui, Add, Edit, % "x10 y+9 w" (Edit1W ? Edit1W : 310) " Multi h" Edit1H " vSource " ES_NOHIDESEL, % SourceText
GuiControlGet, Edit1, Pos
Gui, Font, q5 s8, Verdana
Gui, Add, Button, % "x10 y" Edit1Y + Edit1H + 5 " w52 h23 hwndhButtPlayPause1 gPlayPause vPlayPause1 " BS_ICON
Gui, Add, Button, % "x+3 yp w52 h23 " BS_ICON " hwndhButtStop1 gStop vStop1" (Player ? "" : " Disabled")
Gui, Add, Button, % "x" (Edit1W ? Edit1W - 60 : 250) " yp w70 h23 " BS_ICON " hwndhButtTranslate gTranslate"
Gui, Add, Text, % "x" (Edit1W > 310 ? 10 + (Edit1W - 310)//2 : 10) " y+20", Язык перевода:
Gui, Add, DDL, % "x" (Edit1W > 310 ? 112 + (Edit1W - 310)//2 : 112) " yp-4 w182", % TargetLangNames
Gui, Add, Button, % "x" (Edit1W > 310 ? 297 + (Edit1W - 310)//2 : 297)
. " yp-1 w23 h23 " BS_ICON " hwndhButtChange2 gExchangeLang vExChange2"
Gui, Font, q5 s%Edit2FontSize%, Verdana
if !(SaveSize && Edit1H := oSize.Edit1H)
{
Gui, Add, Edit, x10 y+9 w310 Multi %ES_NOHIDESEL%, % TransText
GuiControlGet, Edit2, Pos
Edit2H < 45 ? Edit2H := 45
Edit2H > 250 ? Edit2H := 250
GuiControl, Move, Edit2, h%Edit2H%
}
else
Gui, Add, Edit, % "x10 y+9 w" (Edit1W ? Edit1W : 310) " Multi h" Edit2H " " ES_NOHIDESEL, % TransText
GuiControlGet, Edit2, Pos
Gui, Font, q5 s8, Verdana
Gui, Add, Button, % "x10 y" Edit2Y + Edit2H + 5 " w52 h23 hwndhButtPlayPause2 gPlayPause vPlayPause2 " BS_ICON
Gui, Add, Button, % "x+3 yp w52 h23 " BS_ICON " hwndhButtStop2 gStop vStop2" (Player ? "" : " Disabled")
Gui, Add, Button, % "x" (Edit1W ? Edit1W - 60 : 250) " yp w70 h23 gGuiClose", OK
if !IsObject(Icons)
{
hIconGoogle := A_IsCompiled ? ExtractIcon(A_ScriptFullPath, 1, 24) : ExtractIcon(A_ScriptDir "\Icons\Google.ico" , 1, 24)
hIconChange := A_IsCompiled ? ExtractIcon(A_ScriptFullPath, 2, 16) : ExtractIcon(A_ScriptDir "\Icons\Change.ico" , 1, 16)
hIconPlayPause := A_IsCompiled ? ExtractIcon(A_ScriptFullPath, 3, 25) : ExtractIcon(A_ScriptDir "\Icons\PlayPause.ico", 1, 25)
hIconStop := A_IsCompiled ? ExtractIcon(A_ScriptFullPath, 4, 12) : ExtractIcon(A_ScriptDir "\Icons\Stop.ico" , 1, 12)
hIconTranslate := A_IsCompiled ? ExtractIcon(A_ScriptFullPath, 5, 16) : ExtractIcon(A_ScriptDir "\Icons\Translate.ico", 1, 16)
Icons := [hIconGoogle, hIconChange, hIconPlayPause, hIconStop, hIconTranslate]
}
DetectHiddenWindows, On
Loop 2
{
PostMessage, BM_SETIMAGE, IMAGE_ICON, hIconChange ,, % "ahk_id" hButtChange%A_Index%
PostMessage, BM_SETIMAGE, IMAGE_ICON, hIconPlayPause ,, % "ahk_id" hButtPlayPause%A_Index%
PostMessage, BM_SETIMAGE, IMAGE_ICON, hIconStop ,, % "ahk_id" hButtStop%A_Index%
}
PostMessage, BM_SETIMAGE, IMAGE_ICON, hIconTranslate,, ahk_id %hButtTranslate%
PostMessage, WM_SETICON,, hIconGoogle,, ahk_id %hGui%
PostMessage, WM_INPUTLANGCHANGEREQUEST,, GetLayoutList()[from = "ru" ? "Ru" : "En"],, ahk_id %A_ScriptHwnd%
DetectHiddenWindows, Off
GuiControlGet, Button8, Pos
Gui, Show, % "hide h" Button8Y + Button8H + 6, Google Translate
GuiControl, Focus, Edit1
if !WinExist("Google Translate ahk_pid" ScriptPID)
{
IniRead, xGUI, % IniName, Location, xGUI, % " "
IniRead, yGUI, % IniName, Location, yGUI, % " "
Gui, Show, % (xGUI = "" ? "" : "x" xGUI " y" yGUI " ") "w" (SaveSize && Edit1W ? Edit1W + 20 : 330)
}
else
{
WinGetPos, X, Y,,, % "ahk_id " (GuiActive ? GuiActive : GUIs[GUIs.MaxIndex()])
Gui, Show, % "x" X + 60 " y" Y + 40 " w" (SaveSize && Edit1W ? Edit1W + 20 : 330)
}
GUIs.Insert(hGui), GuiActive := ""
Return
GuiSize:
if !IsControlPos
return
SetWinDelay, 0
if (SIZING ~= WMSZ_TOP "|" WMSZ_TOPLEFT "|" WMSZ_TOPRIGHT)
{
if A_GuiHeight - Edit1HPos > 32
Resizing(A_GuiWidth, A_GuiHeight, 1)
else
{
if (GetControlPos = "")
_WinGetControlPos(A_Gui), GetControlPos := 1
Resizing(A_GuiWidth, A_GuiHeight, 2)
}
}
else
{
if A_GuiHeight - Edit2HPos > 32
Resizing(A_GuiWidth, A_GuiHeight, 2)
else
{
if (GetControlPos = "")
_WinGetControlPos(A_Gui), GetControlPos := 1
Resizing(A_GuiWidth, A_GuiHeight, 1)
}
}
return
PlayPause:
if IsObject(Player)
{
if Playing := !Playing
Player.Controls.pause()
else
Player.Controls.play()
}
else
{
hGui := A_Gui, Control := A_GuiControl
SetTimer, PlayPauseTimer, -1
}
return
PlayPauseTimer:
n := SubStr(Control, 0)
ControlGet, Text, Selected,, Edit%n%, ahk_id %hGui%
if (Text = "")
ControlGetText, Text, Edit%n%, ahk_id %hGui%
ControlGetText, lng, ComboBox%n%, ahk_id %hGui%
Say(RegExReplace(Text, "\R+", "`n"), LangArray[lng])
return
Stop:
Player.close()
Playing := Player := ""
StopButtonEnableDisable(0)
return
ExchangeLang:
GuiControlGet, to,, ComboBox1
GuiControlGet, from,, ComboBox2
SourceLangNames := TargetLangNames := ""
for k In LangArray
SourceLangNames .= "|" . k . (k = from ? "|" : "")
, TargetLangNames .= "|" . k . (k = to ? "|" : "")
SourceLangNames := RegExReplace(SourceLangNames, "\|$", "||")
GuiControl,, ComboBox1, % SourceLangNames
GuiControl,, ComboBox2, % TargetLangNames
GuiControl, Focus, Edit1
return
Translate:
GuiControlGet, from,, ComboBox1
from := LangArray[from]
GuiControlGet, to,, ComboBox2
to := LangArray[to]
GuiControlGet, SourseText,, Edit1
TransText := Translate(RegExReplace(SourseText, "\R", "`r`n"), from, to, 0)
GuiControl,, Edit2, % TransText
GuiControl, Focus, Edit1
Return
GuiClose:
if (A_Gui = GUIs.1)
IniWriteSizeGui(A_Gui), SaveSize ? IniWriteSizeEdit(A_Gui)
else
{
for k,v in GUIs
if (A_Gui = v)
break
GUIs.Remove(k)
}
Gui, %A_Gui%: Destroy
IfWinNotExist, Google Translate ahk_pid %ScriptPID%
{
Player.close(), Player := "", Voice := []
FileDelete, % A_ScriptDir "\mp3\*.mp3"
Loop % Icons.MaxIndex()
DllCall("DestroyIcon", Ptr, Icons[A_Index])
Icons := "", GUIs := []
}
return
}
TranslateInTheSameWindow(hwnd, SourceText)
{
Translation := Translate(RegExReplace(SourceText, "\R", "`r`n"), from, to, 0)
For k,v In LangArray
SourceLangNames .= "|" . k . (v = from ? "|" : "")
, TargetLangNames .= "|" . k . (v = to ? "|" : "")
Gui, %hwnd%:Default
GuiControl,, ComboBox1, % SourceLangNames
GuiControl,, ComboBox2, % TargetLangNames
GuiControl,, Edit1, % SourceText
GuiControl,, Edit2, % Translation
}
Resizing(W, H, mode)
{
E1H := H - Edit1HPos
E2Y := H - Edit2YPos, E2H := H - Edit2HPos
B2Y := H - Button2YPos, B6Y := H - Button6YPos
if mode = 1
{
GuiControl, Move, Edit1, % "w" W - 20 " h" E1H
GuiControl, Move, Edit2, % "w" W - 20 " y" E2Y
GuiControl, MoveDraw, Button2, % "y" B2Y
GuiControl, MoveDraw, Button3, % "y" B2Y
GuiControl, MoveDraw, Button4, % "x" (W > 200 ? W - 80 : 120) " y" B2Y
GuiControl, MoveDraw, Static2, % "x" (W > 330 ? 10 + (W - 330)//2 : 10) " y" B2Y + 43
GuiControl, Move, ComboBox2, % "x" (W > 330 ? 112 + (W - 330)//2 : 112) " y" B2Y + 39
GuiControl, MoveDraw, Button5, % "x" (W > 330 ? 297 + (W - 330)//2 : 297) " y" B2Y + 38
}
else
{
GuiControl, Move, Edit1, % "w" W - 20
GuiControl, Move, Edit2, % "w" W - 20 " h" (E2H > 32 ? E2H : 32)
GuiControl, MoveDraw, Static2, % "x" (W > 330 ? 10 + (W - 330)//2 : 10)
GuiControl, Move, ComboBox2, % "x" (W > 330 ? 112 + (W - 330)//2 : 112)
GuiControl, MoveDraw, Button5, % "x" (W > 330 ? 297 + (W - 330)//2 : 297)
GuiControl, MoveDraw, Button4, % "x" (W > 200 ? W - 80 : 120)
}
GuiControl, Move, Static1, % "x" (W > 330 ? 10 + (W - 330)//2 : 10)
GuiControl, Move, ComboBox1, % "x" (W > 330 ? 112 + (W - 330)//2 : 112)
GuiControl, MoveDraw, Button1, % "x" (W > 330 ? 297 + (W - 330)//2 : 297)
GuiControl, MoveDraw, Button6, % "y" B6Y
GuiControl, MoveDraw, Button7, % "y" B6Y
GuiControl, MoveDraw, Button8, % "x" (W > 200 ? W - 80 : 120) " y" B6Y
}
InitLangArray()
{
Languages =
(LTrim C
Азербайджанский|az
Албанский|sq
Английский|en
Арабский|ar
Армянский|hy
Африкаанс|af
Баскский|eu
Белорусский|be
Болгарский|bg
Венгерский|hu
Вендский|sb
Вьетнамский|vi
Голландский|nl
Греческий|el
Грузинский|ka
Датский|da
Иврит|he
Идиш|ji
Индонезийский|id
Исландский|is
Испанский|es
Итальянский|it
Каталонский|ca
Китайский|zh
Китайский (Аомынь)|zh-cn
Китайский (Тайвань)|zh-tw
Корейский|ko
Латынь|la
Латышский|lv
Литовский|lt
Македонский|mk
Малайский|ms
Мальтийский|mt
Немецкий|de
Норвежский|no
Польский|pl
Португальский|pt
Румынский|ro
Русский|ru
Сербский|sr
Словацкий|sk
Словенский|sl
Суахили|sw
Тайский|th
Турецкий|tr
Украинский|uk
Урду|ur
Фарси|fa
Финский|fi
Французский|fr
Хинди|hi
Хорватский|hr
Чешский|cs
Шведский|sv
Эсперанто|eo
Эстонский|et
Японский|ja
)
Loop, parse, Languages, `n, `r
{
Key := RegExReplace(A_LoopField, "(.*)\|.*", "$1")
Value := RegExReplace(A_LoopField, ".*\|(.*)", "$1")
LangArray[Key] := Value
}
}
ExtractIcon(sFile, IconNumber, IconSize)
{
coding := A_IsUnicode ? "W" : "A"
SplitPath, sFile,,, ext
if (ext = "ico")
IconNumber := 0
if PrivateExtractIcons := DllCall("GetProcAddress"
, Ptr, DllCall("LoadLibrary", Str, "User32", Ptr)
, AStr, "PrivateExtractIcons" . coding, Ptr)
{
Result := DllCall(PrivateExtractIcons, Str, sFile, Int, IconNumber-1
, Int, IconSize, Int, IconSize, PtrP, hIcon, UIntP, 0, UInt, 1, UInt, 0)
if !Result
MsgBox, 16,, % "Не удалось извлечь иконку.`nОшибка " A_LastError "."
else if (Result = 0xFFFFFFFF || Result = -1)
MsgBox, 16,, Указанный файл не найден!
}
else
{
if !DllCall("Shell32\ExtractIconEx" . coding, Str, sFile, Int, IconNumber-1, PtrP, hIconLarge, PtrP, hIconSmall, UInt, 1)
{
MsgBox, 16,, % "Не удалось извлечь иконку.`nОшибка " A_LastError "."
return
}
SysGet, SmallIconSize, % SM_CXSMICON
if (IconSize <= SmallIconSize)
DllCall("DestroyIcon", Ptr, hIconLarge)
, hIcon := hIconSmall
else
DllCall("DestroyIcon", Ptr, hIconSmall)
, hIcon := hIconLarge
hIcon := DllCall("CopyImage", Ptr, hIcon, UInt, IMAGE_ICON
, Int, IconSize, Int, IconSize, UInt, LR_COPYRETURNORG := 0x4|LR_COPYDELETEORG := 0x8, Ptr)
}
Return hIcon
}
Ping(strHost)
{
Loop 4
bRet := ComObjGet("winmgmts:").Get("Win32_PingStatus.address='" . strHost . "'").StatusCode = 0
until bRet
return bRet
}
Say(Text, lng)
{
static PlaylistOpenNoMedia := 6, Stopped := 1
Player := ComObjCreate("WMPlayer.OCX")
objPlaylist := Player.currentPlaylist
for k,v in Voice
if (v.Text = RegExReplace(Text, "^\s*(\S.+\S)(\s+$|$)", "$1") && v.lng = lng)
{
var := 1
break
}
if var
{
Loop % v.mp3.MaxIndex()
objPlaylist.appendItem(Player.newMedia(v.mp3[A_Index]))
}
else
{
if !Ping("translate.google.com")
{
MsgBox, 16, Ошибка!, Нет ответа от сервера.`nПроверьте соединение с интернетом!
Return
}
PreUrl := "http://translate.google.com/translate_tts?ie=UTF-8&tl=" lng "&q="
Strings := []
If StrLen(Text) > 100
{
StartPos := 1
While StartPos := RegExMatch(Text, ".+?(\.|$)", Found, StartPos) + StrLen(Found)
{
if StrLen(Found) > 100
{
StartPos_ := 1
While StartPos_ := RegExMatch(Found, "(.{1,99}([ ,\t\n]|$))|(.{1,100})", Found_, StartPos_) + StrLen(Found_)
Strings.Insert(Found_)
}
else
Strings.Insert(Found)
}
}
else
Strings.1 := Text
if !FileExist(A_ScriptDir "\mp3")
FileCreateDir, %A_ScriptDir%\mp3
Voice.Insert(o := {Text: RegExReplace(Text, "^\s*(\S.+\S)(\s+$|$)", "$1"), lng: lng, mp3: []})
Loop % count := Strings.MaxIndex()
{
URLDownloadToFile, % PreUrl . URIEncode(RegExReplace(Strings[A_Index], "^\s*([^\s]+)\s*$", "$1"))
, % mp3file := A_ScriptDir "\mp3\" A_TickCount ".mp3"
objPlaylist.appendItem(Player.newMedia(mp3file))
o.mp3.Insert(mp3file)
}
}
StopButtonEnableDisable(1)
Player.Controls.play()
While Player.PlayState != Stopped && Player.OpenState != PlaylistOpenNoMedia && IsObject(Player)
Sleep, 100
Player.close(), Player := objPlaylist := ""
StopButtonEnableDisable(0)
}
StopButtonEnableDisable(key)
{
WinGet, List, List, Google Translate ahk_pid %ScriptPID%
Loop % List
{
Control , % key ? "Enable" : "Disable",, Button3, % "ahk_id" List%A_Index%
Control , % key ? "Enable" : "Disable",, Button7, % "ahk_id" List%A_Index%
}
}
WM_COMMAND(wp, lp)
{
static EN_SETFOCUS := 0x100, CBN_SETFOCUS := 3
if !WinActive("Google Translate") || !(wp>>16 = EN_SETFOCUS || wp>>16 = CBN_SETFOCUS)
return
Gui, %A_Gui%:Default
DetectHiddenWindows, On
if (wp>>16 = EN_SETFOCUS)
{
GuiControlGet, Name, Name, %lp%
if Name != Source
return
GuiControlGet, lang,, ComboBox1
PostMessage, WM_INPUTLANGCHANGEREQUEST,, GetLayoutList()[lang = "Русский" ? "Ru" : "En"],, ahk_id %A_ScriptHwnd%
}
if (wp>>16 = CBN_SETFOCUS)
PostMessage, WM_INPUTLANGCHANGEREQUEST,, GetLayoutList().Ru,, ahk_id %A_ScriptHwnd%
DetectHiddenWindows, Off
}
GetLayoutList()
{
SetFormat, IntegerFast, H
VarSetCapacity(List, A_PtrSize*2)
DllCall("GetKeyboardLayoutList", Int, 2, Ptr, &List)
Locale1 := NumGet(List)
b := SubStr(Locale2 := NumGet(List, A_PtrSize), -3) = 0409
En := b ? Locale2 : Locale1
Ru := b ? Locale1 : Locale2
SetFormat, IntegerFast, D
Return {En: En, Ru: Ru}
}
WM_SIZING(wp)
{
SIZING := wp
}
SetWinEventHook(eventMin, eventMax, hmodWinEventProc, lpfnWinEventProc, idProcess, idThread, dwFlags)
{
return DllCall("SetWinEventHook" , UInt, eventMin, UInt, eventMax
, Ptr, hmodWinEventProc, Ptr, lpfnWinEventProc
, UInt, idProcess, UInt, idThread
, UInt, dwFlags, Ptr)
}
WinGetControlPos(hWinEventHook, event, hwnd)
{
if !GetActiveWindow()
return
if (event = EVENT_SYSTEM_MOVESIZEEND)
IsControlPos := GetControlPos := "", CorrectPos(hwnd)
else
_WinGetControlPos(hwnd)
}
_WinGetControlPos(hwnd)
{
Gui, %hwnd%:Default
GuiControlGet, Edit1, Pos
GuiControlGet, Edit2, Pos
GuiControlGet, Button2, Pos
GuiControlGet, Button6, Pos
VarSetCapacity(Rect, 16)
DllCall("GetClientRect", Ptr, hwnd, Ptr, &Rect)
ClientH := NumGet(Rect, 12, "UInt")
Edit1HPos := ClientH - Edit1H
Edit2HPos := ClientH - Edit2H
Edit2YPos := ClientH - Edit2Y
Button2YPos := ClientH - Button2Y
Button6YPos := ClientH - Button6Y
IsControlPos := 1
}
CorrectPos(hwnd)
{
VarSetCapacity(Rect, 16)
DllCall("GetClientRect", Ptr, hwnd, Ptr, &Rect)
ClientH := NumGet(Rect, 12, "UInt")
Gui, %hwnd%:Default
GuiControlGet, Edit2, Pos
GuiControl, Move, Edit2, % "h" ClientH - Edit2Y - 34
Loop 3
GuiControl, MoveDraw, % "Button" A_Index + 5, % "y" ClientH - 29
}
GetActiveWindow()
{
WinGetActiveTitle, Title
WinGetClass, Class, A
WinGet, PID, PID, A
Return (Title = "Google Translate" && Class = "AutoHotkeyGUI" && PID = ScriptPID) ? WinExist("A") : ""
}
IniReadSizeEdit()
{
IniRead, Edit1W, % IniName, Location, Edit1W, % " "
IniRead, Edit1H, % IniName, Location, Edit1H, % " "
IniRead, Edit2H, % IniName, Location, Edit2H, % " "
Return {Edit1W: Edit1W, Edit1H: Edit1H, Edit2H: Edit2H}
}
IniWriteSizeEdit(hwnd)
{
ControlGetPos,,, Edit1W, Edit1H, Edit1, % "ahk_id" hwnd
ControlGetPos,,,, Edit2H, Edit2, % "ahk_id" hwnd
IniWrite, % Edit1W, % IniName, Location, Edit1W
IniWrite, % Edit1H, % IniName, Location, Edit1H
IniWrite, % Edit2H, % IniName, Location, Edit2H
}
IniWriteSizeGui(hwnd)
{
WinGetPos, X, Y,,, % "ahk_id" hwnd
IniWrite, % X, % IniName, Location, xGUI
IniWrite, % Y, % IniName, Location, yGUI
}
GetObjectFromJSON(string)
{
FirstSim := SubStr(string, 1, 1)
mode := FirstSim = "{" ? "collection" : FirstSim = "[" ? "array" : FirstSim = """" ? ""
. "str" : RegExMatch(FirstSim, "[\d]") ? "num" : "Error"
if (mode = "collection")
{
Obj := {}, StartPos := 2
While StartPos := RegExMatch(string, """(.*?)"":\s*", Found, StartPos)
{
RegExMatch(string, "P)([\[\{""\d])", Found_, StartPos += StrLen(Found))
Content := GetContent(SubStr(string, StartPos))
Obj[Found1] := GetObjectFromJSON(Content)
StartPos := Found_Pos1 + StrLen(Content)
}
}
else if (mode = "array")
{
Obj := [], StartPos := 2
While RegExMatch(string, "P)([\[\{""\d])", Found_, StartPos)
{
Content := GetContent(SubStr(string, Found_Pos1))
Obj.Insert(GetObjectFromJSON(Content))
StartPos := Found_Pos1 + StrLen(Content)
}
}
else if (mode = "str")
Obj := SubStr(string, 2, -1)
else if (mode = "num")
Obj := string
else
MsgBox, Ошибка! Первый символ входящего объекта не может быть "%FirstSim%"!
Return Obj
}
GetContent(string)
{
FirstSim := SubStr(string, 1, 1)
inverse := FirstSim = "{" ? "}" : FirstSim = "[" ? "]" : FirstSim = """" ? """" : ""
if (inverse = "")
Content := RegExReplace(string, "([\de.-]+).*", "$1")
else if (inverse = """")
Content := RegExReplace(string, "(.*?[^\\]"").*", "$1")
else
{
i := 0
Loop, parse, string
{
Content .= A_LoopField
i += ((A_LoopField = FirstSim && PrevSim != "\") ? 1 : (A_LoopField = inverse && PrevSim != "\") ? -1 : 0)
if i = 0
break
PrevSim := A_LoopField
}
}
Return Content
}
GetEditFocus()
{
if !WinActive("Google Translate ahk_pid" ScriptPID)
return
ControlGetFocus, Control, A
return InStr(Control, "Edit") ? SubStr(Control, 0) : ""
}
По нажатию Ctrl+C+C и/или Ctrl+Ins+Ins (по выбору через трей-меню) появляется окно (resizable) с исходным текстом из буфера обмена и с его переводом. По умолчанию, если в исходном тексте присутствует кириллица, переводит с русского на английский, если нет, то язык исходного текста определяется автоматически и переводится на русский. В окне можно сменить языки источника и перевода. В том же окне можно осуществить новый перевод, изменив исходный текст вручную и нажав кнопку "Перевод" или "Enter" на клавиатуре.