Page 1 of 1

Combobox with something like MenuBar ?

Posted: Mon Feb 10, 2014 8:31 pm
by va!n
System: Windows

Is there any way to add something like a menubar to a combobox list?

Code: Select all

[Combobox]
Entry 1
Entry 2
Entry 3
-------------         << MenuBar
Entry 4

Re: Combobox with something like MenuBar ?

Posted: Mon Feb 10, 2014 8:46 pm
by IdeasVacuum
A separator line/bar. You could do it as per your text example, or you could use a line char such as U+2550.

You can also draw your own combo solution using a Canvas Gadget.

Re: Combobox with something like MenuBar ?

Posted: Tue Feb 11, 2014 8:17 pm
by RASHAD
Hi

Code: Select all

#MIM_STYLE            = $00000010
#MNS_NOCHECK          = $80000000
#MIM_BACKGROUND       = $00000002
#MIM_APPLYTOSUBMENUS  = $80000000

Structure MENUINFO
   cbSize.l
   fMask.l
   dwStyle.l
   cyMax.l
   hbrBack.l
   dwContextHelpID.l
   dwMenuData.l
   CompilerIf #PB_Compiler_Processor  = #PB_Processor_x64
    PB_Alignment2.b[12]
   CompilerEndIf
EndStructure

CreateImage(0, 20, 20)
StartDrawing(ImageOutput(0))
   Box(0,0,20,20,$DBFEFD)
StopDrawing()

hBrush0 = CreatePatternBrush_(ImageID(0))

mi.MENUINFO
mi\cbSize = SizeOf(MENUINFO)
mi\fMask = #MIM_STYLE|#MIM_BACKGROUND|#MIM_APPLYTOSUBMENUS
mi\dwStyle = #MNS_NOCHECK
mi\hbrBack = hBrush0

OpenWindow(0,0,0,500,250,"Window",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  ComboBoxGadget(1,10,10,160,22,0)
  TextGadget(2,0,0,0,0,"")   ;Dummy Gadget  
    If CreatePopupMenu(0)
    MenuItem(1, "Cut")
    MenuItem(2, "Copy")
    MenuItem(3, "Paste")
    MenuBar()
      OpenSubMenu("Options")
        MenuItem(4, "Window...")
        MenuItem(5, "Gadget...")
      CloseSubMenu()
    MenuBar()
      OpenSubMenu("Options 2")
        MenuItem(6, "Registry")
        MenuItem(7, "Clean Disk")
      CloseSubMenu()
    MenuBar()
    MenuItem(8, "Quit")
  EndIf
  
  For item = 1 To 8
    AddGadgetItem(1, -1,GetMenuItemText(0,item))
  Next
  
  SetMenuInfo_(MenuID(0),mi)
  
  dlh = FindWindow_("ComboLBox",0)
  CloseWindow_(dlh)
  
Repeat
  Select WaitWindowEvent()
      
      Case #PB_Event_CloseWindow
            Quit = 1
      
      Case #PB_Event_Menu
          Select EventMenu()
           Case 1 To 8
                SetGadgetState(1,EventMenu()-1)
                SetActiveGadget(2)
                Debug GetGadgetText(1)
                          
          EndSelect
      
      Case #WM_LBUTTONDOWN
            If GetActiveGadget() = 1
                 DisplayPopupMenu(0,WindowID(0),GadgetX(1,#PB_Gadget_ScreenCoordinate),GadgetY(1,#PB_Gadget_ScreenCoordinate)+22)
            EndIf

      Case #WM_LBUTTONUP
                  
  EndSelect 

Until Quit = 1
End

Re: Combobox with something like MenuBar ?

Posted: Wed Feb 12, 2014 2:43 am
by electrochrisso
That is pretty 8) RASHAD :)

Re: Combobox with something like MenuBar ?

Posted: Thu Feb 13, 2014 4:20 am
by Sparkie

Code: Select all

;*********************************************
;Sparkies ComboBoxGadget With Menubar type lines
;Windows only
;*********************************************
Enumeration
  #WinMain
EndEnumeration

Enumeration
  #ComboMain
EndEnumeration

Procedure WindowCallback(hwnd, msg, wParam, lParam)
  Result = #PB_ProcessPureBasicEvents
  
  Select msg
    Case #WM_DRAWITEM
      *DrawItem.DRAWITEMSTRUCT = lParam
      *lpdis.DRAWITEMSTRUCT = lParam
     
      If *DrawItem\CtlType = #ODT_COMBOBOX
        SetBkMode_(*DrawItem\hdc, #TRANSPARENT)
        
        If *DrawItem\itemState & #ODS_FOCUS
          ;****** Color the item when in focus *****
          Brush = CreateSolidBrush_(RGB(255, 255, 224))
          FillRect_(*DrawItem\hdc, *DrawItem\rcItem, Brush)
          DeleteObject_(Brush)
          SetTextColor_(*DrawItem\hdc, RGB(139, 69, 19))
        Else
          ;****** Color the item when NOT in focus *****
          FillRect_(*DrawItem\hdc, *DrawItem\rcItem, GetStockObject_(#WHITE_BRUSH))
        EndIf
        If *DrawItem\itemID <> -1
          Text$ = Space(512)
          
          ;***** Get the item text *****
          SendMessage_(*DrawItem\hwndItem, #CB_GETLBTEXT, *DrawItem\itemID, @Text$)
          
          ;****** Draw the text *****
           TextOut_(*DrawItem\hdc, *DrawItem\rcItem\left, *DrawItem\rcItem\top, Text$, Len(Text$))
           
           ;***** If the item data was set to one AND it is not currently selected, draw the line *****
          If *DrawItem\itemData = 1 And *DrawItem\itemState  & #ODS_COMBOBOXEDIT = 0
            
            ;***** Set line thickness *****
            lineH = 2
            
            ;***** Make room at the bottom of the item rect dfor the line *****
            *lpdis\rcItem\top = *lpdis\rcItem\bottom - lineH
            
            ;***** Choose line color *****
            myPen = CreatePen_(#PS_SOLID, lineH, RGB(240, 230, 140))
            
            ;***** Select the pen into the hdc *****
            oldPen = SelectObject_(*DrawItem\hdc, myPen)
            
            ;***** Draw the line *****
            MoveToEx_(*DrawItem\hdc, *lpdis\rcItem\left, *lpdis\rcItem\top, #Null)
            LineTo_(*DrawItem\hdc, *lpdis\rcItem\right, *lpdis\rcItem\top)
            
            ;***** Cleanup *****
            SelectObject_(*DrawItem\hdc, oldPen)
            DeleteObject_(myPen)
           EndIf
           
          EndIf
      EndIf
      
  EndSelect
  
  ProcedureReturn Result
EndProcedure

If OpenWindow(#WinMain, 0, 0, 600, 300, "Combobox Break Line Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget | #PB_Window_TitleBar )
  ComboBoxGadget(#ComboMain, 10, 10, 300, 25,  #CBS_OWNERDRAWFIXED | #CBS_HASSTRINGS)
  SetWindowCallback(@WindowCallback())

  AddGadgetItem(#ComboMain, -1, "Item 0")
  AddGadgetItem(#ComboMain, -1, "Item 1")
  AddGadgetItem(#ComboMain, -1, "Item 2")
  ;***** Items with data set to 1 will have a line added *****
  SetGadgetItemData(#ComboMain, 2, 1)
  AddGadgetItem(#ComboMain, -1, "Item 3")
  AddGadgetItem(#ComboMain, -1, "Item 4")
  AddGadgetItem(#ComboMain, -1, "Item 5")
  ;***** Items with data set to 1 will have a line added *****
  SetGadgetItemData(#ComboMain, 5, 1)
  AddGadgetItem(#ComboMain, -1, "Item 6")
  
  Repeat
  Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf

End 

Re: Combobox with something like MenuBar ?

Posted: Thu Feb 13, 2014 11:41 am
by netmaestro
Sparkie, excellent solution!

No criticism meant, it's hardly worth mentioning but I was just wondering if you'd considered the possibility of DrawFrameControl with DFC_MENU for gui consistency.

Re: Combobox with something like MenuBar ?

Posted: Thu Feb 13, 2014 12:10 pm
by Sparkie
Thanks netmaestro. :)

At first I did DrawFrameControl with DFC_BUTTON and just drew the button 1 pixel high. Never occurred to me to try DFC_MENU. Let me go back and see what results I get with that.

Re: Combobox with something like MenuBar ?

Posted: Thu Feb 13, 2014 12:32 pm
by Sparkie
netmaestro, can't get DFC_MENU to perform this task. What did you have in mind? :?

Re: Combobox with something like MenuBar ?

Posted: Thu Feb 13, 2014 2:18 pm
by Sparkie
This version should be a little more GUI friendly.

Code: Select all

;*********************************************
;Sparkies ComboBoxGadget With Menubar type lines v2
;Windows only
;*********************************************
Enumeration
  #WinMain
EndEnumeration

Enumeration
  #ComboMain
EndEnumeration

Procedure WindowCallback(hwnd, msg, wParam, lParam)
  Result = #PB_ProcessPureBasicEvents
  
  Select msg
    Case #WM_DRAWITEM
      *DrawItem.DRAWITEMSTRUCT = lParam
      *lpdis.DRAWITEMSTRUCT = lParam
     
      If *DrawItem\CtlType = #ODT_COMBOBOX
        SetBkMode_(*DrawItem\hdc, #TRANSPARENT)
        
        ;***** Set line thickness and left/right margins*****
        lineH = 2
        lMargin = 4
        rMargin = 4
        
        If *DrawItem\itemState & #ODS_FOCUS
          ;****** Color the item when in focus *****
          hiLite = GetSysColor_(#COLOR_HIGHLIGHT)
          brush = CreateSolidBrush_(hiLite)
          
          ;***** If item is highlighted and not selected, we don't color with highlight color behind line *****
          If *DrawItem\itemState  & #ODS_COMBOBOXEDIT = 0
            *DrawItem\rcItem\bottom - (lineH * 2)
            FillRect_(*DrawItem\hdc, *DrawItem\rcItem, brush)
            *DrawItem\rcItem\bottom + (lineH * 2)
          Else
            ;***** If item is highlighted and is selected, we color the entire item rect *****
            FillRect_(*DrawItem\hdc, *DrawItem\rcItem, brush)
            *DrawItem\rcItem\bottom + (lineH * 2)
          EndIf
          
          DeleteObject_(bBrush)
          tColor = GetSysColor_(#COLOR_HIGHLIGHTTEXT)
          SetTextColor_(*DrawItem\hdc, tColor)
        Else
          ;****** Color the item when NOT in focus *****
          FillRect_(*DrawItem\hdc, *DrawItem\rcItem, GetStockObject_(#WHITE_BRUSH))
        EndIf
        If *DrawItem\itemID <> -1
          Text$ = Space(512)
          
          ;***** Get the item text *****
          SendMessage_(*DrawItem\hwndItem, #CB_GETLBTEXT, *DrawItem\itemID, @Text$)
          
          ;****** Draw the text *****
           TextOut_(*DrawItem\hdc, *DrawItem\rcItem\left + 2, *DrawItem\rcItem\top + 2, Text$, Len(Text$))
           
           ;***** If the item data was set to one AND it is not currently selected, draw the line *****
          If *DrawItem\itemData = 1 And *DrawItem\itemState  & #ODS_COMBOBOXEDIT = 0
            
                        
            ;***** Choose line color *****
            lineColor = GetSysColor_(#COLOR_MENU)
            myPen = CreatePen_(#PS_SOLID, lineH, lineColor)
            
            ;***** Select the pen into the hdc *****
            oldPen = SelectObject_(*DrawItem\hdc, myPen)
            
            ;***** Draw the line *****
            MoveToEx_(*DrawItem\hdc, *lpdis\rcItem\left + lMargin, *lpdis\rcItem\bottom - lineH / 2, #Null)
            LineTo_(*DrawItem\hdc, *lpdis\rcItem\right - rMargin, *lpdis\rcItem\bottom - lineH / 2)
            
            ;***** Cleanup *****
            SelectObject_(*DrawItem\hdc, oldPen)
            DeleteObject_(myPen)
           EndIf
           
          EndIf
      EndIf
      
  EndSelect
  
  ProcedureReturn Result
EndProcedure

If OpenWindow(#WinMain, 0, 0, 600, 300, "Combobox Break Line Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget | #PB_Window_TitleBar )
  ComboBoxGadget(#ComboMain, 10, 10, 300, 25,  #CBS_OWNERDRAWFIXED | #CBS_HASSTRINGS)
  SetWindowCallback(@WindowCallback())
  
  AddGadgetItem(#ComboMain, -1, "Item 0")
  AddGadgetItem(#ComboMain, -1, "Item 1")
  AddGadgetItem(#ComboMain, -1, "Item 2")
  ;***** Items with data set to 1 will have a line added *****
  SetGadgetItemData(#ComboMain, 2, 1)
  AddGadgetItem(#ComboMain, -1, "Item 3")
  AddGadgetItem(#ComboMain, -1, "Item 4")
  AddGadgetItem(#ComboMain, -1, "Item 5")
  ;***** Items with data set to 1 will have a line added *****
  SetGadgetItemData(#ComboMain, 5, 1)
  AddGadgetItem(#ComboMain, -1, "Item 6")
  ;***** Add a little item height *****
  comboH = SendMessage_(GadgetID(#ComboMain), #CB_GETITEMHEIGHT, 0, 0)
  SendMessage_(GadgetID(#ComboMain), #CB_SETITEMHEIGHT, 0, comboH * 1.5)
  Repeat
  Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf

End

Re: Combobox with something like MenuBar ?

Posted: Sat Feb 15, 2014 11:57 am
by va!n
Wow! 8)
Thanks a lot for the massive feedback with all its examples and different ways to realise this!
You guys are just amazing! Thanks! :)