Multi slider trackbar
Posted: Fri Mar 02, 2007 4:16 pm
someone posted the question of how to create a multi trackbar, and here is my example. its not very optimized, and is a tiny bit buggy, but maybe if some more experienced people could help out and streamline the code, we can all use a really cool gadget. i basically emulated a slider control from Video Avatar, and all the drawing is done to an image on a static control. no flickering, even on a very slow machine. this eliminates the need of constant #wm_paint messages and processing.
Code: Select all
#pb_settrack1=8000
#pb_settrack2=8001
#pb_getselrange=8002
#WM_MOUSEHOVER = $2A1
#WM_MOUSELEAVE = $2A3
#TME_HOVER = 1
#TME_LEAVE = 2
Global ticktomove.l , mousedownx.l,deltaX.l
Structure trackbar
width.l
height.l
pbID.l
tick1pos.l
tick2pos.l
range.l
rangestep.l
pbimage.l
tick1.RECT
tick2.RECT
EndStructure
Procedure.w LOWORD(Value.l) ;windef.h macro
ProcedureReturn (Value & $FFFF)
EndProcedure
Procedure.w HIWORD(Value.l) ;windef.h macro
ProcedureReturn ((Value >> 16) & $FFFF)
EndProcedure
Macro DrawTick(xPos)
Box(xPos-4,4,8,12,#White);tick 1
Box(xPos-3,5,8,13,#Black)
Box(xPos-3,5,7,12,GetSysColor_(#COLOR_BTNFACE))
EndMacro
Procedure TrackbarProc(hwnd,msg,wParam,lParam)
*track.trackbar=GetWindowLong_(hwnd,#GWL_USERDATA)
Select msg
Case #WM_PAINT
Case #WM_LBUTTONDOWN
xPos = LOWORD(lParam)
yPos = HIWORD(lParam)
tick1.RECT
tick1\left=*track\tick1pos-4
tick1\right=*track\tick1pos+4
tick1\top=4
tick1\bottom=16
tick2.RECT
tick2\left=*track\tick2pos-4
tick2\right=*track\tick2pos+4
tick2\top=4
tick2\bottom=16
If ptinrect_(tick1.RECT,xPos,yPos)
SetCapture_(hwnd)
ticktomove=1
mousedownx=xPos
ElseIf ptinrect_(tick2.RECT,xPos,yPos)
SetCapture_(hwnd)
ticktomove=2
mousedownx=xPos
EndIf
ProcedureReturn 0
Case #WM_LBUTTONUP
Select ticktomove
Case 1
*track\tick1pos=*track\tick1pos+deltaX
SetWindowLong_(hwnd,#GWL_USERDATA,*track)
Case 2
*track\tick2pos=*track\tick2pos+deltaX
SetWindowLong_(hwnd,#GWL_USERDATA,*track)
EndSelect
ReleaseCapture_()
Case #WM_RBUTTONDOWN
Case #WM_RBUTTONUP
Case #WM_MOUSEMOVE
deltaX=0
Structure myTRACKMOUSEEVENT
cbSize.l
dwFlags.l
hwndTrack.l
dwHoverTime.l
EndStructure
mte.myTRACKMOUSEEVENT
mte\cbSize = SizeOf(myTRACKMOUSEEVENT)
mte\dwFlags = #TME_LEAVE
mte\hwndTrack = hwnd
TrackMouseEvent_(mte)
If getcapture_()=hwnd
xPos = LOWORD(lParam)
yPos = HIWORD(lParam)
deltaX.l=xPos-mousedownx
Select ticktomove
Case 1
If xPos <= 3 Or xPos>= *track\tick2pos-4
Else
hdc=StartDrawing(ImageOutput(*track\pbimage))
Box(0,0,*track\width,*track\height,GetSysColor_(#COLOR_BTNFACE))
Box(1,10,*track\width,2,#Black) ; center black line
Box(0,20,*track\width,20,$0000B91C) ; slider range
Box(*track\tick1pos+deltaX,20,*track\tick2pos-(*track\tick1pos+deltaX),20,$00FE6A02) ;highlight region
DrawTick(*track\tick1pos+deltaX)
DrawTick(*track\tick2pos)
StopDrawing()
SetGadgetState(*track\pbID,ImageID(*track\pbimage))
ProcedureReturn 0
EndIf
Case 2
If xPos > *track\width-6 Or xPos<= *track\tick1pos+4
Else
hdc=StartDrawing(ImageOutput(*track\pbimage))
Box(0,0,*track\width,*track\height,GetSysColor_(#COLOR_BTNFACE))
Box(1,10,*track\width,2,#Black) ; center black line
Box(0,20,*track\width,20,$0000B91C) ; slider range
Box(*track\tick1pos,20,(*track\tick2pos+deltaX)-(*track\tick1pos),20,$00FE6A02) ;highlight region
DrawTick(*track\tick2pos+deltaX)
DrawTick(*track\tick1pos)
StopDrawing()
SetGadgetState(*track\pbID,ImageID(*track\pbimage))
ProcedureReturn 0
EndIf
EndSelect
EndIf
Case #WM_MOUSEHOVER
Case #WM_MOUSELEAVE
Case #pb_settrack1
Case #pb_settrack2
EndSelect
ProcedureReturn CallWindowProc_(GetProp_(hwnd,"oldproc"),hwnd,msg,wParam,lParam)
EndProcedure
Procedure MultiTrackbar(id.l,x,Y,width,height,TrackRange, Trackstep)
*track.trackbar=AllocateMemory(SizeOf(trackbar))
image.l=CreateImage(#PB_Any,width,height)
hdc=StartDrawing(ImageOutput(image))
Box(0,0,width,height,GetSysColor_(#COLOR_BTNFACE))
Box(1,10,width,2,#Black) ; center black line
Box(0,20,width,20,$0000B91C) ; slider range
xdiv=Round(width/3,0)
Box(xdiv,20,xdiv,20,$00FE6A02) ;highlight region
DrawTick(xdiv) ; tick 1
*track\tick1pos=xdiv
nextdiv.f=xdiv*2
DrawTick(nextdiv);tick 2
*track\tick2pos=nextdiv
StopDrawing()
imagegad.l=ImageGadget(id,x,Y,width,height,ImageID(image))
If id=#PB_Any
*track\pbID=imagegad
hwndreturn=imagegad
hwnd=GadgetID(imagegad)
Else
*track\pbID=id
hwndreturn=imagegad
hwnd=imagegad
EndIf
With *track
\width=width
\height=height
\pbimage=image
\range=TrackRange
\rangestep=Trackstep
EndWith
SetProp_(hwnd,"oldproc",SetWindowLong_(hwnd,#GWL_WNDPROC,@TrackbarProc()))
SetWindowLong_(hwnd,#GWL_USERDATA,*track)
ProcedureReturn hwndreturn
EndProcedure
If OpenWindow(0, 259, 217, 605, 388, "MultiTrackbar", #PB_Window_SystemMenu | #PB_Window_TitleBar | #PB_Window_ScreenCentered )
If CreateGadgetList(WindowID(0))
MultiTrackbar(10,30,100,400,60,1000,50)
EndIf
EndIf
;-Event Loop
Repeat
Select WaitWindowEvent()
Case #PB_Event_Gadget
Select EventGadget()
EndSelect
Case #PB_Event_Menu
Select EventMenu()
EndSelect
Case #PB_Event_CloseWindow
Quit=1
EndSelect
Until Quit=1