Get menu and drop-down combobox dimensions?

Windows specific forum
BarryG
Addict
Addict
Posts: 4168
Joined: Thu Apr 18, 2019 8:17 am

Get menu and drop-down combobox dimensions?

Post by BarryG »

Hi all. I want to draw a rectangle around the current open menu (and systray menu) of my app, and also around the drop-down area of a combobox. I thought the GetForegroundWindow_() API would give me the handles to these, but it doesn't. What would you do? Thanks.
User avatar
spikey
Enthusiast
Enthusiast
Posts: 767
Joined: Wed Sep 22, 2010 1:17 pm
Location: United Kingdom

Re: Get menu and drop-down combobox dimensions?

Post by spikey »

I can't see anything which would supply the overall size of the menu but there is GetMenuItemRect which will get the rect for an for individual item. I'd be thinking about getting the rects for the first and last items and working it out from there.

I don't have any advice for the combobox right now.
BarryG
Addict
Addict
Posts: 4168
Joined: Thu Apr 18, 2019 8:17 am

Re: Get menu and drop-down combobox dimensions?

Post by BarryG »

Thanks for replying. That should work for menus; I'll check it out. As for comboboxes, I just realised I could probably get the individual item height * the number of items, too. Thanks!
User avatar
spikey
Enthusiast
Enthusiast
Posts: 767
Joined: Wed Sep 22, 2010 1:17 pm
Location: United Kingdom

Re: Get menu and drop-down combobox dimensions?

Post by spikey »

If that doesn't work, try this:

Code: Select all

Structure COMBOBOXINFO
  cbSize.l
  rcItem.RECT
  rcButton.RECT
  stateButton.l
  hwndCombo.i
  hwndItem.i
  hwndList.i
EndStructure
  
Define CBInfo.COMBOBOXINFO, ListRect.RECT

If OpenWindow(0, 0, 0, 270, 180, "ComboBoxGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ComboBoxGadget(0, 10, 10, 250, 21, #PB_ComboBox_Editable)
  
  For a = 1 To 6
    AddGadgetItem(0, -1,"ComboBox item " + Str(a))
  Next
  
  SetGadgetState(0, 0)
  CBInfo\cbSize = SizeOf(COMBOBOXINFO)
  
  GetComboBoxInfo_(GadgetID(0), @CBInfo)
  GetClientRect_(CBInfo\hwndList, @ListRect)
  
  StartDrawing(WindowOutput(0))
  Box(GadgetX(0) + ListRect\left, GadgetY(0) + GadgetHeight(0) + ListRect\top, ListRect\right - ListRect\left, ListRect\bottom - ListRect\top, #Red)
  StopDrawing()
  
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
It doesn't include space for the shadow however.
Axolotl
Addict
Addict
Posts: 832
Joined: Wed Dec 31, 2008 3:36 pm

Re: Get menu and drop-down combobox dimensions?

Post by Axolotl »

I was curious about this combobox thing...
Thanks to spikey and the API interface feature

Code: Select all

; - TOP (c) by Axolotl 

EnableExplicit 

Macro LOWORD(nLong) 
  ((nLong) & $FFFF) 
EndMacro 

Macro HIWORD(nLong) 
  (((nLong) >> 16) & $FFFF) 
EndMacro 

Macro ResizeCombobox(RC, ComboBox) 
  RC\left + GadgetX(ComboBox) - 4
  RC\top  + GadgetY(ComboBox) - 4
  RC\right + GadgetX(ComboBox) + 8 
  RC\bottom + GadgetY(ComboBox) + GadgetHeight(ComboBox) + 8 
EndMacro 


Structure COMBOBOXINFO
  cbSize.l
  rcItem.RECT
  rcButton.RECT
  stateButton.l
  hwndCombo.i
  hwndItem.i
  hwndList.i
EndStructure

Global CBInfo.COMBOBOXINFO
Global rc.RECT 
Global a 

Procedure wndcallback(hwnd, uMsg, wparam, lparam) 
  Protected hdc, brush, oldbrush  
  Protected ComboBox 

  Select uMsg
    Case #WM_COMMAND 
      Select HIWORD(wParam) 
        Case #CBN_CLOSEUP 
          ComboBox = LOWORD(wparam) 
;         Debug "CB: Combobox #" + Str(LOWORD(wparam)) + " CBN_CLOSEUP " 

          CBInfo\cbSize = SizeOf(COMBOBOXINFO)
          GetComboBoxInfo_(lparam, @CBInfo) 
          GetClientRect_(CBInfo\hwndList, @rc) 

          ResizeCombobox(rc, ComboBox) 
          RedrawWindow_(hwnd, @rc, #Null, #RDW_ERASE | #RDW_INVALIDATE) 
          ProcedureReturn 0 

;         Case #CBN_SELENDOK 
;           Debug "CB: Combobox #" + Str(LOWORD(wparam)) + " CBN_SELENDOK " 

;         Case #CBN_SELENDCANCEL 
;           Debug "CB: Combobox #" + Str(LOWORD(wparam)) + " CBN_SELENDCANCEL " 
        
        Case #CBN_DROPDOWN 
          ComboBox = LOWORD(wparam) 
          Debug "CB: Combobox #" + Str(LOWORD(wparam)) + " CBN_DROPDOWN " 

          CBInfo\cbSize = SizeOf(COMBOBOXINFO)
          GetComboBoxInfo_(lparam, @CBInfo) 
          GetClientRect_(CBInfo\hwndList, @rc) 

          hdc = GetDC_(hwnd) 
          If hdc 
            brush = CreateSolidBrush_(#Red) ; RGB(row/2*$FF,Col*$33,$FF*row%2)) 
            oldbrush = SelectObject_(hdc, brush)  

            ResizeCombobox(rc, ComboBox) 
            Rectangle_(hdc, rc\left, rc\top, rc\right, rc\bottom) 

            SelectObject_(hdc, oldbrush)  
            DeleteObject_(brush) 
          
            ReleaseDC_(CBInfo\hwndList, hdc) 
          EndIf  

          ProcedureReturn 0 
        
      EndSelect 
  EndSelect 

  ProcedureReturn #PB_ProcessPureBasicEvents 
EndProcedure 

 
If OpenWindow(0, 0, 0, 290, 180, "ComboBoxGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ComboBoxGadget(10, 10, 10, 260, 24, #PB_ComboBox_Editable | #CBS_DROPDOWN | #CBS_DROPDOWNLIST)
  
  For a = 1 To 6
    AddGadgetItem(10, -1,"ComboBox item " + Str(a))
  Next

  SetGadgetState(10, 0)
  SetWindowCallback(@wndcallback(), 0) 
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Just because it worked doesn't mean it works.
PureBasic 6.04 (x86) and <latest stable version and current alpha/beta> (x64) on Windows 11 Home. Now started with Linux (VM: Ubuntu 22.04).
BarryG
Addict
Addict
Posts: 4168
Joined: Thu Apr 18, 2019 8:17 am

Re: Get menu and drop-down combobox dimensions?

Post by BarryG »

You guys beat me to it! Was going to try this later but got sidetracked. Thanks for both solutions. :D

Do you think this can be done for menus? Both from the title bar and pop-up menus? Surely an active open menu would have a handle that we can get the rect with?
Post Reply