Hand Made ComboBox [Windows]

Share your advanced PureBasic knowledge/code with the community.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4953
Joined: Sun Apr 12, 2009 6:27 am

Hand Made ComboBox [Windows]

Post by RASHAD »

Hi

Code: Select all

LoadFont(0,"Arial",10)

Global IsListIconVisible

Procedure winCB(hWnd,uMsg,wParam,lParam)
  Result = #PB_ProcessPureBasicEvents
  Select uMsg 
    Case #WM_SIZE,#WM_MOVE
      If IsWindow(100)
        ResizeWindow(100,GadgetX(1,#PB_Gadget_ScreenCoordinate),GadgetY(1,#PB_Gadget_ScreenCoordinate)+GadgetHeight(1),380,200)
        ResizeGadget(2,0,0,380,200)
        HideWindow(100,1)
        HideGadget(2,1)
        SetActiveGadget(-1)         
        IsListIconVisible = #False
      EndIf 
      
  EndSelect
  ProcedureReturn Result
EndProcedure

OpenWindow(0,0,0,600,400,"Window",#PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_ScreenCentered)
ComboBoxGadget(1,10,10,180,24)   
SetGadgetFont(1,FontID(0))
;**********************************************************************************
OpenWindow(100,GadgetX(1,#PB_Gadget_ScreenCoordinate),GadgetY(1,#PB_Gadget_ScreenCoordinate)+GadgetHeight(1),380,200,"",#PB_Window_BorderLess|#PB_Window_Invisible,WindowID(0))
UseGadgetList(WindowID(100))
ListIconGadget(2,0,0,380,200,"",70,#PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect|#LVS_NOCOLUMNHEADER)
SendMessage_(GadgetID(2), #LVM_SETEXTENDEDLISTVIEWSTYLE,0,SendMessage_(GadgetID(2),#LVM_GETEXTENDEDLISTVIEWSTYLE,0,0)| #LVS_EX_TRACKSELECT)
SendMessage_(GadgetID(2), #LVM_SETHOVERTIME, 0, 10)
SetGadgetColor(2,#PB_Gadget_BackColor,$D5F3FE)
SetGadgetColor(2,#PB_Gadget_LineColor,$0)
AddGadgetColumn(2,1,"",100)
AddGadgetColumn(2,2,"",180)
For i = 0 To 10
  AddGadgetItem(1,i,"Item "+Str(i))
  AddGadgetItem(2,i,"Item "+Str(i)+#LF$+"Text "+Str(i)+#LF$+"another text "+Str(i))
Next
SendMessage_(GadgetID(1), #CB_SETMINVISIBLE, 1, 0)
;*************************************************************************************
UseGadgetList(WindowID(0))
ComboBoxGadget(3,10,40,180,24)
SetGadgetFont(3,FontID(0)) 
For i = 0 To 10
  AddGadgetItem(3,i,"Item "+Str(i))
Next
SetGadgetState(1,2)
SetGadgetState(3,4)
TextGadget(4,10,100,580,24,"Test for zero order",#SS_CENTER|#SS_CENTERIMAGE)
SetGadgetColor(4,#PB_Gadget_BackColor,0)
SetGadgetColor(4,#PB_Gadget_FrontColor,$FFFFFF)

SetWindowCallback(@winCB())
Repeat
  Select WaitWindowEvent()
      
    Case #PB_Event_CloseWindow
      Quit = 1       
      
    Case #WM_LBUTTONDOWN,#WM_LBUTTONDBLCLK
      act = GetActiveGadget()
      Select  act
        Case 1
          If IsListIconVisible
            SetActiveGadget(2)
            HideWindow(100,1)
            HideGadget(2,1)
            SetActiveGadget(-1)         
            IsListIconVisible = #False
          Else
            HideWindow(100,0) 
            HideGadget(2,0)  
            SetActiveGadget(2)
            IsListIconVisible = #True
          EndIf          
          
        Case 2
          text$ = GetGadgetItemText(1,GetGadgetState(2),0)
          SetGadgetText(1,text$) 
          HideWindow(100,1) 
          HideGadget(2,1)            
          IsListIconVisible = #False
          SetActiveGadget(-1)
          
      EndSelect
      
  EndSelect 
  
Until Quit = 1
End

Egypt my love
dige
Addict
Addict
Posts: 1405
Joined: Wed Apr 30, 2003 8:15 am
Location: Germany
Contact:

Re: Hand Made ComboBox [Windows]

Post by dige »

Clever idea! :D thx 4 sharing 👍
"Daddy, I'll run faster, then it is not so far..."
User avatar
ChrisR
Addict
Addict
Posts: 1466
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: Hand Made ComboBox [Windows]

Post by ChrisR »

I really like the idea too :)

To keep the (active) Title bar Color when the ListIcon Window is active, you can add your tip

Code: Select all

Procedure winCB(hWnd,uMsg,wParam,lParam)
  Result = #PB_ProcessPureBasicEvents
  Select uMsg 
    Case #WM_SIZE,#WM_MOVE
      If IsWindow(100)
        ResizeWindow(100,GadgetX(1,#PB_Gadget_ScreenCoordinate),GadgetY(1,#PB_Gadget_ScreenCoordinate)+GadgetHeight(1),380,200)
        ResizeGadget(2,0,0,WindowWidth(100),WindowHeight(100))
        HideWindow(100,1)
        HideGadget(2,1)   ; All HideGadget(2) are not really useful, the window is already hidden
        SetActiveGadget(-1)         
        IsListIconVisible = #False
      EndIf
      
    Case #WM_NCCALCSIZE
      If OSVersion() >= #PB_OS_Windows_10
        *rc.RECT=lParam
        *rc\top - 5   ; small hidden border on win10 and up
      EndIf 
     
    Case #WM_NCACTIVATE
      result = 1    ; draw active title bar and icon  
     
    Case #WM_EXITSIZEMOVE
      InvalidateRect_(hwnd,0,#True)
      
  EndSelect
  ProcedureReturn Result
EndProcedure
User avatar
ChrisR
Addict
Addict
Posts: 1466
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: Hand Made ComboBox [Windows]

Post by ChrisR »

I've just seen a small defect with 2 longer comboboxes, width 480
If you open the ListIcon ComboBox and then the standard ComboBox, the ListIcon remains visible
Looks good by adding

Code: Select all

    Case #PB_Event_ActivateWindow
      If IsListIconVisible And GetActiveWindow() = 0
        HideWindow(100,1)
        IsListIconVisible = #False
      EndIf
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4953
Joined: Sun Apr 12, 2009 6:27 am

Re: Hand Made ComboBox [Windows]

Post by RASHAD »

Taking CrisR point of view :D into consideration and to avoid any click outside the Drop down while it's visible

Code: Select all

LoadFont(0,"Arial",10)

Global IsListIconVisible

Procedure IsMouseOver(hWnd) 
  GetWindowRect_(hWnd,r.RECT) 
  GetCursorPos_(p.POINT) 
  Result = PtInRect_(r,p\y << 32 + p\x) 
  ProcedureReturn Result 
EndProcedure 

Procedure winCB(hWnd,uMsg,wParam,lParam)
  Result = #PB_ProcessPureBasicEvents
  Select uMsg 
    Case #WM_SIZE,#WM_MOVE
      If IsWindow(100)
        ResizeWindow(100,GadgetX(1,#PB_Gadget_ScreenCoordinate),GadgetY(1,#PB_Gadget_ScreenCoordinate)+GadgetHeight(1),380,200)
        ResizeGadget(2,0,0,380,200)
        HideWindow(100,1)
        HideGadget(2,1)
        SetActiveGadget(-1)         
        IsListIconVisible = #False
      EndIf 
      
    Case #WM_NCACTIVATE
      Result = 1      
      
    Case #WM_NCLBUTTONDOWN,#WM_NCLBUTTONDBLCLK
      If  IsListIconVisible = #True 
        HideWindow(100,1)
        HideGadget(2,1)
        SetActiveGadget(-1)         
        IsListIconVisible = #False
      EndIf
      
  EndSelect
  ProcedureReturn Result
EndProcedure

OpenWindow(0,0,0,600,400,"Window",#PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_ScreenCentered)
ComboBoxGadget(1,10,10,280,24)   
SetGadgetFont(1,FontID(0))
;**********************************************************************************
OpenWindow(100,GadgetX(1,#PB_Gadget_ScreenCoordinate),GadgetY(1,#PB_Gadget_ScreenCoordinate)+GadgetHeight(1),380,210,"",#PB_Window_BorderLess|#PB_Window_Invisible,WindowID(0))
UseGadgetList(WindowID(100))
ListIconGadget(2,0,0,380,206,"",70,#PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect|#LVS_NOCOLUMNHEADER)
SendMessage_(GadgetID(2), #LVM_SETEXTENDEDLISTVIEWSTYLE,0,SendMessage_(GadgetID(2),#LVM_GETEXTENDEDLISTVIEWSTYLE,0,0)| #LVS_EX_TRACKSELECT)
SendMessage_(GadgetID(2), #LVM_SETHOVERTIME, 0, 10)
SetGadgetColor(2,#PB_Gadget_BackColor,$D5F3FE)
SetGadgetColor(2,#PB_Gadget_LineColor,$0)
AddGadgetColumn(2,1,"",100)
AddGadgetColumn(2,2,"",180)
For i = 0 To 10
  AddGadgetItem(1,i,"Item "+Str(i))
  AddGadgetItem(2,i,"Item "+Str(i)+#LF$+"Text "+Str(i)+#LF$+"another text "+Str(i))
Next
SendMessage_(GadgetID(1), #CB_SETMINVISIBLE, 1, 0)
;*************************************************************************************
UseGadgetList(WindowID(0))
ComboBoxGadget(3,310,10,280,24)
SetGadgetFont(3,FontID(0)) 
For i = 0 To 10
  AddGadgetItem(3,i,"Item "+Str(i))
Next
SetGadgetState(1,2)
SetGadgetState(3,4)
TextGadget(4,10,40,580,24,"Test for zero order",#SS_CENTER|#SS_CENTERIMAGE)
SetGadgetColor(4,#PB_Gadget_BackColor,0)
SetGadgetColor(4,#PB_Gadget_FrontColor,$FFFFFF)

SetWindowCallback(@winCB())
Repeat
  Select WaitWindowEvent()
      
    Case #PB_Event_CloseWindow
      Quit = 1 
      
    Case #WM_LBUTTONDOWN,#WM_LBUTTONDBLCLK
      If  IsListIconVisible = #True And  IsMouseOver(GadgetID(2)) = 0
        HideWindow(100,1)
        HideGadget(2,1)
        SetActiveGadget(-1)         
        IsListIconVisible = #False
      EndIf
      act = GetActiveGadget()
      Select  act
        Case 1
          If IsListIconVisible
            HideWindow(100,1)
            HideGadget(2,1)
            SetActiveGadget(-1)         
            IsListIconVisible = #False
          Else
            HideWindow(100,0) 
            HideGadget(2,0)  
            SetActiveGadget(2)
            IsListIconVisible = #True
          EndIf          
          
        Case 2
          text$ = GetGadgetItemText(1,GetGadgetState(2),0)
          SetGadgetText(1,text$) 
          HideWindow(100,1) 
          HideGadget(2,1)            
          IsListIconVisible = #False
          SetActiveGadget(-1)
          ;           
      EndSelect      
      
  EndSelect 
  
Until Quit = 1
End
EDIT :
1- Enable active window
2- Detect TitleBar LB click
Egypt my love
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Hand Made ComboBox [Windows]

Post by Kwai chang caine »

Very nice idea, like usual :idea:
Thanks for sharing 8)
ImageThe happiness is a road...
Not a destination
Post Reply