DockToolbar Early Beta Test

Share your advanced PureBasic knowledge/code with the community.
localmotion34
Enthusiast
Enthusiast
Posts: 665
Joined: Fri Sep 12, 2003 10:40 pm
Location: Tallahassee, Florida

DockToolbar Early Beta Test

Post by localmotion34 »

Code updated for 5.20+

for a loooong time now ive been playing around with a version of a docking toolbar much like the MS C++ AFX control bar and others like it to add its functionality to PB. here is a working TEST version of the most BASIC skeleton code. I have written much more in-depth procedures to handle dragging and dropping, multiple rows of docked toolbars, "intellisense" position handling, and even full docking windows that arent toolbars and so forth.

what i need is for others to give me feedback on the basic functionality and look of the system. when i get this finally compiled into a PB LIB, this WILL NOT affect any windowcallback or subclassing in your code. these toolbars and docking windows will be subclassed from the LIB and inaccessible to quirks and procedure re-directing.

Is there anything else that you want to see? any ideas on how to improve the code? any serious design flaws? please give some help on this.

and YES YES. using the FULL AND FINAL LIB will add about 9-15K to your EXE due to all the code, arrays and linked lists i use to handle the toolbars and docking. that is why MS and others with docking windows have runtimes and/or larger EXE. this can take a heck of alot of procedure to handle the subclassing.
NOTE: to undock the toolbars, double click the button at the left hand side of the toolbar

Code: Select all

Global parentrect.RECT,childrect.RECT, rect.RECT,hregion ,drawbox,MouseBtnDownX,MouseBtnDownY
Global hrect.RECT ,originproc,cont

Structure dock
  num.i
  hwnd.i
  pane.i
  rct.RECT
  width.l
  button.i
  toolbar.i
  State.l
  xloc.l
EndStructure

Global NewList dock.dock()
 
Declare undockwindow(dockhandle,x,y,width,height)
Declare dockwindow(dockhandle,parenthandle,x,y,width,height)



Procedure Paneproc(hwnd, uMsg, wParam, lParam)
  Select uMsg
    Case #WM_LBUTTONDOWN
     
    Case #WM_LBUTTONUP
      RedrawWindow_(hwnd,0,0,#RDW_ALLCHILDREN   )
      ShowWindow_(hwnd,#SW_SHOWNORMAL)
     
    Case #WM_MOUSEACTIVATE
      RedrawWindow_(hwnd,0,0,#RDW_ALLCHILDREN   )
      ShowWindow_(hwnd,#SW_SHOWNORMAL)
    Case #WM_PAINT
      RedrawWindow_(hwnd,0,0,#RDW_ALLCHILDREN   )
      ShowWindow_(hwnd,#SW_SHOW)
  EndSelect
  ProcedureReturn DefWindowProc_(hwnd, uMsg, wParam, lParam)
EndProcedure

Procedure buttonproc(hwnd,uMsg,wParam,lParam)
  Select uMsg
    Case #WM_LBUTTONDOWN
      ProcedureReturn 0
    Case #WM_LBUTTONDBLCLK
      ForEach(dock())
        If GetParent_(hwnd)=dock()\hwnd
          SelectElement(dock(),dock()\num)
          strbuffer.s="ToolbarWindow32"
          tb=FindWindowEx_(GetParent_(hwnd),0,@strbuffer,"")
          GetWindowRect_(GetParent_(hwnd),@rect.RECT)
          If dock()\State=#True
            undockwindow(GetParent_(hwnd),rect\left,rect\top,rect\right-rect\left,rect\bottom-rect\top+17)
            SetWindowPos_(tb,0,6,0,0,0,#SWP_NOSIZE)
            dock()\State=#False
          ElseIf dock()\State=#False
            dockwindow(GetParent_(hwnd),dock()\pane,dock()\xloc,0,rect\right-rect\left,30)
            SetWindowPos_(tb,0,6,0,0,0,#SWP_NOSIZE)
            dock()\State=#True
          EndIf
          ProcedureReturn 0
        EndIf
      Next
  EndSelect
  ProcedureReturn CallWindowProc_(GetProp_(hwnd,"OldProc"),hwnd,uMsg,wParam,lParam)
EndProcedure
 
Procedure dockProc(hwnd, uMsg, wParam, lParam)
  Select uMsg
    Case #WM_LBUTTONDOWN
     
    Case #WM_LBUTTONUP
     
    Case #WM_MOUSEMOVE
     
     
    Case #WM_MOVE
     
    Case #WM_MOUSEACTIVATE
     
    Case #WM_PAINT
     
  EndSelect
  ProcedureReturn DefWindowProc_(hwnd, uMsg, wParam, lParam)
EndProcedure
 
ProcedureDLL dockpane(number,parent, x, y, width, height,rows,flags)
  hwnd1=OpenWindow(#PB_Any,x, y, width, height,"",#PB_Window_BorderLess)
  hwnd=WindowID(hwnd1)
  SetParent_(hwnd,parent)
  SetWindowLong_(hwnd,#GWL_STYLE, #WS_CHILD|#WS_DLGFRAME|#WS_EX_CLIENTEDGE|#WS_CLIPCHILDREN|#WS_CLIPSIBLINGS )
  ;SetWindowLong_( hwnd,#GWL_WNDPROC,@Paneproc() )
  ShowWindow_(hwnd,#SW_SHOW)
  ProcedureReturn hwnd
EndProcedure
 
ProcedureDLL CreateDockTB(number,width,dockpane); Create a window in a "Docked" state
  If ListSize(dock())=0
    lastwidth=0
  Else
    ForEach dock()
      lastwidth=lastwidth+dock()\width
    Next
  EndIf
  AddElement(dock())
  dock()\xloc=lastwidth
  hwnd1=OpenWindow( #PB_Any,lastwidth,0,width,30,"",#PB_Window_Invisible)
  hwnd=WindowID(hwnd1)
  SetWindowLong_( hwnd,#GWL_STYLE, #WS_CHILD|#WS_DLGFRAME|#WS_CLIPCHILDREN|#WS_CLIPSIBLINGS )
  originproc=SetWindowLong_( hwnd,#GWL_WNDPROC,@dockProc() )
  SetWindowPos_( hwnd,0,0,0,0,0,#SWP_NOSIZE|#SWP_NOMOVE|#SWP_FRAMECHANGED )
  SetParent_( hwnd, dockpane)
  button=ButtonGadget(#PB_Any,0,0,5,25,"")
  SetProp_(GadgetID(button),"OldProc",SetWindowLong_(GadgetID(button), #GWL_WNDPROC, @buttonproc()))
  ShowWindow_(GadgetID(button),#SW_SHOWNORMAL)
  MoveWindow_(hwnd,lastwidth,0,width,30, #True )
  tb=CreateToolBar(#PB_Any, WindowID(hwnd1))
  strbuffer.s="ToolbarWindow32"
  htoolbar=FindWindowEx_(hwnd,0,@strbuffer,"") 
  ToolBarStandardButton(0, #PB_ToolBarIcon_New)
  ToolBarStandardButton(1, #PB_ToolBarIcon_Open)
  ToolBarStandardButton(2, #PB_ToolBarIcon_Save)
  SetWindowLong_(htoolbar,#GWL_STYLE, GetWindowLong_(htoolbar,#GWL_STYLE)|#CCS_NODIVIDER )
  RedrawWindow_(hwnd,0,0,#RDW_ALLCHILDREN)
  ShowWindow_(hwnd, #SW_SHOW)
  SetWindowPos_(htoolbar,0,6,0,0,0,#SWP_NOSIZE)
  dock()\width=width
  dock()\pane=dockpane
  dock()\button=GadgetID(button)
  dock()\State=#True
  dock()\hwnd=hwnd
  dock()\num=ListIndex(dock())
  ProcedureReturn tb
EndProcedure
 
ProcedureDLL dockwindow(dockhandle,parenthandle,x,y,width,height);Docks Your Window and Makes it Immobile
  ShowWindow_(dockhandle,#SW_HIDE)
  SetWindowLong_( dockhandle,#GWL_STYLE, #WS_CHILD|#WS_DLGFRAME|#WS_EX_CLIENTEDGE|#WS_CLIPCHILDREN|#WS_CLIPSIBLINGS )
  MoveWindow_(dockhandle,x,y,width,height, #True )
  RedrawWindow_(dockhandle,0,0,7)
  SetParent_(dockhandle,parenthandle)
  ShowWindow_(dockhandle,#SW_SHOW)
EndProcedure
 
ProcedureDLL undockwindow(dockhandle,x,y,width,height);Undocks Your Window and Makes it a Free Toolwindow
  ShowWindow_(dockhandle,#SW_HIDE)
  SetWindowLong_(dockhandle,#GWL_STYLE,#WS_CAPTION|#WS_CLIPCHILDREN|#WS_CLIPSIBLINGS )
  SetWindowLong_(dockhandle,#GWL_EXSTYLE,GetWindowLong_(dockhandle,#GWL_EXSTYLE) | #WS_EX_TOOLWINDOW)
  MoveWindow_(dockhandle,x,y,width,height, #True )
  RedrawWindow_(dockhandle,0,0,7)
  SetParent_(dockhandle,#HWND_DESKTOP)
  RedrawWindow_(dockhandle,0,0,7)
  ShowWindow_(dockhandle,#SW_SHOW)
EndProcedure

ProcedureDLL getDockstate(dockhandle);returns a dockwindow state: 0 if undocked, 1 if docked
  State=GetWindowLong_(dockhandle,#GWL_STYLE)
  If State =381681664
    dockstate=0
  Else
    dockstate=1
  EndIf
  ProcedureReturn dockstate
EndProcedure
 
#MENU=0
Enumeration
  #GADGET_MDI
  #Frame3D_0
  #Radio_0
  #Radio_1
  #Combo_0
  #Panel_0
EndEnumeration
 
Enumeration
  #MENU_Dock
  #MENU_unDock
  #MENU_undocktoMDI
  #get_state
  #quick_undock
  #quick_dock
EndEnumeration
 
  ;-Setup our main window
wind=OpenWindow(0, 0, 0, 800, 600, "Docked ToolWindow", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
 
  ;-setup dockwindow 1
 ;here we define the structure associated with the 1st dockwindow
Quit = 0

pane1=dockpane(1,WindowID(0),0,0,420,60,2,0)
Dock1=CreateDockTB(0,100,pane1);create dockwindow 1
Dock2=CreateDockTB(1,100,pane1)
Dock2=CreateDockTB(2,100,pane1)






;ListViewGadget(9,5,10,90,510)
 
  ;-setup dockwindow 2
 
 
 
  ;-Event Loop
Repeat
 
  event = WaitWindowEvent()
 
  Select  event
   
    Case #WM_LBUTTONDOWN 
     
     
     
    Case #PB_Event_CloseWindow
      Quit = 1   
    Case  #PB_Event_Menu
      Select EventMenu()
       
      EndSelect
    Case #PB_Event_Gadget
      event1=EventGadget()
      Select event1
       
      EndSelect
  EndSelect
 
Until Quit = 1 

Code: Select all

!.WHILE status != dwPassedOut
! Invoke AllocateDrink, dwBeerAmount
!MOV Mug, Beer
!Invoke Drink, Mug, dwBeerAmount
!.endw
dontmailme
Enthusiast
Enthusiast
Posts: 537
Joined: Wed Oct 29, 2003 10:35 am

Post by dontmailme »

Looking good....

The click to dock/undock has to be very accurate.... the 'hotspot' should be bigger..... and the 'handle' might be better if it was a square instead of a bar ?!

Are you going to add the ability to 'snap' the docks to the edge of a window etc ?

Good work so far :)
Paid up PB User !
Post Reply