Page 1 of 1

How to trap mouse button up and down in a trackbargadget?

Posted: Sun Oct 19, 2008 11:53 am
by pdwyer
(in windows)
I've been playing around with SetWindowCallback() and watching messages but being a commonctrl using wm_notify etc I'm having a hard time working this out.

Basically I want to get the position of the trackbar at mouse down and then at mouse up to see how far it's moved.

I guess I can get around this if I can know the position before it moves... or for a little loss of efficiency I can trap all notification messages to it and check for changes... I guess this is what I will have to do if this gets difficult

Re: How to trap mouse button up and down in a trackbargadget

Posted: Sun Oct 19, 2008 12:56 pm
by PB
Here's a dirty mod of my old code from http://www.purebasic.fr/english/viewtopic.php?t=16271 :

Code: Select all

If OpenWindow(0,200,200,450,200,"test",#PB_Window_SystemMenu)
  TrackBarGadget(1,10,10,200,30,1,10,#PB_TrackBar_Ticks)
  TextGadget(2,10,50,150,20,"")
  Repeat
    ev=WaitWindowEvent()
    If ev=#PB_Event_Gadget And GetAsyncKeyState_(#VK_LBUTTON)<>0
      start=GetGadgetState(1)
      Repeat : Sleep_(1) : WindowEvent() : Until GetAsyncKeyState_(#VK_LBUTTON)=0
      stop=GetGadgetState(1)
      SetGadgetText(2,"Started at "+Str(start)+", ended at "+Str(stop))
    EndIf
  Until ev=#PB_Event_CloseWindow
EndIf 

Posted: Sun Oct 19, 2008 12:57 pm
by Mistrel

Posted: Sun Oct 19, 2008 2:13 pm
by pdwyer
thanks,

I'm getting there with these

@PB, this doesn't work with all the ways that a trackbar can move, I realise that I only mentioned mouse but I see now that I need everything

@mistrel, thanks, nice tool, it's not helping this time though as it's a common control and all you see is WM_Notify and NM_customdraw

I have a select statement that is nearly working, by that I mean, it works for one app, then I create another and it doesn't anymore, I need to work out where to filter the lparam message, I thought it was just a low word but that isn't always working. If I get it working I'll post it. It's hard working backwards with constants :(

Posted: Sun Oct 19, 2008 2:33 pm
by pdwyer
This either works fine for me or completely fails to catch the events. if it works it will continue to work but if I move the proc to a different app it will fail sometimes.

it's close, but still useless :( I suspect I'm supposed to do something with one of those notify structures you get in a pointer and I'm completely skipping that <cringe>

Code: Select all


Declare.l WinCallback(hWnd, uMsg, wParam, lParam) 


    #FrmMain  = 1
    #Trk_byteloc = 2

Procedure Open_FrmMain()
    If OpenWindow(#FrmMain, 311, 229, 662, 141, "track",  #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar )
        If CreateGadgetList(WindowID(#FrmMain))
        
            TrackBarGadget(#Trk_byteloc, 5, 0, 657, 30, 0, 63, #PB_TrackBar_Ticks)

        EndIf
    EndIf
    
    SetWindowCallback(@WinCallback())  
    
    Repeat   
        Event = WaitWindowEvent()         
    Until Event = #PB_Event_CloseWindow 
    
EndProcedure

Open_FrmMain()

Procedure.l WinCallback(hWnd, uMsg, wParam, lParam) 

    CtrlID.w = wParam&$FFFF
    CtrlMsg.w = (wParam>>16)&$FFFF  
 
    LO_lparam = lParam&$FFFF 
    
    Select uMsg 
    
        Case #WM_NOTIFY

            Select wParam
                Case #Trk_byteloc
                
                    Select LO_lparam 
                    
                        Case 64736, 63184, 63924
                            Debug "Mouse up" + " " + Str(GetGadgetState(#Trk_byteloc))
                        Case 63820
                            Debug "Mouse down" + " " + Str(GetGadgetState(#Trk_byteloc))                   
                        Case 63892
                            Debug "Track moved bymouse drag" + " " + Str(GetGadgetState(#Trk_byteloc))                        
                        Case  63912
                            Debug "Track moved by Keyboard" + " " + Str(GetGadgetState(#Trk_byteloc))                        
                        Case 64548    
                            Debug "Focus change"+  " " + Str(GetGadgetState(#Trk_byteloc))                        
                        Case 63940   
                            Debug "Track moved by mouse wheel" + " " + Str(GetGadgetState(#Trk_byteloc))                       
                        Case 64548
                            Debug "Track control init" + " " +Str(GetGadgetState(#Trk_byteloc))
                        Case 63792
                            Debug "Click on track - jump" + " " +Str(GetGadgetState(#Trk_byteloc))                            
                        Case 63864
                            Debug "Mouse extended down" + " " +Str(GetGadgetState(#Trk_byteloc)) 
                        Default
                            Debug "Uncaptured track event" + " " +Str(GetGadgetState(#Trk_byteloc)) + " " + Str(LO_lparam)   
                    EndSelect                                   

            EndSelect    
        
        Case #WM_COMMAND 
    
            Select CtrlID
                ;Case #Trk_byteloc

            EndSelect          
    EndSelect
    
    ProcedureReturn #PB_ProcessPureBasicEvents 
    
EndProcedure 


Posted: Sun Oct 19, 2008 3:26 pm
by netmaestro
Does this do what you want? It should be completely portable and work inside containers, etc.:

Code: Select all

#TrackBar_MouseDown = #WM_APP+1
#TrackBar_MouseUp   = #WM_APP+2

Procedure TBProc(hwnd, msg, wparam, lparam)
  oldproc = GetProp_(hwnd, "oldproc")
  ctrlid  = GetProp_(hwnd, "PB_ID")
  Select msg
    Case #WM_LBUTTONDOWN
      PostMessage_(GetWindow_(hwnd, #GW_OWNER), #TrackBar_MouseDown, ctrlid, GetGadgetState(ctrlid))
    Case #WM_LBUTTONUP
      PostMessage_(GetWindow_(hwnd, #GW_OWNER), #TrackBar_MouseUp, ctrlid, GetGadgetState(ctrlid))
  EndSelect
  ProcedureReturn CallWindowProc_(oldproc, hwnd, msg, wparam, lparam)
EndProcedure

OpenWindow(0,0,0,640,480,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
TrackBarGadget(1,20,300,600,20,0,100,#PB_TrackBar_Ticks)
SetProp_(GadgetID(1),"oldproc",SetWindowLong_(GadgetID(1),#GWL_WNDPROC,@TBProc()))

Repeat
  ev = WaitWindowEvent()
  Select ev
    Case #TrackBar_MouseDown
      Debug EventwParam() ; gadget#
      Debug EventlParam() ; gadgetstate
    Case #TrackBar_MouseUp
      Debug EventwParam()
      Debug EventlParam()
  EndSelect
Until ev = #PB_Event_CloseWindow

Posted: Sun Oct 19, 2008 3:34 pm
by pdwyer
Even the compiler doesn't understand that :shock:

---------------------------
PureBasic_Compilation3.exe - Entry Point Not Found
---------------------------
The procedure entry point SetWindowLongPtrA could not be located in the dynamic link library USER32.dll.
---------------------------
OK
---------------------------

Posted: Sun Oct 19, 2008 3:37 pm
by netmaestro
It should have, using 4.30 beta 3. I changed it back to SetWindowLong, if you're using 4.2 just add a CreateGadgetList() before creating the gadgets. Could you try it again?

Posted: Mon Oct 20, 2008 3:18 am
by Sparkie
This should handle both mouse and keyboard contol of TrackBarGadgets.

Coded for PB 430, so add CreateGadgetList as needed.

Code: Select all

Procedure WinCallback(hwnd, msg, wParam, lParam) 
  result = #PB_ProcessPureBasicEvents 
  Select msg 
    Case #WM_HSCROLL 
      If lParam = GadgetID(1)
        Select wParam &$FFFF 
          Case #SB_THUMBPOSITION
            sPos =  GetGadgetData(1)
            If sPos = -1
              sPos = 1
            EndIf
            ePos = GetGadgetState(1)
            SetGadgetData(1, ePos)
            SetGadgetText(3, "Started at " + Str(sPos) + " Ended at " + Str(ePos))
          Case #SB_THUMBTRACK 
            If GetGadgetData(1) = -1 
              pos = GetGadgetState(1) 
              SetGadgetData(1, pos) 
            EndIf 
          Case #SB_LINEDOWN, #SB_PAGEDOWN 
            pos = GetGadgetState(1) 
            SetGadgetData(1, pos - 1) 
          Case #SB_LINEUP, #SB_PAGEUP 
            pos = GetGadgetState(1) 
            SetGadgetData(1, pos + 1) 
          Case #SB_ENDSCROLL 
            sPos = GetGadgetData(1) 
            ePos = GetGadgetState(1) 
            SetGadgetText(3, "Started at " + Str(sPos) + " Ended at " + Str(ePos)) 
            SetGadgetData(1, -1) 
        EndSelect 
      EndIf 
    Case #WM_VSCROLL 
      If lParam = GadgetID(2)
        Select wParam &$FFFF 
          Case #SB_THUMBPOSITION
            sPos =  GetGadgetData(2)
            If sPos = -1
              sPos = 1
            EndIf
            ePos = GetGadgetState(2)
            SetGadgetData(2, ePos)
            SetGadgetText(4, "Started at " + Str(sPos) + " Ended at " + Str(ePos))
          Case #SB_THUMBTRACK 
            If GetGadgetData(2) = -1 
              pos = GetGadgetState(2) 
              SetGadgetData(2, pos) 
            EndIf 
          Case #SB_LINEDOWN, #SB_PAGEDOWN 
            pos = GetGadgetState(2) 
            SetGadgetData(2, pos + 1) 
          Case #SB_LINEUP, #SB_PAGEUP 
            pos = GetGadgetState(2) 
            SetGadgetData(2, pos - 1) 
          Case #SB_ENDSCROLL 
            sPos = GetGadgetData(2) 
            ePos = GetGadgetState(2) 
            SetGadgetText(4, "Started at " + Str(sPos) + " Ended at " + Str(ePos)) 
            SetGadgetData(2, -1) 
        EndSelect 
      EndIf 
  EndSelect 
  ProcedureReturn result 
EndProcedure 
If OpenWindow(0,200,200,450,300,"test",#PB_Window_SystemMenu) 
  SetWindowCallback(@WinCallback()) 
  TrackBarGadget(1,10,10,200,30,1,10,#PB_TrackBar_Ticks) 
  SetGadgetData(1, -1) 
  TrackBarGadget(2,300,10,30,200,1,10,#PB_TrackBar_Ticks | #PB_TrackBar_Vertical) 
  SetGadgetData(2, -1) 
  TextGadget(3,10,50,150,20,"") 
  TextGadget(4,250,220,150,20,"") 
  Repeat 
    ev=WaitWindowEvent() 
  Until ev=#PB_Event_CloseWindow 
EndIf 

Posted: Mon Oct 20, 2008 11:51 am
by pdwyer
:shock: OMG !!!!

YOU, are the man!

:lol: Boy was I barking up the wrong tree with that wm_notify thing :)