Seite 1 von 2
ScrollBar Gadget feuert zwei Events. Feature oder Bug?
Verfasst: 12.03.2019 22:40
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
Re: ScrollBar Gadget feuert zwei Events. Feature oder Bug?
Verfasst: 12.03.2019 23:20
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
Re: ScrollBar Gadget feuert zwei Events. Feature oder Bug?
Verfasst: 13.03.2019 10:18
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.
Re: ScrollBar Gadget feuert zwei Events. Feature oder Bug?
Verfasst: 13.03.2019 14:28
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?
Re: ScrollBar Gadget feuert zwei Events. Feature oder Bug?
Verfasst: 14.03.2019 22:08
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?
Re: ScrollBar Gadget feuert zwei Events. Feature oder Bug?
Verfasst: 14.03.2019 22:47
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.
Re: ScrollBar Gadget feuert zwei Events. Feature oder Bug?
Verfasst: 14.03.2019 22:55
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.
Re: ScrollBar Gadget feuert zwei Events. Feature oder Bug?
Verfasst: 14.03.2019 23:41
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.
Re: ScrollBar Gadget feuert zwei Events. Feature oder Bug?
Verfasst: 15.03.2019 00:45
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
Re: ScrollBar Gadget feuert zwei Events. Feature oder Bug?
Verfasst: 15.03.2019 11:23
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.