I am trying to create a custom combobox that can display multiple columns.
A problem I have is that i want to show the dropdown list over the form borders or any container borders but I have no idea how to do that.
Is there a Windows API that cand do just that?
For the vb6 combobox this is default behavior, when the list is bigger than the form borders it goes over, and I want my control to be able to do the exact same thing.
Tried this myself some time ago but put it on the back burner unresolved. I was trying to do it with a normal Listbox.
A Bing for 'Listbox like Combo' turned up this http://www.tek-tips.com/viewthread.cfm?qid=1698989 which may be of interest.
I wonder if the ListBox or other Controls in Krools collection have such abilities; if not an idea for him perhaps...
Another one of interest from Krool at http://www.vbforums.com/showthread.p...lete-interface which may have some of the behaviour you want albeit only with a single column.
Off top of my head, this is not a trivial task and can be done at least a few ways I can think of. All but 1 are advanced. But first, have you searched this forum's Code & Utility banks? Multicolumn comboboxes have been attempted quite often since VB has been around and I'm sure there are several good examples you can learn/borrow from.
1) Easiest: use a separate borderless form (maybe with a borderless listview or custom drawn listing). Load the form, position it under the control and then show the form as owned and set focus to it. When the form loses focus or user clicks on something else, hide the form. When you display the form, you will have to design a way to kinda have your code wait for it to hide
2) Subclass a real combobox and make it owner-drawn. This requires some serious effort in catching the combobox before VB actually creates it so you can change the style properties to at least include CBS_OWNERDRAWFIXED. Once this is done, you are responsible for drawing the text
3) Similar to #1, except instead of using a VB control, create an API window (has benefit of being unicode-compatible)
4) Use whatever is being used now and when the dropdown should happen, create a menu class or other window class via the CreateWindowEx API. Draw your list on that window
Ideas 2-4 do require subclassing
Last edited by LaVolpe; Jan 29th, 2015 at 09:25 AM.
Insomnia is just a byproduct of, "It can't be done"
A problem I have is that i want to show the dropdown list over the form borders or any container borders but I have no idea how to do that.
Is there a Windows API that cand do just that?
For the vb6 combobox this is default behavior, when the list is bigger than the form borders it goes over, and I want my control to be able to do the exact same thing.
The ListBox component of a ComboBox isn't actually "embedded" in the ComboBox itself, unlike with the TextBox portion. It isn't a child of the ComboBox, nor of the parent Form. Rather, it is a child of the Desktop window, just like ToolTips are. That's the reason the ListBox part of a ComboBox isn't clipped by the ComboBox's container - it's because it is outside (and above) the Form. In order to emulate the behavior of the intrinsic ComboBox's ListBox companion, you should change the parent of your custom ComboBox's ListBox to the Desktop window. Here's an example:
Code:
Option Explicit 'Add a CheckBox and UserControl1 to a blank Form
Private Declare Function GetWindowLongW Lib "user32.dll" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Private Declare Function SetWindowLongW Lib "user32.dll" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare Function SetParent Lib "user32.dll" (ByVal hWndChild As Long, Optional ByVal hWndNewParent As Long) As Long
Private Declare Function SetWindowPos Lib "user32.dll" ( _
ByVal hWnd As Long, _
Optional ByVal hWndInsertAfter As Long, _
Optional ByVal X As Long, Optional ByVal Y As Long, _
Optional ByVal cx As Long, Optional ByVal cy As Long, _
Optional ByVal uFlags As Long _
) As Long
Private Sub TurnChildToPopupWnd(ByVal hWndChild As Long)
Const GWL_STYLE = -16&, WS_CHILD = &H40000000, WS_POPUP = &H80000000
Const GWL_EXSTYLE = -20&, WS_EX_TOOLWINDOW = &H80&
Const HWND_TOPMOST = -1&, SWP_NOSIZE = &H1&, SWP_NOMOVE = &H2&
'Make the desktop window the new parent window
SetParent hWndChild
'"Clear the WS_CHILD bit ..."
SetWindowLongW hWndChild, GWL_STYLE, GetWindowLongW(hWndChild, GWL_STYLE) And Not WS_CHILD
'"... and set the WS_POPUP style"
SetWindowLongW hWndChild, GWL_STYLE, GetWindowLongW(hWndChild, GWL_STYLE) Or WS_POPUP
'Prevent the window from appearing in the taskbar or in the Alt+Tab dialog
SetWindowLongW hWndChild, GWL_EXSTYLE, GetWindowLongW(hWndChild, GWL_EXSTYLE) Or WS_EX_TOOLWINDOW
'Place the window above all non-topmost windows
SetWindowPos hWndChild, HWND_TOPMOST, uFlags:=SWP_NOSIZE Or SWP_NOMOVE
End Sub
Private Sub Check1_Click()
UserControl11.Visible = Check1 = vbChecked
End Sub
Private Sub Form_Load()
TurnChildToPopupWnd UserControl11.hWnd
End Sub
Code:
Option Explicit 'In UserControl1
Public Property Get hWnd() As OLE_HANDLE
hWnd = UserControl.hWnd
End Property
On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
I am trying to create a custom combobox that can display multiple columns.
A problem I have is that i want to show the dropdown list over the form borders or any container borders but I have no idea how to do that.
Is there a Windows API that cand do just that?
For the vb6 combobox this is default behavior, when the list is bigger than the form borders it goes over, and I want my control to be able to do the exact same thing.
Any help would be much appreciated
Thank you
For easier coding, I think you'd better use one TextBox + picButton (PictureBox) + ListBox to make your customized multiColumn-ComboBox. You have to use Mr.Bonnie's above trick to place ListBox at the Topmost while DropDown.
For the vb6 combobox this is default behavior, when the list is bigger than the form borders it goes over, and I want my control to be able to do the exact same thing.
You should add some codes to check the ListBox's boundary. perhaps you will use some APIs like GetSystemMetrics(SM_CXSCREEN),GetWindowRect to compute new boundary then use SetWindowPos API to re-position the ListBox.
This won't give you your multiple columns but it will give you your drop-down list to show over the top or bottom borders of your Form.
Last edited by jmsrickland; Jan 30th, 2015 at 12:17 PM.
Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.