Aktualisierung der Klasse Class_ScrollGUI auf AuotHotkey Version 2 Topic is solved
Moderator: jNizM
-
- Posts: 120
- Joined: 17 Jul 2019, 08:49
Aktualisierung der Klasse Class_ScrollGUI auf AuotHotkey Version 2
Hallo zusammen,
wurde die Klasse "Class_ScrollGUI" von just me auf AHK V2 aktualisiert?
vielen Dank im Voraus!
wurde die Klasse "Class_ScrollGUI" von just me auf AHK V2 aktualisiert?
vielen Dank im Voraus!
Re: Aktualisierung der Klasse Class_ScrollGUI auf AuotHotkey Version 2
Moin @Nussbeisser,
ich habe noch eine weitgehend umgestellte Version gefunden (die Methode AdjustToChild() fehlt). Du kannst das ja mal ausprobieren:
Minibeispiel:
ich habe noch eine weitgehend umgestellte Version gefunden (die Methode AdjustToChild() fehlt). Du kannst das ja mal ausprobieren:
Code: Select all
#Requires AutoHotkey v2.0
; ======================================================================================================================
; Namepace: ScrollGUI
; Function: Creates a scrollable GUI as a parent for GUI windows.
; Tested with: AHK 2.0.2
; Tested on: Win 10 Pro (x64)
; License: The Unlicense -> http://unlicense.org
; Change log: 2.0.0/2023-01-??/just me - Initial release for AHK v2
; ======================================================================================================================
Class ScrollGUI {
; ===================================================================================================================
; __New Creates a scrollable parent window (ScrollGUI) for the passed GUI.
; Parameters:
; Child - The GUI object of the child window.
; Width - Width of the client area of the ScrollGUI.
; Pass 0 to set the client area to the width of the child GUI.
; Height - Height of the client area of the ScrollGUI.
; Pass 0 to set the client area to the height of the child GUI.
; ----------- Optional:
; GuiOpts - GUI options to be used when creating the ScrollGUI (e.g. +LabelMyLabel).
; Default: empty (no options)
; ScrollBars - Scroll bars to register:
; 1 : horizontal
; 2 : vertical
; 3 : both
; Default: 3
; Wheel - Register WM_MOUSEWHEEL / WM_MOUSEHWHEEL messages:
; 1 : register WM_MOUSEHWHEEL for horizontal scrolling (reqires Win Vista+)
; 2 : register WM_MOUSEWHEEL for vertical scrolling
; 3 : register both
; 4 : register WM_MOUSEWHEEL for vertical and Shift+WM_MOUSEWHEEL for horizontal scrolling
; Default: 0
; Return values:
; On failure: False
; Remarks:
; The dimensions of the child GUI are determined internally according to the visible children.
; The maximum width and height of the parent GUI will be restricted to the dimensions of the child GUI.
; If you register mouse wheel messages, the messages will be passed to the focused control, unless the mouse
; is hovering on one of the ScrollGUI's scroll bars. If the control doesn't process the message, it will be
; returned back to the ScrollGUI.
; Common controls seem to ignore wheel messages whenever the CTRL is down. So you can use this modifier to
; scroll the ScrollGUI even if a scrollable control has the focus.
; ===================================================================================================================
BF_SCROLL := 0
BF_SIZE := 0
BF_WHEEL := 0
Child := 0
Parent := 0
; ===================================================================================================================
__New(Child, Width := 0, Height := 0, GuiOpts := "", ScrollBars := 3, Wheel := 0) {
Static WS_HSCROLL := "0x100000", WS_VSCROLL := "0x200000"
If !(Type(Child) = "Gui")
Throw TypeError("Paramweter Child must be a Gui object!", -1, Type(Child))
HGUI := Child.Hwnd
If !(Type(Width) = "Integer")
Throw TypeError("Paramweter Width must be an integer!", -1, Type(Width))
If !(Type(Height) = "Integer")
Throw TypeError("Paramweter Height must be an integer!", -1, Type(Height))
If !(Type(ScrollBars) = "Integer")
Throw TypeError("Paramweter ScrollBars must be an integer!", -1, Type(ScrollBars))
If !(Type(Wheel) = "Integer")
Throw TypeError("Paramweter Wheel must be an integer!", -1, Type(Wheel))
Bars := ScrollBars & 3
Wheel &= 7
If (Bars = 0)
Throw ValueError("Paramweter ScrollBars must be an integer between 1 and 3!", -1, ScrollBars)
AutoSize := (Width = -1)
This.BF_SCROLL := ObjBindMethod(This, "On_WM_Scroll")
This.BF_SIZE := ObjBindMethod(This, "On_WM_Size")
This.BF_WHEEL := ObjBindMethod(This, "On_WM_Wheel")
Child.Opt("-Caption -Resize")
Child.Show((AutoSize ? "AutoSize " : "") . "Hide")
Child.GetClientPos( , , &GW, &GH)
WinGetClientPos( , , &CW, &CH, Child.Hwnd)
MaxH := CW
MaxV := CH
LineH := Ceil(MaxH / 20)
LineV := Ceil(MaxV / 20)
; ScrollGUI
If (Width = 0)
Width := GW
If (Height = 0)
Height := GH
Styles := (Bars & 1 ? " +" . WS_HSCROLL : "") . (Bars & 2 ? " +" . WS_VSCROLL : "")
Parent := Gui(GuiOpts . Styles)
Parent.Show("w" . Width . " h" . Height . " Hide")
If AutoSize
Parent.Opt("+MaxSize" . GW . "x" . GH)
WinGetClientPos( , , &CW, &CH, Parent.Hwnd)
PageH := CW + 1
PageV := CH + 1
; Instance variables
This.Parent := Parent
This.Child := Child
This.Width := Width
This.Height := Height
This.UseShift := False
If (Bars & 1) {
This.SetScrollInfo(0, {Max: MaxH, Page: PageH, Pos: 0}) ; SB_HORZ = 0
OnMessage(0x0114, This.BF_SCROLL) ; WM_HSCROLL = 0x0114
If (Wheel & 1)
OnMessage(0x020E, This.BF_WHEEL) ; WM_MOUSEHWHEEL = 0x020E
Else If (Wheel & 4) {
OnMessage(0x020A, This.BF_WHEEL) ; WM_MOUSEWHEEL = 0x020A
This.UseShift := True
}
This.MaxH := MaxH
This.LineH := LineH
This.PageH := PageH
This.PosH := 0
This.ScrollH := True
If (Wheel & 5)
This.WheelH := True
}
If (Bars & 2) {
This.SetScrollInfo(1, {Max: MaxV, Page: PageV, Pos: 0}) ; SB_VERT = 1
OnMessage(0x0115, This.BF_SCROLL) ; WM_VSCROLL = 0x0115
If (Wheel & 6)
OnMessage(0x020A, This.BF_WHEEL) ; WM_MOUSEWHEEL = 0x020A
This.MaxV := MaxV
This.LineV := LineV
This.PageV := PageV
This.PosV := 0
This.ScrollV := True
If (Wheel & 6)
This.WheelV := True
}
; Set the position of the child GUI
Child.Opt("+Parent" . Parent.Hwnd)
Child.Show("x0 y0")
; Adjust the scroll bars
This.Size()
OnMessage(0x0005, This.BF_SIZE) ; WM_SIZE = 0x0005
}
; ===================================================================================================================
; __Delete Destroy the GUIs, if they still exist.
; ===================================================================================================================
__Delete() {
This.Destroy()
}
; ===================================================================================================================
; Show Shows the ScrollGUI.
; Parameters:
; Title - Title of the ScrollGUI window
; ShowOptions - Gui, Show command options, width or height options are ignored
; Return values:
; On success: True
; On failure: False
; ===================================================================================================================
Show(Title := "", ShowOptions := "") {
ShowOptions := RegExReplace(ShowOptions, "i)\+?AutoSize")
WH := Format(" w{:} h{:}", This.Width, This.Height)
If Title != ""
This.Parent.Title := Title
This.Parent.Show(ShowOptions . WH)
Return True
}
; ===================================================================================================================
; Destroy Destroys the ScrollGUI and the associated child GUI.
; Parameters:
; None.
; Return values:
; On success: True
; On failure: False
; Remarks:
; Use this method instead of 'Gui, Destroy' to remove the ScrollGUI from the 'Instances' object.
; ===================================================================================================================
Destroy() {
If This.Parent {
This.Parent.Destroy()
This.Parent := 0
}
If This.BF_SCROLL {
OnMessage(0x0114, This.BF_SCROLL, 0) ; WM_HSCROLL = 0x0114
This.BF_SCROLL := 0
}
If This.BF_SIZE {
OnMessage(0x0005, This.BF_SIZE, 0) ; WM_SIZE = 0x0005
This.BF_SIZE := 0
}
If This.This.BF_WHEEL {
OnMessage(0x020A, This.BF_WHEEL, 0) ; WM_MOUSEWHEEL = 0x020A
OnMessage(0x020E, This.BF_WHEEL, 0) ; WM_MOUSEHWHEEL = 0x020E
This.BF_WHEEL := 0
}
Return True
}
; ===================================================================================================================
; AdjustToChild Adjust the scroll bars to the new child dimensions.
; Parameters:
; None
; Return values:
; On success: True
; On failure: False
; Remarks:
; Call this method whenever the visible area of the child GUI has to be changed, e.g. after adding, hiding,
; unhiding, resizing, or repositioning controls.
; The dimensions of the child GUI are determined internally according to the visible children.
; ===================================================================================================================
AdjustToChild() {
; This.Child.GetPos(&CX, &CY, &CW, &CH)
; VarSetCapacity(RC, 16, 0)
; DllCall("User32.dll\GetWindowRect", "Ptr", This.HGUI, "Ptr", &RC)
; PrevW := NumGet(RC, 8, "Int") - NumGet(RC, 0, "Int")
; PrevH := Numget(RC, 12, "Int") - NumGet(RC, 4, "Int")
; DllCall("User32.dll\ScreenToClient", "Ptr", This.HWND, "Ptr", &RC)
; XC := XN := NumGet(RC, 0, "Int")
; YC := YN := NumGet(RC, 4, "Int")
; If !This.AutoSize(This.HGUI, GuiW, GuiH)
; Return False
; Gui, % This.HGUI . ":Show", x%XC% y%YC% w%GuiW% h%GuiH%
; MaxH := GuiW
; MaxV := GuiH
; Gui, % This.HWND . ":+MaxSize" . MaxH . "x" . MaxV
; If (GuiW < This.Width) || (GuiH < This.Height) {
; Gui, % This.HWND . ":Show", w%GuiW% h%GuiH%
; This.Width := GuiW
; This.SetPage(1, MaxH + 1)
; This.Height := GuiH
; This.SetPage(2, MaxV + 1)
; }
; LineH := Ceil(MaxH / 20)
; LineV := Ceil(MaxV / 20)
; If This.ScrollH {
; This.SetMax(1, MaxH)
; This.LineH := LineH
; If (XC + MaxH) < This.Width {
; XN += This.Width - (XC + MaxH)
; If (XN > 0)
; XN := 0
; This.SetScrollInfo(0, {Pos: XN * -1})
; This.GetScrollInfo(0, SI)
; This.PosH := NumGet(SI, 20, "Int")
; }
; }
; If This.ScrollV {
; This.SetMax(2, MaxV)
; This.LineV := LineV
; If (YC + MaxV) < This.Height {
; YN += This.Height - (YC + MaxV)
; If (YN > 0)
; YN := 0
; This.SetScrollInfo(1, {Pos: YN * -1})
; This.GetScrollInfo(1, SI)
; This.PosV := NumGet(SI, 20, "Int")
; }
; }
; If (XC != XN) || (YC != YN)
; DllCall("User32.dll\ScrollWindow", "Ptr", This.Parent.Hwnd, "Int", XN - XC, "Int", YN - YC, "Ptr", 0, "Ptr", 0)
Return True
}
; ===================================================================================================================
; SetMax Sets the width or height of the scrolling area.
; Parameters:
; SB - Scroll bar to set the value for:
; 1 = horizontal
; 2 = vertical
; Max - Width respectively height of the scrolling area in pixels
; Return values:
; On success: True
; On failure: False
; ===================================================================================================================
SetMax(SB, Max) {
; SB_HORZ = 0, SB_VERT = 1
SB--
If (SB != 0) && (SB != 1)
Return False
If (SB = 0)
This.MaxH := Max
Else
This.MaxV := Max
Return This.SetScrollInfo(SB, {Max: Max})
}
; ===================================================================================================================
; SetLine Sets the number of pixels to scroll by line.
; Parameters:
; SB - Scroll bar to set the value for:
; 1 = horizontal
; 2 = vertical
; Line - Number of pixels.
; Return values:
; On success: True
; On failure: False
; ===================================================================================================================
SetLine(SB, Line) {
; SB_HORZ = 0, SB_VERT = 1
SB--
If (SB != 0) && (SB != 1)
Return False
If (SB = 0)
This.LineH := Line
Else
This.LineV := Line
Return True
}
; ===================================================================================================================
; SetPage Sets the number of pixels to scroll by page.
; Parameters:
; SB - Scroll bar to set the value for:
; 1 = horizontal
; 2 = vertical
; Page - Number of pixels.
; Return values:
; On success: True
; On failure: False
; Remarks:
; If the ScrollGUI is resizable, the page size will be recalculated automatically while resizing.
; ===================================================================================================================
SetPage(SB, Page) {
; SB_HORZ = 0, SB_VERT = 1
SB--
If (SB != 0) && (SB != 1)
Return False
If (SB = 0)
This.PageH := Page
Else
This.PageV := Page
Return This.SetScrollInfo(SB, {Page: Page})
}
; ===================================================================================================================
GetScrollInfo(SB, &SI) {
SI := Buffer(28, 0) ; SCROLLINFO
NumPut("UInt", 28, "UInt", 0x17, SI) ; SIF_ALL = 0x17
Return DllCall("GetScrollInfo", "Ptr", This.Parent.Hwnd, "Int", SB, "Ptr", SI, "UInt")
}
; ===================================================================================================================
SetScrollInfo(SB, Values) {
Static SIF := {Max: 0x01, Page: 0x02, Pos: 0x04}
Static Off := {Max: 12, Page: 16, Pos: 20}
Mask := 0
SI := Buffer(28, 0) ; SCROLLINFO
NumPut("UInt", 28, SI)
For Key, Value In Values.OwnProps() {
If SIF.HasProp(Key) {
Mask |= SIF.%Key%
NumPut("UInt", Value, SI, Off.%Key%)
}
}
If (Mask) {
NumPut("UInt", Mask | 0x08, SI, 4) ; SIF_DISABLENOSCROLL = 0x08
Return DllCall("SetScrollInfo", "Ptr", This.Parent.Hwnd, "Int", SB, "Ptr", SI, "UInt", 1, "UInt")
}
Return False
}
; ===================================================================================================================
On_WM_Scroll(WP, LP, Msg, HWND) {
; WM_HSCROLL = 0x0114, WM_VSCROLL = 0x0115
If (HWND = This.Parent.Hwnd) && (((Msg = 0x0114) && This.ScrollH) || ((Msg = 0x0115) && This.ScrollV))
Return This.Scroll(WP, LP, Msg, HWND)
}
; ===================================================================================================================
Scroll(WP, LP, Msg, HWND) {
; WM_HSCROLL = 0x0114, WM_VSCROLL = 0x0115
Static SB_LINEMINUS := 0, SB_LINEPLUS := 1, SB_PAGEMINUS := 2, SB_PAGEPLUS := 3, SB_THUMBTRACK := 5
If (LP != 0)
Return
SB := (Msg = 0x0114 ? 0 : 1) ; SB_HORZ : SB_VERT
SC := WP & 0xFFFF
SD := (Msg = 0x0114 ? This.LineH : This.LineV)
SI := 0
If !This.GetScrollInfo(SB, &SI)
Return
PA := PN := NumGet(SI, 20, "Int")
Switch SC {
Case 0: PN := PA - SD ; SB_LINEMINUS
Case 1: PN := PA + SD ; SB_LINEPLUS
Case 2: PN := PA - NumGet(SI, 16, "UInt") ; SB_PAGEMINUS
Case 3: PN := PA + NumGet(SI, 16, "UInt") ; SB_PAGEPLUS
Case 5: PN := NumGet(SI, 24, "Int") ; SB_THUMBTRACK
}
If (PN = PA)
Return 0
This.SetScrollInfo(SB, {Pos: PN})
This.GetScrollInfo(SB, &SI)
PN := NumGet(SI, 20, "Int")
If (SB = 0)
This.PosH := PN
Else
This.PosV := PN
If (PA != PN) {
HS := (Msg = 0x0114) ? PA - PN : 0
VS := (Msg = 0x0115) ? PA - PN : 0
DllCall("ScrollWindow", "Ptr", HWND, "Int", HS, "Int", VS, "Ptr", 0, "Ptr", 0)
}
Return 0
}
; ===================================================================================================================
On_WM_Size(WP, LP, Msg, HWND) {
If (HWND = This.Parent.Hwnd) && ((WP = 0) || (WP = 2))
Return This.Size(LP & 0xFFFF, (LP >> 16) & 0xFFFF)
}
; ===================================================================================================================
Size(Width := 0, Height := 0) {
If (Width = 0) || (Height = 0)
WinGetClientPos( , , &Width, &Height, This.Parent.Hwnd)
SH := SV := 0
If This.ScrollH && (Width != This.Width) {
This.SetScrollInfo(0, {Page: Width + 1}),
This.Width := Width,
This.GetScrollInfo(0, &SI),
PosH := NumGet(SI, 20, "Int"),
SH := This.PosH - PosH,
This.PosH := PosH
}
If This.ScrollV && (Height != This.Height) {
This.SetScrollInfo(1, {Page: Height + 1}),
This.Height := Height,
This.GetScrollInfo(1, &SI),
PosV := NumGet(SI, 20, "Int"),
SV := This.PosV - PosV,
This.PosV := PosV
}
If (SH) || (SV)
DllCall("User32.dll\ScrollWindow", "Ptr", This.Parent.Hwnd, "Int", SH, "Int", SV, "Ptr", 0, "Ptr", 0)
Return 0
}
; ===================================================================================================================
On_WM_Wheel(WP, LP, Msg, HWND) {
; MK_SHIFT = 0x0004, WM_MOUSEWHEEL = 0x020A, WM_MOUSEHWHEEL = 0x020E, WM_NCHITTEST = 0x0084
If (HWND != This.Parent.Hwnd) {
If (WinActive("A") = This.Parent.Hwnd) {
OnBar := SendMessage(0x0084, 0, LP & 0xFFFFFFFF, This.Parent.Hwnd)
If (OnBar = 6) && This.WheelH ; HTHSCROLL = 6
Return This.Wheel(WP, LP, 0x020E, This.Parent.Hwnd)
If (OnBar = 7) && This.WheelV ; HTVSCROLL = 7
Return This.Wheel(WP, LP, 0x020A, This.Parent.Hwnd)
}
}
Else If ((Msg = 0x020E) && This.WheelH) ||
((Msg = 0x020A) && (This.WheelV || (This.WheelH && This.UseShift && (WP & 0x0004))))
Return This.Wheel(WP, LP, Msg, HWND)
}
; ===================================================================================================================
Wheel(WP, LP, Msg, HWND) {
; MK_SHIFT = 0x0004, WM_MOUSEWHEEL = 0x020A, WM_MOUSEHWHEEL = 0x020E, WM_HSCROLL = 0x0114, WM_VSCROLL = 0x0115
; SB_LINEMINUS = 0, SB_LINEPLUS = 1
If (Msg = 0x020A) && This.UseShift && (WP & 0x0004)
Msg := 0x020E
Msg := (Msg = 0x020A ? 0x0115 : 0x0114)
SB := ((WP >> 16) > 0x7FFF) || (WP < 0) ? 1 : 0
Return This.Scroll(SB, 0, Msg, HWND)
}
}
Code: Select all
#Requires AutoHotkey v2.0.0
#Include Class_ScrollGUI.ahk
; -------------------------------------------------------------------------------------------------------------------
; ChildGUI 1
Lines := "1`n2`n3`n4`n5`n6`n7`n8"
ChildGui := Gui()
ChildGui.MarginX := 20
ChildGui.MarginY := 20
I := 0
ChildGui.AddText("w370 h20 0x200 Section", "Edit " . ++I)
ChildGui.AddEdit("xp y+0 wp r6")
Loop 4 {
ChildGui.AddText("xp y+0 wp h20 0x200", "Edit " . ++I)
ChildGui.AddEdit("xp y+0 wp r6", Lines)
}
ChildGui.AddText("ys wp h20 0x200", "Edit " . ++I)
ChildGui.AddEdit("xp y+0 wp r6")
Loop 4 {
ChildGui.AddText("xp y+0 wp h20 0x200", "Edit " . ++I)
ChildGui.AddEdit("xp y+0 wp r6", Lines)
}
; Create ScrollGUI1 with both horizontal and vertical scrollbars
SG1 := ScrollGUI(ChildGui, 300, 400, "+Resize +MinSize", , 3)
SG1.Parent.OnEvent("Close", Scroll1Close)
SG1.Parent.OnEvent("Escape", Scroll1Close)
; Show ScrollGUI1
SG1.Show("ScrollGUI1 Title", "")
Return
; ----------------------------------------------------------------------------------------------------------------------
Scroll1Close(*) {
ExitApp
}
-
- Posts: 120
- Joined: 17 Jul 2019, 08:49
Re: Aktualisierung der Klasse Class_ScrollGUI auf AuotHotkey Version 2
Hallo @Just me
Vielen Dank für deine Mühe!
Jetzt habe ich versucht, meine Schaltflächen zu platzieren, aber die letzte 3 erscheinen nicht.
Muss ich beim Positionieren auf etwas Bestimmtes achten?
SG1.Parent.OnEvent("Close", Scroll1Close) funktioniert bei mir nicht.
Das konnte mich mit ChildGui.OnEvent("Close", Scroll1Close) zum laufen bringen.
Vielen Dank für deine Mühe!
Jetzt habe ich versucht, meine Schaltflächen zu platzieren, aber die letzte 3 erscheinen nicht.
Muss ich beim Positionieren auf etwas Bestimmtes achten?
Code: Select all
#Requires AutoHotkey v2.0.0
#Include Class_ScrollGUI.ahk
; -------------------------------------------------------------------------------------------------------------------
; ChildGUI 1
Lines := "1`n2`n3`n4`n5`n6`n7`n8"
ChildGui := Gui()
ChildGui.MarginX := 20
ChildGui.MarginY := 20
I := 0
ChildGui.AddText("w370 h20 0x200 Section", "Edit " . ++I)
ChildGui.AddEdit("xp y+0 wp r6")
Loop 4 {
ChildGui.AddText("xp y+0 wp h20 0x200", "Edit " . ++I)
ChildGui.AddEdit("xp y+0 wp r6", Lines)
}
ChildGui.AddText("ys wp h20 0x200", "Edit " . ++I)
ChildGui.AddEdit("xp y+0 wp r6")
Loop 4 {
ChildGui.AddText("xp y+0 wp h20 0x200", "Edit " . ++I)
ChildGui.AddEdit("xp y+0 wp r6", Lines)
}
ChildGui.SetFont("Norm","verdana")
MeinBtn := ChildGui.Add("Button", "Default w80 xm", "Starten")
MeinBtn := ChildGui.Add("Button", "w80", "Schliessen")
MeinBtn := ChildGui.Add("Button", " w80", "Speichern")
MeinBtn := ChildGui.Add("Button", "w80", "Öffnen")
MeinBtn := ChildGui.Add("Button", "w80 x+", "Ignorieren")
MeinBtn := ChildGui.Add("Button", "w80 x+", "Hilfe")
; Create ScrollGUI1 with both horizontal and vertical scrollbars
SG1 := ScrollGUI(ChildGui, 300, 400, "+Resize +MinSize", , 3)
SG1.Parent.OnEvent("Close", Scroll1Close)
SG1.Parent.OnEvent("Escape", Scroll1Close)
; Show ScrollGUI1
SG1.Show("ScrollGUI1 Title", "")
Return
; ----------------------------------------------------------------------------------------------------------------------
Scroll1Close(*) {
ExitApp
}
SG1.Parent.OnEvent("Close", Scroll1Close) funktioniert bei mir nicht.
Das konnte mich mit ChildGui.OnEvent("Close", Scroll1Close) zum laufen bringen.
Re: Aktualisierung der Klasse Class_ScrollGUI auf AuotHotkey Version 2
Moin,
ich kann Deine Probleme nicht nachvollziehen. Arbeitest Du mit einem Display mit einer Auflösung ungleich 96 DPI?
ich kann Deine Probleme nicht nachvollziehen. Arbeitest Du mit einem Display mit einer Auflösung ungleich 96 DPI?
-
- Posts: 120
- Joined: 17 Jul 2019, 08:49
Re: Aktualisierung der Klasse Class_ScrollGUI auf AuotHotkey Version 2
Hallo Just me,
an DPI habe ich gar nicht gedacht. Ich habe einen 4K-Monitor, und bei voller Auflösung ist immer alles zu klein. Daher habe ich die Auflösung heruntergestellt. Wenn ich die empfohlene Auflösung wähle, sind die Schaltflächen an der richtigen Stelle.
an DPI habe ich gar nicht gedacht. Ich habe einen 4K-Monitor, und bei voller Auflösung ist immer alles zu klein. Daher habe ich die Auflösung heruntergestellt. Wenn ich die empfohlene Auflösung wähle, sind die Schaltflächen an der richtigen Stelle.
Re: Aktualisierung der Klasse Class_ScrollGUI auf AuotHotkey Version 2
Ok, ich schaue mal, ob mir dazu etwas Kluges einfällt.
Ich melde mich wieder.
Ich melde mich wieder.
Re: Aktualisierung der Klasse Class_ScrollGUI auf AuotHotkey Version 2
Moin @Nussbeisser,
das hat etwas länger gedauert als ursprünglich gedacht. Ich habe hier mal eine aktualisierte Sammlung von Funktionen als Ersatz für die Klasse. Einige der neuen Eigenschaften von v2 erleichtern das erheblich. Die einzige Funktion, die Du brauchst, ist ScrollGUI_Init(). Die wird aufgerufen, wenn das Fenster anzeigebereit ist, also kurz vor dem Gui.Show(). Ein übergestülptes 'Elternfenster' gibt es nicht mehr. Alle Einstellungen des bisherigen 'Kindfensters' werden direkt übernommen. Probier doch mal bitte, ob das auch mit der veränderten Bildschirmauflösung funktioniert.
das hat etwas länger gedauert als ursprünglich gedacht. Ich habe hier mal eine aktualisierte Sammlung von Funktionen als Ersatz für die Klasse. Einige der neuen Eigenschaften von v2 erleichtern das erheblich. Die einzige Funktion, die Du brauchst, ist ScrollGUI_Init(). Die wird aufgerufen, wenn das Fenster anzeigebereit ist, also kurz vor dem Gui.Show(). Ein übergestülptes 'Elternfenster' gibt es nicht mehr. Alle Einstellungen des bisherigen 'Kindfensters' werden direkt übernommen. Probier doch mal bitte, ob das auch mit der veränderten Bildschirmauflösung funktioniert.
Code: Select all
#Requires AutoHotkey v2.0
Lines := "1`n2`n3`n4`n5`n6`n7`n8"
MainGui := Gui("+Resize +MinSize")
MainGui.MarginX := 20
MainGui.MarginY := 20
I := 0
MainGui.AddText("w370 h20 0x200 Section", "Edit " . ++I)
MainGui.AddEdit("xp y+0 wp r6")
Loop 4 {
MainGui.AddText("xp y+0 wp h20 0x200", "Edit " . ++I)
MainGui.AddEdit("xp y+0 wp r6", Lines)
}
MainGui.AddText("ys wp h20 0x200", "Edit " . ++I)
MainGui.AddEdit("xp y+0 wp r6")
Loop 4 {
MainGui.AddText("xp y+0 wp h20 0x200", "Edit " . ++I)
MainGui.AddEdit("xp y+0 wp r6", Lines)
}
MainGui.SetFont("Norm", "Verdana")
Btn1 := MainGui.Add("Button", "xm w80 Default", "Starten")
Btn2 := MainGui.Add("Button", "xm w80", "Schliessen")
Btn3 := MainGui.Add("Button", "xm w80", "Speichern")
Btn4 := MainGui.Add("Button", "xm w80", "Öffnen")
Btn5 := MainGui.Add("Button", "x+m yp w80", "Ignorieren")
Btn6 := MainGui.Add("Button", "x+m yp w80", "Hilfe")
ScrollGui_InitGui(MainGui, , 4)
MainGui.Show("w300 h300")
;=======================================================================================================================
; Namepace: ScrollGUI
; Function: Functions to make a GUI window scrollable.
; Tested with: AHK 2.0.13
; Tested on: Win 10 Pro (x64)
; License: The Unlicense -> http://unlicense.org
; Change log: 1.0.0/2024-04-21/just me - Initial release
;=======================================================================================================================
; Prepares a GUI window to be scrollable.
; Parameters:
; GuiObj - GUI object
; Bars - Scroll bars to register:
; 1 : horizontal
; 2 : vertical
; 3 : both
; Default: 3
; Wheels - Register WM_MOUSEWHEEL / WM_MOUSEHWHEEL messages:
; 1 : register WM_MOUSEHWHEEL for horizontal scrolling (reqires Win Vista+)
; 2 : register WM_MOUSEWHEEL for vertical scrolling
; 3 : register both
; 4 : register WM_MOUSEWHEEL for vertical and Shift+WM_MOUSEWHEEL for horizontal scrolling
; Default: 0
; Return value:
; None
;=======================================================================================================================
ScrollGui_InitGui(GuiObj, Bars := 3, Wheels := 0) {
Static ScrollH := 0, ScrollV := 0, WheelH := 0, WheelV := 0
If !(GuiObj Is Gui)
Throw TypeError("Paramweter GuiObj must be an GUI object!", -1, Type(GuiObj))
If !(Type(Bars) = "Integer")
Throw TypeError("Paramweter Bars must be an integer!", -1, Type(Bars))
If (Bars < 1) || (Bars > 3)
Throw ValueError("Paramweter Bars must be an integer between 1 and 3!", -1, Bars)
If !(Type(Wheels) = "Integer")
Throw TypeError("Paramweter Wheels must be an integer!", -1, Type(Wheels))
If (Wheels < 0) || (Wheels > 4)
Throw ValueError("Paramweter Wheels must be an integer between 0 and 4!", -1, Wheels)
GuiObj.Opt((Bars & 1 ? "+" : "-") . "0x100000") ; WS_HSCROLL
GuiObj.Opt((Bars & 2 ? "+" : "-") . "0x200000") ; WS_VSCROLL
GuiObj.Opt("+Resize")
If (Bars & 1) {
If (ScrollH = 0) {
OnMessage(0x0114, ScrollGui_Scroll) ; WM_HSCROLL
ScrollH := 1
}
If (Wheels & 1) && (WheelH = 0) {
OnMessage(0x020E, ScrollGui_Wheel) ; WM_MOUSEHWHEEL = 0x020E
WheelH := 1
}
If (Wheels & 4) && (WheelV = 0) {
OnMessage(0x020A, ScrollGui_Wheel) ; WM_MOUSEWHEEL = 0x020A
WheelV := 1
}
}
If (Bars & 2) {
If (ScrollV = 0) {
OnMessage(0x0115, ScrollGui_Scroll) ; WM_VSCROLL
ScrollV := 1
}
If (Wheels & 6) && (WheelV = 0) {
OnMessage(0x020A, ScrollGui_Wheel) ; WM_MOUSEWHEEL = 0x020A
WheelV := 1
}
}
GuiObj.OnEvent("Size", ScrollGui_Size)
GuiObj.ScrollInfo := {Bars: Bars, Wheels: Wheels}
}
;=======================================================================================================================
ScrollGui_GetScrollInfo(GuiObj, Bar) {
If !(GuiObj Is Gui)
Throw TypeError("Paramweter GuiObj must be an GUI object!", -1, Type(GuiObj))
If !(Type(Bar) = "Integer")
Throw TypeError("Paramweter Bar must be an integer!", -1, Type(Bar))
If (Bar < 0) || (Bar > 1)
Throw ValueError("Paramweter Bar must be an integer between 0 and 1!", -1, Bar)
Local SI := Buffer(28, 0)
NumPut("UInt", 28, "UInt", 0x17, SI) ; cbSize, fMask: SIF_ALL
If !DllCall("GetScrollInfo", "Ptr", GuiObj.Hwnd, "Int", Bar, "Ptr", SI, "UInt")
Throw Error("DllCall GetScrollInfo failed with error " . A_LastError, -1)
Return {Min: NumGet(SI, 8, "Int"), ; nMin
Max: NumGet(SI, 12, "Int"), ; nMax
Page: NumGet(SI, 16, "UInt"), ; nPage
Pos: NumGet(SI, 20, "Int")} ; nPos
}
;=======================================================================================================================
ScrollGui_Scroll(WP, LP, Msg, HWND) {
Static SCROLL_STEP := 10
Critical -1
Local GuiObj := GuiFromHwnd(WinExist())
If !GuiObj || !(GuiObj.Hwnd = HWND) || !GuiObj.HasProp("ScrollInfo")
Return
Local Bar := (Msg = 0x0115) ; SB_HORZ=0, SB_VERT=1
Local SI := ScrollGui_GetScrollInfo(GuiObj, Bar)
Local NewPos := SI.Pos
Switch (WP & 0xFFFF) {
Case 0: NewPos -= SCROLL_STEP ; SB_LINEUP
Case 1: NewPos += SCROLL_STEP ; SB_LINEDOWN
Case 2: NewPos -= SI.Page ; SB_PAGEUP
Case 3: NewPos += SI.Page ; SB_PAGEDOWN
Case 4, 5: NewPos := WP >> 16 ; SB_THUMBTRACK, SB_THUMBPOSITION
Default: Return
}
NewPos := Min(NewPos, SI.Max - SI.Page)
NewPos := Max(SI.Min, NewPos)
Local X := (Bar = 0) ? SI.Pos - NewPos : 0
Local Y := (Bar = 1) ? SI.Pos - NewPos : 0
If (X || Y) {
; Scroll contents of window and invalidate uncovered area.
DllCall("ScrollWindow", "Ptr", HWND, "Int", X, "Int", Y, "Ptr", 0, "Ptr", 0)
; Update scroll bar.
SI := Buffer(28, 0)
NumPut("UInt", 28, "UInt", 4, SI) ; cbSize , fMask: SIF_POS = 0x04
NumPut("Int", NewPos, SI, 20)
DllCall("SetScrollInfo", "Ptr", GuiObj.Hwnd, "Int", Bar, "Ptr", SI, "Int", 1)
}
}
;=======================================================================================================================
ScrollGui_Wheel(WP, LP, Msg, HWND) {
Critical -1
Local GuiObj := GuiFromHwnd(WinExist())
If !GuiObj || !(GuiObj.Hwnd = HWND) || !GuiObj.HasProp("ScrollInfo")
Return
Local Bars := GuiObj.ScrollInfo.Bars
Local Wheels := GuiObj.ScrollInfo.Wheels
If ((Msg = 0x020A) && (Bars & 1) && (Wheels & 4) && (WP & 0x04)) {
Msg := 0x020E
}
If ((Msg = 0x020E) && (Bars & 1) && (Wheels & 5)) || ((Msg = 0x020A) && (Bars & 2) && (Wheels & 6)) {
Local SB := (WP & 0x80000000) ? 1 : 0 ; SB_LINEDOWN = 1, SB_LINEUP = 0
Local SM := (Msg = 0x020A) ? 0x0115 : 0x0114
Return ScrollGui_Scroll(SB, 0, SM, HWND)
}
}
;=======================================================================================================================
ScrollGui_Size(GuiObj, MinMax, Width, Height) {
Critical -1
If !(MinMax = 1) && GuiObj.HasProp("ScrollInfo")
ScrollGui_UpdateBars(GuiObj, Width, Height)
}
;=======================================================================================================================
ScrollGui_GetTotalSize(GuiObj) {
Local Width := 0, Height := 0
Local GuiCtrl, X, Y, W, H
For GuiCtrl In GuiObj {
GuiCtrl.GetPos(&X, &Y, &W, &H)
Width := Max(Width, W + X)
Height := Max(Height, H + Y)
}
GuiObj.TotalWidth := Width + GuiObj.MarginX
GuiObj.TotalHeight := Height + GuiObj.MarginY
}
;=======================================================================================================================
ScrollGui_UpdateBars(GuiObj, Width, Height) {
; SIF_RANGE = 0x01, SIF_PAGE = 0x02, SIF_DISABLENOSCROLL = 0x04, SB_HORZ = 0, SB_VERT = 1
; Calculate scrolling area.
If !GuiObj.HasProp("TotalWidth")
ScrollGui_GetTotalSize(GuiObj)
Local TotalWidth := GuiObj.TotalWidth
Local TotalHeight := GuiObj.TotalHeight
; Initialize SCROLLINFO.
Local SI := Buffer(28, 0)
NumPut("UInt", 28, "UInt", 11, SI) ; cbSize , fMask: SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL
; Update horizontal scroll bar.
NumPut("Int", TotalWidth, "Int", Width, SI, 12) ; nMax , nPage
DllCall("SetScrollInfo", "Ptr", GuiObj.Hwnd, "Int", 0, "Ptr", SI, "Int", 1) ; SB_HORZ
; Update vertical scroll bar.
NumPut("Int", TotalHeight, "UInt", Height, SI, 12) ; nMax , nPage
DllCall("SetScrollInfo", "Ptr", GuiObj.Hwnd, "Int", 1, "Ptr", SI, "Int", 1) ; SB_VERT
}
;=======================================================================================================================
-
- Posts: 120
- Joined: 17 Jul 2019, 08:49
Re: Aktualisierung der Klasse Class_ScrollGUI auf AuotHotkey Version 2
Hallo @just me
Vielen lieben Dank für deine Arbeit.
Es funktioniert nun auch mit der geänderten Bildschirmauflösung.
Ich habe zwei Fragen:
1. Ist es möglich, die Vertikalscrollgeschwindigkeit anzupassen? Wenn ich das Mausrad drehe, würde ich gerne mehrere Zeilen auf einmal nach oben oder unten scrollen können. Ich weiß, dass man die Mausgeschwindigkeit global einstellen kann, aber bei GUI ist sehr langsam.
2. Sobald ein Steuerelement unter den Mauszeiger gerät – sei es ein Text, ein Button oder ein Bild –, hört das Scrollen auf. Gibt es eine Möglichkeit, dieses Verhalten zu ändern?
Vielen lieben Dank für deine Arbeit.
Es funktioniert nun auch mit der geänderten Bildschirmauflösung.
Ich habe zwei Fragen:
1. Ist es möglich, die Vertikalscrollgeschwindigkeit anzupassen? Wenn ich das Mausrad drehe, würde ich gerne mehrere Zeilen auf einmal nach oben oder unten scrollen können. Ich weiß, dass man die Mausgeschwindigkeit global einstellen kann, aber bei GUI ist sehr langsam.
2. Sobald ein Steuerelement unter den Mauszeiger gerät – sei es ein Text, ein Button oder ein Bild –, hört das Scrollen auf. Gibt es eine Möglichkeit, dieses Verhalten zu ändern?
Re: Aktualisierung der Klasse Class_ScrollGUI auf AuotHotkey Version 2 Topic is solved
Moin @Nussbeisser,
danke fürs Testen und die Rückmeldung. Zu Deinen Fragen:
danke fürs Testen und die Rückmeldung. Zu Deinen Fragen:
- Es ist schwierig, die Werte für das 'zeilenweise' Scrollen in einem Control (hier das Gui-Fenster) zu ermitteln, das keine Zeilen hat. Ich habe jetzt versucht, die Werte für das vertikale und horizontale Scrollen variabel relativ zum gesamten Scrollbereich festzulegen. Außerdem übernimmt die Funktion die aktuellen Mauseinstellungen des Benutzers. Hat der einen Wert von 3 Zeilen für das vertikale Scrollen eingestellt, wird auch dreifach gescrollt. Als Hintertür kannst Du die Werte in GuiObjekt.ScrollInfo.DeltaX (horizontal) und GuiObjekt.ScrollInfo.DeltaY (vertikal) anpassen, wenn Dir das nicht gefällt.
- Seit dem Erstellen der ursprünglichen Klasse für v1 hat sich im System anscheinend einiges verändert. Ich habe damals in der Beschreibung der Klasse geschrieben:
Ich weiß nicht mehr, für welche Controls ich das festgestellt habe. Für die im Beispielfenster anhaltenen Buttons gilt es jedenfalls nicht (mehr). Und die Edits müssen die Scrollnachrichten bekommen. Zu dieser Frage habe ich deshalb nichts geändert bzw. ändern können.; If you register mouse wheel messages, the messages will be passed to the focused control, unless the mouse
; is hovering on one of the ScrollGUI's scroll bars. If the control doesn't process the message, it will be
; returned back to the ScrollGUI.
; Common controls seem to ignore wheel messages whenever the CTRL is down. So you can use this modifier to
; scroll the ScrollGUI even if a scrollable control has the focus.
Code: Select all
#Requires AutoHotkey v2.0
Lines := "1`n2`n3`n4`n5`n6`n7`n8"
MainGui := Gui("+Resize +MinSize")
MainGui.MarginX := 20
MainGui.MarginY := 20
I := 0
MainGui.AddText("w370 h20 0x200 Section", "Edit " . ++I)
MainGui.AddEdit("xp y+0 wp r6")
Loop 4 {
MainGui.AddText("xp y+0 wp h20 0x200", "Edit " . ++I)
MainGui.AddEdit("xp y+0 wp r6", Lines)
}
MainGui.AddText("ys wp h20 0x200", "Edit " . ++I)
MainGui.AddEdit("xp y+0 wp r6")
Loop 4 {
MainGui.AddText("xp y+0 wp h20 0x200", "Edit " . ++I)
MainGui.AddEdit("xp y+0 wp r6", Lines)
}
MainGui.SetFont("Norm", "Verdana")
Btn1 := MainGui.Add("Button", "xm w80 Default", "Starten")
Btn2 := MainGui.Add("Button", "xm w80", "Schliessen")
Btn3 := MainGui.Add("Button", "xm w80", "Speichern")
Btn4 := MainGui.Add("Button", "xm w80", "Öffnen")
Btn5 := MainGui.Add("Button", "x+m yp w80", "Ignorieren")
Btn6 := MainGui.Add("Button", "x+m yp w80", "Hilfe")
ScrollGui_InitGui(MainGui, , 3)
MainGui.Show("w300 h300")
Sleep(100)
MsgBox("TotalW: " . MainGui.ScrollInfo.TotalW . "`nDeltyX: " . MainGui.ScrollInfo.DeltaX . "`n" .
"TotalH: " . MainGui.ScrollInfo.TotalH . "`nDeltyY: " . MainGui.ScrollInfo.DeltaY, "MainGui")
; ======================================================================================================================
; Namepace: ScrollGUI
; Function: Functions to make a GUI window scrollable.
; Tested with: AHK 2.0.13
; Tested on: Win 10 Pro (x64)
; License: The Unlicense -> http://unlicense.org
; Change log: 1.0.0/2024-04-21/just me - Initial release
; ======================================================================================================================
; Prepares a GUI window to be scrollable.
; Parameters:
; GuiObj - GUI object
; Bars - Scroll bars to register:
; 1 : horizontal
; 2 : vertical
; 3 : both
; Default: 3
; Wheels - Register WM_MOUSEWHEEL / WM_MOUSEHWHEEL messages:
; 1 : register WM_MOUSEHWHEEL for horizontal scrolling (reqires Win Vista+)
; If not HWHEEL is present, use Shift+WM_MOUSEWHEEL instead.
; 2 : register WM_MOUSEWHEEL for vertical scrolling
; 3 : register both
; Default: 0
; DisableNoScroll - Disable the scroll bars instead of removing them if the whole client area is visible.
; False : Remove
; True : Disable
; Default: True
; Return value:
; None
; Notes:
; On success, the function adds a property called 'ScrollInfo' to the Gui-object. ScrollInfo contains an object
; containing the following keys:
; Bars - parameter Bars passed to this function.
; Wheels - parameter Wheels passed to this function
; DisableNoScroll - parameter DisableNoScroll passed to this function
; DeltaX - default value in pixels used for horizontal scrolling by one unit (line)
; DeltaY - default value in pixels used for horizontal scrolling by one unit (char)
; You may change the values of DeltaX and/or DeltaY to adjust the amount of scrolling.
; ======================================================================================================================
ScrollGui_InitGui(GuiObj, Bars := 3, Wheels := 0, DisableNoScroll := True) {
Static MouseVWheel := SysGet(75) ; SM_MOUSEWHEELPRESENT
Static MouseHWheel := SysGet(91) ; SM_MOUSEHORIZONTALWHEELPRESENT
Static ScrollH := 0, ScrollV := 0, WheelH := 0, WheelV := 0
If !(GuiObj Is Gui)
Throw TypeError("Paramweter GuiObj must be an GUI object!", -1, Type(GuiObj))
If !(Type(Bars) = "Integer")
Throw TypeError("Paramweter Bars must be an integer!", -1, Type(Bars))
If (Bars < 1) || (Bars > 3)
Throw ValueError("Paramweter Bars must be an integer between 1 and 3!", -1, Bars)
If !(Type(Wheels) = "Integer")
Throw TypeError("Paramweter Wheels must be an integer!", -1, Type(Wheels))
If (Wheels < 0) || (Wheels > 3)
Throw ValueError("Paramweter Wheels must be an integer between 0 and 3!", -1, Wheels)
GuiObj.Opt((Bars & 1 ? "+" : "-") . "0x100000") ; WS_HSCROLL
GuiObj.Opt((Bars & 2 ? "+" : "-") . "0x200000") ; WS_VSCROLL
GuiObj.Opt("+Resize")
If (Bars & 1) {
If (ScrollH = 0) {
OnMessage(0x0114, ScrollGui_Scroll) ; WM_HSCROLL
ScrollH := 1
}
If (Wheels & 1){
If (MouseHWheel) && (WheelH = 0) {
OnMessage(0x020E, ScrollGui_Wheel) ; WM_MOUSEHWHEEL = 0x020E
WheelH := 1
}
Else If (MouseVWheel) && (WheelV = 0)
OnMessage(0x020A, ScrollGui_Wheel) ; WM_MOUSEWHEEL = 0x020A
WheelV := 1
}
}
If (Bars & 2) {
If (ScrollV = 0) {
OnMessage(0x0115, ScrollGui_Scroll) ; WM_VSCROLL
ScrollV := 1
}
If (Wheels & 2) (MouseVWheel) && (WheelV = 0) {
OnMessage(0x020A, ScrollGui_Wheel) ; WM_MOUSEWHEEL = 0x020A
WheelV := 1
}
}
GuiObj.OnEvent("Size", ScrollGui_Size)
GuiObj.ScrollInfo := {Bars: Bars, Wheels: Wheels, DisableNoScroll: DisableNoScroll, DeltaX: 6, DeltaY: 12}
}
; ======================================================================================================================
ScrollGui_GetScrollInfo(GuiObj, Bar) {
If !(GuiObj Is Gui)
Throw TypeError("Paramweter GuiObj must be an GUI object!", -1, Type(GuiObj))
If !(Type(Bar) = "Integer")
Throw TypeError("Paramweter Bar must be an integer!", -1, Type(Bar))
If (Bar < 0) || (Bar > 1)
Throw ValueError("Paramweter Bar must be an integer between 0 and 1!", -1, Bar)
Local SI := Buffer(28, 0)
NumPut("UInt", 28, "UInt", 0x17, SI) ; cbSize, fMask: SIF_ALL
If !DllCall("GetScrollInfo", "Ptr", GuiObj.Hwnd, "Int", Bar, "Ptr", SI, "UInt")
Throw Error("DllCall GetScrollInfo failed with error " . A_LastError, -1)
Return {Min: NumGet(SI, 8, "Int"), ; nMin
Max: NumGet(SI, 12, "Int"), ; nMax
Page: NumGet(SI, 16, "UInt"), ; nPage
Pos: NumGet(SI, 20, "Int")} ; nPos
}
; ======================================================================================================================
ScrollGui_Scroll(WP, LP, Msg, HWND) {
Critical -1
Local GuiObj := GuiFromHwnd(WinExist())
If !GuiObj || !(GuiObj.Hwnd = HWND) || !GuiObj.HasProp("ScrollInfo")
Return
Local Bar := (Msg = 0x0115) ; SB_HORZ=0, SB_VERT=1
Local SI := ScrollGui_GetScrollInfo(GuiObj, Bar)
Local NewPos := SI.Pos
Local LineStep := (Bar = 0 ? GuiObj.ScrollInfo.DeltaX : GuiObj.ScrollInfo.DeltaY)
Switch (WP & 0xFFFF) {
Case 0: NewPos -= LineStep ; SB_LINEUP
Case 1: NewPos += LineStep ; SB_LINEDOWN
Case 2: NewPos -= SI.Page ; SB_PAGEUP
Case 3: NewPos += SI.Page ; SB_PAGEDOWN
Case 4, 5: NewPos := WP >> 16 ; SB_THUMBTRACK, SB_THUMBPOSITION
Default: Return
}
Switch {
Case (NewPos < SI.Min): NewPos := SI.Min
Case (NewPos > (SI.Max - SI.Page)): NewPos := SI.Max - SI.Page
}
Local X := (Bar = 0) ? SI.Pos - NewPos : 0
Local Y := (Bar = 1) ? SI.Pos - NewPos : 0
If (X || Y) {
; Scroll contents of window and invalidate uncovered area.
DllCall("ScrollWindow", "Ptr", HWND, "Int", X, "Int", Y, "Ptr", 0, "Ptr", 0)
; Update scroll bar.
SI := Buffer(28, 0)
NumPut("UInt", 28, "UInt", 4, SI) ; cbSize , fMask: SIF_POS = 0x04
NumPut("Int", NewPos, SI, 20)
DllCall("SetScrollInfo", "Ptr", GuiObj.Hwnd, "Int", Bar, "Ptr", SI, "Int", 1)
}
}
; ======================================================================================================================
ScrollGui_Wheel(WP, LP, Msg, HWND) {
Static SCROLL_STEP := 10
Static WheelScrollChars := GetWheelScrollChars()
Static WheelScrollLines := GetWheelScrollLines()
Critical -1
Local GuiObj := GuiFromHwnd(HWND)
If !GuiObj || !GuiObj.HasProp("ScrollInfo")
Return
Local WheelDelta := WP << 32 >> 48
Local Bars := GuiObj.ScrollInfo.Bars
Local Wheels := GuiObj.ScrollInfo.Wheels
If ((Msg = 0x020A) && (Bars & 1) && (Wheels & 1) && (WP & 0x04)) {
Msg := 0x020E
}
If ((Msg = 0x020E) && (Bars & 1) && (Wheels & 1)) || ((Msg = 0x020A) && (Bars & 2) && (Wheels & 2)) {
Local Bar := (Msg = 0x020A)
Local SI := ScrollGui_GetScrollInfo(GuiObj, Bar)
Local NewPos := SI.Pos
Local Dir := (WP & 0x80000000) ? 1 : -1
Switch Bar {
Case 0: NewPos += GuiObj.ScrollInfo.DeltaX * WheelScrollChars * Dir
Case 1: NewPos += (WheelScrollLines = -1 ? SI.Page : GuiObj.ScrollInfo.DeltaY * WheelScrollLines) * Dir
}
Switch {
Case (NewPos < SI.Min): NewPos := SI.Min
Case (NewPos > (SI.Max - SI.Page)): NewPos := SI.Max - SI.Page
}
Local X := (Bar = 0) ? SI.Pos - NewPos : 0
Local Y := (Bar = 1) ? SI.Pos - NewPos : 0
If (X || Y) {
; Scroll contents of window and invalidate uncovered area.
DllCall("ScrollWindow", "Ptr", GuiObj.Hwnd, "Int", X, "Int", Y, "Ptr", 0, "Ptr", 0)
; Update scroll bar.
SI := Buffer(28, 0)
NumPut("UInt", 28, "UInt", 4, SI) ; cbSize , fMask: SIF_POS = 0x04
NumPut("Int", NewPos, SI, 20)
DllCall("SetScrollInfo", "Ptr", GuiObj.Hwnd, "Int", Bar, "Ptr", SI, "Int", 1)
}
}
; -------------------------------------------------------------------------------------------------------------------
GetWheelScrollChars() {
Local ScrollChars := 3 ; default
DllCall("SystemParametersInfoW", "UInt", 0x006C, "UInt", 0, "UIntP", &ScrollChars, "UInt", 0)
Return ScrollChars
}
GetWheelScrollLines() {
Local ScrollLines := 3 ; default
DllCall("SystemParametersInfoW", "UInt", 0x0068, "UInt", 0, "IntP", &ScrollLines, "UInt", 0)
Return ScrollLines
}
}
; ======================================================================================================================
ScrollGui_Size(GuiObj, MinMax, Width, Height) {
Critical -1
If !(MinMax = 1) && GuiObj.HasProp("ScrollInfo")
ScrollGui_UpdateBars(GuiObj, Width, Height)
}
;=======================================================================================================================
ScrollGui_GetTotalSize(GuiObj) {
If !GuiObj.HasProp("ScrollInfo")
Return False
Local Width := 0, Height := 0
Local GuiCtrl, X, Y, W, H
For GuiCtrl In GuiObj {
GuiCtrl.GetPos(&X, &Y, &W, &H)
Width := Max(Width, W + X)
Height := Max(Height, H + Y)
}
Width += GuiObj.MarginX
Height += GuiObj.MarginY
GuiObj.ScrollInfo.TotalW := Width
GuiObj.ScrollInfo.TotalH := Height
GuiObj.ScrollInfo.DeltaX := Max(6, Width // 100)
GuiObj.ScrollInfo.DeltaY := Max(12, Height // 100)
GuiObj.Opt("+MaxSize" . Width . "x" . Height)
}
; ======================================================================================================================
ScrollGui_UpdateBars(GuiObj, Width, Height) {
; SIF_RANGE = 0x01, SIF_PAGE = 0x02, SIF_DISABLENOSCROLL = 0x08, SB_HORZ = 0, SB_VERT = 1
; Calculate scrolling area.
If !GuiObj.HasProp("ScrollInfo")
Return False
Local DisableNoScroll := GuiObj.ScrollInfo.DisableNoScroll
If !GuiObj.ScrollInfo.HasProp("TotalW")
ScrollGui_GetTotalSize(GuiObj)
Local TotalW:= GuiObj.ScrollInfo.TotalW
Local TotalH := GuiObj.ScrollInfo.TotalH
; Initialize SCROLLINFO.
Local Mask := 3 | (DisableNoScroll ? 8 : 0) ; SIF_RANGE | SIF_PAGE | ? SIF_DISABLENOSCROLL
Local SI := Buffer(28, 0)
NumPut("UInt", 28, "UInt", Mask, SI) ; cbSize , fMask
; Update horizontal scroll bar.
NumPut("Int", TotalW, "Int", Width, SI, 12) ; nMax , nPage
DllCall("SetScrollInfo", "Ptr", GuiObj.Hwnd, "Int", 0, "Ptr", SI, "Int", 1) ; SB_HORZ
; Update vertical scroll bar.
NumPut("Int", TotalH, "UInt", Height, SI, 12) ; nMax , nPage
DllCall("SetScrollInfo", "Ptr", GuiObj.Hwnd, "Int", 1, "Ptr", SI, "Int", 1) ; SB_VERT
}
; ======================================================================================================================
-
- Posts: 120
- Joined: 17 Jul 2019, 08:49
Re: Aktualisierung der Klasse Class_ScrollGUI auf AuotHotkey Version 2
Vielen Dank für die Hilfe. Die Scroll-Geschwindigkeit ist jetzt perfekt.
Das ist jetzt nur ein Luxusproblem aber gibt es eine einfache Möglichkeit, die Breite des Scrollbalkens anzupassen? Vielleicht durch eine Art 'SendMessage', um dem Scrollbalken mehr Platz zu geben. Aber ich könnte auch links neben der Scrollbalken etwas Platz lassen um störungsfreier zu Scrollen.
Das ist jetzt nur ein Luxusproblem aber gibt es eine einfache Möglichkeit, die Breite des Scrollbalkens anzupassen? Vielleicht durch eine Art 'SendMessage', um dem Scrollbalken mehr Platz zu geben. Aber ich könnte auch links neben der Scrollbalken etwas Platz lassen um störungsfreier zu Scrollen.
Re: Aktualisierung der Klasse Class_ScrollGUI auf AuotHotkey Version 2
Moin @Nussbeisser,
die Breite der Scrollbalken ist im System definiert. Ich weiß nicht, ob und wie man die ändern kann.
Meine Funktionssammlung habe ich nochmal überarbeitet. Ich habe einige Fehler korrigiert und die Funktionen redaktionell überarbeitet.
Die Option 4 für den Parameter Wheels gibt es nicht mehr. Die Funktion prüft intern, ob die Maus horizontales Scrollen anbietet. Wenn nicht, wird das horizontale Scrollen automatisch auf Shift+Scrollrad gelegt, wenn ein horizontaler Scrollbalken angezeigt werden soll.
die Breite der Scrollbalken ist im System definiert. Ich weiß nicht, ob und wie man die ändern kann.
Meine Funktionssammlung habe ich nochmal überarbeitet. Ich habe einige Fehler korrigiert und die Funktionen redaktionell überarbeitet.
Die Option 4 für den Parameter Wheels gibt es nicht mehr. Die Funktion prüft intern, ob die Maus horizontales Scrollen anbietet. Wenn nicht, wird das horizontale Scrollen automatisch auf Shift+Scrollrad gelegt, wenn ein horizontaler Scrollbalken angezeigt werden soll.
Code: Select all
#Requires AutoHotkey v2.0
Lines := "1`n2`n3`n4`n5`n6`n7`n8"
MainGui := Gui("+Resize +MinSize")
MainGui.MarginX := 20
MainGui.MarginY := 20
I := 0
MainGui.AddText("w370 h20 0x200 Section", "Edit " . ++I)
MainGui.AddEdit("xp y+0 wp r6")
Loop 4 {
MainGui.AddText("xp y+0 wp h20 0x200", "Edit " . ++I)
MainGui.AddEdit("xp y+0 wp r6", Lines)
}
MainGui.AddText("ys wp h20 0x200", "Edit " . ++I)
MainGui.AddEdit("xp y+0 wp r6")
Loop 4 {
MainGui.AddText("xp y+0 wp h20 0x200", "Edit " . ++I)
MainGui.AddEdit("xp y+0 wp r6", Lines)
}
MainGui.SetFont("Norm", "Verdana")
Btn1 := MainGui.Add("Button", "xm w80 Default", "Starten")
Btn2 := MainGui.Add("Button", "xm w80", "Schliessen")
Btn3 := MainGui.Add("Button", "xm w80", "Speichern")
Btn4 := MainGui.Add("Button", "xm w80", "Öffnen")
Btn5 := MainGui.Add("Button", "x+m yp w80", "Ignorieren")
Btn6 := MainGui.Add("Button", "x+m yp w80", "Hilfe")
ScrollGui_InitGui(MainGui, , 3)
MainGui.Show("w300 h300")
Sleep(100)
MsgBox("TotalW: " . MainGui.ScrollInfo.TotalW . "`nLineH: " . MainGui.ScrollInfo.LineH . "`n" .
"TotalH: " . MainGui.ScrollInfo.TotalH . "`nLineV: " . MainGui.ScrollInfo.LineV, "MainGui")
; ======================================================================================================================
; Namepace: ScrollGUI
; Function: Functions to make a GUI window scrollable.
; Tested with: AHK 2.0.13
; Tested on: Win 10 Pro (x64)
; License: The Unlicense -> http://unlicense.org
; Change log: 1.0.0/2024-04-21/just me - Initial release
; ======================================================================================================================
; Prepares a GUI window to be scrollable.
; Parameters:
; GuiObj - GUI object
; Bars - Scroll bars to register:
; 1 : horizontal
; 2 : vertical
; 3 : both
; Default: 3
; Wheels - Register WM_MOUSEWHEEL / WM_MOUSEHWHEEL messages:
; 1 : register WM_MOUSEHWHEEL for horizontal scrolling (reqires Win Vista+)
; If not HWHEEL is present, use Shift+WM_MOUSEWHEEL instead.
; 2 : register WM_MOUSEWHEEL for vertical scrolling
; 3 : register both
; Default: 0
; DisableNoScroll - Disable the scroll bars instead of removing them if the whole client area is visible.
; False : Remove
; True : Disable
; Default: True
; Return value:
; None
; Notes:
; On success, the function adds a property called 'ScrollInfo' to the Gui-object. ScrollInfo contains an object
; containing the following keys:
; Bars - parameter Bars passed to this function.
; Wheels - parameter Wheels passed to this function
; Disable - parameter DisableNoScroll passed to this function
; LineH - default value in pixels used for horizontal scrolling by one unit (char)
; LineV - default value in pixels used for vertical scrolling by one unit (line)
; PosH - current horizontal scroll position
; PosV - current vertical scroll position
; TotalH - total height of the scrolling area
; TotalW - total width of the scrolling area
; You may change the values of LineH and/or LineV to adjust the amount of scrolling. You must not touch any other
; property.
; ======================================================================================================================
ScrollGui_InitGui(GuiObj, Bars := 3, Wheels := 0, DisableNoScroll := True) {
Static MouseVWheel := SysGet(75) ; SM_MOUSEWHEELPRESENT
Static MouseHWheel := SysGet(91) ; SM_MOUSEHORIZONTALWHEELPRESENT
Static ScrollH := 0, ScrollV := 0, WheelH := 0, WheelV := 0
If !(GuiObj Is Gui)
Throw TypeError("Paramweter GuiObj must be an GUI object!", -1, Type(GuiObj))
If !(Type(Bars) = "Integer")
Throw TypeError("Paramweter Bars must be an integer!", -1, Type(Bars))
If (Bars < 1) || (Bars > 3)
Throw ValueError("Paramweter Bars must be an integer between 1 and 3!", -1, Bars)
If !(Type(Wheels) = "Integer")
Throw TypeError("Paramweter Wheels must be an integer!", -1, Type(Wheels))
If (Wheels < 0) || (Wheels > 3)
Throw ValueError("Paramweter Wheels must be an integer between 0 and 3!", -1, Wheels)
GuiObj.Opt((Bars & 1 ? "+" : "-") . "0x100000") ; WS_HSCROLL
GuiObj.Opt((Bars & 2 ? "+" : "-") . "0x200000") ; WS_VSCROLL
GuiObj.Opt("+Resize")
If (Bars & 1) {
If (ScrollH = 0) {
OnMessage(0x0114, ScrollGui_Scroll) ; WM_HSCROLL
ScrollH := 1
}
If (Wheels & 1){
If (MouseHWheel) && (WheelH = 0) {
OnMessage(0x020E, ScrollGui_Wheel) ; WM_MOUSEHWHEEL = 0x020E
WheelH := 1
}
Else If (MouseVWheel) && (WheelV = 0)
OnMessage(0x020A, ScrollGui_Wheel) ; WM_MOUSEWHEEL = 0x020A
WheelV := 1
}
}
If (Bars & 2) {
If (ScrollV = 0) {
OnMessage(0x0115, ScrollGui_Scroll) ; WM_VSCROLL
ScrollV := 1
}
If (Wheels & 2) && (MouseVWheel) && (WheelV = 0) {
OnMessage(0x020A, ScrollGui_Wheel) ; WM_MOUSEWHEEL = 0x020A
WheelV := 1
}
}
GuiObj.OnEvent("Size", ScrollGui_Size)
Local DNS := DisableNoScroll ? 8 : 0
GuiObj.ScrollInfo := {Bars: Bars, Wheels: Wheels, Disable: DNS, LineH: 6, LineV: 12, PosH: 0, PosV: 0}
}
; ======================================================================================================================
ScrollGui_Scroll(WP, LP, Msg, HWND) {
Critical -1
Local GuiObj := GuiFromHwnd(WinExist())
If !GuiObj || !(GuiObj.Hwnd = HWND) || !GuiObj.HasProp("ScrollInfo")
Return
Local Bar := (Msg = 0x0115) ; SB_HORZ=0, SB_VERT=1
Local SI := ScrollGui_GetScrollInfo(GuiObj, Bar)
Local NewPos := SI.Pos
Local LineStep := (Bar = 0 ? GuiObj.ScrollInfo.LineH : GuiObj.ScrollInfo.LineV)
Switch (WP & 0xFFFF) {
Case 0: NewPos -= LineStep ; SB_LINEUP
Case 1: NewPos += LineStep ; SB_LINEDOWN
Case 2: NewPos -= SI.Page ; SB_PAGEUP
Case 3: NewPos += SI.Page ; SB_PAGEDOWN
Case 4, 5: NewPos := WP >> 16 ; SB_THUMBTRACK, SB_THUMBPOSITION
Default: Return
}
NewPos := Max(SI.Min, NewPos)
NewPos := Min(SI.Max - SI.Page + 1, NewPos)
Local X := (Bar = 0) ? SI.Pos - NewPos : 0
Local Y := (Bar = 1) ? SI.Pos - NewPos : 0
If (X || Y) {
; Scroll contents of window and invalidate uncovered area.
DllCall("ScrollWindow", "Ptr", HWND, "Int", X, "Int", Y, "Ptr", 0, "Ptr", 0)
; Update scroll bar.
DllCall("SetScrollPos", "Ptr", GuiObj.Hwnd, "Int", Bar, "Ptr", NewPos, "Int", 1)
Switch Bar {
Case 0: GuiObj.ScrollInfo.PosH := NewPos
Case 1: GuiObj.ScrollInfo.PosV := NewPos
}
}
}
; ======================================================================================================================
ScrollGui_Wheel(WP, LP, Msg, HWND) {
Static SCROLL_STEP := 10
Static WheelScrollChars := GetWheelScrollChars()
Static WheelScrollLines := GetWheelScrollLines()
Critical -1
Local GuiObj := GuiFromHwnd(HWND)
If !GuiObj || !GuiObj.HasProp("ScrollInfo")
Return
Local WheelDelta := WP << 32 >> 48
Local Bars := GuiObj.ScrollInfo.Bars
Local Wheels := GuiObj.ScrollInfo.Wheels
If ((Msg = 0x020A) && (Bars & 1) && (Wheels & 1) && (WP & 0x04)) {
Msg := 0x020E
}
If ((Msg = 0x020E) && (Bars & 1) && (Wheels & 1)) || ((Msg = 0x020A) && (Bars & 2) && (Wheels & 2)) {
Local Bar := (Msg = 0x020A)
Local SI := ScrollGui_GetScrollInfo(GuiObj, Bar)
Local NewPos := SI.Pos
Local Dir := (WheelDelta < 0) ? 1 : -1
Switch Bar {
Case 0: NewPos += GuiObj.ScrollInfo.LineH * WheelScrollChars * Dir
Case 1: NewPos += (WheelScrollLines = -1 ? SI.Page : GuiObj.ScrollInfo.LineV * WheelScrollLines) * Dir
}
NewPos := Max(SI.Min, NewPos)
NewPos := Min(SI.Max - SI.Page + 1, NewPos)
Local ScrollH := (Bar = 0) ? SI.Pos - NewPos : 0
Local ScrollV := (Bar = 1) ? SI.Pos - NewPos : 0
If (ScrollH || ScrollV) {
; Scroll contents of window and invalidate uncovered area.
DllCall("ScrollWindow", "Ptr", GuiObj.Hwnd, "Int", ScrollH, "Int", ScrollV, "Ptr", 0, "Ptr", 0)
; Update scroll bar.
DllCall("SetScrollPos", "Ptr", GuiObj.Hwnd, "Int", Bar, "Ptr", NewPos, "Int", 1)
Switch Bar {
Case 0: GuiObj.ScrollInfo.PosH := NewPos
Case 1: GuiObj.ScrollInfo.PosV := NewPos
}
}
}
; -------------------------------------------------------------------------------------------------------------------
GetWheelScrollChars() {
Local ScrollChars := 3 ; default
DllCall("SystemParametersInfoW", "UInt", 0x006C, "UInt", 0, "UIntP", &ScrollChars, "UInt", 0)
Return ScrollChars
}
GetWheelScrollLines() {
Local ScrollLines := 3 ; default
DllCall("SystemParametersInfoW", "UInt", 0x0068, "UInt", 0, "IntP", &ScrollLines, "UInt", 0)
Return ScrollLines
}
}
; ======================================================================================================================
ScrollGui_Size(GuiObj, MinMax, Width, Height) {
Critical -1
If (MinMax != -1) && GuiObj.HasProp("ScrollInfo")
ScrollGui_UpdateBars(GuiObj, Width, Height)
}
; ======================================================================================================================
ScrollGui_GetScrollInfo(GuiObj, Bar) {
If !(GuiObj Is Gui)
Throw TypeError("Paramweter GuiObj must be an GUI object!", -1, Type(GuiObj))
If !(Type(Bar) = "Integer")
Throw TypeError("Paramweter Bar must be an integer!", -1, Type(Bar))
If (Bar < 0) || (Bar > 1)
Throw ValueError("Paramweter Bar must be an integer between 0 and 1!", -1, Bar)
Local SI := Buffer(28, 0)
NumPut("UInt", 28, "UInt", 0x17, SI) ; cbSize, fMask: SIF_ALL
If !DllCall("GetScrollInfo", "Ptr", GuiObj.Hwnd, "Int", Bar, "Ptr", SI, "UInt")
Throw Error("DllCall GetScrollInfo failed with error " . A_LastError, -1)
Return {Min: NumGet(SI, 8, "Int"), ; nMin
Max: NumGet(SI, 12, "Int"), ; nMax
Page: NumGet(SI, 16, "UInt"), ; nPage
Pos: NumGet(SI, 20, "Int")} ; nPos
}
;=======================================================================================================================
ScrollGui_GetTotalSize(GuiObj) {
If !GuiObj.HasProp("ScrollInfo")
Return False
Local TotalW := 0, TotalH := 0
Local GuiCtrl, X, Y, W, H
For GuiCtrl In GuiObj {
GuiCtrl.GetPos(&X, &Y, &W, &H)
TotalW := Max(TotalW, W + X - 1)
TotalH := Max(TotalH, H + Y - 1)
}
TotalW += GuiObj.MarginX
TotalH += GuiObj.MarginY
GuiObj.ScrollInfo.TotalW := TotalW
GuiObj.ScrollInfo.TotalH := TotalH
GuiObj.ScrollInfo.LineH := Max(6, TotalW // 100)
GuiObj.ScrollInfo.LineV := Max(12, TotalH // 100)
GuiObj.Opt("+MaxSize" . TotalW . "x" . TotalH)
}
; ======================================================================================================================
ScrollGui_UpdateBars(GuiObj, Width, Height) {
; SIF_RANGE = 0x01, SIF_PAGE = 0x02, SIF_DISABLENOSCROLL = 0x08, SB_HORZ = 0, SB_VERT = 1
If !GuiObj.HasProp("ScrollInfo")
Return False
Local DisableNoScroll := GuiObj.ScrollInfo.Disable
If !GuiObj.ScrollInfo.HasProp("TotalW")
ScrollGui_GetTotalSize(GuiObj)
; Calculate scrolling area.
Local TotalW := GuiObj.ScrollInfo.TotalW
Local TotalH := GuiObj.ScrollInfo.TotalH
; Initialize SCROLLINFO.
Local Mask := 3 | GuiObj.ScrollInfo.Disable ; SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL?
Local SI := Buffer(28, 0)
NumPut("UInt", 28, "UInt", Mask, SI) ; cbSize , fMask
Local PosH := 0, PosV := 0, ScrollH := ScrollV := 0
If (GuiObj.ScrollInfo.Bars & 1) { ; update the horizontal scroll bar
NumPut("Int", TotalW, "Int", Width +1, SI, 12) ; nMax , nPage
DllCall("SetScrollInfo", "Ptr", GuiObj.Hwnd, "Int", 0, "Ptr", SI, "Int", 1) ; SB_HORZ
PosH := ScrollGui_GetScrollInfo(GuiObj, 0).Pos
ScrollH := GuiObj.ScrollInfo.PosH - PosH
GuiObj.ScrollInfo.PosH := PosH
}
If (GuiObj.ScrollInfo.Bars & 2) { ; update the vertical scroll bar
NumPut("Int", TotalH, "UInt", Height + 1, SI, 12) ; nMax , nPage
DllCall("SetScrollInfo", "Ptr", GuiObj.Hwnd, "Int", 1, "Ptr", SI, "Int", 1) ; SB_VERT
PosV := ScrollGui_GetScrollInfo(GuiObj, 1).Pos
ScrollV := GuiObj.ScrollInfo.PosV - PosV
GuiObj.ScrollInfo.PosV := PosV
}
If (ScrollH || ScrollV)
DllCall("ScrollWindow", "Ptr", GuiObj.Hwnd, "Int", ScrollH, "Int", ScrollV, "Ptr", 0, "Ptr", 0)
Return True
}
; ======================================================================================================================
-
- Posts: 120
- Joined: 17 Jul 2019, 08:49
Re: Aktualisierung der Klasse Class_ScrollGUI auf AuotHotkey Version 2
Nochmals vielen Dank!