Plain text
复制到剪贴板
Open code in new window
EnlighterJS 3 Syntax Highlighter
; 一款比较好用的鼠标坐标和按键历史记录工具
; 来源:https://autohotkey.com/boards/viewtopic.php?f=6&t=26059
; If the most recent event is a mouse-move and the mouse moves again,
; enable this to update it instead of adding another mouse-move event.
MERGE_MOVE := true
#NoEnv
#Persistent
#MouseHistory(10)
Gui, +LastFound -DPIScale
WinSet, Transparent, 200
Gui, +ToolWindow +AlwaysOnTop
Gui, Margin, 10, 10
Gui, Font,, Lucida Console
Gui, Add, Text, vMH, . .
GuiControlGet, MH, Pos
GuiControl,, MH ; clear dummy sizing text
gosub Resize
OnMessage(0x201, "WM_LBUTTONDOWN")
return
#MaxThreadsBuffer, On
!WheelUp::
!WheelDown::
#MaxThreadsBuffer, Off
history_size := #MouseHistory() + ((A_ThisHotkey="!WheelUp") ? +1 : -1)
#MouseHistory(history_size>0 ? history_size : 1)
; Delay resize to improve hotkey responsiveness.
SetTimer, Resize, -10
return
Resize:
; Resize label to fit mouse history.
gui_h := MHH*(#MouseHistory())
GuiControl, Move, MH, h%gui_h%
gui_h += 20
Gui, +LastFound
; Determine visibility.
WinGet, style, Style
gui_visible := style & 0x10000000
; Determine current position and height.
WinGetPos, gui_x, gui_y, , gui_h_old
; Use old height to determine if we should reposition, *only when shrinking*.
; This way we can move the GUI somewhere else, and the script won't reposition it.
;if (gui_h_old < gui_h)
; gui_h_old := gui_h
; Determine working area (primary screen size minus taskbar.)
SysGet, wa_, MonitorWorkArea
SysGet, twc_h, 51 ; SM_CYSMCAPTION
SysGet, bdr_h, 8 ; SM_CYFIXEDFRAME
if (!gui_visible)
{
gui_x = 10 ; Initially on the left side.
gui_y := wa_bottom-(gui_h+twc_h+bdr_h*2+10)
}
else
{ ; Move relative to bottom edge when closer to the bottom.
if (gui_y+gui_h//2 > (wa_bottom-wa_top)//2)
gui_y += gui_h_old-(gui_h+twc_h+bdr_h*2)
}
Gui, Show, x%gui_x% y%gui_y% h%gui_h% NA, Mouse History
return
Show:
SetFormat, FloatFast, .2
text =
buf_size := #MouseHistory()
Loop, % buf_size
{
SetFormat, IntegerFast, D
if MouseHistory(A_Index, msg, x, y, mouseData, flags, time, elapsed)
{
SetFormat, IntegerFast, H
msg := (msg + 0) ""
SetFormat, IntegerFast, D
; WM_LBUTTONDOWN/UP/DBLCLK, WM_NC..
if msg in 0x201,0x202,0x203,0xA1,0xA2,0xA3
btn = Left
; WM_RBUTTONDOWN/UP/DBLCLK, WM_NC..
else if msg in 0x204,0x205,0x206,0xA4,0xA5,0xA6
btn = Right
; WM_MBUTTONDOWN/UP/DBLCLK, WM_NC..
else if msg in 0x207,0x208,0x209,0xA7,0xA8,0xA9
btn = Middle
; WM_XBUTTONDOWN/UP/DBLCLK, WM_NC..
else if msg in 0x20B,0x20C,0x20D,0xAB,0xAC,0xAD
btn := (mouseData & 0x10000) ? "X1" : "X2"
; WM_MOUSEWHEEL
else if msg = 0x20A
{
mouseData := mouseData << 32 >> 48
btn := (mouseData < 0) ? "WD" : "WU"
}
; WM_MOUSEHWHEEL
else if msg = 0x20E
{
mouseData := mouseData << 32 >> 48
btn := (mouseData < 0) ? "WL" : "WR"
}
; WM_MOUSEMOVE
else if msg = 0x200
btn =
; ???
else btn := msg
clickCount =
; WM_LBUTTONDBLCLK, WM_NC.., ..R/M/XBUTTONDBLCLK..
if msg in 0x203,0xA3,0x206,0xA6,0x209,0xA9,0x20D,0xAD
{
clickCount := 2
}
; WM_MOUSEWHEEL, WM_MOUSEHWHEEL
else if msg in 0x20A,0x20E
{
clickCount := Abs(mouseData)
if !clickCount
clickCount =
}
; WM_L/R/M/XBUTTONDOWN, WM_NC..
else if msg in 0x201,0x204,0x207,0x20B,0xA1,0xA4,0xA7,0xAB
{
clickCount = Down
}
; WM_L/R/M/XBUTTONUP, WM_NC..
else if msg in 0x202,0x205,0x208,0x20C,0xA2,0xA5,0xA8,0xAC
{
clickCount = Up
}
text .= ((flags & 1) ? "* " : " ")
;. SubStr(msg " ", 1, 6)
. SubStr(btn " ", 1, 8)
. SubStr(" " x, -4) " " SubStr(" " y, -4)
. SubStr(" " clickCount, -5)
. SubStr(" " elapsed/1000.0, -6) "`n"
}
else break
}
GuiControl,, MH, % text
Return
GuiClose:
ExitApp
MouseHistory(N, ByRef msg, ByRef x, ByRef y, ByRef mouseData, ByRef flags, ByRef time, ByRef elapsed=-1)
{
global MouseBuffer
if N is not integer
return false
buf_max := #MouseHistory()
if (N < 1 or N > buf_max)
return false
x := NumGet(MouseBuffer, ofs:=(N-1)*24, "int")
y := NumGet(MouseBuffer, ofs+4, "int")
mouseData := NumGet(MouseBuffer, ofs+8, "uint")
flags := NumGet(MouseBuffer, ofs+12, "uint")
time := NumGet(MouseBuffer, ofs+16, "uint")
msg := NumGet(MouseBuffer, ofs+20, "uint")
elapsed := time - ((time2 := NumGet(MouseBuffer, N*24+16, "uint")) ? time2 : time)
return !!msg
}
#MouseHistory(NewSize="")
{
global MouseBuffer
static MouseHook, MouseHookProc
if NewSize = ; Get current history length.
return (cap:=VarSetCapacity(MouseBuffer)//24)>0 ? cap-1 : 0
if NewSize
{
if !MouseHook
{ ; Register the mouse hook.
MouseHookProc := RegisterCallback("Mouse")
MouseHook := DllCall("SetWindowsHookEx", "int", 14, "ptr", MouseHookProc, "uint", 0, "uint", 0, "ptr")
}
new_cap := (NewSize+1)*24 ; sizeof(MSLLHOOKSTRUCT)=24
cap := VarSetCapacity(MouseBuffer)
if (cap > new_cap)
cap := new_cap
VarSetCapacity(old_buffer, cap)
; Back up previous history.
DllCall("RtlMoveMemory", "ptr", &old_buffer, "ptr", &MouseBuffer, "ptr", cap)
; Set new history length.
VarSetCapacity(MouseBuffer, 0) ; FORCE SHRINK
VarSetCapacity(MouseBuffer, new_cap, 0)
; Restore previous history.
DllCall("RtlMoveMemory", "ptr", &MouseBuffer, "ptr", &old_buffer, "ptr", cap)
; (Remember N+1 mouse events to simplify calculation of the Nth mouse event's elapsed time.)
; Put tick count so the initial mouse event has a meaningful value for "elapsed".
NumPut(A_TickCount, MouseBuffer, 16, "uint")
}
else
{
if MouseHook
{ ; Unregister the mouse hook.
DllCall("UnhookWindowsHookEx", "ptr", MouseHook)
DllCall("GlobalFree", "ptr", MouseHookProc)
MouseHook =
}
; Clear history entirely.
VarSetCapacity(MouseBuffer, 0)
}
}
; Mouse hook callback - records mouse events into MouseBuffer.
Mouse(nCode, wParam, lParam)
{
global MouseBuffer, MERGE_MOVE
Critical
if (buf_max:=#MouseHistory()) > 0
{
if MERGE_MOVE && NumGet(MouseBuffer, 20, "uint") = 0x200
;if MERGE_MOVE && wParam = 0x200 && NumGet(MouseBuffer, 20, "uint") = 0x200
{
; Update the most recent (mouse-move) event.
DllCall("RtlMoveMemory", "ptr", &MouseBuffer, "ptr", lParam, "ptr", 20)
}
else
{
; Push older mouse events to the back.
if (buf_max > 1)
DllCall("RtlMoveMemory", "ptr", &MouseBuffer+24, "ptr", &MouseBuffer, "ptr", buf_max*24)
; Copy current mouse event to the buffer.
DllCall("RtlMoveMemory", "ptr", &MouseBuffer, "ptr", lParam, "ptr", 20)
}
NumPut(wParam, MouseBuffer, 20, "uint") ; Put wParam in place of dwEventInfo.
; "gosub Show" slows down the mouse hook and causes problems, so use a timer.
SetTimer, Show, -10
}
return DllCall("CallNextHookEx", "uint", 0, "int", nCode, "ptr", wParam, "ptr", lParam, "ptr")
}
WM_LBUTTONDOWN(wParam, lParam)
{
global text
StringReplace, Clipboard, text, `n, `r`n, All
}
; 一款比较好用的鼠标坐标和按键历史记录工具 ; 来源:https://autohotkey.com/boards/viewtopic.php?f=6&t=26059 ; If the most recent event is a mouse-move and the mouse moves again, ; enable this to update it instead of adding another mouse-move event. MERGE_MOVE := true #NoEnv #Persistent #MouseHistory(10) Gui, +LastFound -DPIScale WinSet, Transparent, 200 Gui, +ToolWindow +AlwaysOnTop Gui, Margin, 10, 10 Gui, Font,, Lucida Console Gui, Add, Text, vMH, . . GuiControlGet, MH, Pos GuiControl,, MH ; clear dummy sizing text gosub Resize OnMessage(0x201, "WM_LBUTTONDOWN") return #MaxThreadsBuffer, On !WheelUp:: !WheelDown:: #MaxThreadsBuffer, Off history_size := #MouseHistory() + ((A_ThisHotkey="!WheelUp") ? +1 : -1) #MouseHistory(history_size>0 ? history_size : 1) ; Delay resize to improve hotkey responsiveness. SetTimer, Resize, -10 return Resize: ; Resize label to fit mouse history. gui_h := MHH*(#MouseHistory()) GuiControl, Move, MH, h%gui_h% gui_h += 20 Gui, +LastFound ; Determine visibility. WinGet, style, Style gui_visible := style & 0x10000000 ; Determine current position and height. WinGetPos, gui_x, gui_y, , gui_h_old ; Use old height to determine if we should reposition, *only when shrinking*. ; This way we can move the GUI somewhere else, and the script won't reposition it. ;if (gui_h_old < gui_h) ; gui_h_old := gui_h ; Determine working area (primary screen size minus taskbar.) SysGet, wa_, MonitorWorkArea SysGet, twc_h, 51 ; SM_CYSMCAPTION SysGet, bdr_h, 8 ; SM_CYFIXEDFRAME if (!gui_visible) { gui_x = 10 ; Initially on the left side. gui_y := wa_bottom-(gui_h+twc_h+bdr_h*2+10) } else { ; Move relative to bottom edge when closer to the bottom. if (gui_y+gui_h//2 > (wa_bottom-wa_top)//2) gui_y += gui_h_old-(gui_h+twc_h+bdr_h*2) } Gui, Show, x%gui_x% y%gui_y% h%gui_h% NA, Mouse History return Show: SetFormat, FloatFast, .2 text = buf_size := #MouseHistory() Loop, % buf_size { SetFormat, IntegerFast, D if MouseHistory(A_Index, msg, x, y, mouseData, flags, time, elapsed) { SetFormat, IntegerFast, H msg := (msg + 0) "" SetFormat, IntegerFast, D ; WM_LBUTTONDOWN/UP/DBLCLK, WM_NC.. if msg in 0x201,0x202,0x203,0xA1,0xA2,0xA3 btn = Left ; WM_RBUTTONDOWN/UP/DBLCLK, WM_NC.. else if msg in 0x204,0x205,0x206,0xA4,0xA5,0xA6 btn = Right ; WM_MBUTTONDOWN/UP/DBLCLK, WM_NC.. else if msg in 0x207,0x208,0x209,0xA7,0xA8,0xA9 btn = Middle ; WM_XBUTTONDOWN/UP/DBLCLK, WM_NC.. else if msg in 0x20B,0x20C,0x20D,0xAB,0xAC,0xAD btn := (mouseData & 0x10000) ? "X1" : "X2" ; WM_MOUSEWHEEL else if msg = 0x20A { mouseData := mouseData << 32 >> 48 btn := (mouseData < 0) ? "WD" : "WU" } ; WM_MOUSEHWHEEL else if msg = 0x20E { mouseData := mouseData << 32 >> 48 btn := (mouseData < 0) ? "WL" : "WR" } ; WM_MOUSEMOVE else if msg = 0x200 btn = ; ??? else btn := msg clickCount = ; WM_LBUTTONDBLCLK, WM_NC.., ..R/M/XBUTTONDBLCLK.. if msg in 0x203,0xA3,0x206,0xA6,0x209,0xA9,0x20D,0xAD { clickCount := 2 } ; WM_MOUSEWHEEL, WM_MOUSEHWHEEL else if msg in 0x20A,0x20E { clickCount := Abs(mouseData) if !clickCount clickCount = } ; WM_L/R/M/XBUTTONDOWN, WM_NC.. else if msg in 0x201,0x204,0x207,0x20B,0xA1,0xA4,0xA7,0xAB { clickCount = Down } ; WM_L/R/M/XBUTTONUP, WM_NC.. else if msg in 0x202,0x205,0x208,0x20C,0xA2,0xA5,0xA8,0xAC { clickCount = Up } text .= ((flags & 1) ? "* " : " ") ;. SubStr(msg " ", 1, 6) . SubStr(btn " ", 1, 8) . SubStr(" " x, -4) " " SubStr(" " y, -4) . SubStr(" " clickCount, -5) . SubStr(" " elapsed/1000.0, -6) "`n" } else break } GuiControl,, MH, % text Return GuiClose: ExitApp MouseHistory(N, ByRef msg, ByRef x, ByRef y, ByRef mouseData, ByRef flags, ByRef time, ByRef elapsed=-1) { global MouseBuffer if N is not integer return false buf_max := #MouseHistory() if (N < 1 or N > buf_max) return false x := NumGet(MouseBuffer, ofs:=(N-1)*24, "int") y := NumGet(MouseBuffer, ofs+4, "int") mouseData := NumGet(MouseBuffer, ofs+8, "uint") flags := NumGet(MouseBuffer, ofs+12, "uint") time := NumGet(MouseBuffer, ofs+16, "uint") msg := NumGet(MouseBuffer, ofs+20, "uint") elapsed := time - ((time2 := NumGet(MouseBuffer, N*24+16, "uint")) ? time2 : time) return !!msg } #MouseHistory(NewSize="") { global MouseBuffer static MouseHook, MouseHookProc if NewSize = ; Get current history length. return (cap:=VarSetCapacity(MouseBuffer)//24)>0 ? cap-1 : 0 if NewSize { if !MouseHook { ; Register the mouse hook. MouseHookProc := RegisterCallback("Mouse") MouseHook := DllCall("SetWindowsHookEx", "int", 14, "ptr", MouseHookProc, "uint", 0, "uint", 0, "ptr") } new_cap := (NewSize+1)*24 ; sizeof(MSLLHOOKSTRUCT)=24 cap := VarSetCapacity(MouseBuffer) if (cap > new_cap) cap := new_cap VarSetCapacity(old_buffer, cap) ; Back up previous history. DllCall("RtlMoveMemory", "ptr", &old_buffer, "ptr", &MouseBuffer, "ptr", cap) ; Set new history length. VarSetCapacity(MouseBuffer, 0) ; FORCE SHRINK VarSetCapacity(MouseBuffer, new_cap, 0) ; Restore previous history. DllCall("RtlMoveMemory", "ptr", &MouseBuffer, "ptr", &old_buffer, "ptr", cap) ; (Remember N+1 mouse events to simplify calculation of the Nth mouse event's elapsed time.) ; Put tick count so the initial mouse event has a meaningful value for "elapsed". NumPut(A_TickCount, MouseBuffer, 16, "uint") } else { if MouseHook { ; Unregister the mouse hook. DllCall("UnhookWindowsHookEx", "ptr", MouseHook) DllCall("GlobalFree", "ptr", MouseHookProc) MouseHook = } ; Clear history entirely. VarSetCapacity(MouseBuffer, 0) } } ; Mouse hook callback - records mouse events into MouseBuffer. Mouse(nCode, wParam, lParam) { global MouseBuffer, MERGE_MOVE Critical if (buf_max:=#MouseHistory()) > 0 { if MERGE_MOVE && NumGet(MouseBuffer, 20, "uint") = 0x200 ;if MERGE_MOVE && wParam = 0x200 && NumGet(MouseBuffer, 20, "uint") = 0x200 { ; Update the most recent (mouse-move) event. DllCall("RtlMoveMemory", "ptr", &MouseBuffer, "ptr", lParam, "ptr", 20) } else { ; Push older mouse events to the back. if (buf_max > 1) DllCall("RtlMoveMemory", "ptr", &MouseBuffer+24, "ptr", &MouseBuffer, "ptr", buf_max*24) ; Copy current mouse event to the buffer. DllCall("RtlMoveMemory", "ptr", &MouseBuffer, "ptr", lParam, "ptr", 20) } NumPut(wParam, MouseBuffer, 20, "uint") ; Put wParam in place of dwEventInfo. ; "gosub Show" slows down the mouse hook and causes problems, so use a timer. SetTimer, Show, -10 } return DllCall("CallNextHookEx", "uint", 0, "int", nCode, "ptr", wParam, "ptr", lParam, "ptr") } WM_LBUTTONDOWN(wParam, lParam) { global text StringReplace, Clipboard, text, `n, `r`n, All }
; 一款比较好用的鼠标坐标和按键历史记录工具
; 来源:https://autohotkey.com/boards/viewtopic.php?f=6&t=26059

; If the most recent event is a mouse-move and the mouse moves again,
; enable this to update it instead of adding another mouse-move event.
MERGE_MOVE := true

#NoEnv
#Persistent
#MouseHistory(10)

Gui, +LastFound -DPIScale
WinSet, Transparent, 200
Gui, +ToolWindow +AlwaysOnTop
Gui, Margin, 10, 10
Gui, Font,, Lucida Console
Gui, Add, Text, vMH, .                                 .
GuiControlGet, MH, Pos
GuiControl,, MH  ; clear dummy sizing text
gosub Resize
OnMessage(0x201, "WM_LBUTTONDOWN")
return

#MaxThreadsBuffer, On
!WheelUp::
!WheelDown::
#MaxThreadsBuffer, Off
    history_size := #MouseHistory() + ((A_ThisHotkey="!WheelUp") ? +1 : -1)
    #MouseHistory(history_size>0 ? history_size : 1)
    ; Delay resize to improve hotkey responsiveness.
    SetTimer, Resize, -10
return

Resize:
    ; Resize label to fit mouse history.
    gui_h := MHH*(#MouseHistory())
    GuiControl, Move, MH, h%gui_h%
    gui_h += 20

    Gui, +LastFound
    ; Determine visibility.
    WinGet, style, Style
    gui_visible := style & 0x10000000
    
    ; Determine current position and height.
    WinGetPos, gui_x, gui_y, , gui_h_old
    ; Use old height to determine if we should reposition, *only when shrinking*.
    ; This way we can move the GUI somewhere else, and the script won't reposition it.
    ;if (gui_h_old < gui_h)
    ;    gui_h_old := gui_h
    ; Determine working area (primary screen size minus taskbar.)
    SysGet, wa_, MonitorWorkArea

    SysGet, twc_h, 51 ; SM_CYSMCAPTION
    SysGet, bdr_h, 8  ; SM_CYFIXEDFRAME
    if (!gui_visible)
    {
        gui_x = 10 ; Initially on the left side.
        gui_y := wa_bottom-(gui_h+twc_h+bdr_h*2+10)
    }
    else
    {   ; Move relative to bottom edge when closer to the bottom.
        if (gui_y+gui_h//2 > (wa_bottom-wa_top)//2)
            gui_y += gui_h_old-(gui_h+twc_h+bdr_h*2)
    }
    Gui, Show, x%gui_x% y%gui_y% h%gui_h% NA, Mouse History
return

Show:
    SetFormat, FloatFast, .2
    text =
    buf_size := #MouseHistory()
    Loop, % buf_size
    {
        SetFormat, IntegerFast, D
        
        if MouseHistory(A_Index, msg, x, y, mouseData, flags, time, elapsed)
        {
            SetFormat, IntegerFast, H
            msg := (msg + 0) ""
            SetFormat, IntegerFast, D
            
            ; WM_LBUTTONDOWN/UP/DBLCLK, WM_NC..
            if msg in 0x201,0x202,0x203,0xA1,0xA2,0xA3
                btn = Left
            ; WM_RBUTTONDOWN/UP/DBLCLK, WM_NC..
            else if msg in 0x204,0x205,0x206,0xA4,0xA5,0xA6
                btn = Right
            ; WM_MBUTTONDOWN/UP/DBLCLK, WM_NC..
            else if msg in 0x207,0x208,0x209,0xA7,0xA8,0xA9
                btn = Middle
            ; WM_XBUTTONDOWN/UP/DBLCLK, WM_NC..
            else if msg in 0x20B,0x20C,0x20D,0xAB,0xAC,0xAD
                btn := (mouseData & 0x10000) ? "X1" : "X2"
            ; WM_MOUSEWHEEL
            else if msg = 0x20A
            {
                mouseData := mouseData << 32 >> 48
                btn := (mouseData < 0) ? "WD" : "WU"
            }
            ; WM_MOUSEHWHEEL
            else if msg = 0x20E
            {
                mouseData := mouseData << 32 >> 48
                btn := (mouseData < 0) ? "WL" : "WR"
            }
            ; WM_MOUSEMOVE
            else if msg = 0x200
                btn =
            ; ???
            else btn := msg
            
            clickCount =
            
            ; WM_LBUTTONDBLCLK, WM_NC.., ..R/M/XBUTTONDBLCLK..
            if msg in 0x203,0xA3,0x206,0xA6,0x209,0xA9,0x20D,0xAD
            {
                clickCount := 2
            }
            ; WM_MOUSEWHEEL, WM_MOUSEHWHEEL
            else if msg in 0x20A,0x20E
            {
                clickCount := Abs(mouseData)
                if !clickCount
                    clickCount =
            }
            ; WM_L/R/M/XBUTTONDOWN, WM_NC..
            else if msg in 0x201,0x204,0x207,0x20B,0xA1,0xA4,0xA7,0xAB
            {
                clickCount = Down
            }
            ; WM_L/R/M/XBUTTONUP, WM_NC..
            else if msg in 0x202,0x205,0x208,0x20C,0xA2,0xA5,0xA8,0xAC
            {
                clickCount = Up
            }

            text .= ((flags & 1) ? "* " : "  ")
                 ;.  SubStr(msg "      ", 1, 6)
                 .  SubStr(btn "        ", 1, 8)
                 .  SubStr("    " x, -4) "  " SubStr("    " y, -4)
                 .  SubStr("      " clickCount, -5)
                 .  SubStr("      " elapsed/1000.0, -6) "`n"
        }
        else break
    }
    GuiControl,, MH, % text
Return

GuiClose:
ExitApp


MouseHistory(N, ByRef msg, ByRef x, ByRef y, ByRef mouseData, ByRef flags, ByRef time, ByRef elapsed=-1)
{
    global MouseBuffer
    if N is not integer
        return false
    buf_max := #MouseHistory()
    if (N < 1 or N > buf_max)
        return false
    x           := NumGet(MouseBuffer, ofs:=(N-1)*24, "int") 
    y           := NumGet(MouseBuffer, ofs+4, "int")
    mouseData   := NumGet(MouseBuffer, ofs+8, "uint")
    flags       := NumGet(MouseBuffer, ofs+12, "uint")
    time        := NumGet(MouseBuffer, ofs+16, "uint")
    msg         := NumGet(MouseBuffer, ofs+20, "uint")
    elapsed := time - ((time2 := NumGet(MouseBuffer, N*24+16, "uint")) ? time2 : time)
    return !!msg
}

#MouseHistory(NewSize="")
{
    global MouseBuffer
    static MouseHook, MouseHookProc

    if NewSize =    ; Get current history length.
        return (cap:=VarSetCapacity(MouseBuffer)//24)>0 ? cap-1 : 0

    if NewSize
    {
        if !MouseHook
        {   ; Register the mouse hook.
            MouseHookProc := RegisterCallback("Mouse")
            MouseHook := DllCall("SetWindowsHookEx", "int", 14, "ptr", MouseHookProc, "uint", 0, "uint", 0, "ptr")
        }
        
        new_cap := (NewSize+1)*24 ; sizeof(MSLLHOOKSTRUCT)=24
        cap := VarSetCapacity(MouseBuffer)
        if (cap > new_cap)
            cap := new_cap
        VarSetCapacity(old_buffer, cap)
        ; Back up previous history.
        DllCall("RtlMoveMemory", "ptr", &old_buffer, "ptr", &MouseBuffer, "ptr", cap)
        
        ; Set new history length.
        VarSetCapacity(MouseBuffer, 0) ; FORCE SHRINK
        VarSetCapacity(MouseBuffer, new_cap, 0)
        
        ; Restore previous history.
        DllCall("RtlMoveMemory", "ptr", &MouseBuffer, "ptr", &old_buffer, "ptr", cap)
        
        ; (Remember N+1 mouse events to simplify calculation of the Nth mouse event's elapsed time.)
        ; Put tick count so the initial mouse event has a meaningful value for "elapsed".
        NumPut(A_TickCount, MouseBuffer, 16, "uint")
    }
    else
    {
        if MouseHook
        {   ; Unregister the mouse hook.
            DllCall("UnhookWindowsHookEx", "ptr", MouseHook)
            DllCall("GlobalFree", "ptr", MouseHookProc)
            MouseHook =
        }
        ; Clear history entirely.
        VarSetCapacity(MouseBuffer, 0)
    }
}

; Mouse hook callback - records mouse events into MouseBuffer.
Mouse(nCode, wParam, lParam)
{
    global MouseBuffer, MERGE_MOVE
    Critical
    if (buf_max:=#MouseHistory()) > 0
    {
        if MERGE_MOVE && NumGet(MouseBuffer, 20, "uint") = 0x200
        ;if MERGE_MOVE && wParam = 0x200 && NumGet(MouseBuffer, 20, "uint") = 0x200
        {
            ; Update the most recent (mouse-move) event.
            DllCall("RtlMoveMemory", "ptr", &MouseBuffer, "ptr", lParam, "ptr", 20)
        }
        else
        {
            ; Push older mouse events to the back.
            if (buf_max > 1)
                DllCall("RtlMoveMemory", "ptr", &MouseBuffer+24, "ptr", &MouseBuffer, "ptr", buf_max*24)
            ; Copy current mouse event to the buffer.
            DllCall("RtlMoveMemory", "ptr", &MouseBuffer, "ptr", lParam, "ptr", 20)
        }
        NumPut(wParam, MouseBuffer, 20, "uint") ; Put wParam in place of dwEventInfo.
        ; "gosub Show" slows down the mouse hook and causes problems, so use a timer.        
        SetTimer, Show, -10
    }
    return DllCall("CallNextHookEx", "uint", 0, "int", nCode, "ptr", wParam, "ptr", lParam, "ptr")
}

WM_LBUTTONDOWN(wParam, lParam)
{
    global text
    StringReplace, Clipboard, text, `n, `r`n, All
}

 

声明:站内资源为整理优化好的代码上传分享与学习研究,如果是开源代码基本都会标明出处,方便大家扩展学习路径。请不要恶意搬运,破坏站长辛苦整理维护的劳动成果。本站为爱好者分享站点,所有内容不作为商业行为。如若本站上传内容侵犯了原著者的合法权益,请联系我们进行删除下架。