Code: Select all
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
;
; Gesture Recognition
;
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
;---------------------------------------------------------------
; Get cursor position and target information
; Implemented by lukewarm
; ModIfied by Pyonkichi
;---------------------------------------------------------------
MG_GetMousePosInfo()
{
global
MG_TickCount:=A_TickCount
CoordMode,Mouse,Screen
MouseGetPos, MG_X, MG_Y, MG_HWND, MG_HCTL, 3
SendMessage,0x84,0,% MG_Y<<16|MG_X,,ahk_id %MG_HCTL% ; %
If (ErrorLevel == 4294967295) {
MouseGetPos,,,,MG_HCTL, 2
}
IfWinExist,ahk_id %MG_HWND%,,,,{
WinGetClass, MG_WClass
WinGet, MG_PID, PID
WinGet, MG_Exe, ProcessName
WinGetTitle, MG_Title
}
WinGetClass, MG_CClass, ahk_id %MG_HCTL%
If (MG_CClass = "Button") {
MG_CorrectDlgCtrlHandle()
}
}
;---------------------------------------------------------------
; Correct target control handle in a dialog box
; Implemented by Pyonkichi
;---------------------------------------------------------------
MG_CorrectDlgCtrlHandle()
{
global MG_X, MG_Y, MG_HCTL, MG_WClass
rc := DllCall("GlobalAlloc", "UInt",0x40, "UInt",16, "Ptr")
hParent := DllCall("GetParent", "Ptr",MG_HCTL)
hCtrl := MG_HCTL
while (hCtrl)
{
hCtrl := DllCall("FindWindowEx", "Ptr",hParent, "Ptr",hCtrl, "Ptr",0, "Ptr",0, "Ptr")
If (!hCtrl) {
break
}
DllCall("GetWindowRect", "Ptr",hCtrl, "Ptr",rc)
If (DllCall("PtInRect", "Ptr",rc, "Int64",MG_Y<<32|MG_X, "Ptr"))
{
WinGet, dwStyle, Style, ahk_id %hCtrl%
If (dwStyle & 0x10000000) {
MG_HCTL := hCtrl
}
}
}
WinGetClass, MG_CClass, ahk_id %MG_HCTL%
DllCall("GlobalFree", "Ptr",rc)
}
;---------------------------------------------------------------
; Process trigger-down actions
; Implemented by lukewarm
; ModIfied by Pyonkichi
;---------------------------------------------------------------
MG_TriggerDown(name)
{
global
Critical
If (!InStr(MG_CurTriggers,name . "_"))
{
MG_TriggerCount++
MG_CurTriggers=%MG_CurTriggers%%name%_
If (MG_Active && MG_TimedOut)
{
GoSub,MG_%name%_Down
}
else If (MG_TriggerCount==1)
{
; Begin to process gesture at first trigger-down
If (A_TickCount>(MG_LastTime+MG_WaitNext))
{
MG_Gesture = %name%_
MG_1stTrigger := MG_Gesture
}
else
{
MG_Gesture = %MG_Gesture%%name%_
}
MG_GetMousePosInfo()
MG_NowX:=MG_PreX:=MG_TX:=MG_TL:=MG_TR:=MG_X
MG_NowY:=MG_PreY:=MG_TY:=MG_TT:=MG_TB:=MG_Y
MG_PrevTime := A_TickCount
MG_PrevGesture := ""
MG_NaviPrstStr := ""
If (MG_IsDisableObj.()) {
GoSub,MG_%name%_Down
}
else {
MG_StartNavi()
MG_Aborted:=0
MG_Check()
If (MG_Aborted) {
MG_StopNavi(0)
GoSub,MG_%name%_Down
} else {
MG_Recognition(1)
}
}
}
else
{
; Otherwise execute gesture
MG_Recognition()
MG_Gesture=%MG_Gesture%%name%_
MG_Check()
MG_PreX:=MG_NowX, MG_PreY:=MG_NowY, MG_PrevTime:=A_TickCount
}
}
}
;---------------------------------------------------------------
; Process trigger-up actions
; Implemented by lukewarm
; ModIfied by Pyonkichi
;---------------------------------------------------------------
MG_TriggerUp(name)
{
local px, py
Critical
If (!RegExMatch(MG_CurTriggers,"(?<=_|^)" . name . "_")) {
return
}
If (!MG_Aborted) {
MG_Recognition()
}
MG_TriggerCount := (MG_TriggerCount>0) ? (MG_TriggerCount-1) : 0
MG_CurTriggers := RegExReplace(MG_CurTriggers,"(?<=_|^)" . name . "_")
If (!MG_Active || MG_TimedOut)
{
GoSub, MG_%name%_Up
}
else
{
MG_Gesture = %MG_Gesture%_
If (!MG_Aborted) {
MG_Check()
}
If (MG_TriggerCount < 1)
{
If (MG_NaviPrstStr)
{
MG_NaviPrst := 1
SetTimer, MG_NaviPersistTimer, %MG_NaviPersist%
}
MG_StopNavi(0)
If (!MG_Executed)
{
; Emulate trigger If gesture is not executed
CoordMode,Mouse,Screen
SetMouseDelay,-1
; WinGetActiveTitle, WinTitle
; If (WinTitle != "") ; TrayMenu
BlockInput,On
MouseGetPos,px,py
MouseMove,%MG_X%,%MG_Y%,0
GoSub,MG_%name%_Down
MouseMove,%px%,%py%,0
Sleep,1
GoSub,MG_%name%_Up
BlockInput,Off
}
}
}
}
;---------------------------------------------------------------
; Check gesture updates
; Implemented by lukewarm
; ModIfied by Pyonkichi
;---------------------------------------------------------------
MG_Check(g="")
{
local ges,ex,tmp
MG_LastTime:=A_TickCount
If (StrLen(MG_Gesture)>MG_MaxLength)
{
; Gesture is too long
MG_Gesture=%MG_CurTriggers%
}
else
{
If (g) {
ges:=g
} else {
ges:=MG_Gesture
}
If (IsLabel("MG_Gesture_" . ges))
{
If (MG_NaviPersist > 0) {
MG_NaviPrstStr := MG_Gesture
}
IfWinExist,ahk_id %MG_HWND%,,,,{
}
ex := MG_Executed++
Gosub,MG_Gesture_%ges%
If (ex != MG_Executed) {
If (!g) {
MG_Gesture := MG_CurTriggers
}
return 1
}
else {
return (MG_WaitNext != 0)
}
}
}
}
;---------------------------------------------------------------
; Recognition function
; fInit : 1 = Initialize recognition process
; 0 = Recognition only
; Implemented by lukewarm
; ModIfied by Pyonkichi
;---------------------------------------------------------------
MG_Recognition(fInit=0)
{
global
static px, py, plx, ply, d1, d2, orange, next_timeout
local powx, powy
;...........................................................................
; Initialization of recognition process
If (fInit)
{
MG_Active:=1, MG_Aborted:=0, MG_WaitNext:=0, MG_Executed:=0, MG_TimedOut:=0
px:=plx:=MG_X, py:=ply:=MG_Y, d1:="", d2:=""
orange:=MG_ORange%MG_ORangeDefault%, next_timeout:=A_TickCount+MG_Timeout
SetTimer, MG_RecogTimer, %MG_Interval%
}
;...........................................................................
; Recognition process
CoordMode,Mouse,Screen
MouseGetPos,MG_NowX,MG_NowY
If (MG_TriggerCount < 1)
{
; Release all triggers : ???????????
SetTimer, MG_RecogTimer, Off
MG_Active:=0,MG_TriggerCount:=0,MG_CurTriggers:=""
MG_StopNavi(0)
}
else If ((MG_X-MG_NowX)**2+(MG_Y-MG_NowY)**2 < MG_TimeoutThreshold**2)
{
; Tiny movement : ?????
next_timeout:=A_TickCount+MG_Timeout
}
else If (!MG_TimedOut
&& (MG_Aborted || ((A_TickCount>next_timeout) && (MG_Executed==0))))
{
; Time out when moving : ??????????
MG_StopNavi(0)
Critical
SetMouseDelay,-1
MG_TimedOut=1
BlockInput,On
MouseMove,%MG_X%,%MG_Y%,0
Loop,Parse,MG_CurTriggers,_
{
If (A_LoopField) {
GoSub,MG_%A_LoopField%_Down
}
}
MouseMove,%MG_NowX%,%MG_NowY%,0
BlockInput,Off
Critical,Off
}
else If (!MG_TimedOut && ((powx:=(MG_NowX-px)**2)+(powy:=(MG_NowY-py)**2) >= MG_Threshold**2))
{
; Check Normal Movement : ????
If (orange > Abs(0.7853981634-Abs(ATan((MG_NowX-px)/(MG_NowY-py))))) {
d2 := (MG_NowX>px) ? ((MG_NowY>py) ? 3 : 9) : ((MG_NowY>py) ? 1 : 7)
} else {
d2 := (powx>powy) ? ((MG_NowX>px) ? 6 : 4) : ((MG_NowY>py) ? 2 : 8)
}
; Judge Normal Movement
local fChanged := 0
If (d1 != d2) {
fChanged := 1
}
else {
; Check Long Movement
fChanged := ((MG_NowX-plx)**2+(MG_NowY-ply)**2 >= MG_LongThreshold**2)
}
; Judge Overall Movement
If (fChanged)
{
MG_Gesture=%MG_Gesture%%d2%
If (d2 & 1) {
orange := MG_ORange%MG_ORangeB%
} else {
orange := MG_ORange%MG_ORangeA%
}
plx:=px, ply:=py
d1 := MG_Check() ? "" : d2
;MG_PreX:=MG_NowX, MG_PreY:=MG_NowY, MG_PrevTime:=A_TickCount
}
MouseGetPos,px,py
next_timeout:=A_TickCount+MG_Timeout
MG_PreX:=px, MG_PreY:=py, MG_PrevTime:=A_TickCount
}
}
MG_RecogTimer:
MG_Recognition()
return
;---------------------------------------------------------------
; Emulate the mouse button events
; Implemented by Pyonkichi
;---------------------------------------------------------------
MG_SendButton(name, btn, mode="")
{
global
SetMouseDelay,-1
Send, % "{Blind}{" . btn . (mode ? " "mode : "") . "}" ; %
; CoordMode, ToolTip, Screen
; ToolTip, %name%`n%mode%, 1000, 0
}
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
;
; Script Control Functions
;
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
;---------------------------------------------------------------
; Abort the gesture
; Implemented by lukewarm
;---------------------------------------------------------------
MG_Abort()
{
global
MG_Aborted := 1
}
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
;
; Retrieving Information of the Target
;
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
;---------------------------------------------------------------
; Hittest the target ListView
; Implemented by lukewarm
;---------------------------------------------------------------
MG_LvHitTest()
{
global MG_PID, MG_CClass, MG_HCTL, MG_X, MG_Y
If (MG_CClass="SysListView32" || MG_CClass="SysListView321" || MG_CClass="TListView")
{
pt := DllCall("GlobalAlloc", "UInt",0x40, "UInt",8, "Ptr")
NumPut(MG_X, pt+0, 0, "Int")
NumPut(MG_Y, pt+0, 4, "Int")
DllCall("ScreenToClient", "Ptr",MG_HCTL, "Ptr",pt)
hp := DllCall("OpenProcess", "UInt",0x001F0FFF, "UInt",0, "UInt",MG_PID, "Ptr")
size := 8 + A_PtrSize*3
pi := DllCall("VirtualAllocEx", "Ptr",hp, "Ptr",0, "UInt",size, "UInt",0x1000, "UInt",0x4, "Ptr")
DllCall("WriteProcessMemory", "Ptr",hp, "Ptr",pi, "Ptr",pt, "Int",8, "Ptr",0)
SendMessage, 0x1012, 0, %pi%,, ahk_id %MG_HCTL%
DllCall("ReadProcessMemory", "Ptr",hp, "Ptr",pi+8, "PtrP",flag, "UInt",A_PtrSize, "Ptr",0)
DllCall("VirtualFreeEx", "Ptr",hp, "Ptr",pi, "UInt",0, "UInt",0x8000)
DllCall("CloseHandle", Ptr,hp)
DllCall("GlobalFree", "Ptr",pt)
flag := flag & 15
return (flag<4) ? ((flag<2) ? 0 : "ItemIcon") : ((flag<8) ? "ItemLabel" : "ItemState")
}
return 0
}
;---------------------------------------------------------------
; Hittest the target TreeView
; Implemented by lukewarm
;---------------------------------------------------------------
MG_TvHitTest()
{
global MG_PID, MG_CClass, MG_HCTL, MG_X, MG_Y
If (MG_CClass="SysTreeView32"|| MG_CClass="SysListView321" || MG_CClass="TTreeView" || MG_CClass="Shell_TrayWnd" || (MG_CClass="DV2ControlHost") || (MG_CClass="TaskListThuXB1nailWnd") || (MG_CClass="BaseBar") || (MG_CClass="FreeLaunchBarMenu") || (MG_CClass="FreeLaunchBarWindow1") || (MG_CClass="#32768") || (MG_CClass="#32770") || (MG_CClass="#43") || (MG_CClass="OwnerDrawnMenuMsgWin") || (MG_CClass="Windows.UI.Core.CoreWindow") || (MG_CClass="TTaargetDlg") || (MG_CClass="InputIndicatorButton1") || (MG_CClass="TrayButton2") || || (MG_CClass="SB3D_MainWindow") || (MG_CClass="MSTaskListWClass1") || (MG_CClass="ToolbarWindow321") || (MG_CClass="ToolbarWindow322") || (MG_CClass="ToolbarWindow323") || (MG_CClass="ToolbarWindow324") || (MG_CClass="ToolbarWindow327") || (MG_CClass="ToolbarWindow329") || (MG_CClass="ToolbarWindow3210") || (MG_CClass="ToolbarWindow3211") || (MG_CClass="ToolbarWindow3212") || (MG_CClass="ReBarWindow321") || (MG_CClass="SysPager1") || (MG_CClass="wxGLCanvasClass1") || (MG_CClass="wxWindowClassNR") || (MG_CClass="MultitaskingViewFrame") || (MG_CClass="N/A") || (MG_CClass=""))
{
pt := DllCall("GlobalAlloc", "UInt",0x40, "UInt",8, "Ptr")
NumPut(MG_X, pt+0, 0, "Int")
NumPut(MG_Y, pt+0, 4, "Int")
DllCall("ScreenToClient", "Ptr",MG_HCTL, "Ptr",pt)
hp := DllCall("OpenProcess", "UInt",0x001F0FFF, "UInt",0, "UInt",MG_PID, "Ptr")
size := 8 + A_PtrSize*2
pi := DllCall("VirtualAllocEx", "Ptr",hp, "Ptr",0, "UInt",size, "UInt",0x1000, "UInt",0x4, "Ptr")
DllCall("WriteProcessMemory", "Ptr",hp, "Ptr",pi, "Ptr",pt, "Int",8, "Ptr",0)
SendMessage, 0x1111, 0, %pi%,, ahk_id %MG_HCTL%
DllCall("ReadProcessMemory", "Ptr",hp, "Ptr",pi+8, "PtrP",flag, "UInt",A_PtrSize, "Ptr",0)
DllCall("VirtualFreeEx", "Ptr",hp, "Ptr",pi, "UInt",0, "UInt",0x8000)
DllCall("CloseHandle", Ptr,hp)
DllCall("GlobalFree", "Ptr",pt)
flag := flag & 127
return (flag<16) ? ((flag<4) ? ((flag<2) ? 0 : "ItemIcon") : ((flag<8) ? "ItemLabel" : "Indent")) : ((flag<32) ? "Button" : ((flag<64) ? "Right" : "ItemState"))
}
return 0
}
;---------------------------------------------------------------
; Hittest the DirectUIHWND
; Implemented by Pyonkichi
;---------------------------------------------------------------
MG_DuiHitTest()
{
global MG_CClass, MG_X, MG_Y
If (MG_CClass = "DirectUIHWND")
{
uia := ComObjCreate("{ff48dba4-60ef-4201-aa87-54103eef594e}","{30cbe57d-d9d0-452a-ab13-7ac5ac4825ee}")
If (uia)
{
uia := new MGC_UIAInterface(uia)
uia.base.base.__UIA := uia
ele := uia.FromPoint(MG_X, MG_Y)
return (ele.id==50006 || ele.id==50007) ? "ItemIcon" : (ele.id==50004) ? "ItemLabel" : 0
}
}
return 0
}
;---------------------------------------------------------------
; Check whether the cursor is on the item of the ListView and TreeView
; fLvLabel : 0 = Detect only icon of the ListView
; : 1 = Include text label of the ListView
; fTvLabel : 0 = Detect only icon of the TreeView
; : 1 = Include text label of the TreeView
; Implemented by lukewarm
; ModIfied by Pyonkichi
;---------------------------------------------------------------
MG_TreeListHitTest(fLvLabel=1, fTvLabel=1)
{
lvht := MG_LvHitTest()
If (!lvht) {
lvht := MG_DuiHitTest()
}
If (lvht) {
return (fLvLabel ? true : lvht!="ItemLabel")
}
else If (tvht := MG_TvHitTest()) {
If (!fTvLabel && (tvht="ItemLabel")) {
return false
} else {
return InStr(tvht, "Item")
}
}
return false
}
;---------------------------------------------------------------
; Update Gesture Hints
; Implemented by Pyonkichi
;---------------------------------------------------------------
MG_NaviUpdate:
MG_UpdateAdNavi()
return
;---------------------------------------------------------------
; Hints Persistence Timer
; Implemented by Pyonkichi
;---------------------------------------------------------------
MG_NaviPersistTimer:
SetTimer, MG_NaviPersistTimer, Off
MG_StopNavi(1)
return
;---------------------------------------------------------------
; Start Gesture Hints
; Implemented by Pyonkichi
;---------------------------------------------------------------
MG_StartNavi()
{
global
SetTimer, MG_NaviPersistTimer, Off
MG_NaviPrst := 0
GoSub, MG_NaviUpdate
SetTimer, MG_NaviUpdate, %MG_NaviInterval%
}
;---------------------------------------------------------------
; Stop Gesture Hints
; Implemented by Pyonkichi
;---------------------------------------------------------------
MG_StopNavi(fForce=1)
{
global
; ToolTip, MG_StopNavi
SetTimer, MG_NaviUpdate, Off
Gui, MGW_ExNavi:Show, w1 h1 Hide
}
;---------------------------------------------------------------
; Create Gesture Hints Window
; Implemented by lukewarm
; ModIfied by Pyonkichi
;---------------------------------------------------------------
MG_CreateExNavi()
{
global
; ToolTip, MG_CreateExNavi
Gui, MGW_ExNavi:New
Gui, MGW_ExNavi:+HwndMG_ExNaviHwnd -Caption +ToolWindow +AlwaysOnTop +LastFound
MG_AdNavIfG2 := MG_ConvertHex(MG_AdNavIfG)
MG_AdNaviNI2 := MG_ConvertHex(MG_AdNaviNI)
MG_AdNaviBG2 := MG_ConvertHex(MG_AdNaviBG)
MG_AdNaviTransClr := MG_MakeTransColor(MG_AdNaviBG)
MG_AdNaviTransClr2 := MG_ConvertHex(MG_AdNaviTransClr)
Gui, MGW_ExNavi:Color, %MG_AdNaviBG%
local colorBG := MG_AdNaviTransClr
WinSet, TransColor, %colorBG%
}
;---------------------------------------------------------------
; Make Transparent Color
; Implemented by Pyonkichi
;---------------------------------------------------------------
MG_MakeTransColor(color)
{
RegExMatch(color, "([a-zA-Z0-9][a-zA-Z0-9])([a-zA-Z0-9][a-zA-Z0-9])([a-zA-Z0-9][a-zA-Z0-9])", $)
RR := "0x" . $1, RR += (RR>0) ? -1 : 1
GG := "0x" . $2, GG += (GG>0) ? -1 : 1
BB := "0x" . $3, BB += (BB>0) ? -1 : 1
SetFormat, IntegerFast, H
colTrans := (RR<<16) + (GG<<8) + BB
colTrans := RegExReplace(colTrans, "^0x")
SetFormat, IntegerFast, D
len := StrLen(colTrans)
Loop, % (6 - len) ; %
{
colTrans := "0" . colTrans
}
return colTrans
}
;---------------------------------------------------------------
; Convert String Hexadecimal
; Implemented by Pyonkichi
;---------------------------------------------------------------
MG_ConvertHex(hex)
{
return RegExReplace(hex ,"([a-zA-Z0-9][a-zA-Z0-9])([a-zA-Z0-9][a-zA-Z0-9])([a-zA-Z0-9][a-zA-Z0-9])"
,"0x$3$2$1")
}
;---------------------------------------------------------------
; Destroy Gesture Hints Window
; Implemented by lukewarm
; ModIfied by Pyonkichi
;---------------------------------------------------------------
MG_DestroyExNavi()
{
Gui, MGW_ExNavi:Destroy
}
;---------------------------------------------------------------
; Update Arrow Hints
; Implemented by lukewarm
; ModIfied by Pyonkichi
;---------------------------------------------------------------
MG_UpdateExNavi()
{
global
static prevX:=0, prevY:=0
;...........................................................................
; Critical Section
static fCritical := 0
If (fCritical) {
return
}
fCritical := 1
;...........................................................................
; Make Arrows String and Check Gesture Conditions
local szGesture := MG_NaviPrst ? MG_NaviPrstStr : MG_Gesture
; local szArrows := MG_MakeArrowsStr(szGesture)
If (!szArrows)
{
fCritical := 0
return
}
;...........................................................................
; Decide Drawing Position
local winX, winY
If (MG_ExNaviMargin < 0)
{
winX:=MG_X, winY:=MG_Y
}
else
{
CoordMode, Mouse, Screen
MouseGetPos, winX, winY
winX += MG_ExNaviMargin
winY += MG_ExNaviMargin
}
;...........................................................................
; Draw Arrows
If (szArrows != MG_PrevGesture)
{
RegExMatch(szGesture, "(\w+)_", $)
local fgc := (MG_ExNavIfG_%$1% != "") ? MG_ExNaviIdvFG : MG_ExNavIfG2
local bgc := MG_ExNaviIdvBG ? MG_ExNaviIdvBG : MG_ExNaviBG2
local hDC := DllCall("GetWindowDC", "Ptr",MG_ExNaviHwnd, "Ptr")
local hFont := MG_CreateFont("Wingdings", MG_ExNaviSize)
local hFntOld := DllCall("SelectObject", "Ptr",hDC, "Ptr",hFont, "Ptr")
DllCall("SetTextColor","Ptr",hDC, "UInt",fgc)
DllCall("SetBkColor","Ptr",hDC, "UInt",bgc)
DllCall("SelectObject", "Ptr",hDC, "Ptr",hFntOld)
DllCall("DeleteObject", "Ptr",hFont)
DllCall("ReleaseDC", "Ptr",MG_ExNaviHwnd, "Ptr",hDC)
}
;...........................................................................
; Only Move Window
else If (prevX!=winX || prevY!=winY)
{
Gui, MGW_ExNavi:Show, x%winX% y%winY% NA
}
prevX:=winX, prevY:=winY
MG_PrevGesture := szArrows
fCritical := 0
}
;---------------------------------------------------------------
; Update Hint Arrows Type 1
; Implemented by Pyonkichi
;---------------------------------------------------------------
MG_UpdateArrowHints1(hDC, szGesture, szArrows, winX, winY)
{
global
DllCall("SetTextCharacterExtra", "Ptr",hDC, "Int",MG_ExNaviSpacing)
local size
VarSetCapacity(size, 8, 0)
DllCall("GetTextExtentPoint32", "Ptr",hDC, "Str",szArrows, "Int",StrLen(szArrows), "Ptr",&size)
local winW := NumGet(size, 0, "UInt") + MG_ExNaviPadding*2
local winH := NumGet(size, 4, "UInt") + MG_ExNaviPadding*2
If (winW && winH)
{
Gui, MGW_ExNavi:Show, x%winX% y%winY% w%winW% h%winH% NA
DllCall("TextOut", "Ptr",hDC, "Int",MG_ExNaviPadding, "Int",MG_ExNaviPadding, "Str",szArrows, "Int",StrLen(szArrows))
}
}
;---------------------------------------------------------------
; Update Advanced Gesture Hints
; Implemented by Pyonkichi
;---------------------------------------------------------------
MG_UpdateAdNavi()
{
global
static prevX:=0, prevY:=0
;...........................................................................
; Critical Section
static fCritical := 0
If (fCritical) {
return
}
fCritical := 1
;...........................................................................
; Check Gesture Conditions
local szGesture := MG_NaviPrst ? MG_NaviPrstStr : MG_Gesture
If (!szGesture)
{
fCritical := 0
return
}
If (szGesture = MG_1stTrigger)
{
Gui, MGW_ExNavi:Hide
fCritical := 0
return
}
;...........................................................................
; Decide Drawing Position
local winX, winY
CoordMode,Mouse,Screen
MouseGetPos, winX, winY
winX += MG_AdNaviMargin
winY += MG_AdNaviMargin
;...........................................................................
; Draw Gesture Pattern
If (szGesture != MG_PrevGesture)
{
local hDC := DllCall("GetWindowDC", "Ptr",MG_ExNaviHwnd, "Ptr")
MG_hFntBtn := MG_CreateFont(MG_AdNavIfont, MG_AdNaviSize, 700)
MG_hFntDir := MG_CreateFont("Wingdings", MG_AdNaviSize)
MG_hFntAct := MG_CreateFont(MG_AdNavIfont, MG_AdNaviSize)
DllCall("SetBkColor", "Ptr",hDC, "UInt",MG_AdNaviBG2)
MG_UpdateAdNavi1(hDC, winX, winY, szGesture)
DllCall("DeleteObject", "Ptr",MG_hFntBtn)
DllCall("DeleteObject", "Ptr",MG_hFntDir)
DllCall("DeleteObject", "Ptr",MG_hFntAct)
DllCall("ReleaseDC", "Ptr",MG_ExNaviHwnd, "Ptr",hDC)
}
;...........................................................................
; Only Move Window
else If (prevX!=winX || prevY!=winY)
{
local dwStyle
WinGet, dwStyle, Style, ahk_id %MG_ExNaviHwnd%
If (dwStyle & 0x10000000) {
Gui, MGW_ExNavi:Show, x%winX% y%winY% NA
}
}
prevX:=winX, prevY:=winY
MG_PrevGesture := szGesture
fCritical := 0
}
;---------------------------------------------------------------
; Update Advanced Gesture Hints Type 1
; Implemented by Pyonkichi
;---------------------------------------------------------------
MG_UpdateAdNavi1(hDC, winX, winY, szGesture)
{
global
local gesW, gesH
MG_DrawGesture(hDC, 0, 0, szGesture, gesW, gesH, 1)
MG_ActionStr := ""
If (IsLabel("MG_GetAction_" . szGesture . "_")) {
GoSub, MG_GetAction_%szGesture%_
}
local actW:=0, actH:=0
If (MG_ActionStr)
{
MG_ActionStr := " : " . MG_ActionStr
MG_DrawAction(hDC, 0, 0, MG_ActionStr, 1, actW, actH)
}
local winW := gesW + actW + MG_AdNaviPaddingL + MG_AdNaviPaddingR
local winH := (gesH>actH ? gesH : actH) + MG_AdNaviPaddingT + MG_AdNaviPaddingB
If (! winW || !winH) {
return
}
; MG_SetAdNaviPos(winX, winY, winW, winH)
Gui, MGW_ExNavi:Show, x%winX% y%winY% w%winW% h%winH% NA
DllCall("SetTextColor", "Ptr",hDC, "UInt",MG_AdNavIfG2)
MG_DrawGesture(hDC, MG_AdNaviPaddingL, MG_AdNaviPaddingT, szGesture, gesW, gesH)
If (actW) {
MG_DrawAction(hDC, MG_AdNaviPaddingL+gesW, MG_AdNaviPaddingT, MG_ActionStr)
}
}
;---------------------------------------------------------------
; Draw Action String
; Implemented by Pyonkichi
;---------------------------------------------------------------
MG_DrawAction(hDC, ptX, ptY, szAction, fMeasure=0, ByRef strW=0, ByRef strH=0)
{
global MG_hFntAct, MG_AdNaviNI2
hFntOld := DllCall("SelectObject", "Ptr",hDC, "Ptr",MG_hFntAct, "Ptr")
If (fMeasure)
{
VarSetCapacity(size, 8, 0)
DllCall("GetTextExtentPoint32", "Ptr",hDC, "Str",szAction, "Int",StrLen(szAction), "Ptr",&size)
strW := NumGet(size, 0, "UInt")
strH := NumGet(size, 4, "UInt")
}
else
{
DllCall("TextOut", "Ptr",hDC, "Int",ptX, "Int",ptY, "Str",szAction, "Int",StrLen(szAction))
}
DllCall("SelectObject", "Ptr",hDC, "Ptr",hFntOld)
}
;===========================================================================
;
; MouseGestureL.ahk - Common Functions Library
;
; Created by Pyonkichi
;===========================================================================
;------------------------------------------------------------------------
; Create Font
; Implemented by Pyonkichi
;------------------------------------------------------------------------
MG_CreateFont(szFace, nSize, nWeight=0, nQuality=0)
{
return DllCall("CreateFont"
,"Int",-nSize ; nHeight
,"Int",0 ; nWidth
,"Int",0 ; nEscapement
,"Int",0 ; nOrientation
,"Int",nWeight ; nWeight
,"UInt",0 ; fdwItalic
,"UInt",0 ; fdwUnderline
,"UInt",0 ; fdwStrikeOut
,"UInt",(szFace="Wingdings" ? 2 : 1) ; fdwCharset
,"UInt",0 ; fdwOutPrecision
,"UInt",0 ; fdwClipPrecision
,"UInt",nQuality ; fdwQuality
,"UInt",0 ; fdwPitchAndFamily
,"Str",szFace ; pszFaceName
,"Ptr")
}
;------------------------------------------------------------------------
; Draw Gesture Pattern
; Implemented by Pyonkichi
;------------------------------------------------------------------------
MG_DrawGesture(hDC, ptX, ptY, szGesture, ByRef strW=0, ByRef strH=0, fMeasure=0, nGesLen=0)
{
global MG_BtnNames, MG_AdNaviNI2, MG_hFntBtn, MG_hFntDir, MG_AdNaviSize
static DirD=0xEA, DirL=0xE7, DirR=0xE8, DirU=0xE9
static Dir1=0xED, Dir2=0xEA, Dir3=0xEE, Dir4=0xE7, Dir6=0xE8, Dir7=0xEB, Dir8=0xE9, Dir9=0xEC
If (!fMeasure) {
hRgn := DllCall("CreateRectRgn", "Int",ptX, "Int",ptY, "Int",ptX+strW, "Int",ptY+strH, "Ptr")
DllCall("SelectClipRgn", "Ptr",hDC, "Ptr",hRgn)
}
DllCall("SetTextAlign", "Ptr",hDC, "Ptr",24)
hFntOld := DllCall("SelectObject", "Ptr",hDC, "Ptr",MG_hFntBtn, "Ptr")
VarSetCapacity(size, 8, 0)
max:=StrLen(szGesture), pos:=1, preFont:=1, nowX:=ptX, strH:=0, sftBase:=MG_AdNaviSize//6
while (pos <= max)
{
shIft := 0
If (SubStr(szGesture, pos, 1) == "_")
{
newFont := 1
szDraw := "_"
offset := 1
shIft := fDown ? 0 : (sftBase-MG_AdNaviSize)
fDown := 0
}
else
{
fDown := 0
Loop, Parse, MG_BtnNames, _
{
If (A_LoopField && InStr(SubStr(szGesture, pos), A_LoopField) == 1) {
newFont := 1
szDraw := A_LoopField
offset := StrLen(A_LoopField)
fDown := 1
break
}
}
If (!fDown) {
newFont := 2
dir := "Dir" . SubStr(szGesture, pos, 1)
szDraw := Chr(%dir%)
offset := 1
shIft := (dir="DirD"||dir="Dir2") ? sftBase : 0
}
}
If (preFont != newFont) {
preFont := newFont
DllCall("SelectObject", "Ptr",hDC, "Ptr",(newFont==1 ? MG_hFntBtn : MG_hFntDir))
}
If (!fMeasure) {
DllCall("TextOut", "Ptr",hDC, "Int",nowX, "Int",ptY+MG_AdNaviSize+shIft, "Str",szDraw, "Int",StrLen(szDraw))
}
DllCall("GetTextExtentPoint32", "Ptr",hDC, "Str",szDraw, "Int",StrLen(szDraw), "Ptr",&size)
nowX += NumGet(size, 0, "UInt")
h := NumGet(size, 4, "UInt")
If (h > strH) {
strH := h
}
pos += offset
If (pos == nGesLen+1) {
DllCall("SetTextColor", "Ptr",hDC, "UInt",MG_AdNaviNI2)
}
}
strW := nowX - ptX
DllCall("SelectObject", "Ptr",hDC, "Ptr",hFntOld)
DllCall("SetTextAlign", "Ptr",hDC, "Ptr",0)
If (!fMeasure) {
DllCall("SelectClipRgn", "Ptr",hDC, "Ptr",0)
DllCall("DeleteObject", "Ptr",hRgn)
}
}