Seite 1 von 2

ScrollBarGadget und Repeat-Schleife

Verfasst: 19.09.2022 08:58
von Re42
Hallo, ich verwende ein ScrollBarGadget, aber die Repeat-Schleife hält an, wenn ich mit der Maus da drauf klicke. Dabei wäre es ja gerade bei einem ScrollBarGadget schön, wenn die Schleife nicht anhält, wenn z.B. Töne hintereinander abgespielt werden, deren Lautstärke dann über das ScrollBarGadget geändert werden sollen.

Gibt es evtl. eine Möglichkeit (Code? Settings?) daß die Schleife beim Anklicken eines ScrollBarGadgets weiterläuft oder ist das aus technischen Gründen gar nicht möglich? Man kann ja zwar auch den Slider mit der Tastatur koppeln und dann läuft die Schleife weiter, aber das andere würde mich jetzt auch mal interessieren. Danke.

Re: ScrollBarGadget und Repeat-Schleife

Verfasst: 19.09.2022 09:06
von jacdelad
Ich kenne deine Schleife nicht, weil du keinen Code gepostet hast. Mal ins Blaue geraten könnte dir eventuell BindGadgetEvent() helfen.

Re: ScrollBarGadget und Repeat-Schleife

Verfasst: 19.09.2022 09:22
von Re42
Das liegt wohl nicht am Code, denn in dem Beispiel, was PureBasic zum ScrollBarGadget zeigt, ist das nämlich auch so. BinGadgetEvent kenne ich noch nicht, werde ich mir aber mal ansehen, wenn ich nachher wieder mehr Zeit habe. Danke.

Re: ScrollBarGadget und Repeat-Schleife

Verfasst: 19.09.2022 11:00
von mk-soft
Wie geschrieben, verwendet BindGadgetEvent.
Im WaitWindowEvent werden von PB die Events teilweise und mit Absicht gefiltert. Wie bei ScrollBar, ResizeWindow nur das letzte Event beim loslassen.

Es gibt auch noch das TrackBarGadget ;)

Code: Alles auswählen

;-TOP

#ProgramTitle = "Main Window"
#ProgramVersion = "v1.01.2"

Enumeration Windows
  #Main
EndEnumeration

Enumeration MenuBar
  #MainMenu
EndEnumeration

Enumeration MenuItems
  #MainMenuAbout
  #MainMenuExit
EndEnumeration

Enumeration Gadgets
  #MainTrack
  #MainTrackValue
EndEnumeration

Enumeration StatusBar
  #MainStatusBar
EndEnumeration

; ----

Procedure DoEventTrackBar()
  SetGadgetText(#MainTrackValue, Str(GetGadgetState(#MainTrack)))
EndProcedure

Procedure UpdateWindow()
  Protected dx, dy
  dx = WindowWidth(#Main)
  dy = WindowHeight(#Main) - StatusBarHeight(#MainStatusBar) - MenuHeight()
  ; Resize gadgets
EndProcedure

Procedure Main()
  Protected dx, dy
  
  #MainStyle = #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget
  
  If OpenWindow(#Main, #PB_Ignore, #PB_Ignore, 800, 600, #ProgramTitle , #MainStyle)
    ; Menu
    CreateMenu(#MainMenu, WindowID(#Main))
    MenuTitle("&File")
    CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
      MenuItem(#PB_Menu_About, "")
    CompilerElse
      MenuItem(#MainMenuAbout, "About")
      MenuBar()
    CompilerEndIf
    
    MenuItem(#MainMenuExit, "E&xit")
    
    ; StatusBar
    CreateStatusBar(#MainStatusBar, WindowID(#Main))
    AddStatusBarField(#PB_Ignore)
    
    ; Gadgets
    dx = WindowWidth(#Main)
    dy = WindowHeight(#Main) - StatusBarHeight(#MainStatusBar) - MenuHeight()
    
    ;ScrollBarGadget(#MainTrack, 15, 10, 30, 200, 0, 100, 1, #PB_ScrollBar_Vertical)
    TrackBarGadget(#MainTrack, 20, 10, 30, 200, 0, 100, #PB_TrackBar_Vertical)
    TextGadget(#MainTrackValue, 10, 220, 50, 25, "", #PB_Text_Border | #PB_Text_Center)
    
    ; Bind Events
    BindEvent(#PB_Event_SizeWindow, @UpdateWindow(), #Main)
    
    BindGadgetEvent(#MainTrack, @DoEventTrackBar())
    
    ; Event Loop
    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          Select EventWindow()
            Case #Main
              Break
              
          EndSelect
          
        Case #PB_Event_Menu
          Select EventMenu()
            CompilerIf #PB_Compiler_OS = #PB_OS_MacOS   
              Case #PB_Menu_About
                PostEvent(#PB_Event_Menu, #Main, #MainMenuAbout)
                
              Case #PB_Menu_Preferences
                
              Case #PB_Menu_Quit
                PostEvent(#PB_Event_CloseWindow, #Main, #Null)
                
            CompilerEndIf
            
          Case #MainMenuAbout
            MessageRequester("About", #ProgramTitle + #LF$ + #ProgramVersion, #PB_MessageRequester_Info)
              
          Case #MainMenuExit
            PostEvent(#PB_Event_CloseWindow, #Main, #Null)
            
          EndSelect
          
        Case #PB_Event_Gadget
          Select EventGadget()
              
          EndSelect
          
      EndSelect
    ForEver
    
  EndIf
  
EndProcedure : Main()

Re: ScrollBarGadget und Repeat-Schleife

Verfasst: 19.09.2022 13:25
von Re42
Vielen Dank für die Mühe mit dem Code. Ich habe den mal laufen lassen, allerdings ändert das doch dann auch nichts an der Situation, denn auch in Deinem Code bleibt ja die Repeat-Schleife stehen, wenn man die Maus drückt. Das TrackBarGadget dagegen (Danke für den Tipp) macht doch vor, daß es auch anders geht. Wenn das TrackBarGadget dann vertikal auch noch nach links zu haben wäre, wäre das ja super, denn ich brauche den Regler am rechten Rand im Programm und nirgendwo anders. Was hat sich denn PureBasic überhaupt dabei gedacht, beim ScrollBarGadget einfach die Schleife anzuhalten, wenn man da drauf klickt? Danke nochmals.

Re: ScrollBarGadget und Repeat-Schleife

Verfasst: 19.09.2022 15:30
von mk-soft
Es gibt Controls die von der OS erst wieder Events liefert wenn diese fertig ist, z.B. Menu.

Weiteres Beispiel mit ResizeGadget

Code: Alles auswählen

;-TOP

#ProgramTitle = "Main Window"
#ProgramVersion = "v1.01.2"

Enumeration Windows
  #Main
EndEnumeration

Enumeration MenuBar
  #MainMenu
EndEnumeration

Enumeration MenuItems
  #MainMenuAbout
  #MainMenuExit
EndEnumeration

Enumeration Gadgets
  #MainTrackBarV
  #MainTrackBarH
EndEnumeration

Enumeration StatusBar
  #MainStatusBar
EndEnumeration

; ----

Procedure DoEventTrackBar()
  Protected info.s, x, y
  x = GetGadgetState(#MainTrackBarH)
  y = 100 - GetGadgetState(#MainTrackBarv)
  info = " X = " + Str(x) + " / Y = " + Str(y)
  StatusBarText(#MainStatusBar, 0, info)
EndProcedure

Procedure UpdateWindow()
  Protected dx, dy
  dx = WindowWidth(#Main)
  dy = WindowHeight(#Main) - StatusBarHeight(#MainStatusBar) - MenuHeight()
  ; Resize gadgets
  ResizeGadget(#MainTrackBarV, dx - 40, 10, 30, dy - 50)
  ResizeGadget(#MainTrackBarH, 10, dy - 40, dx - 50, 30)
    
EndProcedure

Procedure Main()
  Protected dx, dy
  
  #MainStyle = #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget
  
  If OpenWindow(#Main, #PB_Ignore, #PB_Ignore, 800, 600, #ProgramTitle , #MainStyle)
    ; Menu
    CreateMenu(#MainMenu, WindowID(#Main))
    MenuTitle("&File")
    CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
      MenuItem(#PB_Menu_About, "")
    CompilerElse
      MenuItem(#MainMenuAbout, "About")
      MenuBar()
    CompilerEndIf
    
    MenuItem(#MainMenuExit, "E&xit")
    
    ; StatusBar
    CreateStatusBar(#MainStatusBar, WindowID(#Main))
    AddStatusBarField(#PB_Ignore)
    
    ; Gadgets
    dx = WindowWidth(#Main)
    dy = WindowHeight(#Main) - StatusBarHeight(#MainStatusBar) - MenuHeight()
    
    TrackBarGadget(#MainTrackBarV, dx - 40, 10, 30, dy - 50, 0, 100, #PB_TrackBar_Vertical)
    TrackBarGadget(#MainTrackBarH, 10, dy - 40, dx - 50, 30, 0, 300)
    SetGadgetState(#MainTrackBarV, 100)
    
    ; Bind Events
    BindEvent(#PB_Event_SizeWindow, @UpdateWindow(), #Main)
    
    BindGadgetEvent(#MainTrackBarV, @DoEventTrackBar())
    BindGadgetEvent(#MainTrackBarH, @DoEventTrackBar())
    
    DoEventTrackBar()
    
    ; Event Loop
    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          Select EventWindow()
            Case #Main
              Break
              
          EndSelect
          
        Case #PB_Event_Menu
          Select EventMenu()
            CompilerIf #PB_Compiler_OS = #PB_OS_MacOS   
              Case #PB_Menu_About
                PostEvent(#PB_Event_Menu, #Main, #MainMenuAbout)
                
              Case #PB_Menu_Preferences
                
              Case #PB_Menu_Quit
                PostEvent(#PB_Event_CloseWindow, #Main, #Null)
                
            CompilerEndIf
            
          Case #MainMenuAbout
            MessageRequester("About", #ProgramTitle + #LF$ + #ProgramVersion, #PB_MessageRequester_Info)
              
          Case #MainMenuExit
            PostEvent(#PB_Event_CloseWindow, #Main, #Null)
            
          EndSelect
          
        Case #PB_Event_Gadget
          Select EventGadget()
              
          EndSelect
          
      EndSelect
    ForEver
    
  EndIf
  
EndProcedure : Main()

Re: ScrollBarGadget und Repeat-Schleife

Verfasst: 19.09.2022 18:12
von Shardik
Re42 hat geschrieben: 19.09.2022 13:25 Was hat sich denn PureBasic überhaupt dabei gedacht, beim ScrollBarGadget einfach die Schleife anzuhalten, wenn man da drauf klickt?
Die Frage müsste eigentlich lauten, was Microsoft sich dabei gedacht hat, die Schleife anzuhalten. Denn PureBasic verwendet lediglich das von Microsoft zur Verfügung gestellte "SCROLLBAR"-Control. Die zugrunde liegenden Steuerelemente der jeweiligen Betriebssysteme kann man übrigens in diesem PureBasic Blog-Beitrag nachschauen.

Mit sogenannten API-Befehlen, die das jeweilige Betriebssystem zur Verfügung stellt, kann man auch während der Zieh-Operationen den aktuellen ScrollBarGadget-Wert anzeigen lassen. In diesen Fällen lohnt sich oft eine Suche in diesem deutschen oder vor allem auch im englischen Forum. Im deutschen Forum habe ich ein altes Beispiel und im englischen Forum drei alte Beispiele gefunden, die aber auch unter WIndows 10 noch funktionieren:
- Fluid Byte
- srod
- gnozal
- RichardL

Die Beispiele von Fluid Byte und gnozal zeigen die Compiler-Warnung "Veraltete Funktion 'CreateGadgetList()" an. Dies liegt daran, dass CreateGadgetList() in PureBasic mittlerweile nicht mehr existiert und einfach ersatzlos entfernt werden kann.

Das letzte Beispiel von RichardL zeigt sogar den aktuellen Wert beim Ziehen in einem ToolTip (ein Text-Kästchen oberhalb des Cursors) an!

Re: ScrollBarGadget und Repeat-Schleife

Verfasst: 19.09.2022 23:54
von Re42
Leider konnte ich erst spät wieder hier ins Forum gehen (Dienst), habe mir aber alles gründlich angesehen und ausprobiert, was zwischenzeitlich noch als Tipps gekommen war. Vielen Dank dafür, aber leider bringt mich auch das nicht weiter. BindGadgetEvent reicht ja eigentlich völlig aus, aber das Problem ist ja, daß in meinem Code die Schleife weiterlaufen muß, wenn ich den Slider anklicke und dann verschiebe. Irgendeinen Zwangsbefehl wird es ja wahrscheinlich nicht geben, damit die Schleife läuft, oder?

Re: ScrollBarGadget und Repeat-Schleife

Verfasst: 20.09.2022 10:13
von HeX0R
Für eine WindowEvent-Queue ist es überhaupt kein Problem, wenn die Abarbeitung pausiert, während Du die ScrollBar verschiebst.
Da kannst Du ohnehin währenddessen keine anderen Events auslösen.

Deine Töne, die Du da parallel offensichtlich abspielst, haben mit dem Fenster selbst und daher auch für das Eventhandling überhaupt nichts zu tun.

D.h. das musst Du anders lösen, z.B. mit Hilfe von Threads.

Würdest Du Deinen Code zeigen (wegen mir auch abgespeckt, aber trotzdem lauffähig), hätte Dir sicherlich schon längst jemand aufs Pferd geholfen.

Ach ja:
Cross-Posting ist extrem uncool!
Wenn Du Pech hast, antwortet jetzt niemand mehr hier.

Re: ScrollBarGadget und Repeat-Schleife

Verfasst: 20.09.2022 16:00
von mk-soft
Mit dem TrackBarGadget geht es unter Windows und Linux. Bei macOS hängt es. (Hatte aber mal eine Lösung gehabt ...)

Code: Alles auswählen

;-TOP

#ProgramTitle = "Main Window"
#ProgramVersion = "v1.01.2"

Enumeration Windows
  #Main
EndEnumeration

Enumeration MenuBar
  #MainMenu
EndEnumeration

Enumeration MenuItems
  #MainMenuAbout
  #MainMenuExit
EndEnumeration

Enumeration Gadgets
  #MainTrackBarV
  #MainTrackBarH
EndEnumeration

Enumeration StatusBar
  #MainStatusBar
EndEnumeration

; ----

Procedure DoEventTrackBar()
  Protected info.s, x, y
  x = GetGadgetState(#MainTrackBarH)
  y = 100 - GetGadgetState(#MainTrackBarv)
  info = " X = " + Str(x) + " / Y = " + Str(y)
  StatusBarText(#MainStatusBar, 0, info)
EndProcedure

Procedure UpdateWindow()
  Protected dx, dy
  dx = WindowWidth(#Main)
  dy = WindowHeight(#Main) - StatusBarHeight(#MainStatusBar) - MenuHeight()
  ; Resize gadgets
  ResizeGadget(#MainTrackBarV, dx - 40, 10, 30, dy - 50)
  ResizeGadget(#MainTrackBarH, 10, dy - 40, dx - 50, 30)
    
EndProcedure

Procedure Main()
  Protected dx, dy
  
  #MainStyle = #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget
  
  If OpenWindow(#Main, #PB_Ignore, #PB_Ignore, 800, 600, #ProgramTitle , #MainStyle)
    ; Menu
    CreateMenu(#MainMenu, WindowID(#Main))
    MenuTitle("&File")
    CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
      MenuItem(#PB_Menu_About, "")
    CompilerElse
      MenuItem(#MainMenuAbout, "About")
      MenuBar()
    CompilerEndIf
    
    MenuItem(#MainMenuExit, "E&xit")
    
    ; StatusBar
    CreateStatusBar(#MainStatusBar, WindowID(#Main))
    AddStatusBarField(#PB_Ignore)
    
    ; Gadgets
    dx = WindowWidth(#Main)
    dy = WindowHeight(#Main) - StatusBarHeight(#MainStatusBar) - MenuHeight()
    
    TrackBarGadget(#MainTrackBarV, dx - 40, 10, 30, dy - 50, 0, 100, #PB_TrackBar_Vertical)
    TrackBarGadget(#MainTrackBarH, 10, dy - 40, dx - 50, 30, 0, 300)
    SetGadgetState(#MainTrackBarV, 100)
    
    ; Bind Events
    BindEvent(#PB_Event_SizeWindow, @UpdateWindow(), #Main)
    
    BindGadgetEvent(#MainTrackBarV, @DoEventTrackBar())
    BindGadgetEvent(#MainTrackBarH, @DoEventTrackBar())
    
    DoEventTrackBar()
    
    AddWindowTimer(#Main, 1, 1000)
    
    ; Event Loop
    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          Select EventWindow()
            Case #Main
              Break
              
          EndSelect
          
        Case #PB_Event_Menu
          Select EventMenu()
            CompilerIf #PB_Compiler_OS = #PB_OS_MacOS   
              Case #PB_Menu_About
                PostEvent(#PB_Event_Menu, #Main, #MainMenuAbout)
                
              Case #PB_Menu_Preferences
                
              Case #PB_Menu_Quit
                PostEvent(#PB_Event_CloseWindow, #Main, #Null)
                
            CompilerEndIf
            
          Case #MainMenuAbout
            MessageRequester("About", #ProgramTitle + #LF$ + #ProgramVersion, #PB_MessageRequester_Info)
              
          Case #MainMenuExit
            PostEvent(#PB_Event_CloseWindow, #Main, #Null)
            
          EndSelect
          
        Case #PB_Event_Gadget
          Select EventGadget()
            Case #MainTrackBarH, #MainTrackBarV
              Debug "H = " + GetGadgetState(#MainTrackBarH) + " / V = " + GetGadgetState(#MainTrackBarV)
              
          EndSelect
          
        Case #PB_Event_Timer
          Select EventTimer()
            Case 1
              Debug "Timer 1"
          EndSelect
          
      EndSelect
    ForEver
    
  EndIf
  
EndProcedure : Main()