ScrollBar Gadget feuert zwei Events. Feature oder Bug?

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
Kurzer
Beiträge: 1617
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

ScrollBar Gadget feuert zwei Events. Feature oder Bug?

Beitrag von Kurzer »

Hallo zusammen,

mir fällt gerade auf, dass das Scrollbar Gadget zwei Events feuert, wenn man die die beiden vor/zurück Buttons [<] [>] benutzt.

Habe dazu den Code aus der Hilfe etwas verkürzt:

Code: Alles auswählen

EnableExplicit

Procedure BindHScrollDatas()
	Static.i iAufrufe = 1
	Debug iAufrufe
	iAufrufe + 1
EndProcedure

If OpenWindow(0, 0, 0, 380, 100, "ScrollBarGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) 
	TextGadget       (2,  10, 25, 350,  30, "ScrollBar Standard  (Start = 50, Seite = 30/100)")
	ScrollBarGadget  (0,  10, 50, 350,  20, 0, 100, 30)
	SetGadgetState   (0,  50)   ; setze den ersten Scrollbalken (ID = 0) auf 50 von 100
	
	BindGadgetEvent(0, @BindHScrollDatas())
	
	Repeat 
		Select WaitWindowEvent() 
			Case  #PB_Event_CloseWindow 
				End 
		EndSelect
	ForEver 
EndIf
Ist das ein Fehler oder hat das andere Gründe?
Man kann beim ScrollBar-Gadget ja kein EventType() auswerten, insofern bleibt es im Dunkeln warum der Eventhandler zweimal aufgerufen wird.

Gruß Kurzer
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.02 x64, OS: Win 7 Pro x64 & Win 11 x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Useralter in 2024: 56 Jahre.
Joshua314
Beiträge: 115
Registriert: 06.04.2005 22:44

Re: ScrollBar Gadget feuert zwei Events. Feature oder Bug?

Beitrag von Joshua314 »

Ich kann es zwar nicht abfangen....

Aber ich vermute, dass es Mouse_LButton_Down und dann Mouse_LButton_Up ist .
Wie man es abfrägt, keine Ahnung.
Gruß Thomas
Benutzeravatar
RSBasic
Admin
Beiträge: 8022
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: ScrollBar Gadget feuert zwei Events. Feature oder Bug?

Beitrag von RSBasic »

Für mich sieht es auch so aus, dass #WM_LBUTTONDOWN und #WM_LBUTTONUP gefeuert wird.
Komisch ist, dass die Eventabfrage ohne BindGadgetEvent nur ein Event ausgelöst wird:

Code: Alles auswählen

If OpenWindow(0, 0, 0, 500, 400, "Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  TextGadget       (2,  10, 25, 350,  30, "ScrollBar Standard  (Start = 50, Seite = 30/100)")
   ScrollBarGadget  (0,  10, 50, 350,  20, 0, 100, 30)
   SetGadgetState   (0,  50)   ; setze den ersten Scrollbalken (ID = 0) auf 50 von 100
   
  Repeat
    Event = WaitWindowEvent()
    Select Event
      Case #PB_Event_Gadget
        Select EventGadget()
          Case 0
            Debug Event
        EndSelect
      Case #PB_Event_CloseWindow
        End
    EndSelect
  ForEver
EndIf
\\Edit:
Okay, die Erklärung ist einfach, da man bei der direkten Eventabfrage ohne BindGadgetEvent() mit dem gedrückten Mausklick die Schleife unterbricht und erst nach Loslassen ein Event ausgelöst wird.

Da fehlen dann wohl #PB_EventType_LeftClick_Down und _Up, um das besser zu unterscheiden, wann jemand auf den Scrollbutton drückt und wann er wieder loslässt.

Um das zu unterschieden, ist es derzeit nur mit einem Callback möglich.

Bezüglich der Frage, ob Bug oder Feature: Ich würde eher "fehlendes Feature" sagen.
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Benutzeravatar
Kurzer
Beiträge: 1617
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Re: ScrollBar Gadget feuert zwei Events. Feature oder Bug?

Beitrag von Kurzer »

Danke für die weiteren Untersuchungen und Deine Schlussfolgerung, RSBasic.
Es scheint sich offenbar wirklich um die beiden Events Mouse_down und Mouse_up zu handeln.

Blöd, wenn man im Eventhandler rechenintensive Prozesse hat, die dann zwangsläufig zweimal ausgeführt werden.

Ich stelle das mal ins englische Forum, evtl. gibt es ja ne Lösung dafür in PB 5.71?
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.02 x64, OS: Win 7 Pro x64 & Win 11 x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Useralter in 2024: 56 Jahre.
Nino
Beiträge: 1300
Registriert: 13.05.2010 09:26
Wohnort: Berlin

Re: ScrollBar Gadget feuert zwei Events. Feature oder Bug?

Beitrag von Nino »

Hoffentlich ist das folgende hier nicht zu sehr off topic ...

Ich verstehe das 2. Beispiel in der Hilfe überhaupt nicht. Hier der komplette Code:

Code: Alles auswählen

Procedure BindHScrollDatas()
   SetWindowTitle(0, "ScrollBarGadget (" + GetGadgetState(0) + ")" )
EndProcedure

Procedure BindVScrollDatas()
   SetWindowTitle(0, "ScrollBarGadget (" + GetGadgetState(1) + ")" )
EndProcedure


If OpenWindow(0, 0, 0, 400, 400, "ScrollBarGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) 
   TextGadget       (2,  10, 25, 350,  30, "ScrollBar Standard  (Start = 50, Seite = 30/100)")
   ScrollBarGadget  (0,  10, 50, 350,  20, 0, 100, 30)
   SetGadgetState   (0,  50)   ; setze den ersten Scrollbalken (ID = 0) auf 50 von 100
   TextGadget       (3,  10, 120, 350,  30, "ScrollBar vertical  (Start = 100, Seite = 50/300)")
   ScrollBarGadget  (1, 175, 160,  25, 120 ,0, 300, 50, #PB_ScrollBar_Vertical)
   SetGadgetState   (1, 100)   ; setze den zweiten Scrollbalken (ID = 1) auf 100 von 300
   
   BindGadgetEvent(0, @ BindHScrollDatas())
   BindGadgetEvent(1, @ BindVScrollDatas())
   
   Repeat 
      Select WaitWindowEvent() 
         Case  #PB_Event_CloseWindow 
            End 
         Case  #PB_Event_Gadget 
            Select EventGadget()
               Case 0
                  MessageRequester("Info","Der Scrollbalken 0 wurde verwendet ! (" + GetGadgetState(0) +
                                          ")" ,#PB_MessageRequester_Ok)
               Case 1
                  MessageRequester("Info","Der Scrollbalken 1 wurde verwendet ! (" + GetGadgetState(1) +
                                          ")" ,#PB_MessageRequester_Ok) 
                  
            EndSelect 
      EndSelect
   ForEver 
EndIf
Da die Ereignisse der Gadgets 0 und 1 an die Prozeduren BindHScrollDatas() und BindVScrollDatas() gebunden werden, wie können sie dann trotzdem noch (offenbar erfolgreich) in der Ereignis-Schleife abgefragt werden?
Benutzeravatar
mk-soft
Beiträge: 3700
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: ScrollBar Gadget feuert zwei Events. Feature oder Bug?

Beitrag von mk-soft »

Nino hat geschrieben:Da die Ereignisse der Gadgets 0 und 1 an die Prozeduren BindHScrollDatas() und BindVScrollDatas() gebunden werden, wie können sie dann trotzdem noch (offenbar erfolgreich) in der Ereignis-Schleife abgefragt werden?
Das ist normal...
BindEvent erhält man mehr Event. Bei WaitWindowEvent wird mehr gefiltert...
Zum Beispiel ResizeWindow erhalt man bei BindEvent jede Größenänderung und bei WaitWindowEvent nur ein Event Wenn ResizeWinndow
fertig ist.
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Nino
Beiträge: 1300
Registriert: 13.05.2010 09:26
Wohnort: Berlin

Re: ScrollBar Gadget feuert zwei Events. Feature oder Bug?

Beitrag von Nino »

mk-soft hat geschrieben:BindEvent erhält man mehr Event. Bei WaitWindowEvent wird mehr gefiltert...
Ja, das ist für mich verständlich und OK. So kann man je nach Bedarf wählen, ob man in einer gegenbenen Situation das eine oder das andere verwendet.
Aber beides zugleich wie in dem Beispiel ergibt für mich keinen Sinn. Entweder die Ereignisse des betr. Gadgets sind an eine Prozedur gebunden oder sie sind es nicht.
matbal
Beiträge: 246
Registriert: 30.03.2011 20:53

Re: ScrollBar Gadget feuert zwei Events. Feature oder Bug?

Beitrag von matbal »

Du kannst sogar mehrere Prozeduren an ein Gadget binden. Dann bekommt jede Prozedur die Events.

Sinnvoll ist das z.B. bei Modulen, die auf Events reagieren sollen. Ein Autoresizer zum Beispiel. Das Modul kann auf das Resize-Event reagieren. Wenn du ein anderes Verhalten für ein paar Gadgets brauchst, bindest du für die noch deine Prozedur ein.
Benutzeravatar
mk-soft
Beiträge: 3700
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: ScrollBar Gadget feuert zwei Events. Feature oder Bug?

Beitrag von mk-soft »

Ach ja, wegen den Events vom Scrollbar.
Es scheint das PB nur ein Pull von Event bei BindEvent verwendet. Das passt aber nicht immer wie man es braucht.

Vielleicht SetGadgetCallback die Messages von Control selber auswerten.

Code: Alles auswählen

;-TOP

; Comment : Module SetGadgetCallback (Windows Only)
; Author  : mk-soft
; Version : v0.02
; Created : 10.06.2018
; Updated : 
;
; Syntax Callback:
;           Procedure GadgetCB(hWnd,uMsg,wParam,lParam)
;             Select uMsg
;               ;TODO
;             EndSelect
;             ; Call previous gadget procedure
;             ProcedureReturn CallGadgetProc(hWnd,uMsg,wParam,lParam)
;           EndProcedure
;
; *****************************************************************************

DeclareModule GadgetCallback
  
  Declare SetGadgetCallback(Gadget, *lpNewFunc) 
  Declare CallGadgetProc(hWnd, uMsg, wParam, lParam)
  
EndDeclareModule

Module GadgetCallback
  
  EnableExplicit
  
  Global NewMap *lpPrevFunc()
  Global MutexCB = CreateMutex()
  
  ; ---------------------------------------------------------------------------
  
  Procedure SetGadgetCallback(Gadget, *lpNewFunc)
    Protected GadgetID, GadgetKey.s
    
    GadgetID = GadgetID(Gadget)
    GadgetKey = Hex(GadgetID)
    
    ; Remove exists Callback
    If FindMapElement(*lpPrevFunc(), GadgetKey)
      SetWindowLongPtr_(GadgetID, #GWL_WNDPROC, *lpPrevFunc())
      DeleteMapElement(*lpPrevFunc())
    EndIf
    
    If *lpNewFunc
      If AddMapElement(*lpPrevFunc(), GadgetKey)
        *lpPrevFunc() = SetWindowLongPtr_(GadgetID, #GWL_WNDPROC, *lpNewFunc)
        ProcedureReturn *lpPrevFunc()
      EndIf
    EndIf
    
    ProcedureReturn 0
    
  EndProcedure
  
  ; ---------------------------------------------------------------------------
  
  Procedure CallGadgetProc(hWnd, uMsg, wParam, lParam)
    Protected result
    
    LockMutex(MutexCB)
    If FindMapElement(*lpPrevFunc(), Hex(hWnd))
      result = CallWindowProc_(*lpPrevFunc(), hWnd, uMsg, wParam, lParam)
    EndIf
    UnlockMutex(MutexCB)
    
    ProcedureReturn result
    
  EndProcedure
  
EndModule

; *****************************************************************************

EnableExplicit

UseModule GadgetCallback

Procedure GadgetCB(hWnd,uMsg,wParam,lParam)
  Select uMsg
    Case #SBM_SETSCROLLINFO
      Debug "#SBM_SETSCROLLINFO"
    Case #SBM_GETSCROLLINFO
      Debug "#SBM_GETSCROLLINFO"
      
  EndSelect
  ProcedureReturn CallGadgetProc(hWnd,uMsg,wParam,lParam)
EndProcedure

Procedure BindHScrollDatas()
  Static.i iProcedureCalls = 1
  ; Filter
  If GetGadgetData(EventGadget()) <> GetGadgetState(EventGadget())
    SetGadgetData(EventGadget(), GetGadgetState(EventGadget()))
    Debug "BindEventProcedure call #" + Str(iProcedureCalls) + " Position = " + GetGadgetState(0)
    iProcedureCalls + 1
  EndIf
EndProcedure

Global.i iEvent, iEventLoopCalls = 1

If OpenWindow(0, 0, 0, 380, 120, "ScrollBarGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) 
  ScrollBarGadget  (0,  10, 40, 350,  20, 0, 100, 30)
  SetGadgetState   (0,  50)   ; setze den ersten Scrollbalken (ID = 0) auf 50 von 100
  
  SetGadgetCallback(0, @GadgetCB())
  
  BindGadgetEvent(0, @BindHScrollDatas())
  
  Repeat 
    iEvent = WaitWindowEvent()
    Select iEvent
      Case #PB_Event_Gadget
        Select EventGadget()
          Case 0
            Debug "Eventloop call #" + Str(iEventLoopCalls)
            iEventLoopCalls + 1
        EndSelect
      Case  #PB_Event_CloseWindow 
        End 
    EndSelect
  ForEver 
EndIf
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Nino
Beiträge: 1300
Registriert: 13.05.2010 09:26
Wohnort: Berlin

Re: ScrollBar Gadget feuert zwei Events. Feature oder Bug?

Beitrag von Nino »

matbal hat geschrieben:Du kannst sogar mehrere Prozeduren an ein Gadget binden. Dann bekommt jede Prozedur die Events.
Vielen Dank für die Information :!:
Das wusste ich überhaupt nicht ... und es ist auch nicht in der PB-Hilfe erklärt. :-(
Antworten