├── README.md ├── LICENSE └── Sources └── Class_ScrollGUI.ahk /README.md: -------------------------------------------------------------------------------- 1 | # Class_ScrollGUI 2 | Creates a scrollable GUI as a parent for AHK GUI windows. 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | 26 | -------------------------------------------------------------------------------- /Sources/Class_ScrollGUI.ahk: -------------------------------------------------------------------------------- 1 | ; ====================================================================================================================== 2 | ; Namepace: ScrollGUI 3 | ; Function: Creates a scrollable GUI as a parent for GUI windows. 4 | ; Tested with: AHK 1.1.20.03 (1.1.20+ required) 5 | ; Tested on: Win 8.1 (x64) 6 | ; License: The Unlicense -> http://unlicense.org 7 | ; Change log: 8 | ; 1.0.00.00/2015-02-06/just me - initial release on ahkscript.org 9 | ; 1.0.01.00/2015-02-08/just me - bug fixes 10 | ; 1.1.00.00/2015-02-13/just me - bug fixes, mouse wheel handling, AutoSize method 11 | ; 1.2.00.00/2015-03-12/just me - mouse wheel handling, resizing, OnMessage, bug fixes 12 | ; ====================================================================================================================== 13 | Class ScrollGUI { 14 | Static Instances := [] 15 | ; =================================================================================================================== 16 | ; __New Creates a scrollable parent window (ScrollGUI) for the passed GUI. 17 | ; Parameters: 18 | ; HGUI - HWND of the GUI child window. 19 | ; Width - Width of the client area of the ScrollGUI. 20 | ; Pass 0 to set the client area to the width of the child GUI. 21 | ; Height - Height of the client area of the ScrollGUI. 22 | ; Pass 0 to set the client area to the height of the child GUI. 23 | ; ----------- Optional: 24 | ; GuiOptions - GUI options to be used when creating the ScrollGUI (e.g. +LabelMyLabel). 25 | ; Default: empty (no options) 26 | ; ScrollBars - Scroll bars to register: 27 | ; 1 : horizontal 28 | ; 2 : vertical 29 | ; 3 : both 30 | ; Default: 3 31 | ; Wheel - Register WM_MOUSEWHEEL / WM_MOUSEHWHEEL messages: 32 | ; 1 : register WM_MOUSEHWHEEL for horizontal scrolling (reqires Win Vista+) 33 | ; 2 : register WM_MOUSEWHEEL for vertical scrolling 34 | ; 3 : register both 35 | ; 4 : register WM_MOUSEWHEEL for vertical and Shift+WM_MOUSEWHEEL for horizontal scrolling 36 | ; Default: 0 37 | ; Return values: 38 | ; On failure: False 39 | ; Remarks: 40 | ; The dimensions of the child GUI are determined internally according to the visible children. 41 | ; The maximum width and height of the parent GUI will be restricted to the dimensions of the child GUI. 42 | ; If you register mouse wheel messages, the messages will be passed to the focused control, unless the mouse 43 | ; is hovering on one of the ScrollGUI's scroll bars. If the control doesn't process the message, it will be 44 | ; returned back to the ScrollGUI. 45 | ; Common controls seem to ignore wheel messages whenever the CTRL is down. So you can use this modifier to 46 | ; scroll the ScrollGUI even if a scrollable control has the focus. 47 | ; =================================================================================================================== 48 | __New(HGUI, Width, Height, GuiOptions := "", ScrollBars := 3, Wheel := 0) { 49 | Static WS_HSCROLL := "0x100000", WS_VSCROLL := "0x200000" 50 | Static FN_SCROLL := ObjBindMethod(ScrollGui, "On_WM_Scroll") 51 | Static FN_SIZE := ObjBindMethod(ScrollGui, "On_WM_Size") 52 | Static FN_WHEEL := ObjBindMethod(ScrollGUI, "On_WM_Wheel") 53 | ScrollBars &= 3 54 | Wheel &= 7 55 | If ((ScrollBars <> 1) && (ScrollBars <> 2) && (ScrollBars <> 3)) 56 | || ((Wheel <> 0) && (Wheel <> 1) && (Wheel <> 2) && (Wheel <> 3) && (Wheel <> 4)) 57 | Return False 58 | If !DllCall("User32.dll\IsWindow", "Ptr", HGUI, "UInt") 59 | Return False 60 | VarSetCapacity(RC, 16, 0) 61 | ; Child GUI 62 | If !This.AutoSize(HGUI, GuiW, GuiH) 63 | Return False 64 | Gui, %HGUI%:-Caption -Resize 65 | Gui, %HGUI%:Show, w%GuiW% h%GuiH% Hide 66 | MaxH := GuiW 67 | MaxV := GuiH 68 | LineH := Ceil(MaxH / 20) 69 | LineV := Ceil(MaxV / 20) 70 | ; ScrollGUI 71 | If (Width = 0) || (Width > MaxH) 72 | Width := MaxH 73 | If (Height = 0) || (Height > MaxV) 74 | Height := MaxV 75 | Styles := (ScrollBars & 1 ? " +" . WS_HSCROLL : "") . (ScrollBars & 2 ? " +" . WS_VSCROLL : "") 76 | Gui, New, %GuiOptions% %Styles% +hwndHWND 77 | Gui, %HWND%:Show, w%Width% h%Height% Hide 78 | Gui, %HWND%:+MaxSize%MaxH%x%MaxV% 79 | PageH := Width + 1 80 | PageV := Height + 1 81 | ; Instance variables 82 | This.HWND := HWND + 0 83 | This.HGUI := HGUI 84 | This.Width := Width 85 | This.Height := Height 86 | This.UseShift := False 87 | If (ScrollBars & 1) { 88 | This.SetScrollInfo(0, {Max: MaxH, Page: PageH, Pos: 0}) ; SB_HORZ = 0 89 | OnMessage(0x0114, FN_SCROLL) ; WM_HSCROLL = 0x0114 90 | If (Wheel & 1) 91 | OnMessage(0x020E, FN_WHEEL) ; WM_MOUSEHWHEEL = 0x020E 92 | Else If (Wheel & 4) { 93 | OnMessage(0x020A, FN_WHEEL) ; WM_MOUSEWHEEL = 0x020A 94 | This.UseShift := True 95 | } 96 | This.MaxH := MaxH 97 | This.LineH := LineH 98 | This.PageH := PageH 99 | This.PosH := 0 100 | This.ScrollH := True 101 | If (Wheel & 5) 102 | This.WheelH := True 103 | } 104 | If (ScrollBars & 2) { 105 | This.SetScrollInfo(1, {Max: MaxV, Page: PageV, Pos: 0}) ; SB_VERT = 1 106 | OnMessage(0x0115, FN_SCROLL) ; WM_VSCROLL = 0x0115 107 | If (Wheel & 6) 108 | OnMessage(0x020A, FN_WHEEL) ; WM_MOUSEWHEEL = 0x020A 109 | This.MaxV := MaxV 110 | This.LineV := LineV 111 | This.PageV := PageV 112 | This.PosV := 0 113 | This.ScrollV := True 114 | If (Wheel & 6) 115 | This.WheelV := True 116 | } 117 | ; Set the position of the child GUI 118 | Gui, %HGUI%:+Parent%HWND% 119 | Gui, %HGUI%:Show, x0 y0 120 | ; Adjust the scroll bars 121 | This.Instances[This.HWND] := &This 122 | This.Size() 123 | OnMessage(0x0005, FN_SIZE) ; WM_SIZE = 0x0005 124 | } 125 | ; =================================================================================================================== 126 | ; __Delete Destroy the GUIs, if they still exist. 127 | ; =================================================================================================================== 128 | __Delete() { 129 | This.Destroy() 130 | } 131 | ; =================================================================================================================== 132 | ; Show Shows the ScrollGUI. 133 | ; Parameters: 134 | ; Title - Title of the ScrollGUI window 135 | ; ShowOptions - Gui, Show command options, width or height options are ignored 136 | ; Return values: 137 | ; On success: True 138 | ; On failure: False 139 | ; =================================================================================================================== 140 | Show(Title := "", ShowOptions := "") { 141 | ShowOptions := RegExReplace(ShowOptions, "i)\+?AutoSize") 142 | W := This.Width 143 | H := This.Height 144 | Gui, % This.HWND . ":Show", %ShowOptions% w%W% h%H%, %Title% 145 | Return True 146 | } 147 | ; =================================================================================================================== 148 | ; Destroy Destroys the ScrollGUI and the associated child GUI. 149 | ; Parameters: 150 | ; None. 151 | ; Return values: 152 | ; On success: True 153 | ; On failure: False 154 | ; Remarks: 155 | ; Use this method instead of 'Gui, Destroy' to remove the ScrollGUI from the 'Instances' object. 156 | ; =================================================================================================================== 157 | Destroy() { 158 | If This.Instances.HasKey(This.HWND) { 159 | Gui, % This.HWND . ":Destroy" 160 | This.Instances.Remove(This.HWND, "") 161 | Return True 162 | } 163 | } 164 | ; =================================================================================================================== 165 | ; AdjustToChild Adjust the scroll bars to the new child dimensions. 166 | ; Parameters: 167 | ; None 168 | ; Return values: 169 | ; On success: True 170 | ; On failure: False 171 | ; Remarks: 172 | ; Call this method whenever the visible area of the child GUI has to be changed, e.g. after adding, hiding, 173 | ; unhiding, resizing, or repositioning controls. 174 | ; The dimensions of the child GUI are determined internally according to the visible children. 175 | ; =================================================================================================================== 176 | AdjustToChild() { 177 | VarSetCapacity(RC, 16, 0) 178 | DllCall("User32.dll\GetWindowRect", "Ptr", This.HGUI, "Ptr", &RC) 179 | PrevW := NumGet(RC, 8, "Int") - NumGet(RC, 0, "Int") 180 | PrevH := Numget(RC, 12, "Int") - NumGet(RC, 4, "Int") 181 | DllCall("User32.dll\ScreenToClient", "Ptr", This.HWND, "Ptr", &RC) 182 | XC := XN := NumGet(RC, 0, "Int") 183 | YC := YN := NumGet(RC, 4, "Int") 184 | If !This.AutoSize(This.HGUI, GuiW, GuiH) 185 | Return False 186 | Gui, % This.HGUI . ":Show", x%XC% y%YC% w%GuiW% h%GuiH% 187 | MaxH := GuiW 188 | MaxV := GuiH 189 | Gui, % This.HWND . ":+MaxSize" . MaxH . "x" . MaxV 190 | If (GuiW < This.Width) || (GuiH < This.Height) { 191 | Gui, % This.HWND . ":Show", w%GuiW% h%GuiH% 192 | This.Width := GuiW 193 | This.SetPage(1, MaxH + 1) 194 | This.Height := GuiH 195 | This.SetPage(2, MaxV + 1) 196 | } 197 | LineH := Ceil(MaxH / 20) 198 | LineV := Ceil(MaxV / 20) 199 | If This.ScrollH { 200 | This.SetMax(1, MaxH) 201 | This.LineH := LineH 202 | If (XC + MaxH) < This.Width { 203 | XN += This.Width - (XC + MaxH) 204 | If (XN > 0) 205 | XN := 0 206 | This.SetScrollInfo(0, {Pos: XN * -1}) 207 | This.GetScrollInfo(0, SI) 208 | This.PosH := NumGet(SI, 20, "Int") 209 | } 210 | } 211 | If This.ScrollV { 212 | This.SetMax(2, MaxV) 213 | This.LineV := LineV 214 | If (YC + MaxV) < This.Height { 215 | YN += This.Height - (YC + MaxV) 216 | If (YN > 0) 217 | YN := 0 218 | This.SetScrollInfo(1, {Pos: YN * -1}) 219 | This.GetScrollInfo(1, SI) 220 | This.PosV := NumGet(SI, 20, "Int") 221 | } 222 | } 223 | If (XC <> XN) || (YC <> YN) 224 | DllCall("User32.dll\ScrollWindow", "Ptr", This.HWND, "Int", XN - XC, "Int", YN - YC, "Ptr", 0, "Ptr", 0) 225 | Return True 226 | } 227 | ; =================================================================================================================== 228 | ; SetMax Sets the width or height of the scrolling area. 229 | ; Parameters: 230 | ; SB - Scroll bar to set the value for: 231 | ; 1 = horizontal 232 | ; 2 = vertical 233 | ; Max - Width respectively height of the scrolling area in pixels 234 | ; Return values: 235 | ; On success: True 236 | ; On failure: False 237 | ; =================================================================================================================== 238 | SetMax(SB, Max) { 239 | ; SB_HORZ = 0, SB_VERT = 1 240 | SB-- 241 | If (SB <> 0) && (SB <> 1) 242 | Return False 243 | If (SB = 0) 244 | This.MaxH := Max 245 | Else 246 | This.MaxV := Max 247 | Return This.SetScrollInfo(SB, {Max: Max}) 248 | } 249 | ; =================================================================================================================== 250 | ; SetLine Sets the number of pixels to scroll by line. 251 | ; Parameters: 252 | ; SB - Scroll bar to set the value for: 253 | ; 1 = horizontal 254 | ; 2 = vertical 255 | ; Line - Number of pixels. 256 | ; Return values: 257 | ; On success: True 258 | ; On failure: False 259 | ; =================================================================================================================== 260 | SetLine(SB, Line) { 261 | ; SB_HORZ = 0, SB_VERT = 1 262 | SB-- 263 | If (SB <> 0) && (SB <> 1) 264 | Return False 265 | If (SB = 0) 266 | This.LineH := Line 267 | Else 268 | This.LineV := Line 269 | Return True 270 | } 271 | ; =================================================================================================================== 272 | ; SetPage Sets the number of pixels to scroll by page. 273 | ; Parameters: 274 | ; SB - Scroll bar to set the value for: 275 | ; 1 = horizontal 276 | ; 2 = vertical 277 | ; Page - Number of pixels. 278 | ; Return values: 279 | ; On success: True 280 | ; On failure: False 281 | ; Remarks: 282 | ; If the ScrollGUI is resizable, the page size will be recalculated automatically while resizing. 283 | ; =================================================================================================================== 284 | SetPage(SB, Page) { 285 | ; SB_HORZ = 0, SB_VERT = 1 286 | SB-- 287 | If (SB <> 0) && (SB <> 1) 288 | Return False 289 | If (SB = 0) 290 | This.PageH := Page 291 | Else 292 | This.PageV := Page 293 | Return This.SetScrollInfo(SB, {Page: Page}) 294 | } 295 | ; =================================================================================================================== 296 | ; Methods for internal or system use!!! 297 | ; =================================================================================================================== 298 | AutoSize(HGUI, ByRef Width, ByRef Height) { 299 | DHW := A_DetectHiddenWindows 300 | DetectHiddenWindows, On 301 | VarSetCapacity(RECT, 16, 0) 302 | Width := Height := 0 303 | HWND := HGUI 304 | CMD := 5 ; GW_CHILD 305 | L := T := R := B := LH := TH := "" 306 | While (HWND := DllCall("GetWindow", "Ptr", HWND, "UInt", CMD, "UPtr")) && (CMD := 2) { 307 | WinGetPos, X, Y, W, H, ahk_id %HWND% 308 | W += X, H += Y 309 | WinGet, Styles, Style, ahk_id %HWND% 310 | If (Styles & 0x10000000) { ; WS_VISIBLE 311 | If (L = "") || (X < L) 312 | L := X 313 | If (T = "") || (Y < T) 314 | T := Y 315 | If (R = "") || (W > R) 316 | R := W 317 | If (B = "") || (H > B) 318 | B := H 319 | } 320 | Else { 321 | If (LH = "") || (X < LH) 322 | LH := X 323 | If (TH = "") || (Y < TH) 324 | TH := Y 325 | } 326 | } 327 | DetectHiddenWindows, %DHW% 328 | If (LH <> "") { 329 | VarSetCapacity(POINT, 8, 0) 330 | NumPut(LH, POINT, 0, "Int") 331 | DllCall("ScreenToClient", "Ptr", HGUI, "Ptr", &POINT) 332 | LH := NumGet(POINT, 0, "Int") 333 | } 334 | If (TH <> "") { 335 | VarSetCapacity(POINT, 8, 0) 336 | NumPut(TH, POINT, 4, "Int") 337 | DllCall("ScreenToClient", "Ptr", HGUI, "Ptr", &POINT) 338 | TH := NumGet(POINT, 4, "Int") 339 | } 340 | NumPut(L, RECT, 0, "Int"), NumPut(T, RECT, 4, "Int") 341 | NumPut(R, RECT, 8, "Int"), NumPut(B, RECT, 12, "Int") 342 | DllCall("MapWindowPoints", "Ptr", 0, "Ptr", HGUI, "Ptr", &RECT, "UInt", 2) 343 | Width := NumGet(RECT, 8, "Int") + (LH <> "" ? LH : NumGet(RECT, 0, "Int")) 344 | Height := NumGet(RECT, 12, "Int") + (TH <> "" ? TH : NumGet(RECT, 4, "Int")) 345 | Return True 346 | } 347 | ; =================================================================================================================== 348 | GetScrollInfo(SB, ByRef SI) { 349 | VarSetCapacity(SI, 28, 0) ; SCROLLINFO 350 | NumPut(28, SI, 0, "UInt") 351 | NumPut(0x17, SI, 4, "UInt") ; SIF_ALL = 0x17 352 | Return DllCall("User32.dll\GetScrollInfo", "Ptr", This.HWND, "Int", SB, "Ptr", &SI, "UInt") 353 | } 354 | ; =================================================================================================================== 355 | SetScrollInfo(SB, Values) { 356 | Static SIF := {Max: 0x01, Page: 0x02, Pos: 0x04} 357 | Static Off := {Max: 12, Page: 16, Pos: 20} 358 | Mask := 0 359 | VarSetCapacity(SI, 28, 0) ; SCROLLINFO 360 | NumPut(28, SI, 0, "UInt") 361 | For Key, Value In Values { 362 | If SIF.HasKey(Key) { 363 | Mask |= SIF[Key] 364 | NumPut(Value, SI, Off[Key], "UInt") 365 | } 366 | } 367 | If (Mask) { 368 | NumPut(Mask | 0x08, SI, 4, "UInt") ; SIF_DISABLENOSCROLL = 0x08 369 | Return DllCall("User32.dll\SetScrollInfo", "Ptr", This.HWND, "Int", SB, "Ptr", &SI, "UInt", 1, "UInt") 370 | } 371 | Return False 372 | } 373 | ; =================================================================================================================== 374 | On_WM_Scroll(WP, LP, Msg, HWND) { 375 | ; WM_HSCROLL = 0x0114, WM_VSCROLL = 0x0115 376 | If (Instance := Object(This.Instances[HWND])) 377 | If ((Msg = 0x0114) && Instance.ScrollH) 378 | || ((Msg = 0x0115) && Instance.ScrollV) 379 | Return Instance.Scroll(WP, LP, Msg, HWND) 380 | } 381 | ; =================================================================================================================== 382 | Scroll(WP, LP, Msg, HWND) { 383 | ; WM_HSCROLL = 0x0114, WM_VSCROLL = 0x0115 384 | Static SB_LINEMINUS := 0, SB_LINEPLUS := 1, SB_PAGEMINUS := 2, SB_PAGEPLUS := 3, SB_THUMBTRACK := 5 385 | If (LP <> 0) 386 | Return 387 | SB := (Msg = 0x0114 ? 0 : 1) ; SB_HORZ : SB_VERT 388 | SC := WP & 0xFFFF 389 | SD := (Msg = 0x0114 ? This.LineH : This.LineV) 390 | SI := 0 391 | If !This.GetScrollInfo(SB, SI) 392 | Return 393 | PA := PN := NumGet(SI, 20, "Int") 394 | PN := (SC = 0) ? PA - SD ; SB_LINEMINUS 395 | : (SC = 1) ? PA + SD ; SB_LINEPLUS 396 | : (SC = 2) ? PA - NumGet(SI, 16, "UInt") ; SB_PAGEMINUS 397 | : (SC = 3) ? PA + NumGet(SI, 16, "UInt") ; SB_PAGEPLUS 398 | : (SC = 5) ? NumGet(SI, 24, "Int") ; SB_THUMBTRACK 399 | : PA 400 | If (PA = PN) 401 | Return 0 402 | This.SetScrollInfo(SB, {Pos: PN}) 403 | This.GetScrollInfo(SB, SI) 404 | PN := NumGet(SI, 20, "Int") 405 | If (SB = 0) 406 | This.PosH := PN 407 | Else 408 | This.PosV := PN 409 | If (PA <> PN) { 410 | HS := (Msg = 0x0114) ? PA - PN : 0 411 | VS := (Msg = 0x0115) ? PA - PN : 0 412 | DllCall("User32.dll\ScrollWindow", "Ptr", This.HWND, "Int", HS, "Int", VS, "Ptr", 0, "Ptr", 0) 413 | } 414 | Return 0 415 | } 416 | ; =================================================================================================================== 417 | On_WM_Size(WP, LP, Msg, HWND) { 418 | If ((WP = 0) || (WP = 2)) && (Instance := Object(This.Instances[HWND])) 419 | Return Instance.Size(LP & 0xFFFF, (LP >> 16) & 0xFFFF) 420 | } 421 | ; =================================================================================================================== 422 | Size(Width := 0, Height := 0) { 423 | If (Width = 0) || (Height = 0) { 424 | VarSetCapacity(RC, 16, 0) 425 | DllCall("User32.dll\GetClientRect", "Ptr", This.HWND, "Ptr", &RC) 426 | Width := NumGet(RC, 8, "Int") 427 | Height := Numget(RC, 12, "Int") 428 | } 429 | SH := SV := 0 430 | If This.ScrollH { 431 | If (Width <> This.Width) { 432 | This.SetScrollInfo(0, {Page: Width + 1}) 433 | This.Width := Width 434 | This.GetScrollInfo(0, SI) 435 | PosH := NumGet(SI, 20, "Int") 436 | SH := This.PosH - PosH 437 | This.PosH := PosH 438 | } 439 | } 440 | If This.ScrollV { 441 | If (Height <> This.Height) { 442 | This.SetScrollInfo(1, {Page: Height + 1}) 443 | This.Height := Height 444 | This.GetScrollInfo(1, SI) 445 | PosV := NumGet(SI, 20, "Int") 446 | SV := This.PosV - PosV 447 | This.PosV := PosV 448 | } 449 | } 450 | If (SH) || (SV) 451 | DllCall("User32.dll\ScrollWindow", "Ptr", This.HWND, "Int", SH, "Int", SV, "Ptr", 0, "Ptr", 0) 452 | Return 0 453 | } 454 | ; =================================================================================================================== 455 | On_WM_Wheel(WP, LP, Msg, HWND) { 456 | ; MK_SHIFT = 0x0004, WM_MOUSEWHEEL = 0x020A, WM_MOUSEHWHEEL = 0x020E, WM_NCHITTEST = 0x0084 457 | HACT := WinActive("A") + 0 458 | If (HACT <> HWND) && (Instance := Object(This.Instances[HACT])) { 459 | SendMessage, 0x0084, 0, % (LP & 0xFFFFFFFF), , ahk_id %HACT% 460 | OnBar := ErrorLevel 461 | If (OnBar = 6) && Instance.WheelH ; HTHSCROLL = 6 462 | Return Instance.Wheel(WP, LP, 0x020E, HACT) 463 | If (OnBar = 7) && Instance.WheelV ; HTVSCROLL = 7 464 | Return Instance.Wheel(WP, LP, 0x020A, HACT) 465 | } 466 | If (Instance := Object(This.Instances[HWND])) { 467 | If ((Msg = 0x020E) && Instance.WheelH) 468 | || ((Msg = 0x020A) && (Instance.WheelV || (Instance.WheelH && Instance.UseShift && (WP & 0x0004)))) 469 | Return Instance.Wheel(WP, LP, Msg, HWND) 470 | } 471 | } 472 | ; =================================================================================================================== 473 | Wheel(WP, LP, Msg, HWND) { 474 | ; MK_SHIFT = 0x0004, WM_MOUSEWHEEL = 0x020A, WM_MOUSEHWHEEL = 0x020E, WM_HSCROLL = 0x0114, WM_VSCROLL = 0x0115 475 | ; SB_LINEMINUS = 0, SB_LINEPLUS = 1 476 | If (Msg = 0x020A) && This.UseShift && (WP & 0x0004) 477 | Msg := 0x020E 478 | Msg := (Msg = 0x020A ? 0x0115 : 0x0114) 479 | SB := ((WP >> 16) > 0x7FFF) || (WP < 0) ? 1 : 0 480 | Return This.Scroll(SB, 0, Msg, HWND) 481 | } 482 | } --------------------------------------------------------------------------------