Guest User

DragToScroll(Modified).ahk

a guest
Apr 6th, 2016
150
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ; Note: This is not the original code of DragToScroll.ahk
  2. ;   The hIconDragging data has been modified
  3.  
  4. /*
  5. DragToScroll.ahk
  6. http://www.autohotkey.com/forum/viewtopic.php?t=59726
  7.  
  8. Scroll any active window by clicking and dragging with the right mouse button.
  9. Should not interfere with normal right clicking.
  10. See the discussion link above for more information.
  11.  
  12. This script has one dependency, on Tuncay's ini lib, found at:
  13. http://www.autohotkey.com/forum/viewtopic.php?t=46226
  14.  
  15. */
  16.  
  17. #SingleInstance Force
  18. #Persistent
  19. #NoEnv
  20. #NoTrayIcon
  21. #Include %A_ScriptDir%\ini.ahk
  22. GoSub, Init
  23. Return
  24.  
  25. ApplySettings:
  26. ; Settings
  27. ;--------------------------------
  28.  
  29. ; Global toggle. Should generally always be false
  30. Setting("ScrollDisabled", false)
  31.  
  32. ; The chosen hotkey button
  33. ; Should work with pretty much any button, though
  34. ; mouse or KB special keys (ctrl, alt, etc) are preferred.
  35. Setting("Button", "RButton")                
  36.  
  37. ; Delay time before drag starts
  38. ; You must click and release "Button" before this time;
  39. ; Increase if you are having trouble getting "normal behavior"
  40. Setting("DragDelay", 150)                     ; in ms.
  41.  
  42. ; How often to poll for mouse movement & drag
  43. ; The major time unit for this script, everything happens on this
  44. ; schedule. Affects script responsiveness, scroll speed, etc.
  45. Setting("PollFrequency", 20)                  ; in ms
  46.  
  47. ; Speed
  48. ; Affects the overall speed of scrolling before acceleration
  49. ; Speed is "normalized" to 1.0 as a default
  50. Setting("DragThreshold", 0)                   ; in pixels
  51. Setting("SpeedX", 1.0)                        
  52. Setting("SpeedY", 1.0)                        
  53.  
  54. ; MovementCheck
  55. ; if enabled, this check will abort dragging
  56. ; if you have not moved the mouse over MovementThreshold
  57. ; within the first MovementCheckDelay ms
  58. ; This is used for compatibility with other button-hold actions
  59. Setting("UseMovementCheck", false)
  60. Setting("MovementCheckDelay", 200)            ; in ms
  61. Setting("MovementThreshold", 0)               ; in px
  62.  
  63. ; scroll method
  64. ; choose one of: mWheelKey, mWheelMessage, mScrollMessage
  65. ; WheelMessage & WheelKey are preferred; your results may vary
  66. Setting("ScrollMethodX", mScrollMessage)
  67. Setting("ScrollMethodY", mWheelMessage)
  68.  
  69. ; invert drag
  70. ; by default, you "drag" the document; moving up drags the document up,
  71. ; showing more of the document below. This behavior is the inverse of
  72. ; scrolling up, where you see more of the document above.
  73. ; The invert flag switches the drag to the "scroll" behavior
  74. Setting("InvertDrag", false)
  75.  
  76. ; Edge Scrolling
  77. ; allows you to hover over a window edge
  78. ; to continue scrolling, at a fixed rate
  79. Setting("UseEdgeScrolling", true)
  80. Setting("EdgeScrollingThreshold", 15)         ; in px, distance from window edge
  81. Setting("EdgeScrollSpeed", 2.0)               ; in 'speed'; 1.0 is about 5px/sec drag
  82.  
  83. ; Targeting
  84. ; if Confine is enabled, drag will be immediately halted
  85. ; if the mouse leaves the target window or control
  86. ;
  87. ; it is advisable to not use BOTH confine and EdgeScrolling
  88. ; in that case, edge scrolling will only work if you
  89. ; never leave the bounds of the window edge
  90. Setting("UseControlTargeting", true)
  91. Setting("ConfineToWindow", false)
  92. Setting("ConfineToControl", false)
  93.  
  94.  
  95. ; Acceleration & momentum
  96. Setting("UseAccelerationX", false)
  97. Setting("UseAccelerationY", true)
  98. Setting("MomentumThreshold", 0.7)             ; in 'speed'. Minimum speed to trigger momentum. 1 is always
  99. Setting("MomentumStopSpeed", 0.25)            ; in 'speed'. Scrolling is stopped when momentum slows to this value
  100. Setting("MomentumInertia", .93)               ; (0 < VALUE < 1) Describes how fast the scroll momentum dampens
  101. Setting("UseScrollMomentum", true)
  102.  
  103. ; Acceleration function
  104. ; - modify very carefully!!
  105. ; - default is a pretty modest curve
  106. ;
  107.  
  108. ; Based on the initial speed "arg", accelerate and return the updated value
  109. ; Think of this function as a graph of drag-speed v.s. scroll-speed.
  110. ;
  111. Accelerate(arg)
  112. {
  113.   return .006 * arg **3 + arg
  114. }
  115.  
  116. ; double-click checking
  117. ;
  118. ; If enabled, a custom action can be performed a double-click is detected.
  119. ; Simply set UseDoubleClickCheck := true
  120. ; Define ButtonDoubleClick (below) to do anything you want
  121. Setting("DoubleClickThreshold", DllCall("GetDoubleClickTime"))
  122. Setting("UseDoubleClickCheck", true)
  123.  
  124. ; Gesture checking
  125. ;
  126. ; If enabled, simple gestures are detected, (only supports flick UDLR)
  127. ; and gesture events are called for custom actions,
  128. ; rather than dragging with momentum.
  129. Setting("UseGestureCheck", true)
  130. Setting("GestureThreshold", 30)
  131. Setting("GesturePageSize", 15)
  132. Setting("GestureBrowserNames", "chrome.exe,firefox.exe,iexplore.exe")
  133.  
  134.  
  135. ; Server settings
  136. ; if enabled, the script automatically checks for updates at startup
  137. Setting("UseUpdateCheck", true)
  138.  
  139. ; Change Mouse Cursor
  140. ; If enabled, mouse cursor is set to the DtS hand icon during a drag
  141. Setting("ChangeMouseCursor", true)
  142.  
  143. Return
  144.  
  145.  
  146. ; User-Customizable Handlers
  147. ;--------------------------------
  148.  
  149. ; double-click handler
  150. ; this label is called by DoubleClickCheck
  151. ;
  152. ButtonDoubleClick:
  153.  ; change this to whatever you want to happen at Button double-click
  154.   ; default behavior below toggles "slow mode"
  155.  
  156.   ; close the menu that probably popped up  
  157.   ; the extra "menu" popup is unavoidable.
  158.   ; You may however attempt to close it automatically
  159.   ; this may yield unintended results, sending a random {esc}
  160.   Sleep 200
  161.   Send {Esc}
  162.  
  163.   slowSpeed := .5
  164.   bSlowMode := !bSlowMode
  165.   Tooltip((bSlowMode ? "Slow" : "Fast") . " Mode")
  166.  
  167.   if (bSlowMode)
  168.   {
  169.     SpeedY *= slowSpeed
  170.     SpeedX *= slowSpeed
  171.   }
  172.   else
  173.   {
  174.     SpeedY /= slowSpeed
  175.     SpeedX /= slowSpeed
  176.   }
  177. Return
  178.  
  179. ; Handlers for gesture actions
  180. ; The Up/Down gestures will scroll the page
  181. ;
  182. GestureU:
  183.  if (WinProcessName = "AcroRd32.exe")
  184.     Send, ^{PgDn}
  185.   else if (Get("ScrollMethodY") = mWheelMessage)
  186.     Loop, % GesturePageSize
  187.       Scroll(-1 * (GesturePageSize-A_Index))
  188.   else
  189.     Send, {PgDn}
  190. Return
  191.  
  192. GestureD:
  193.  if (WinProcessName = "AcroRd32.exe")
  194.     Send, ^{PgUp}
  195.   else if (Get("ScrollMethodY") = mWheelMessage)
  196.     Loop, % GesturePageSize
  197.       Scroll((GesturePageSize-A_Index))
  198.   else
  199.     Send, {PgUp}
  200. Return
  201.  
  202. GestureL:
  203.  if WinProcessName in %GestureBrowserNames%
  204.   {
  205.     ToolTip("Back", 1)
  206.     Send {Browser_Back}
  207.   }
  208.   else
  209.     Send {Home}
  210. Return
  211.  
  212. GestureR:
  213.  if WinProcessName in %GestureBrowserNames%
  214.   {
  215.     ToolTip("Forward", 1)
  216.     Send {Browser_Forward}
  217.   }
  218.   else
  219.     Send {End}
  220. Return
  221.  
  222.  
  223. ;--------------------------------
  224. ;--------------------------------
  225. ;--------------------------------
  226. ; END OF SETTINGS
  227. ; MODIFY BELOW CAREFULLY
  228. ;--------------------------------
  229. ;--------------------------------
  230. ;--------------------------------
  231.  
  232. ; Init
  233. ;--------------------------------
  234. Init:
  235.  CoordMode, Mouse, Screen
  236.   Gosub, Constants
  237.   Gosub, Reset
  238.   Gosub, LoadLocalSettings
  239.  
  240.   ; initialize non-setting & non-reset vars
  241.   ;ScrollDisabled := false
  242.   DragStatus := DS_NEW
  243.   TimeOfLastButtonDown := 0
  244.   TimeOf2ndLastButtonDown:= 0
  245.   TimeOfLastButtonUp := 0
  246.  
  247.   ; Initialize menus & Hotkeys
  248.   Gosub, MenuInit
  249.  
  250.   ; Initialize icons
  251.   Menu, Tray, Icon
  252.   GoSub, TrayIconInit
  253.   GoSub, UpdateTrayIcon
  254.   GoSub, LoadServerSettings
  255.  
  256. Return
  257.  
  258. ; Constants
  259. ;--------------------------------
  260. Constants:
  261.  VERSION = 2.4
  262.   DEBUG = 0
  263.   WM_HSCROLL = 0x114
  264.   WM_VSCROLL = 0x115
  265.   WM_MOUSEWHEEL = 0x20A
  266.   WM_MOUSEHWHEEL = 0x20E
  267.   WHEEL_DELTA = 120
  268.   SB_LINEDOWN = 1
  269.   SB_LINEUP = 0
  270.   SB_LINELEFT = 0
  271.   SB_LINERIGHT = 1
  272.   X_ADJUST = .2     ; constant. normalizes user setting Speed to 1.0
  273.   Y_ADJUST = .2     ; constant. normalizes user setting Speed to 1.0
  274.   ;DragStatus
  275.   DS_NEW = 0        ; click has taken place, no action taken yet
  276.   DS_DRAGGING = 1   ; handler has picked up the click, suppressed normal behavior, and started a drag
  277.   DS_HANDLED = 2    ; click is handled; either finished dragging, normal behavior, or double-clicked
  278.   DS_HOLDING = 3    ; drag has been skipped, user is holding down button
  279.   DS_MOMENTUM = 4   ; drag is finished, in the momentum phase
  280.   INI_GENERAL := "General"
  281.   INI_EXCLUDE = ServerSettings
  282.   ; scroll method
  283.   mWheelKey := "WheelKey"              ; simulate mousewheel
  284.   mWheelMessage := "WheelMessage"      ; send WHEEL messages
  285.   mScrollMessage := "ScrollMessage"    ; send SCROLL messages
  286.   URL_SERVERSETTINGS := "http://dragtoscroll.dreamhosters.com/ServerSettings.ini"
  287.   URL_DISCUSSION := "http://www.autohotkey.com/forum/viewtopic.php?t=59726"
  288. Return
  289.  
  290.  
  291. ; Cleans up after each drag.
  292. ; Ensures there are no false results from info about the previous drag
  293. ;
  294. Reset:
  295.  OldY=
  296.   OldX=
  297.   NewX=
  298.   NewY=
  299.   DiffX=
  300.   DiffY=
  301.   DiffXSpeed=
  302.   DiffYSpeed=
  303.   OriginalX=
  304.   OriginalY=
  305.   CtrlClass=
  306.   WinClass=
  307.   WinProcessName=
  308.   WinHwnd=
  309.   CtrlHwnd=
  310.   NewWinHwnd=
  311.   NewCtrlHwnd=
  312.   Target=
  313. Return
  314.  
  315.  
  316. ; Implementation
  317. ;--------------------------------
  318.  
  319. ; Hotkey Handler for button down
  320. ;
  321. ButtonDown:
  322. Critical
  323. ; Critical forces a hotkey handler thread to be attended to handling any others.
  324. ; If not, a rapid click could cause the Button-Up event to be processed
  325. ; before Button-Down, thanks to AHK's pseudo-multithreaded handling of hotkeys.
  326. ;
  327. ; Thanks to 'Guest' for an update to these hotkey routines.
  328. ; This update further cleans up, bigfixes, and simplifies the updates.
  329.  
  330.    ; Initialize DragStatus, indicating a new click
  331.    DragStatus := DS_NEW
  332.    GoSub, Reset
  333.  
  334.    ; Keep track of the last two click times.
  335.    ; This allows us to check for double clicks.
  336.    ;
  337.    ; Move the previously recorded time out, for the latest button press event.
  338.    ; Record the current time at the last click
  339.    ; The stack has only 2 spaces; older values are discarded.
  340.    TimeOf2ndLastButtonDown := TimeOfLastButtonDown
  341.    TimeOfLastButtonDown := A_TickCount
  342.  
  343.     ; Capture the original position mouse position
  344.     ; Window and Control Hwnds being hovered over
  345.     ; for use w/ "Constrain" mode & messaging
  346.     ; Get class names, and process name for per-app settings
  347.     MouseGetPos, OriginalX, OriginalY, WinHwnd, CtrlHwnd, 3
  348.     MouseGetPos, ,,, CtrlClass, 1
  349.     WinGetClass, WinClass, ahk_id %WinHwnd%
  350.     WinGet, WinProcessName, ProcessName, ahk_id %WinHwnd%
  351.     WinGet, WinProcessID, PID, ahk_id %WinHwnd%
  352.     WinProcessPath := GetModuleFileNameEx(WinProcessID)
  353.  
  354.     ; Figure out the target
  355.     if (UseControlTargeting && CtrlHwnd)
  356.       Target := "Ahk_ID " . CtrlHwnd
  357.     else if (WinHwnd)
  358.       Target := "Ahk_ID " . WinHwnd
  359.     else
  360.       Target := ""
  361.    
  362.     ;ToolTip("Target: " . Target . "    ID-WC:" . WinHwnd . "/" . CtrlHwnd . "     X/Y:" . OriginalX . "/" . OriginalY . "     Class-WC:" . WinClass . "/" CtrlClass . "     Process:" . WinProcessPath)
  363.    
  364.     ; if we're using the WheelKey method for this window,
  365.     ; activate the window, so that the wheel key messages get picked up
  366.     if (Get("ScrollMethodY") = mWheelKey && !WinActive("ahk_id " . WinHwnd))
  367.       WinActivate, ahk_id %WinHwnd%  
  368.    
  369.    ; Optionally start a timer to see if
  370.    ; user is holding but not moving the mouse
  371.    if (Get("UseMovementCheck"))
  372.      SetTimer, MovementCheck, % -1 * Abs(MovementCheckDelay)
  373.  
  374.    if (!Get("ScrollDisabled"))
  375.    {
  376.      ; if scrolling is enabled,
  377.      ; schedule the drag to start after the delay.
  378.      ; specifying a negative interval forces the timer to run once
  379.      SetTimer, DragStart, % -1 * Abs(DragDelay)
  380.    }
  381.    else
  382.      GoSub, HoldStart
  383. Return
  384.  
  385. ; Hotkey Handler for button up
  386. ;
  387. ButtonUp:
  388.  
  389.   ; Check for a double-click
  390.   ; DoubleClickCheck may mark DragStatus as HANDLED
  391.   if (UseDoubleClickCheck)
  392.     GoSub CheckDoubleClick
  393.  
  394.   ; abort any pending checks to click/hold mouse
  395.   ; and release any holds already started.
  396.   SetTimer, MovementCheck, Off
  397.   if (DragStatus == DS_HOLDING && GetKeyState(Button))
  398.       GoSub, HoldStop
  399.  
  400.   ; If status is still NEW (not already dragging, or otherwise handled),
  401.   ; then the user has released before the drag threshold.
  402.   ; Check if the user has performed a gesture.
  403.   if (DragStatus == DS_NEW && UseGestureCheck)
  404.     GoSub, GestureCheck
  405.    
  406.   ; If status is STILL NEW (not a gesture either)
  407.   ; then user has quick press-released, without moving.
  408.   ; Skip dragging, and treat like a normal click.
  409.   if (DragStatus == DS_NEW)
  410.     GoSub, DragSkip
  411.  
  412.   ; check for and apply momentum
  413.   if (DragStatus == DS_DRAGGING)
  414.     GoSub, DragMomentum
  415.  
  416.   ; Always stop the drag.
  417.   ; This marks the status as HANDLED,
  418.   ; and cleans up any drag that may have started.
  419.   GoSub, DragStop
  420. Return
  421.  
  422. DisabledButtonDown:
  423.  Send, {%Button% Down}
  424. Return
  425.  
  426. DisabledButtonUp:
  427.  Send, {%Button% Up}
  428. Return
  429.  
  430. ; Handler for dragging
  431. ; Checking to see if scrolling should take place
  432. ; for both horizontal and vertical scrolling.
  433. ;
  434. ; This handler repeatedly calls itself to continue
  435. ; the drag once it has been started. Dragging will continue
  436. ; until stopped by calling DragStop, halting the timmer.
  437. ;
  438. DragStart:
  439.  ; double check that the click wasn't already handled
  440.   if (DragStatus == DS_HANDLED)
  441.      return
  442.  
  443.   ; schedule the next run of this handler
  444.   SetTimer, DragStart, % -1 * Abs(PollFrequency)
  445.  
  446.   ; if status is still NEW
  447.   ; user is starting to drag
  448.   ; initialize scrolling
  449.   if (DragStatus == DS_NEW)
  450.   {
  451.     ; Update the status, we're dragging now
  452.     DragStatus := DS_DRAGGING
  453.    
  454.     ; Update the cursor & icon
  455.     SetTrayIcon(hIconDragging)
  456.     if (ChangeMouseCursor)
  457.       SetSystemCursor(hIconDragging)
  458.  
  459.     ; set up for next pass
  460.     ; to find the difference (New - Old)
  461.     OldX := OriginalX
  462.     OldY := OriginalY
  463.   }
  464.   Else
  465.   {
  466.     ; DragStatus is now DRAGGING
  467.     ; get the new mouse position and new hovering window
  468.     MouseGetPos, NewX, NewY, NewWinHwnd, NewCtrlHwnd, 3
  469.  
  470.     ;ToolTip % "@(" . NewX . "X , " . NewY . "Y) ctrl_" . CtrlClass . "   win_" . WinClass . "     " . WinProcessName
  471.  
  472.     ; If the old and new HWNDs do not match,
  473.     ; We have moved out of the original window.
  474.     ; If "Constrain" mode is on, stop scrolling.
  475.     if (ConfineToControl && CtrlHwnd != NewCtrlHwnd)
  476.       GoSub DragStop
  477.     if (ConfineToWindow && WinHwnd != NewWinHwnd)
  478.       GoSub DragStop
  479.  
  480.  
  481.     ; Calculate/Scroll - X
  482.     ; Find the absolute difference in X values
  483.     ; i.e. the amount the mouse moved in _this iteration_ of the DragStart handler
  484.     ; If the distance the mouse moved is over the threshold,
  485.     ; then scroll the window & update the coords for the next pass
  486.     DiffX := NewX - OldX
  487.     if (abs(DiffX) > DragThreshold)
  488.     {
  489.       Scroll(DiffX, true)
  490.       if (DragThreshold > 0)
  491.         OldX := NewX
  492.     }
  493.  
  494.     ; Calculate/Scroll  - Y
  495.     ; SAME AS X
  496.     DiffY := NewY - OldY
  497.     if (abs(DiffY) > DragThreshold)
  498.     {
  499.       Scroll(DiffY)
  500.       if (DragThreshold > 0)
  501.         OldY := NewY
  502.     }
  503.  
  504.     ; Check for window edge scrolling
  505.     GoSub CheckEdgeScrolling
  506.  
  507.     ; a threshold of 0 means we update coords
  508.     ; and attempt to drag every iteration.
  509.     ; whereas with a positive non-zero threshold,
  510.     ; coords are updated only when threshold crossing (above)
  511.     if (DragThreshold <= 0)
  512.     {
  513.       OldX := NewX
  514.       OldY := NewY
  515.     }
  516.   }
  517. Return
  518.  
  519. ; Handler for stopping and cleaning up after a drag is started
  520. ; We should always call this after every click is handled
  521. ;
  522. DragStop:
  523.  ; stop drag timer immediately
  524.   SetTimer, DragStart, Off
  525.  
  526.   ; finish drag
  527.   DragStatus := DS_HANDLED
  528.  
  529.   ; update icons & cursor
  530.   GoSub UpdateTrayIcon
  531.   if (ChangeMouseCursor)
  532.     RestoreSystemCursor()
  533. Return
  534.  
  535.  
  536. ; Handler for skipping a drag
  537. ; This just passes the mouse click.
  538. ;
  539. DragSkip:
  540.     DragStatus := DS_HANDLED
  541.      Send {%Button%}
  542. Return
  543.  
  544. ; Entering the HOLDING state
  545. HoldStart:
  546.  ; abort any pending drag, update status, start holding
  547.   SetTimer, DragStart, Off
  548.   DragStatus := DS_HOLDING
  549.   Send, {%Button% Down}
  550. Return
  551.  
  552. ; Exiting the HOLDING state.
  553. ; Should probably mark DragStatus as handled
  554. HoldStop:
  555.  DragStatus := DS_HANDLED
  556.   Send {%Button% Up}
  557.   GoSub UpdateTrayIcon
  558. Return
  559.  
  560. ; This handler allows a click-hold to abort dragging,
  561. ; if the mouse has not moved beyond a threshold
  562. MovementCheck:
  563.  Critical
  564.   ; Calculate the distance moved, pythagorean thm
  565.   MouseGetPos, MoveX, MoveY
  566.   MoveDist := sqrt((OriginalX - MoveX)**2 + (OriginalY - MoveY)**2)
  567.  
  568.   ; if we havent moved past the threshold start hold
  569.   if (MoveDist <= MovementThreshold)
  570.     GoSub, HoldStart
  571.   Critical, Off
  572. Return
  573.  
  574. ; Handler to apply momentum at DragStop
  575. ; This code continues to scroll the window if
  576. ; a "fling" action is detected, where the user drags
  577. ; and releases the drag while moving at a minimum speed
  578. ;
  579. DragMomentum:
  580.  
  581.   ; Check for abort cases
  582.   ;  momentum disabled
  583.   ;  below threshold to use momentum
  584.   if (abs(DiffYSpeed) <= MomentumThreshold)
  585.     return
  586.   if (!Get("UseScrollMomentum"))
  587.     return
  588.  
  589.   ; passed checks, now using momentum
  590.   DragStatus := DS_MOMENTUM
  591.  
  592.   ; Immediately stop dragging,
  593.   ; momentum should not respond to mouse movement
  594.   SetTimer, DragStart, Off
  595.  
  596.   ; capture the speed when mouse released
  597.   ; we want to gradually slow to scroll speed
  598.   ; down to a stop from this initial speed
  599.   mSpeed := DiffYSpeed * (Get("InvertDrag")?-1:1)
  600.  
  601.   Loop
  602.   {
  603.     ; stop case: status changed, indicating a user abort
  604.     ; another hotkey thread has picked up execution from here
  605.     ; simply exit, do not reset.
  606.     if (DragStatus != DS_MOMENTUM)
  607.       Exit
  608.    
  609.     ; stop case: momentum slowed to minum speed
  610.     if (abs(mSpeed) <= MomentumStopSpeed)
  611.       return
  612.  
  613.     ; for each iteration in the loop,
  614.     ; reduce the momentum speed linearly
  615.     ; scroll the window
  616.     mSpeed *= MomentumInertia
  617.     Scroll(mSpeed, false, "speed")
  618.  
  619.     Sleep % Abs(PollFrequency)
  620.   }
  621. Return
  622.  
  623. ; Implementation of Scroll
  624. ;
  625. ; Summary:
  626. ;  This is the business end, it simulates input to scroll the window.
  627. ;  This handler is called when the mouse cursor has been click-dragged
  628. ;  past the drag threshold.
  629. ;
  630. ;  Arguments:
  631. ;  * arg
  632. ;   - measured in Pixels, can just pass mouse coords difference
  633. ;   - the sign determins direction: positive is down or right
  634. ;   - the magnitude determines speed
  635. ;  * horizontal
  636. ;   - Any non-zero/null/empty value
  637. ;     will scroll horizontally instead of vertically
  638. ;  * format
  639. ;   - Used in some rare cases where passing in 'speed' instead of px
  640. ;
  641. ;  The goal is to take the amount dragged (arg), and convert it into
  642. ;  an appropriate amount of scroll in the window (Factor).
  643. ;  First we scale the drag-ammount, according to speed and acceleration
  644. ;  to the final scroll amount.
  645. ;  Then we scroll the window, according to the method selected.
  646. ;
  647. Scroll(arg, horizontal="", format="px")
  648. {
  649.   global
  650.   local Direction, Factor, Method, wparam
  651.  
  652.   ; get the speed and direction from arg arg
  653.   Direction := ( arg < 0 ? -1 : 1 ) * ( Get("InvertDrag") ? -1 : 1 )
  654.   Factor := abs( arg )
  655.  
  656.   ; Special "hidden" setting, for edge cases (visual studio 2010)
  657.   if (horizontal && Get("InvertDragX"))
  658.     Direction *= -1
  659.  
  660.   ; Do the math to convert this raw px measure into scroll speed
  661.   if (format = "px")
  662.   {
  663.     ; Scale by the user-set scroll speed & const adjust
  664.     if (!horizontal)
  665.       Factor *= Get("SpeedY") * Y_ADJUST
  666.     else
  667.       Factor *= Get("SpeedX") * X_ADJUST
  668.  
  669.     ; Scale by the acceleration function, if enabled
  670.     if (!horizontal && Get("UseAccelerationY"))
  671.       Factor := Accelerate(Factor)
  672.     if (horizontal && Get("UseAccelerationX"))
  673.       Factor := Accelerate(Factor)
  674.   }
  675.  
  676.   ;if (!horizontal) ToolTip, Speed: %arg% -> %Factor%
  677.  
  678.   ; Capture the current speed
  679.   if (!horizontal)
  680.     DiffYSpeed := Factor * Direction
  681.   else
  682.     DiffXSpeed := Factor * Direction
  683.  
  684.   ; Get the requested scroll method    
  685.   if (!horizontal)
  686.     Method := Get("ScrollMethodY")
  687.   else
  688.     Method := Get("ScrollMethodX")
  689.    
  690.   ; Do scroll
  691.   ;  According to selected method
  692.   ;  wparam is used in all methods, as the final "message" to send.
  693.   ;  All methods check for direction by comparing (NewY < OldY)
  694.   if (Method = mWheelMessage)
  695.   {
  696.     ; format wparam; one wheel tick scaled by yFactor
  697.     ; format and send the message to the original window, at the original mouse location
  698.     wparam := WHEEL_DELTA * Direction * Factor
  699.     ;ToolTip, %arg% -> %factor% -> %wparam%
  700.     if (!horizontal)
  701.       PostMessage, WM_MOUSEWHEEL, (wparam<<16), (OriginalY<<16)|OriginalX,, %Target%
  702.     else
  703.     {
  704.       wparam *= -1 ; reverse the direction for horizontal
  705.       PostMessage, WM_MOUSEHWHEEL, (wparam<<16), (OriginalY<<16)|OriginalX,, %Target%
  706.     }
  707.   }
  708.   else if (Method = mWheelKey)
  709.   {
  710.     ; format wparam; either WheelUp or WheelDown
  711.     ; send as many messages needed to scroll at the desired speed
  712.     if (!horizontal)
  713.       wparam := Direction < 0 ? "{WheelDown}" : "{WheelUp}"
  714.     else
  715.       wparam := Direction < 0 ? "{WheelLeft}" : "{WheelRight}"
  716.      
  717.     Loop, %Factor%
  718.       Send, %wparam%
  719.   }
  720.   else if (Method = mScrollMessage)
  721.   {
  722.     ; format wparam; either LINEUP, LINEDOWN, LINELEFT, or LINERIGHT
  723.     ; send as many messages needed to scroll at the desired speed
  724.     if (!horizontal)
  725.     {
  726.       wparam := Direction < 0 ? SB_LINEDOWN : SB_LINEUP
  727.       Loop, %Factor%
  728.         PostMessage, WM_VSCROLL, wparam, 0,, Ahk_ID %CtrlHwnd%
  729.     }
  730.     else
  731.     {
  732.       wparam := Direction < 0 ? SB_LINERIGHT : SB_LINELEFT
  733.       Loop, %Factor%
  734.         PostMessage, WM_HSCROLL, wparam, 0,, Ahk_ID %CtrlHwnd%
  735.     }
  736.   }
  737. }
  738.  
  739. ; Handler to check for a double-click of the right mouse button
  740. ; (press-release-press-release), quickly.
  741. ; This is called every time the button is released.
  742. ;
  743. ; We assume that if the mouse button was released,
  744. ; then it had to be pressed down to begin with (reasonable?);
  745. ; this should be handled by AHK's 'Critical' declaration.
  746. ;
  747. CheckDoubleClick:
  748.   if (!UseDoubleClickCheck)
  749.      return
  750.  
  751.    ; Record latest button release time and
  752.    ; Calculate difference between previous click-release and re-click
  753.    ; if the difference is below the threshold, treat it as a double-click
  754.    TimeOfLastButtonUp := A_TickCount
  755.    DClickDiff := TimeOfLastButtonUp - TimeOf2ndLastButtonDown
  756.    if (DClickDiff <= DoubleClickThreshold)
  757.    {
  758.       ; Mark the status as Handled,
  759.       ; so the user-configurable ButtonDoubleClick doesn't have to
  760.       ; Call the user defined function.
  761.       DragStatus := DS_HANDLED
  762.       GoSub ButtonDoubleClick
  763.    }
  764. Return
  765.  
  766.  
  767. ; Handler to check for edge scrolling
  768. ; Activated when the mouse is dragging and stops
  769. ; within a set threshold of the window's edge
  770. ; Causes the window to keep scrolling at a set rate
  771. ;
  772. CheckEdgeScrolling:
  773.  if (!Get("UseEdgeScrolling"))
  774.     return
  775.  
  776.   ; Get scrolling window position
  777.   WinGetPos, WinX, WinY, WinWidth, WinHeight, ahk_id %WinHwnd%
  778.   ; Find mouse position relative to the window
  779.   WinMouseX := NewX - WinX
  780.   WinMouseY := NewY - WinY
  781.  
  782.   ; find which edge we're closest to and the distance to it
  783.   InLowerHalf :=  (WinMouseY > WinHeight/2)
  784.   EdgeDistance := (InLowerHalf) ? Abs( WinHeight - WinMouseY ) : Abs( WinMouseY )
  785.   ;atEdge := (EdgeDistance <= EdgeScrollingThreshold ? " @Edge" : "")         ;debug
  786.   ;ToolTip, %WinHwnd%: %WinMouseY% / %WinHeight% -> %EdgeDistance%  %atEdge%  ;debug
  787.  
  788.   ; if we're close enough, scroll the window
  789.   if (EdgeDistance <= EdgeScrollingThreshold)
  790.   {
  791.     ; prep and call scrolling
  792.     ; the second arg requests the scroll at the set speed without accel
  793.     arg := (InLowerHalf ? 1 : -1) * (Get("InvertDrag") ? -1 : 1) * Get("EdgeScrollSpeed")
  794.     Scroll(arg, false, "speed")
  795.   }
  796. Return
  797.  
  798.  
  799. ; Handler to check for gesture actions
  800. ; This handler only supports simple "flick" gestures;
  801. ; because the whole gesture needs to be completed before DragThreshold,
  802. ; and also makes the logic easy, by a simple threshold
  803. ;
  804. GestureCheck:
  805.  MouseGetPos, MoveX, MoveY
  806.   MoveAmount := (abs(OriginalY-MoveY) >= abs(OriginalX-MoveX)) ? OriginalY-MoveY : OriginalX-MoveX
  807.   MoveDirection := (abs(OriginalY-MoveY) >= abs(OriginalX-MoveX)) ? (OriginalY>MoveY ? "U" : "D") : (OriginalX>MoveX ? "L" : "R")
  808.  
  809.   ; If the move amount is above the threshold,
  810.   ; Immediately stop/cancel dragging and call the correct gesture handler  
  811.   if (abs(MoveAmount) >= GestureThreshold)
  812.   {
  813.     GoSub, DragStop
  814.     GoSub, Gesture%MoveDirection%
  815.   }
  816. Return
  817.  
  818.  
  819. ; Settings Functions
  820. ;--------------------------------
  821.  
  822. ; A wrapper around the GetSetting function.
  823. ; Returns the ini GetSetting value, or the
  824. ; in-memory global variable of the same name.
  825. ;
  826. ; Provides and easy and seamless wrapper to
  827. ; overlay user preferences on top of app settings.
  828. ;
  829. Get(name, SectionName="")
  830. {
  831.   global
  832.   local temp
  833.  
  834.   if (DEBUG)
  835.   {
  836.     temp := %name%
  837.     return temp    
  838.   }
  839.  
  840.   temp := GetSetting(name, SectionName)
  841.   if (temp != "")
  842.     return temp
  843.   else
  844.   {
  845.     temp := %name%
  846.     return temp    
  847.   }
  848. }
  849.  
  850. ; Retrieves a named setting from the global ini
  851. ; This function operates both as a "search" of
  852. ; the ini, as well as a named get. You can optionally
  853. ; specify a section name to retrieve a specific value.
  854. ;
  855. ; By Default, this searches the ini file in any of
  856. ; a set of valid SectionNames. The default section 'General'
  857. ; is a last resort, if an app specific setting was not found.
  858. ; Section names are searched for the target control class,
  859. ; window class, and process name. If any of these named sections
  860. ; exist in ini, its key value is returned first.
  861. ;
  862. GetSetting(name, SectionName="")
  863. {
  864.   global INI_GENERAL
  865.   global CtrlClass, WinClass, WinProcessName, WinProcessPath
  866.   global ini, ConfigSections
  867.  
  868.   ; find the section, using the cached list
  869.   if (!SectionName)
  870.   {
  871.     ; by control class
  872.     IfNotEqual, CtrlClass
  873.       If CtrlClass in %ConfigSections%
  874.         SectionName := CtrlClass
  875.     ; by window class
  876.     IfNotEqual, WinClass
  877.       If WinClass in %ConfigSections%
  878.         SectionName := WinClass
  879.     ; by process name
  880.     IfNotEqual, WinProcessName
  881.       If WinProcessName in %ConfigSections%
  882.         SectionName := WinProcessName
  883.     ; by process path
  884.     IfNotEqual, WinProcessPath,
  885.       If WinProcessPath in %ConfigSections%
  886.         SectionName := WinProcessPath
  887.    
  888.     ; last chance
  889.     if (!SectionName)
  890.       SectionName := INI_GENERAL
  891.   }
  892.  
  893.   ;get the value
  894.   temp := ini_getValue(ini, SectionName, name)
  895.  
  896.   ; check for special keywords
  897.   if (temp = "false")
  898.     temp := 0
  899.   if (temp = "true")
  900.     temp := 1
  901.  
  902.   ;if (SectionName != INI_GENERAL)
  903.   ;  ToolTip, % "Request " . name . ":`n" . ini_getSection(ini, SectionName)
  904.    
  905.   return temp
  906. }
  907.  
  908. ; Saves a setting/variable to the ini file
  909. ; in the given section name (default General)
  910. ; with the given value, or the current variable value
  911. ;
  912. SaveSetting(name, value="", SectionName="General")
  913. {
  914.   ; prep value
  915.   global
  916.   local keyList, temp
  917.  
  918.   if (SectionName = "")
  919.   {
  920.     MsgBox, 16, DtS, Setting Save Failed `nEmpty SectionName
  921.     return
  922.   }
  923.    
  924.   keyList := ini_getAllKeyNames(ini, SectionName)
  925.   if (!value)
  926.     value := %name%
  927.    
  928.   ; if no section
  929.   if SectionName not in %ConfigSections%
  930.   {
  931.     if (!ini_insertSection(ini, SectionName, name . "=" . value))
  932.     {
  933.       MsgBox, 16, DtS, Setting Save Failed `ninsertSection %ErrorLevel%
  934.       return
  935.     }
  936.     ConfigSections := ini_getAllSectionNames(ini)
  937.   }
  938.   ; if no value
  939.   else if name not in %keyList%
  940.   {
  941.     if (!ini_insertKey(ini, SectionName, name . "=" . value))
  942.     {
  943.       MsgBox, 16, DtS, Setting Save Failed `ninsertKey %ErrorLevel%
  944.       return
  945.     }
  946.   }
  947.   ; value exists, Update
  948.   else
  949.   {
  950.     if (!ini_replaceValue(ini, SectionName, name, value))
  951.     {
  952.       MsgBox, 16, DtS, Setting Save Failed `nreplaceValue %ErrorLevel%
  953.       return
  954.     }
  955.   }
  956.  
  957.   ; finally save the setings
  958.   ini_save(ini)
  959.   if (ErrorLevel)
  960.     MsgBox, 16, DtS, Settings File Write Failed
  961. }
  962.  
  963. ; An initialization function for settings
  964. ; The given variable name should be created
  965. ; with the value loaded from ini General Section
  966. ; or, if not set, the provided default
  967. ;
  968. Setting(variableName, defaultValue)
  969. {
  970.   global
  971.   local value
  972.  
  973.   %variableName%_d := defaultValue
  974.  
  975.   if variableName not in %SettingsList%
  976.     SettingsList .= (SettingsList != "" ? "," : "") . variableName
  977.  
  978.   value := GetSetting(variableName, INI_GENERAL)
  979.   if (value != "")
  980.     %variableName% := value
  981.   else
  982.     %variableName% := defaultValue
  983. }
  984.  
  985. ; check and reload of settings
  986. ;
  987. LoadLocalSettings:
  988.  Critical
  989.   ini_load(temp)
  990.   changed := (temp != ini)
  991.  
  992.   if (temp = "" && SettingsList = "")
  993.     GoSub, ApplySettings
  994.  
  995.   if (A_ThisMenuItem != "")
  996.     ToolTip("Reloading Settings..." . (changed ? " Change detected." : ""))
  997.  
  998.   if (!changed || temp = "")
  999.     return
  1000.  
  1001.   ; apply new ini
  1002.   ini := temp
  1003.   GoSub, LoadLocalSettingSections
  1004.   GoSub, ApplySettings
  1005.   Critical, Off
  1006. Return
  1007.  
  1008. LoadLocalSettingSections:
  1009.    ; apply new config sections
  1010.     ConfigSections=
  1011.     ConfigProfileSections=
  1012.     temp := ini_getAllSectionNames(ini)
  1013.     Loop, Parse, temp, `,
  1014.     {
  1015.       ConfigSections .= (ConfigSections != "" ? "," : "") . A_LoopField
  1016.       if A_LoopField not in %INI_EXCLUDE%
  1017.         ConfigProfileSections .= (ConfigProfileSections != "" ? "," : "") . A_LoopField
  1018.     }
  1019. Return
  1020.  
  1021. ; Loads a simple ini settings file from the web
  1022. ; This allows the script to do automatic update checking
  1023. ; computername is included only to get a basic idea of user count
  1024. ;
  1025. LoadServerSettings:
  1026.  ; check for stop cases
  1027.   SettingsCheckTime := GetSetting("LastCheckTime", "ServerSettings")
  1028.   if (SettingsCheckTime != "")
  1029.   {
  1030.     SettingsCheckDiff=
  1031.     EnvSub, SettingsCheckDiff, %SettingsCheckTime%, Minutes
  1032.     if (SettingsCheckDiff < 30 && !A_ThisMenuItem && VERSION == GetSetting("LastSentVersion", "ServerSettings"))
  1033.       return  
  1034.   }
  1035.   if (DEBUG  && !A_ThisMenuItem)
  1036.     return
  1037.    
  1038.   if (A_ThisMenuItem)
  1039.     ToolTip("Reloading Server Settings...")
  1040.    
  1041.     ; load remote settings  
  1042.   if (InternetFileRead(ServerSettings, URL_SERVERSETTINGS . "?v=" . VERSION . "&u=" . A_UserName . "@" . A_ComputerName ))
  1043.   {
  1044.     SaveSetting("LastCheckTime", A_Now, "ServerSettings")
  1045.     SaveSetting("LastSentVersion", VERSION, "ServerSettings")
  1046.    
  1047.     ; version check
  1048.     if (UseUpdateCheck)
  1049.     {
  1050.       current := ini_GetValue(ServerSettings, "Version", "Current")
  1051.       updateMessage := ini_GetValue(ServerSettings, "Version", "UpdateMessage")
  1052.       if (VERSION < current)
  1053.       {
  1054.         MsgBox, 36, DtS Update Available!, DragToScroll v%current% is available`nWould you like to get to get this update?`n%updateMessage%
  1055.         IfMsgBox Yes
  1056.           Run, %URL_DISCUSSION%
  1057.       }
  1058.     }
  1059.   }
  1060. Return
  1061.  
  1062.  
  1063. ; Thanks to SKAN
  1064. ; http://www.autohotkey.com/forum/topic45718.html
  1065. ;
  1066. InternetFileRead( ByRef V, URL="", RB=0, bSz=1024, DLP="", F=0x84000000 ) {
  1067.  Static LIB="WININET\", QRL=16, CL="00000000000000", N=""
  1068.  If ! DllCall( "GetModuleHandle", Str,"wininet.dll" )
  1069.       DllCall( "LoadLibrary", Str,"wininet.dll" )
  1070.  If ! hIO:=DllCall( LIB "InternetOpenA", Str,N, UInt,4, Str,N, Str,N, UInt,0 )
  1071.    Return -1
  1072.  If ! (( hIU:=DllCall( LIB "InternetOpenUrlA", UInt,hIO, Str,URL, Str,N, Int,0, UInt,F, UInt,0 ) ) || ErrorLevel )
  1073.    Return 0 - ( !DllCall( LIB "InternetCloseHandle", UInt,hIO ) ) - 2
  1074.  If ! ( RB  )
  1075.    If ( SubStr(URL,1,4) = "ftp:" )
  1076.      CL := DllCall( LIB "FtpGetFileSize", UInt,hIU, UIntP,0 )
  1077.    Else If ! DllCall( LIB "HttpQueryInfoA", UInt,hIU, Int,5, Str,CL, UIntP,QRL, UInt,0 )
  1078.      Return 0 - ( !DllCall( LIB "InternetCloseHandle", UInt,hIU ) )
  1079.               - ( !DllCall( LIB "InternetCloseHandle", UInt,hIO ) ) - 4
  1080.  VarSetCapacity( V,64 ), VarSetCapacity( V,0 )
  1081.  SplitPath, URL, FN,,,, DN
  1082.  FN:=(FN ? FN : DN), CL:=(RB ? RB : CL), VarSetCapacity( V,CL,32 ), P:=&V,
  1083.  B:=(bSz>CL ? CL : bSz), TtlB:=0, LP := RB ? "Unknown" : CL,  %DLP%( True,CL,FN )
  1084.  Loop {
  1085.        If ( DllCall( LIB "InternetReadFile", UInt,hIU, UInt,P, UInt,B, UIntP,R ) && !R )
  1086.        Break
  1087.        P:=(P+R), TtlB:=(TtlB+R), RemB:=(CL-TtlB), B:=(RemB<B ? RemB : B), %DLP%( TtlB,LP )
  1088.        Sleep -1
  1089.  } TtlB<>CL ? VarSetCapacity( T,TtlB ) DllCall( "RtlMoveMemory", Str,T, Str,V, UInt,TtlB )
  1090.   . VarSetCapacity( V,0 ) . VarSetCapacity( V,TtlB,32 ) . DllCall( "RtlMoveMemory", Str,V
  1091.   , Str,T, UInt,TtlB ) . %DLP%( TtlB, TtlB ) : N
  1092.  If ( !DllCall( LIB "InternetCloseHandle", UInt,hIU ) )
  1093.   + ( !DllCall( LIB "InternetCloseHandle", UInt,hIO ) )
  1094.    Return -6
  1095. Return, VarSetCapacity(V)+((ErrorLevel:=(RB>0 && TtlB<RB)||(RB=0 && TtlB=CL) ? 0 : 1)<<64)
  1096. }
  1097.  
  1098. ; Retrieve the full path of a process with ProcessID
  1099. ; thanks to HuBa & shimanov
  1100. ; http://www.autohotkey.com/forum/viewtopic.php?t=18550
  1101. ;
  1102. GetModuleFileNameEx(ProcessID)  
  1103. {
  1104.   if A_OSVersion in WIN_95, WIN_98, WIN_ME
  1105.     Return
  1106.   hProcess := DllCall( "OpenProcess", "UInt", 0x10|0x400, "Int", False, "UInt", ProcessID)
  1107.   if (ErrorLevel or hProcess = 0)
  1108.     Return
  1109.   FileNameSize := 260
  1110.   VarSetCapacity(ModuleFileName, FileNameSize, 0)
  1111.   CallResult := DllCall("Psapi.dll\GetModuleFileNameExA", "UInt", hProcess, "UInt", 0, "Str", ModuleFileName, "UInt", FileNameSize)
  1112.   DllCall("CloseHandle", hProcess)
  1113.   Return ModuleFileName
  1114. }
  1115.  
  1116. ; Settings Gui : App Settings
  1117. ;--------------------------------
  1118.  
  1119. GuiAppSettings:
  1120.  if (!GuiAppBuilt)
  1121.     GoSub, GuiAppSettingsBuild
  1122.   Gui, 2:Show,, DtS App Settings
  1123.   GoSub, GuiAppSectionLoad
  1124.   Return
  1125.  
  1126.   GuiAppSettingsBuild:
  1127.  GuiAppBuilt := true
  1128.   Gui +Delimiter|
  1129.   Gui, 2:Default
  1130.   Gui, Add, ComboBox, x10 y15 w225 h20 r10 vGuiAppSection gGuiAppSectionChange
  1131.   Gui, Add, Button, x240 y15 w20 h20 gGuiAppSectionRemove , -
  1132.   Gui, Add, GroupBox, x10 y42 w250 h76 , Scroll Method
  1133.   Gui, Add, Text, x20 y63 w10 h10 , Y
  1134.   Gui, Add, Text, x20 y93 w10 h10 , X
  1135.   Gui, Add, DropDownList, x32 y60 w218 h20 r3 Choose1 vGuiScrollMethodY , WheelMessage|WheelKey|ScrollMessage
  1136.   Gui, Add, DropDownList, x32 y90 w218 h20 r3 Choose1 vGuiScrollMethodX , WheelMessage|WheelKey|ScrollMessage
  1137.  
  1138.   Gui, Add, GroupBox, x10 y120 w250 h80 , Speed && Acceleration
  1139.   Gui, Add, Text, x20 y143 w10 h20 , Y
  1140.   Gui, Add, Edit, x30 y140 w40 h20 vGuiSpeedY
  1141.   Gui, Add, UpDown
  1142.   Gui, Add, CheckBox, x75 y140 w50 h20 vGuiUseAccelerationY , Accel
  1143.   Gui, Add, Text, x140 y143 w10 h20 , X
  1144.   Gui, Add, Edit, x150 y140 w40 h20 vGuiSpeedX
  1145.   Gui, Add, UpDown
  1146.   Gui, Add, CheckBox, x195 y140 w50 h20 vGuiUseAccelerationX , Accel
  1147.   Gui, Add, CheckBox, x20 y165 w85 h20 vGuiUseEdgeScrolling , Edge Scrolling
  1148.   Gui, Add, Edit, x150 y165 w40 h20 vGuiEdgeScrollSpeed
  1149.   Gui, Add, UpDown
  1150.   Gui, Add, Text, x195 y168 w60 h20 , Edge Speed
  1151.  
  1152.   Gui, Add, GroupBox, x10 y200 w250 h110 , Options
  1153.   Gui, Add, CheckBox, x20 y220 w170 h20 vGuiScrollDisabled , Scroll Disabled
  1154.   Gui, Add, CheckBox, x20 y240 w170 h20 vGuiUseScrollMomentum , Scroll Momentum
  1155.   Gui, Add, CheckBox, x20 y260 w170 h20 vGuiInvertDrag , Invert Drag
  1156.   Gui, Add, CheckBox, x20 y280 w170 h20 vGuiUseMovementCheck , Movement Check
  1157.   Gui, Add, Button, x10 y315 w120 h30 Default gGuiAppApply , Apply
  1158.   Gui, Add, Button, x140 y315 w120 h30 gGuiClose , Close
  1159. Return
  1160.  
  1161. GuiAppSectionLoad:
  1162.  Gui, +Delimiter`,
  1163.   GuiControlGet, temp,, GuiAppSection
  1164.   GuiControl, , GuiAppSection, % "," . ConfigProfileSections
  1165.   if temp in %ConfigProfileSections%
  1166.     GuiControl, ChooseString, GuiAppSection, %temp%
  1167.   else
  1168.     GuiControl, Choose, GuiAppSection, 1
  1169.   GoSub, GuiAppSectionChange
  1170. Return
  1171.  
  1172. GuiAppSectionRemove:
  1173.  GuiControlGet, GuiAppSection
  1174.   if (GuiAppSection = INI_GENERAL)
  1175.   {
  1176.     Msgbox, 16, DtS Configuration, Cannot delete the general settings section
  1177.     Return
  1178.   }
  1179.   MsgBox, 36, DtS Configuration, Are you sure you want to delete settings for this section?`n  %GuiAppSection%
  1180.   IfMsgBox, Yes
  1181.   {
  1182.     ini_replaceSection(ini, GuiAppSection)
  1183.     ini_save(ini)
  1184.     GoSub, LoadLocalSettingSections
  1185.     GoSub, GuiAppSectionLoad
  1186.   }
  1187. Return
  1188.  
  1189. GuiAppSectionChange:
  1190.  GuiControlGet, GuiAppSection
  1191.   if (GuiAppSection not in ConfigProfileSections)
  1192.     return
  1193.   ;DDLs
  1194.   temp=ScrollMethodX,ScrollMethodY
  1195.   Loop, Parse, temp, `,
  1196.     GuiControl, Choose, Gui%A_LoopField%, % Get(A_LoopField, GuiAppSection)
  1197.   ;Checkboxes & Edit boxes
  1198.   temp=UseAccelerationX,UseAccelerationY,UseEdgeScrolling,ScrollDisabled,UseScrollMomentum,InvertDrag,UseMovementCheck,SpeedX,SpeedY,EdgeScrollSpeed
  1199.   Loop, Parse, temp, `,
  1200.     GuiControl,, Gui%A_LoopField%, % Get(A_LoopField, GuiAppSection)
  1201. Return
  1202.  
  1203. GuiAppApply:
  1204.  GuiControlGet, GuiAppSection
  1205.   temp=ScrollMethodX,ScrollMethodY,UseAccelerationX,UseAccelerationY,UseEdgeScrolling,ScrollDisabled,UseScrollMomentum,InvertDrag,UseMovementCheck,SpeedX,SpeedY,EdgeScrollSpeed
  1206.   Loop, Parse, temp, `,
  1207.   {
  1208.     GuiControlGet, value,, Gui%A_LoopField%
  1209.     SaveSetting(A_LoopField, value, GuiAppSection)
  1210.   }
  1211.  
  1212.   GoSub, LoadLocalSettingSections
  1213.   GoSub, GuiAppSectionLoad
  1214. Return
  1215.  
  1216.  
  1217. ; Settings Gui : All Settings
  1218. ;--------------------------------
  1219.  
  1220. GuiAllSettings:
  1221.  if (!GuiAllBuilt)
  1222.     GoSub, BuildGuiAllSettings
  1223.   Gui, 3:Show,, DtS All Settings
  1224.   Return
  1225.  
  1226.   BuildGuiAllSettings:
  1227.  GuiAllBuilt := true
  1228.   Gui, 3:Default
  1229.   wSp := 5, wCH := 20, wCW := 150, wOffset := 60, wCX := wSp*2 + wCW, wCX2 := wSp*4 + wCW*2, wCX3 := wSp*5 + wCW*3
  1230.   Gui, Add, Text, x%wSp% y%wSp%, This lists all settings registered with this script. `nChanging values and pressing 'Ok' immediately updates the setting in memory, `nand writes your changes to the ini General section
  1231.   Loop, Parse, SettingsList, `,
  1232.   {
  1233.     if (A_LoopField = "")
  1234.       continue
  1235.  
  1236.     temp := A_LoopField . "_d"
  1237.     color := ( %A_LoopField% == %temp% ? "" : "cBlue")
  1238.     temp := %A_LoopField%
  1239.  
  1240.     left := !left    
  1241.     if (left)
  1242.     {
  1243.       Gui, Add, Text, x%wSp% y%wOffset% w%wCW% h%wCH% right, %A_LoopField%
  1244.       Gui, Add, Edit, x%wCX% y%wOffset% w%wCW% h%wCH% center %color% v%A_LoopField% gGuiAllEvent, %temp%
  1245.     }
  1246.     else
  1247.     {
  1248.       Gui, Add, Text, x%wCX2% y%wOffset% w%wCW% h%wCH% right, %A_LoopField%
  1249.       Gui, Add, Edit, x%wCX3% y%wOffset% w%wCW% h%wCH% center %color% v%A_LoopField% gGuiAllEvent, %temp%
  1250.       wOffset += wCH + wSp
  1251.     }
  1252.   }
  1253.  
  1254.   if (left)
  1255.     wOffset += wCH + wSp * 3
  1256.   else
  1257.     wOffset += wSp * 2
  1258.    
  1259.   Gui, Font, bold
  1260.   Gui, Add, Button, x%wCX% y%wOffset% w%wCW% h%wCH% Default gGuiAllOk, Ok
  1261.   Gui, Add, Button, x%wCX2% y%wOffset% w%wCW% h%wCH% gGuiClose, Cancel
  1262.   wOffset += wCH + wSp
  1263. Return
  1264.  
  1265. GuiAllEvent:
  1266.  GuiControlGet, value,, %A_GuiControl%
  1267.   temp := A_GuiControl . "_d"
  1268.   temp := %temp%
  1269.  
  1270.   if (temp != value)
  1271.     GuiControl, +cBlue, %A_GuiControl%
  1272.   else
  1273.     GuiControl, +cDefault, %A_GuiControl%
  1274. Return
  1275.  
  1276. GuiAllOk:
  1277.  GuiControlGet, temp, ,Button
  1278.   Hotkey, %temp%,, UseErrorLevel
  1279.   if ErrorLevel in 5,6
  1280.   {
  1281.     HotKey, %Button%, Off
  1282.     HotKey, %Button% Up, Off
  1283.     HotKey, ^%Button%, Off
  1284.     HotKey, ^%Button% Up, Off
  1285.   }
  1286.  
  1287.   Gui, Submit
  1288.   Loop, Parse, SettingsList, `,
  1289.   {
  1290.     if (A_LoopField = "")
  1291.       continue
  1292.     SaveSetting(A_LoopField)
  1293.   }
  1294.   GoSub, mnuEnabledInit
  1295. Return
  1296.  
  1297. GuiClose:
  1298.   Gui, %A_Gui%:Cancel
  1299. Return
  1300.  
  1301.  
  1302. ; Menu
  1303. ;--------------------------------
  1304.  
  1305. ; This section builds the menu of system-tray icon for this script
  1306. ; MenuInit is called in the auto-exec section of this script at the top.
  1307. ;
  1308. MenuInit:
  1309.  
  1310. ;
  1311. ; SCRIPT SUBMENU
  1312. ;
  1313.  
  1314. Menu, mnuScript, ADD, Reload, mnuScriptReload
  1315. Menu, mnuScript, ADD, Reload Settings, LoadLocalSettings
  1316. Menu, mnuScript, ADD, Reload Server-Settings, LoadServerSettings
  1317.  
  1318. Menu, mnuScript, ADD, Debug, mnuScriptDebug
  1319.  
  1320. Menu, mnuScript, ADD
  1321. if (!A_IsCompiled)
  1322.   Menu, mnuScript, ADD, Open/Edit Script, mnuScriptEdit
  1323. Menu, mnuScript, ADD, Open Directory, mnuScriptOpenDir
  1324. Menu, mnuScript, ADD, Open Settings File,  mnuScriptOpenSettingsIni
  1325. IfExist, Readme.txt
  1326.   Menu, mnuScript, ADD, Open Readme, mnuScriptOpenReadme
  1327. Menu, mnuScript, Add, Open Discussion, mnuScriptOpenDiscussion
  1328.  
  1329. ;
  1330. ; SETTINGS SUBMENU
  1331. ;
  1332.  
  1333. Menu, mnuSettings, ADD, All Settings, GuiAllSettings
  1334. Menu, mnuSettings, ADD, App Settings, GuiAppSettings
  1335.  
  1336.  
  1337.  
  1338. ;
  1339. ; TRAY MENU
  1340. ;
  1341.  
  1342. ; remove standard, and add name (w/ reload)
  1343. Menu, Tray, NoStandard
  1344. Menu, Tray, ADD, Drag To Scroll v%VERSION%, mnuEnabled
  1345. Menu, Tray, Default, Drag To Scroll v%VERSION%
  1346. Menu, TRAY, ADD
  1347.  
  1348. ; Enable/Disable
  1349. ; Add the menu item and initialize its state
  1350. Menu, Tray, ADD, Enabled, mnuEnabled
  1351. GoSub, mnuEnabledInit
  1352.  
  1353. ; submenus
  1354. Menu, Tray, ADD, Script, :mnuScript
  1355. Menu, TRAY, ADD, Settings, :mnuSettings
  1356.  
  1357. ; exit
  1358. Menu, TRAY, ADD
  1359. Menu, TRAY, ADD, Exit, mnuExit
  1360.  
  1361.  
  1362. Return
  1363.  
  1364.  
  1365. ; Menu Handlers
  1366. ;--------------------------------
  1367.  
  1368. ; Simple menu handlers for 'standard' replacements
  1369. mnuScriptReload:
  1370.  Reload
  1371. Return
  1372.  
  1373. mnuScriptDebug:
  1374.   ListLines
  1375. Return
  1376.  
  1377. mnuScriptOpenDir:
  1378.   Run, %A_ScriptDir%
  1379. Return
  1380.  
  1381. mnuScriptEdit:
  1382.  Edit
  1383. Return
  1384.  
  1385. mnuScriptOpenSettingsIni:
  1386.  IfExist, DragToScroll.ini
  1387.     Run DragToScroll.ini
  1388.   Else
  1389.     MsgBox, 16, DtS, DragToScroll.ini not found...
  1390. Return
  1391.  
  1392. mnuScriptOpenReadme:
  1393.  IfExist, Readme.txt
  1394.     Run, Readme.txt
  1395.   Else
  1396.     MsgBox, 16, DtS, Readme.txt not found...
  1397. Return
  1398.  
  1399. mnuScriptOpenDiscussion:
  1400.  Run, %URL_DISCUSSION%
  1401. Return
  1402.  
  1403. mnuExit:
  1404.  ExitApp
  1405. Return
  1406.  
  1407.  
  1408. ; This section defines the handlers for these above menu items
  1409. ; Each handler has an inner 'init' label that allows the handler to
  1410. ; both to set the initial value and to change the value, keeping the menu in sync.
  1411. ; Each handler either sets, or toggles the associated property
  1412. ;
  1413.  
  1414. mnuEnabled:
  1415.  ScrollDisabled := !ScrollDisabled
  1416.   ToolTip("Scrolling " . (ScrollDisabled ? "Disabled" : "Enabled"), 1)
  1417.   GoSub, DragStop ; safety measure. force stop all drags
  1418.   mnuEnabledInit:
  1419.  if (!ScrollDisabled)
  1420.   {
  1421.     Menu, TRAY, Check, Enabled
  1422.     Menu, TRAY, tip, Drag To Scroll v%VERSION%
  1423.     HotKey, %Button%, ButtonDown, On
  1424.     HotKey, %Button% Up, ButtonUp, On
  1425.     HotKey, ^%Button%, DisabledButtonDown, On
  1426.     HotKey, ^%Button% Up, DisabledButtonUp, On
  1427.     HotKey, ~LButton, ToolTipCancel, On
  1428.   }
  1429.   else
  1430.   {
  1431.     Menu, TRAY, Uncheck, Enabled
  1432.     Menu, TRAY, tip, Drag To Scroll v%VERSION% (Disabled)
  1433.     HotKey, %Button%, Off
  1434.     HotKey, %Button% Up, Off
  1435.     HotKey, ^%Button%, Off
  1436.     HotKey, ^%Button% Up, Off
  1437.   }
  1438.    
  1439.   Gosub, UpdateTrayIcon
  1440. Return
  1441.  
  1442. ; Icons
  1443. ;--------------------------------
  1444. ; The following section contains HEX data and code to load+parse data & set tray icons
  1445. ; adapted from http://www.autohotkey.com/forum/topic33955.html
  1446. ;
  1447. TrayIconInit:
  1448.  ; ENABLED icon data
  1449.   IconEnabledHex =
  1450.   ( join
  1451. 00000100010010100000010020006804000016000000280000001000000020000000010020000000000000000000130B000
  1452. 0130B000000000000000000000000000000000000000000000000000000000000E3E3E30C9999994D4D4D4D9A393939C62E
  1453. 2E2ED33F3F3FBB53535390A7A7A73E606060070000000000000000000000000000000000000000AEAEAE03B3B3B33E40404
  1454. 0C75A5A5AFFACACACFFDCDCDCFFE7E7E7FFD5D5D5FFA2A2A2FF494949FF5B5B5BA0EBEBEB12000000000000000000000000
  1455. C6C6C6038F8F8F63313131FABABABAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF717171FF525
  1456. 252AAC5C5C50500000000000000009797975F333333FFE6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  1457. FFFFFFFFFFFFFFFFFFFFFFFFFF414141FFB1B1B14700000000ACACAC492C2C2CF9DFDFDFFFFFFFFFFFFDFDFDFFFFFFFFFFF
  1458. FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4A4A4FF4444449ACBCBCB2C333333E6C8C8C8FFFFFF
  1459. FFFFC3C3C3FF969696FECCCCCCFDFCFCFCFEFAFAFAFEFFFFFFFFFFFFFFFFEAEAEAFEBDBDBDFDFBFBFBFFD7D7D7FF141414B
  1460. B363636A7919191FFFFFFFFFFB4B4B4FF454545D93F3F3FD4B7B7B7FED3D3D3FC848484FC9A9A9AFC989898FD717171FC6B
  1461. 6B6BFAFFFFFFFEDEDEDEFF111111C122222270656565F88A8A8AFF535353CE5858583F444444B1EAEAEAFFE2E2E2FD95959
  1462. 5FC838383FB898989FB9B9B9BFDB0B0B0FCDEDEDEFEE0E0E0FF121212C0333333044141415A5151516A7F7F7F2D00000000
  1463. 0E0E0EC1DFDFDFFFD6D6D6FFC9C9C9FDFFFFFFFE969696FBFFFFFFFF7D7D7DFAA2A2A2FDE7E7E7FF121212BF00000000000
  1464. 000000000000000000000000000001B1B1BC1E7E7E7FF969696FF6C6C6CFCFFFFFFFD2C2C2CFCFFFFFFFE717171FB9F9F9F
  1465. FEE8E8E8FF121212BF00000000000000000000000000000000000000001B1B1BC1E8E8E8FF999999FF717171FCFFFFFFFE3
  1466. 63636FCFFFFFFFE747474FBA6A6A6FEEEEEEEFF121212C100000000000000000000000000000000000000001E1E1EC1E8E8
  1467. E8FF9A9A9AFF727272FCFFFFFFFE373737FCFFFFFFFE757575FB878787FFC3C3C3FF111111C100000000000000000000000
  1468. 00000000000000000232323C4EEEEEEFFA0A0A0FF727272FCFFFFFFFE383838FCFFFFFFFE808080FE181818E55C5C5CD237
  1469. 3737510000000000000000000000000000000000000000454545AF808080FF525252FF777777FCFFFFFFFD323232FCFDFDF
  1470. DFF6F6F6FFF535353684040401A424242030000000000000000000000000000000000000000D6D6D62766666686393939AE
  1471. 616161FFE1E1E1FF171717F8454545F42B2B2BC8D4D4D415000000000000000000000000000000000000000000000000000
  1472. 000000000000069696905E2E2E212535353AA262626DC95959566B4B4B41861616111000000000000000000000000F80700
  1473. 00F0010000E0010000C00000008000000000000000000000000000000098000000F8000000F8000000F8000000F8000000F
  1474. 8030000F8030000FE070000
  1475.   )
  1476.   ; Load above data into a handle, hIconEnabled
  1477.   hIconEnabled := CreateIconResource(IconEnabledHex)
  1478.   IconEnabledHex := ""
  1479.  
  1480.  
  1481.   ; DISABLED icon data
  1482.   IconDisabledHex =
  1483.   ( join
  1484. 00000100010010100000010020006804000016000000280000001000000020000000010020000000000000000000130B000
  1485. 0130B000000000000000000000606CA230606CA5C000000000000000000000000E3E3E30C9999994D4D4D4D9A393939C62E
  1486. 2E2ED33F3F3FBB53535390A7A7A73E6060600700000000000000000606CA5C0606CADA0606CA2B7C7CB405B4B4B33E40404
  1487. 0C75A5A5AFFACACACFFDCDCDCFFE7E7E7FFD5D5D5FFA2A2A2FF494949FF5B5B5BA0EBEBEB12000000000000C8220000C9C8
  1488. 0606D0EB6666B476353533FABBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF717171FF525
  1489. 252AAC5C5C505000000003D3DD7080909A4E60000B9FFA0A0DBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  1490. FFFFFFFFFFFFFFFFFFFFFFFFFF414141FFB1B1B14700000000BFBFAD463A3A3BEB5757D8FF1212D8FFA7A7EDFFFEFEFBFFF
  1491. FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4A4A4FF4444449ACBCBCB2C333333E6C9C9C7FFFFFF
  1492. FFFF3737ACFF0000C4FF8686DBFEFCFCFAFEFBFBF9FEFFFFFFFFFFFFFFFFEAEAEAFEBDBDBDFDFBFBFBFFD7D7D7FF141414B
  1493. B363636A7919191FFFFFFFFFFB7B7B5FF57574FD932329DE00000C6FF7878D8FE939394FC9D9D9AFC989898FD717171FC6B
  1494. 6B6BFAFFFFFFFEDEDEDEFF111111C122222270656565F88A8A8AFF535353CE5959573F42423DB37C7CD4FF0505CFFF15158
  1495. 7FD828284FB8A8A86FB9B9B9BFDB0B0B0FCDEDEDEFEE0E0E0FF121212C0333333044141415A5151516A7F7F7F2D00000000
  1496. 0F0F0DC1EAEAE1FF7070BEFF0D0DD4FF6D6DEAFF939398FCFFFFFFFF7D7D7DFAA2A2A2FDE7E7E7FF121212BF00000000000
  1497. 000000000000000000000000000001B1B1BC1E9E9E8FFA4A49BFF50508FFD0909CBFF090994FEF2F2FCFE74746FFA9F9F9F
  1498. FEE8E8E8FF121212BF00000000000000000000000000000000000000001B1B1BC1E8E8E8FF9A9A99FF77776EFCBDBDF0FE0
  1499. 707C4FF3D3DD5FF6A6A7CFBA9A9A4FEEEEEEEFF121212C100000000000000000000000000000000000000001E1E1EC1E8E8
  1500. E8FF9A9A9AFF727272FCFFFFFFFE2D2D56FC1E1ECFFF1919BBFE717188FFC5C5BFFF111111C100000000000000000000000
  1501. 00000000000000000232323C4EEEEEEFFA0A0A0FF727272FCFFFFFFFE393933FCDADAF8FE1A1AC1FF1212BBFF4C4C79D13B
  1502. 3B2D4B0000000000000000000000000000000000000000454545AF808080FF525252FF777777FCFFFFFFFD323232FCFFFFF
  1503. EFF616177FF0404C1DB0909BBF91111B6430000000000000000000000000000000000000000D6D6D62766666686393939AE
  1504. 616161FFE1E1E1FF171717F8454545F42D2D2AC8C9C9DA240505CCBA0505CDA400000000000000000000000000000000000
  1505. 000000000000069696905E2E2E212535353AA262626DC95959566B4B4B41861616111000000000606CA360606CA3E380700
  1506. 001001000000010000800000008000000000000000000000000000000098000000F8000000F8000000F8000000F8000000F
  1507. 8000000F8000000FE040000
  1508.   )
  1509.   ; Load above data into a handle, hIconDisabled
  1510.   hIconDisabled := CreateIconResource(IconDisabledHex)
  1511.   IconDisabledHex := ""
  1512.  
  1513.  
  1514.   ; DRAGGING png data
  1515.   ; http://tu.etang.info/uploads/2016/04/32x32.png
  1516.   Png_Dragging_Base64 =
  1517.   (LTrim Join
  1518.     iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAABGdBTUEAALGPC/xhBQAAACBj
  1519.     SFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAUVBMVEUAAAAAAAAA
  1520.     AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEREQiIiIAAAD//////8zd3d2IiIgz
  1521.     MzPMzMyqqqru7u67u7t3d3dVVVXZnMIpAAAADXRSTlMADgUYMDoTSD8dKycKQVwVUgAAAAFi
  1522.     S0dEAIgFHUgAAAAHdElNRQfgBAcCMSRLHRhWAAAAl0lEQVQ4y+2RwRLCIAxESwtUq5DQBgj+
  1523.     /4capj0GD151N7d9k9lMpumvLxSi+ZgCJhBmHuSSnhN0JO54oEwKiRaVILyUwWpVCHAvVSyA
  1524.     81oFxhy6K6sAVdlN4pAOFYhcLyDDqnUwJESrDVuB2125Yl46gdJSX9CJFzMXGCzoBIFoBbXi
  1525.     WWNzztmH3UYfm4333jzN6Fs/rTdkcAoM2pbPmAAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNi0w
  1526.     NC0wN1QwMjo0OTozNiswODowMBhiB+0AAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTYtMDQtMDdU
  1527.     MDI6NDk6MzYrMDg6MDBpP79RAAAAAElFTkSuQmCC
  1528.   )
  1529.   ; hIconDragging := CreateIconResource(IconDraggingHex)
  1530.   hIconDragging := base64_to_hicon(Png_Dragging_Base64)
  1531.   IconDraggingHex := ""
  1532. Return
  1533.  
  1534. base64_to_hicon(base64) { ; Modified from just me's ImageToInclude
  1535.   hBitmap := 0
  1536.   VarSetCapacity(B64, StrLen(base64) << !!A_IsUnicode)
  1537.   B64 := base64
  1538.   If !DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", &B64, "UInt", 0, "UInt", 0x01, "Ptr", 0, "UIntP", DecLen, "Ptr", 0, "Ptr", 0)
  1539.      Return False
  1540.   VarSetCapacity(Dec, DecLen, 0)
  1541.   If !DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", &B64, "UInt", 0, "UInt", 0x01, "Ptr", &Dec, "UIntP", DecLen, "Ptr", 0, "Ptr", 0)
  1542.      Return False
  1543.   ; Bitmap creation adopted from "How to convert Image data (JPEG/PNG/GIF) to hBITMAP?" by SKAN
  1544.   ; -> http://www.autohotkey.com/board/topic/21213-how-to-convert-image-data-jpegpnggif-to-hbitmap/?p=139257
  1545.   hData := DllCall("Kernel32.dll\GlobalAlloc", "UInt", 2, "UPtr", DecLen, "UPtr")
  1546.   pData := DllCall("Kernel32.dll\GlobalLock", "Ptr", hData, "UPtr")
  1547.   DllCall("Kernel32.dll\RtlMoveMemory", "Ptr", pData, "Ptr", &Dec, "UPtr", DecLen)
  1548.   DllCall("Kernel32.dll\GlobalUnlock", "Ptr", hData)
  1549.   DllCall("Ole32.dll\CreateStreamOnHGlobal", "Ptr", hData, "Int", True, "PtrP", pStream)
  1550.   hGdip := DllCall("Kernel32.dll\LoadLibrary", "Str", "Gdiplus.dll", "UPtr")
  1551.   VarSetCapacity(SI, 16, 0), NumPut(1, SI, 0, "UChar")
  1552.   DllCall("Gdiplus.dll\GdiplusStartup", "PtrP", pToken, "Ptr", &SI, "Ptr", 0)
  1553.   DllCall("Gdiplus.dll\GdipCreateBitmapFromStream",  "Ptr", pStream, "PtrP", pBitmap)
  1554.   DllCall("Gdiplus.dll\GdipCreateHICONFromBitmap", "Ptr", pBitmap, "PtrP", hBitmap, "UInt", 0)
  1555.   DllCall("Gdiplus.dll\GdipDisposeImage", "Ptr", pBitmap)
  1556.   DllCall("Gdiplus.dll\GdiplusShutdown", "Ptr", pToken)
  1557.   DllCall("Kernel32.dll\FreeLibrary", "Ptr", hGdip)
  1558.   DllCall(NumGet(NumGet(pStream + 0, 0, "UPtr") + (A_PtrSize * 2), 0, "UPtr"), "Ptr", pStream)
  1559.   Return hBitmap
  1560. }
  1561.  
  1562. ; Create and returns an icon resource handle
  1563. ; from raw (ASCII) hex data
  1564. ;
  1565. ;http://www.autohotkey.com/forum/viewtopic.php?p=389135
  1566. ;http://www.autohotkey.com/forum/viewtopic.php?t=63234
  1567. ;http://msdn.microsoft.com/en-us/library/ms648061%28VS.85%29.aspx
  1568. ;
  1569. CreateIconResource(data)
  1570. {
  1571.   VarSetCapacity( IconData,( nSize:=StrLen(data)//2) )
  1572.   Loop %nSize%
  1573.     NumPut( "0x" . SubStr(data,2*A_Index-1,2), IconData, A_Index-1, "Char" )
  1574.  
  1575.   Return % DllCall( "CreateIconFromResourceEx", UInt,&IconData+22, UInt,NumGet(IconData,14), Int,1, UInt,0x30000, Int,16, Int,16, UInt,0 )
  1576. }
  1577.  
  1578. ; Update the tray icon for the current script
  1579. ; to the icon represented by the handle
  1580. ;
  1581. SetTrayIcon(iconHandle)
  1582. {
  1583.   PID := DllCall("GetCurrentProcessId"), VarSetCapacity( NID,444,0 ), NumPut( 444,NID )
  1584.   DetectHiddenWindows, On
  1585.   NumPut( WinExist( A_ScriptFullPath " ahk_class AutoHotkey ahk_pid " PID),NID,4 )
  1586.   DetectHiddenWindows, Off
  1587.   NumPut( 1028,NID,8 ), NumPut( 2,NID,12 ), NumPut( iconHandle,NID,20 )
  1588.   DllCall( "shell32\Shell_NotifyIcon", UInt,0x1, UInt,&NID )
  1589. }
  1590.  
  1591. ; Set the mouse cursor
  1592. ; Thanks go to Serenity -- http://www.autohotkey.com/forum/topic35600.html
  1593. ;
  1594. SetSystemCursor(cursorHandle)
  1595. {
  1596.   Cursors = 32512,32513,32514,32515,32516,32640,32641,32642,32643,32644,32645,32646,32648,32649,32650,32651
  1597.   Loop, Parse, Cursors, `,
  1598.   {
  1599.     temp := DllCall( "CopyIcon", UInt,cursorHandle)
  1600.     DllCall( "SetSystemCursor", Uint,temp, Int,A_Loopfield )
  1601.   }
  1602. }
  1603.  
  1604. RestoreSystemCursor()
  1605. {
  1606.    DllCall( "SystemParametersInfo", UInt,0x57, UInt,0, UInt,0, UInt,0 )
  1607. }
  1608.  
  1609. ; Update the tray icon automatically
  1610. ; to the Enabled or Disabled state
  1611. ; Called by the menu handler
  1612. ;
  1613. UpdateTrayIcon:
  1614.  if (ScrollDisabled)
  1615.     SetTrayIcon(hIconDisabled)
  1616.   else
  1617.     SetTrayIcon(hIconEnabled)
  1618. Return
  1619.  
  1620. ; Function wrapper to set a tooltip with automatic timeout
  1621. ;
  1622. ToolTip(Text, visibleSec=2)
  1623. {
  1624.   ToolTip, %Text%
  1625.   SetTimer, ToolTipCancel, % abs(visibleSec) * -1000
  1626.   return
  1627.  
  1628.   ToolTipCancel:
  1629.  ToolTip
  1630.   Return
  1631. }
Add Comment
Please, Sign In to add comment