I wanted to change my regular combobox with an ImageCombo, but I see no way to get the same kind of handling like a regular combobox with dropdownlist style.
Is there a way to prevent the imagecombo from looking like a textbox? I know I can set locked to true, but that still makes it act like a textbox.
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
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.
The ImageCombo only has one style as far as I can tell.
Each ComboItem within it supports an Indentation property as well. The idea is to have a hierarchical combo-style control, sort of like a TreeView. Basically it's a kind of "collapsed TreeView" control.
I have no idea what is being shown in the first screenshot in post #3 above.
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.
This might be of help. Not sure if it's what you are looking for but it does appear to show images in a combobox.
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.
The ImageCombo only has one style as far as I can tell.
Indeed, the ImageCombo control from MS Windows Common Controls 6.0 is limited to the vbComboDropDown style only.
Originally Posted by dilettante
I have no idea what is being shown in the first screenshot in post #3 above.
It's from Image ComboBox Control. MSDN says that the "ComboBoxEx controls support only the following ComboBox styles":
CBS_SIMPLE
CBS_DROPDOWN
CBS_DROPDOWNLIST
WS_CHILD
Originally Posted by SuperDre
I wanted to change my regular combobox with an ImageCombo, but I see no way to get the same kind of handling like a regular combobox with dropdownlist style.
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
Option Explicit
Private Declare Function EnumChildWindows Lib "user32" (ByVal hWndParent As Long, ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Private Const WS_DISABLED As Long = &H8000000
Private Const GWL_STYLE = (-16)
Private mlngEditHwnd As Long
Private Function EnumChildProc(ByVal lhwnd As Long, ByVal lParam As Long) As Long
Dim strWinClassBuf As String * 255
Dim strClassName As String
GetClassName lhwnd, strWinClassBuf, 255
strClassName = StripNulls(strWinClassBuf)
If strClassName = "Edit" Then
mlngEditHwnd = lhwnd
EnumChildProc = False
Else
EnumChildProc = True
End If
End Function
Private Function StripNulls(ByVal OriginalStr As String) As String
If (InStr(OriginalStr, Chr(0)) > 0) Then
OriginalStr = Left(OriginalStr, InStr(OriginalStr, Chr(0)) - 1)
End If
StripNulls = OriginalStr
End Function
Public Sub DisableImageComboEditBox(ByVal lhwnd As Long)
Dim lngStyle As Long
mlngEditHwnd = 0
EnumChildWindows lhwnd, AddressOf EnumChildProc, 0
If mlngEditHwnd <> 0 Then
lngStyle = GetWindowLong(mlngEditHwnd, GWL_STYLE) ' get current Style
SetWindowLong mlngEditHwnd, GWL_STYLE, lngStyle Or WS_DISABLED ' set the WS_DISABLED bit
End If
End Sub
In form
Code:
Option Explicit
Private Sub Form_Load()
ImageCombo1.ComboItems.Add , , "1"
ImageCombo1.ComboItems.Add , , "2"
ImageCombo1.ComboItems.Add , , "3"
ImageCombo1.ComboItems.Add , , "4"
ImageCombo1.ComboItems.Add , , "5"
ImageCombo1.ComboItems.Add , , "6"
ImageCombo1.ComboItems(1).Selected = True
End Sub
Private Sub Command1_Click()
DisableImageComboEditBox ImageCombo1.hwnd
End Sub
One problem, the ImageCombo will not focused by Tab key.
Sight, damn MS, even in their own example of how to use the ImageCombo they show an image of how I want it to look (full row select and 'disabled' textbox entry)... http://msdn.microsoft.com/en-us/libr...(v=vs.60).aspx
But damn Bonnie West, that's a great link to a great replacement (sadly I propably won't be able to use it due to the already large project and I don't want to replace all my controls, but I'm certainly gonna look into it, as I too want to get rid of the needed OCX's and be able to have more control over the controls).
Thanx 4x2y, I'm gonna try a variation on your proposal..
grrr. even simple stuff like the routines I used for setting a DropDownCount on a normal combobox don't seem to work on a ImageCombo..
Code:
'##############################################################################
'##
'## Sub p_SetDropDownCount
'##
'##############################################################################
'lDropDownCount: -1 = Autosize, -2 = ShowAll, >-1 = fixed amount
Public Sub p_SetDropDownCount(ByRef cbo As ComboBoxImageCombo, _
Optional ByVal lDropDownCount As Long = ddcAutosize)
Dim lItemHeight As Long
Dim lNewHeight As Long
Dim lWidth As Long
Dim pt As POINTAPI
Dim rcCombobox As RECT
Dim rcParent As RECT
lNewHeight = 0
'--------------------------------------------------------------
'Get the systemheight of a single combobox list item
lItemHeight = SendMessage(cbo.hWnd, CB_GETITEMHEIGHT, 0, 0)
'--------------------------------------------------------------
'Get the co-ordinates of the combobox relative to the screen
Call GetWindowRect(cbo.hWnd, rcCombobox)
'--------------------------------------------------------------
'Calculate the desired height
Select Case lDropDownCount
'===================================================
Case ddcAll 'All
lNewHeight = lItemHeight * (cbo.ListCount.ComboItems.Count + 2)
'===================================================
Case ddcAutosize 'Autosize
Call GetWindowRect(cbo.Parent.hWnd, rcParent)
If rcCombobox.Top < rcParent.Bottom Then
'--------------------------------------------------------------
'Calculate the max height from the top of the combobox to the bottom of the window
lNewHeight = rcParent.Bottom - rcCombobox.Top
'--------------------------------------------------------------
'Calculate the max height to the max height based on the itemheight
lNewHeight = (lNewHeight \ lItemHeight) * lItemHeight
End If 'If rcCombobox.Top<rcParent.Bottom
'===================================================
Case Else 'Fixed amount
lNewHeight = lItemHeight * (lDropDownCount + 2)
End Select
'--------------------------------------------------------------
'Is the new height less then the height of 2 items then set the height to at least 2 items
If lNewHeight < (2 * lItemHeight) Then lNewHeight = 2 * lItemHeight
'--------------------------------------------------------------
'Set the new height
'--------------------------------------------------------------
'Get the co-ordinates of the combobox relative to the screen
pt.X = rcCombobox.Left
pt.Y = rcCombobox.Top
'--------------------------------------------------------------
'Calculate the width of the combobox
lWidth = rcCombobox.Right - rcCombobox.Left
'--------------------------------------------------------------
'translate into coordinates relative to the form
Call ScreenToClient(cbo.Container.hWnd, pt)
'--------------------------------------------------------------
'using the values returned and set above reposition the combobox
Call MoveWindow(cbo.hWnd, pt.X, pt.Y, lWidth, lNewHeight, True)
End Sub
Also by replacing the cbo.hwnd (MoveWindow) with the hwnd of the childwindow "ComboBox" doesn't work..
I also saw Kroon's version in the CommonControls replacement, and it seems to work for his version directly on the ImageCombo Handle, so I guess the OCX implementation fubars any changes you make to the size of the window (I think it just recalculates it everytime before dropdown (but after the dropdown event).
Also SendMessage(icbo.hWnd, CB_SETMINVISIBLE, MyCount, ByVal 0) doesn't seem to work (neither the CB_GETMINVISIBLE) (also not on the ComboBox ChildWindowHandle)..
But changing the window with using CB_SETDROPPEDWIDTH does work... grrrrrrrrrrr...
4x2y this is the version I came up with based on your example for blocking the entry, no need for enumchild:
Code:
Dim lHwnd As Long
'--------------------------------------------------------------
'Look for the "ComboBox" childwindow
lHwnd = FindWindowEx(icboTables.hWnd, 0, "ComboBox", vbNullString)
If lHwnd <> 0 Then
'--------------------------------------------------------------
'Look for the "Edit" childwindow
lHwnd = FindWindowEx(lHwnd, 0, "Edit", vbNullString)
If lHwnd <> 0 Then
'--------------------------------------------------------------
'Get current Style and set the WS_DISABLED bit
Call SetWindowLong(lHwnd, GWL_STYLE, GetWindowLong(lHwnd, GWL_STYLE) Or WS_DISABLED)
End If
End If
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
However, MS Win Common Controls 6.0 remains unaffected even if the manifest specified comctl32.dll v6.
That's because "MS Win Common Controls 6.0" (MSCOMCTL.OCX) does not use comctl32.dll but contains its own implementation, thus a manifest can't make a difference.
Sight, damn MS, even in their own example of how to use the ImageCombo they show an image of how I want it to look (full row select and 'disabled' textbox entry)... http://msdn.microsoft.com/en-us/libr...(v=vs.60).aspx
Not really. See the "drop button" in those screenshots, which are only showing examples in "dropped" state?
4x2y this is the version I came up with based on your example for blocking the entry, no need for enumchild:
Code:
Dim lHwnd As Long
'--------------------------------------------------------------
'Look for the "ComboBox" childwindow
lHwnd = FindWindowEx(icboTables.hWnd, 0, "ComboBox", vbNullString)
If lHwnd <> 0 Then
'--------------------------------------------------------------
'Look for the "Edit" childwindow
lHwnd = FindWindowEx(lHwnd, 0, "Edit", vbNullString)
If lHwnd <> 0 Then
'--------------------------------------------------------------
'Get current Style and set the WS_DISABLED bit
Call SetWindowLong(lHwnd, GWL_STYLE, GetWindowLong(lHwnd, GWL_STYLE) Or WS_DISABLED)
End If
End If
To highlight the combo when got the focus, you may use
Code:
Private Sub ImageCombo1_Dropdown()
ImageCombo1.BackColor = vbWindowBackground
ImageCombo1.ForeColor = vbWindowText
End Sub
Private Sub ImageCombo1_GotFocus()
ImageCombo1.BackColor = vbHighlight
ImageCombo1.ForeColor = vbHighlightText
End Sub
Private Sub ImageCombo1_LostFocus()
ImageCombo1.BackColor = vbWindowBackground
ImageCombo1.ForeColor = vbWindowText
End Sub
4x2y, I added your great suggestion (I do that myself with checkbuttons), and I tried it, code should work as suggested, but when you run it, it really goed fubar. It seems Dropdown isn't triggered correctly all the time (or it has something to do with how the creators of the OCX variant are dealing with dropdown), but the highlighted backcolor is show in the dropdown if you move over it with your mouse (or scroll) with the previous items staying colored with the highlight.. also you can sometimes see exactly the edit window itself..
Man they really did a hackjob with that ImageCombo in the OCX..
I also tried some other stuff with trying to resize the ammount of items you can see in de dropdown, but all the old tricks don't seem to work, it really seems like they do some ugly stuff before the dropdown with that OCX version..
So if anybody has an interesting idea of being able to set the ammount of dropdown items, I'm all ears..
Since you're already using an OCX, you may want to give this ComboListBoxControls a try.
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
Have you considered creating the control yourself? The "real" imagecombo control supports the drop down list style from what I see on MSDN. I'll look further into it if I have time this week.
Code:
hwnd = CreateWindowEx(0, WC_COMBOBOXEX, 0, WS_BORDER Or WS_VISIBLE Or WS_CHILD Or CBS_DROPDOWNLIST, [...]
Since you're already using an OCX, you may want to give this ComboListBoxControls a try.
But the OCX i'm using is a MS original OCX which came with VB6, the only OCXes I'll ever use are the ones which come with VB6 (or come with the OS itself). otherwise I'm not in the habit of using OCXes, way too many problems with them (for one you need to have it installed and registered to windows). Only if thirdparty OCXes comes with code I'll even consider it (mostly I'll just take the code and implement it in the project itself).
The only interesting project for me at the moment is the one you already mentioned before, that awesome common controls replacement project (again, thanx for that one).
Originally Posted by fafalone
Have you considered creating the control yourself? The "real" imagecombo control supports the drop down list style from what I see on MSDN. I'll look further into it if I have time this week.
Code:
hwnd = CreateWindowEx(0, WC_COMBOBOXEX, 0, WS_BORDER Or WS_VISIBLE Or WS_CHILD Or CBS_DROPDOWNLIST, [...]
for that, check out the excellent common controls replacement project Bonnie mentioned before in this thread..
For now I think, I'll just scrap the ImageCombo and go back to the original combobox I already used and just use an asterix in front of the caption, at the moment it's only used internally anyway.. Not as beautifull, but it'll do the job, I could accept the not fullrow selection, but I cannot accept the not being able to set the dropdowncount as there are a lot of items shown normally (I use it in a dataeditor for showing the tables in a database (but also needed to show views for some specific databases and wanted to do a nice differentiation between tables and views)).
thanx boys and girls, especially for the direction to the awesome common controls replacement project which I didn't knew at all..