It is currently Mon Oct 14, 2019 2:03 am

All times are UTC + 1 hour




Post new topic Reply to topic  [ 4 posts ] 
Author Message
 Post subject: [Done] ScrollBar buttons: Eventhandler is called twice
PostPosted: Wed Mar 13, 2019 1:45 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sun Jun 11, 2006 12:07 am
Posts: 489
Location: Germany / one of the fishheads
It's probably not a mistake, but at least in some cases it's a nuisance.

If you bind the events of a ScrollBar gadget to an event procedure using BindGadgetEvent(), this procedure will be called twice when you use the transport buttons of the ScrollBar [<] and [>].
In the German forum we assume that the events Mouse_down and Mouse_up are responsible for this. Since you cannot use EventType() with a scrollbar event handler, it is not possible to distinguish between the two calls.

In my case 2D graphic intensive processes are executed in the event procedure, therefore a double call of the procedure is very annoying.

Here is an example code that illustrates the problem.

Code:
EnableExplicit

Procedure BindHScrollDatas()
   Static.i iProcedureCalls = 1
   Debug "BindEventProcedure call #" + Str(iProcedureCalls)
   iProcedureCalls + 1
EndProcedure

Global.i iEvent, iEventLoopCalls = 1

If OpenWindow(0, 0, 0, 380, 100, "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
   
   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

_________________
PB 5.62, OS: Windows 7 Pro x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520, User age: 51y
"Happiness is a pet." | "Never run a changing system!"


Top
 Profile  
Reply with quote  
 Post subject: Re: ScrollBar transport buttons: Eventhandler is called twic
PostPosted: Thu Mar 14, 2019 11:03 pm 
Offline
Addict
Addict
User avatar

Joined: Fri May 12, 2006 6:51 pm
Posts: 1956
Location: Germany
A pull of window events will be bound with BindEvent.
Unfortunately they don't always fit to what you need.
Maybe use GadgetCallback to evaluate the appropriate events.
Code:
;-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

_________________
My Projects ThreadToGUI / OOP-BaseClass / OOP-BaseClassDispatch / EventDesigner V3
PB v3.30 / v5.70 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace


Top
 Profile  
Reply with quote  
 Post subject: Re: ScrollBar transport buttons: Eventhandler is called twic
PostPosted: Thu Mar 14, 2019 11:52 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sun Jun 11, 2006 12:07 am
Posts: 489
Location: Germany / one of the fishheads
Thanks for your code, mk-soft.

I always found callbacks a bit confusing, so I was very happy about the introduction of BindGadgetEvent() in PureBasic (I had written myself an event manager before to simulate something like BindGadgetEvent).

But your filtering in the eventhandler is a nice idea, I'll do that. :D

Ah, damn. I already use GadgetData for holding the Gadgetstructure of my custom gadget (the scrollbar gadget is a part of the custom gadget, so i cannot use the filter aproach). Hmm, but I could use an additional field within my gadgetstructur to save the last state of the scrollbar.

_________________
PB 5.62, OS: Windows 7 Pro x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520, User age: 51y
"Happiness is a pet." | "Never run a changing system!"


Top
 Profile  
Reply with quote  
 Post subject: Re: ScrollBar transport buttons: Eventhandler is called twic
PostPosted: Wed Apr 10, 2019 8:00 pm 
Offline
Administrator
Administrator

Joined: Fri May 17, 2002 4:39 pm
Posts: 13622
Location: France
Fixed.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye