; Виртуальная 10-ти "клавишная" клавиатура + менеджер буфера обмена + разбивка строк ; Автор - serzh82saratov ; http://forum.script-coding.com/viewtopic.php?pid=88135#p88135 #UseHook #SingleInstance Force #NoTrayIcon #NoEnv #HotkeyInterval 0 #InputLevel 1 SetBatchLines -1 ListLines Off OnExit GuiClose FixIE(0) Global Relative := 1.0 ; Относительный размер клавиатуры. Например: "1.2" = +20% , Bank := "Num" ; Стартовая раскладка - sRu | bRu | sEn | bEn | Emb | Num , TimeOut := 1500 ; Таймаут авто ввода символа после последнего выбора , TrayIcon := 1 ; Иконка только в трее, или только на панели задач , AutoRegistr := 1 ; Переключать в нижний регистр, после ввода символа из верхнего , cBg := "2F4F4F" ; Цвет фона , cBorder := "767676" ; Цвет окантовки клавиш , sBorder := 1 ; Толщина окантовки клавиш , cChr := "000000" ; Цвет шрифта , cSel := "ffffff" ; Цвет шрифта выбранного символа , cCtrl := "DACB51" ; Цвет шрифта кнопок "Ctrl+..." , wKey := 130 * Relative , hKey := wKey//2 , hCap := hKey//3 Menu, Tray, UseErrorLevel Menu, Tray, Icon, Shell32.dll, 174 If TrayIcon { Menu, Tray, Icon Menu, Tray, Click, 1 Menu, Tray, NoStandard Menu, Tray, Add, Min/Max, MinMax Menu, Tray, Default, Min/Max Menu, Tray, Disable, Min/Max Gui, +Owner } Menu, Tray, Add, ExitApp, GuiClose GoSub Init Gui, Tip: Margin, 0, 0 Gui, Tip: Color, %cBg% Gui, Tip: -DPIScale -Caption +Lastfound +AlwaysOnTop +Owner +HWNDhGuiTip Gui, Tip: Add, ActiveX, voDocTip HWNDhTip, HTMLFile oDocTip.body.innerHTML := htmltip WinSet, Transparent, 235 Gui, Margin, 0, 0 Gui, Color, %cBg% Gui, -DPIScale -Caption +Lastfound +AlwaysOnTop +HWNDhThisGui Gui, Add, ActiveX, % "voDoc w" hKey*9+2 " h" hKey*4+hCap, HTMLFile oDoc.body.innerHTML := html Loop 10 (elem := oDoc.getElementById("p" A_Index)).style.top := [0,0,0,hKey,hKey,hKey,hKey*2,hKey*2,hKey*2,hKey*3][A_Index] + hCap . "px" , elem.style.left := [0,wKey,wKey*2,0,wKey,wKey*2,0,wKey,wKey*2,wKey][A_Index] . "px" WinSet, Region, % "0-0 " wKey*3 "-0 " wKey*3 "-" (t := hKey*3+hCap) " 0-" t " 0-0 " . wKey "-" t " " wKey*2 "-" t " " wKey*2 "-" t+hKey " " wKey "-" t+hKey " " wKey "-" t WinSet, Transparent, 235 OnMessage(0x201, "WM_LBUTTONDOWN"), OnMessage(0x200, "WM_MOUSEMOVE") ComObjError(false), Layout(Bank) WinGetPos, X, Y, W, , ahk_class Shell_TrayWnd ahk_exe explorer.exe Gui, Show, % "NA x" (X+W)-(hKey*9)-28 " y" Y - (hKey * 4) - hCap - 2 " w" hKey*9+2, Virtual mini keyboard SetTimer, OnTop, 500 (Clipboard = "" ? 0 : ClipInsert(Clipboard)), ClipInsert := 1 OnMessage(0xC, "WM_SETTEXT") ClipManShow() Return ; _________________________________________________ HotKey _________________________________________________ #If (!Minimize) ; Если окно скрипта не свёрнуто. Условие для клавиш клавиатуры. #If (IsGuiScript || WinActive("ahk_id" hThisGui)) ; Запрет вывода меню. *+F10:: *AppsKey:: Return #If IsGuiScript *WheelDown:: If (GetKeyState("RButton", "P")) (Area = "ClipTip" || Area = "ClipMan" ? Send("{Tab}") : Area = "Caption" ? Send("{Right}") : Send("^+{Right}")) Else If Area is number K_ChangeBank() Else If Area = ClipMan t := (e := oDoc.getElementById("ClipMan")).scrollTop, e.scrollTop := t+hKey, MouseDrag() Return *WheelUp:: If (GetKeyState("RButton", "P")) (Area = "ClipTip" || Area = "ClipMan" ? Send("+{Tab}") : Area = "Caption" ? Send("{Left}") : Send("^+{Left}")) Else If Area is number NextChr(Area) Else If Area = ClipMan t := (e := oDoc.getElementById("ClipMan")).scrollTop, e.scrollTop := t-hKey, MouseDrag() Return *MButton:: If (Area = "ClipMan" && GetKeyState("RButton", "P")) ClipManDelItem() Else If Area is number K_ChangeRegistr() Else If (Area = "Caption" || Area = "ClipMan") ClipManShow() Return *RButton:: If Area is number K_Input() Else If Area = Caption InputCancel(), oDoc.getElementById("viewinput").InnerText := "", ViewInput := "" Else If Area = ClipMan ClipTip() Return #If (IsGuiScript && Area != "Caption") *LButton:: If (GetKeyState("RButton", "P")) (Area = "ClipTip" ? ClipManSelect() : Area != "ClipMan" ? EmbBank() : 0) Else If Area is number NextChr(Area) Else If Area = Del Chr.P ? InputCancel() : ClickKey() Else If Area = Ret ClickKey() Else If Area = ClipMan ClipManSelect() Else If Area = Emb EmbBank() Else If Area = Turn Gosub K_MinMax Else If Area = Close ExitApp Return #If ; _________________________________________________ ClipMan _________________________________________________ OnClipboardChange: If (ClipInsert && A_EventInfo = 1) ClipInsert(Clipboard) Return ClipManShow() { x1 := wKey*3+2, x2 := x1+hKey*3, y2 := hKey*3+hCap, ClipManShow := !ClipManShow, it := 8, st := (hKey*3)/it Gui, +Lastfound Loop % it { Sleep 1 rest := A_Index = it ? 0 : hKey*3-A_Index*st WinSet, Region, % "0-0 0-" y2 " " wKey "-" y2 " " wKey "-" y2+hKey " " . wKey*2 "-" y2+hKey " " wKey*2 "-" y2 " " wKey*3 "-" y2 " " wKey*3 "-0 " . (ClipManShow ? x1 "-0 " x2-rest "-0 " x2-rest "-" y2 " " x1 "-" y2 " " x1 "-0" : x1 "-0 " x1+rest "-0 " x1+rest "-" y2 " " x1 "-" y2 " " x1 "-0") } } ClipInsert(str) { For K, V in Clips.Clone(), Clips := [], i := 1 { If (K = 24 || str == V[1] "") Continue h .= "
" V[2] "
", Clips[i] := [V[1] "", V[2]] } Clips[1] := [str "", ih := TransformHTML(SubStr(str, 1, 96))] (e := oDoc.getElementById("ClipMan")).innerHTML := "
" ih "
" h e.scrollTop := 0, (Area = "ClipMan" ? MouseDrag() : 0) } ClipManSelect() { Static tClipboardAll If (oNode.Id = "ClipMan") Return ClipInsert := 0 tClipboardAll := ClipboardAll Clipboard := (Area = "ClipTip" ? ClipsTip[oNode.Id] : Clips[oNode.Id][1]) Send("^{vk56}") SetTimer, ClipInsert, -50 Return ClipInsert: Clipboard := tClipboardAll Sleep 50 ClipInsert := 1, MouseDrag(2, 2) Return } ClipTip() { If (oNode.Id = "ClipMan") Return SetTimer, OnTop, Off text := Clips[oNode.Id][1], str := SubStr(text, 1, 1500) StringReplace, str, str, `r`n, `n, 1 StringReplace, str, str, `r, `n, 1 i := 0, ClipsTip := StrSplit(str, "`n") Transform, str, HTML, %str%, 3 StringReplace, str, str, %A_Tab%,       , 1 StringReplace, str, str, %A_Space%,  , 1 Loop, parse, str, `n html .= "
" (IsSpace(A_LoopField) ? "
" : A_LoopField) "
" html .= (StrLen(text) > 1500 ? "
. . . . . . . . . . . . . .
" : "") (e := oDocTip.getElementById("ClipTip")).innerHTML := html pbrt := e.getBoundingClientRect() w := pbrt.right-pbrt.left, h := pbrt.bottom-pbrt.top CalculatePopupWindowPosition(x, y, w, h, 20) Gui, Tip: Show, % "NA x" x " y" y " w" w " h" h WinMove, ahk_id %hTip%, , 0, 0, w, h KeyWait RButton Gui, Tip: Show, Hide SetTimer, OnTop, 500 MouseDrag() } ClipManClean() { Clips := [], oDoc.getElementById("ClipMan").innerHTML := "" ToolTip } ClipManDelItem() { If (oNode.Id = "ClipMan") Return Clips.Remove(oNode.Id) ToolTip For K, V in Clips, i := 0 h .= "
" V[2] "
", Clips[i] := [V[1] "", V[2]] oDoc.getElementById("ClipMan").innerHTML := h, MouseDrag() } TransformHTML(str) { Transform, str, HTML, %str%, 3 StringReplace, str, str,
, ↵, 1 StringReplace, str, str, %A_Space%, →, 1 StringReplace, str, str, %A_Tab%, ↔, 1 Return str } ; _________________________________________________ Logic _________________________________________________ Layout(b) { Loop 10 (elem := oDoc.getElementById("p" A_Index)).innerHTML := Ins[b "_" A_Index] , elem.style.fontSize := Param[t := Type[b "_" A_Index]][1] . "px" , elem.style.paddingTop := Param[t][2] . "em", elem.style.color := Param[t][3] PrBank := Bank, Bank := b, Chr.P := "" Caps := (t := SubStr(Bank, 1, 1)) = "b" ? 1 : t = "s" ? 0 : Caps } ChangeBank() { Layout(Caps ? {"bRu":"bEn","bEn":"Num","Emb":"bRu","Num":"bRu"}[Bank] : {"sRu":"sEn","sEn":"Num","Emb":"sRu","Num":"sRu"}[Bank]) } ChangeRegistr() { Layout({"sRu":"bRu","bRu":"sRu","sEn":"bEn","bEn":"sEn","Emb":"Num","Num":"Emb"}[Bank]) } NextChr(A) { Chr.E.style.color := Chr.Color Chr.P && Chr.P != A ? Input() : 0 Chr.C := (Chr.P = A ? (++Chr.C > Bank_%Bank%[A].maxindex() ? 1 : Chr.C) : 1) Chr.P := A, Chr.Color := Param[t := Type[Bank "_" Chr.P]][3] (Chr.E := oDoc.getElementById("p" Chr.P "c" Chr.C)).style.color := cSel SetTimer, Input, % t = "ctrl" || t = "num" ? -30 : "-" TimeOut Chr.S := Bank_%Bank%[Chr.P][Chr.C] } Input(man=0) { SetTimer, Input, Off Chr.E.style.color := Chr.Color Send((Ex := Send_Exception[Chr.S]) = "" ? "{Raw}" Chr.S : Ex) add := Ex = "" ? Chr.S : !InStr(Ex, "{Raw}") ? "" : Chr.E.InnerText oDoc.getElementById("viewinput").InnerText := (ViewInput := SubStr(ViewInput add, -96)) . (ViewInput != "" ? "|" : "") (!man && AutoRegistr && (Bank = "bEn" || Bank = "bRu") && Chr.P) ? Layout({"bRu":"sRu","bEn":"sEn"}[Bank]) : 0, Chr.P := "" } Input: Input() Return InputCancel() { SetTimer, Input, Off Chr.E.style.color := Chr.Color, Chr.P := "" } EmbBank() { InputCancel(), Layout(Bank = "Emb" ? PrBank : "Emb") } K_ChangeBank() { Chr.P ? InputCancel() : ChangeBank() } K_ChangeRegistr() { Chr.P ? Input(1) : 0 Layout({"sRu":"bRu","bRu":"sRu","sEn":"bEn","bEn":"sEn","Emb":"Num","Num":"Emb"}[Bank]) } K_Input() { Chr.P ? Input() : 0 } Send(k) { SendInput %k% } ClickKey() { Static Key Key := Area (Key = "Del" ? Send("{BS}") : Input()) SetTimer, ClickKey, -650 oDoc.getElementById(Key).style.color := cSel KeyWait LButton SetTimer, ClickKey, Off oDoc.getElementById(Key).style.color := cChr Return ClickKey: (Key = "Del" ? Send("{BS}") : Input()) SetTimer, ClickKey, -30 Return } CalculatePopupWindowPosition(byref left, byref top, w, h, offset = 0, x = "", y = "") { VarSetCapacity(POINT, 8, 0), VarSetCapacity(structs, 24, 0) If (x = "" || y = "") DllCall("GetCursorPos", "ptr", &POINT) Else NumPut(x, POINT, 0, "int"), NumPut(y, POINT, 4, "int") NumPut(w + offset, structs, 0, "int"), NumPut(h + offset, structs, 4, "int") ; SIZE Loop 2 { If !DllCall("CalculatePopupWindowPosition" , "ptr", &POINT , "ptr", &structs , "int", [0, 0x0008][A_Index] , "ptr", 0 , "ptr", &structs + 8) Return 0 _left := NumGet(structs, 8, "int"), _top := NumGet(structs, 12, "int") If !(_left < NumGet(POINT, 0, "int") && _top < NumGet(POINT, 4, "int") && (out := 1)) Break } left := _left + (out ? 0 : offset), top := _top + (out ? 0 : offset) Return 1 } IsSpace(var) { if var is space Return 1 } ; Для управления сообщениями: SendMessage, 0xC, 3, "NextChr", , Virtual mini keyboard ahk_class AutoHotkeyGUI WM_SETTEXT(wp, lp) { Return True, IsFunc(F := StrGet(lp)) ? %F%(wp) : 0 } ; _________________________________________________ Window _________________________________________________ WM_MOUSEMOVE(wp, lp, msg, hwnd) { Doc := A_GuiControl = "oDocTip" ? "oDocTip" : "oDoc" Area := (oNode := %Doc%.elementFromPoint(lp & 0xFFFF, lp >> 16)).name If Doc = oDocTip Area = ClipTip PrArea = Area ? 0 : (PrArea := Area) SetTimer, IsThisGui, -30 } IsThisGui: MouseGetPos, , , WinID If ((hThisGui = WinID || hGuiTip = WinID) && (IsGuiScript := 1)) SetTimer, IsThisGui, -50 Else Area := PrArea := Chr.P := "", IsGuiScript := 0 Return OnTop: If (!Minimize) Gui, Show, NA Return GuiSize: If A_Eventinfo = 2 Return Minimize := A_Eventinfo If (IsStart && !Minimize) SendInput !{Esc} IsStart := 1 Return MinMax: K_MinMax: If TrayIcon { Gui, Show, % Minimize ? "NA" : "Hide" SetTimer, OnTop, % (Minimize := !Minimize) ? "Off" : "On" Minimize ? InputCancel() : Send("!{Esc}") Minimize && A_ThisLabel = "MinMax" ? Send("!{Esc}") : 0 } Else Gui, % Minimize = 1 ? "Show" : "Minimize" InputCancel() Return WM_LBUTTONDOWN() { ; Перетаскивание окна If Area = Caption { PostMessage, 0xA1, 2 KeyWait LButton IfWinActive SendInput !{Esc} } } MouseDrag(offset=1, speed=0) { MouseMove, "-" offset, 0, speed, R MouseMove, offset, 0, speed, R } FixIE(Fix) { Static Key := "Software\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION" If A_IsCompiled ExeName := A_ScriptName Else SplitPath, A_AhkPath, ExeName If Fix RegWrite, REG_DWORD, HKCU, %Key%, %ExeName%, 0 Else RegDelete, HKCU, %Key%, %ExeName% } GuiClose: GuiEscape: oDoc := "" ExitApp ; _________________________________________________ Init _________________________________________________ Init: Global hThisGui, hTip, oDoc, oDocTip, Area, PrArea, PrBank, Caps, ViewInput, ClipManShow, ClipInsert, oNode , hGuiTip, Chr := {}, Ins := {}, Type := {}, Clips := [], ClipsTip := [] , Bank_Num := [[1],[2],[3],[4],[5],[6],[7],[8],[9],[0]] , Bank_Chr_1 := ["→",".","`,","!","?","""","`%"] , Bank_Chr_10 := ["↵","+","-","*",":","(",")","|"] , Bank_bRu := [Bank_Chr_1,["А","Б","В","Г"],["Д","Е","Ё","Ж","З"],["И","Й","К","Л"],["М","Н","О","П"] ,["Р","С","Т","У"],["Ф","Х","Ц","Ч"],["Ш","Щ","Ь","Ы"],["Ъ","Э","Ю","Я"],Bank_Chr_10] , Bank_sRu := [Bank_Chr_1,["а","б","в","г"],["д","е","ё","ж","з"],["и","й","к","л"],["м","н","о","п"] ,["р","с","т","у"],["ф","х","ц","ч"],["ш","щ","ь","ы"],["ъ","э","ю","я"],Bank_Chr_10] , Bank_bEn := [Bank_Chr_1,["A","B","C"],["D","E","F"],["G","H","I"],["J","K","L"] ,["M","N","O"],["P","Q","R","S"],["T","U","V"],["W","X","Y","Z"],Bank_Chr_10] , Bank_sEn := [Bank_Chr_1,["a","b","c"],["d","e","f"],["g","h","i"],["j","k","l"] ,["m","n","o"],["p","q","r","s"],["t","u","v"],["w","x","y","z"],Bank_Chr_10] , Bank_Emb := [Bank_Chr_1,["{","}","<",">","`[","`]"],["+","-","*",":","=","_"] ,["↵","&","'","|","``","~"],["(",")","/","\","^","#","$"] ,["↔","`;","@","№"],["Ctrl+C"],["Ctrl+V"],["Ctrl+A"],["Ctrl+Z"]] , Send_Exception := {"Ctrl+C":"^{vk43}","Ctrl+V":"^{vk56}","Ctrl+A":"^{vk41}","Ctrl+Z":"^{vk5A}" ,"→":"{Raw}" A_Space,"↵":"{Raw}`n","↔":"{Raw}" A_Tab} , Param := {big:[hKey/1.91,0.35,cChr], small:[hKey/1.71,0.22,cChr], num:[hKey/1.35,0.08,cChr] , emb:[hKey/2.0,0.4,cChr], ctrl:[hKey/1.91,0.35,cCtrl]} Loop 10 p_spans .= "" html := " ( " p_spans " DEL EMB RET ×

	

	
	)"

	htmltip := "
	(
	
	

	

	
	)"

	For a, b in ["bRu","sRu","bEn","sEn","Emb","Num"]
		For c, d in Bank_%b%
		{
			Loop % d.maxindex()
				e .= "" d[A_Index] ""
			Ins[b "_" c] := e, e := ""
			Type[b "_" c] := (t := SubStr(b, 1, 1)) = "b" ? (InStr(c, "1") ? "emb" : "big")
				: t = "s" ? (InStr(c, "1") ? "emb" : "small")
				: t = "E" ? (c > 6 ? "ctrl" : "emb") : "num"
		}
	Return