dcsimg
Results 1 to 15 of 15

Thread: VB6 Simple Virtual ComboBox (OwnerDrawn)

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Jun 2013
    Posts
    3,779

    VB6 Simple Virtual ComboBox (OwnerDrawn)

    As the title says, a simple approach to accomplish ownerdrawing from Data in external Data-Containers
    in a "DropDown-scenario".

    As usual with virtual (bound) Controls, they are internally lightweight, since the Drawing happens on the outside.

    Nevertheless (depending on what the OwnerDraw-Event offers), a typical scenario
    can usually be implemented in only a few lines of OwnerDraw-Handler-Code -
    right on the Data of your exernal DataSource-Container (be that an Array, a Collection or a Recordset).

    The implementation below is based on only about 140 Lines of UserControl-Code.
    Feel free to swap the SubClasser (Tricks clsSubClass currently) to your own implementation, if you like...

    And since "Multi-Select-DropDown-scenarios" are apparently "en vouge" these days,
    the Control supports this as well - as the ScreenShot below shows:


    Ok, here's the Demo-Code: VirtualCombo.zip

    Have fun with it...

    Edit: enhancement of the MinVisibleItems-Prop, to work also in non-manifested environments.
    Edit2: MouseWheel-based Scrolling now updates the currently selected Item-under the Mouse + additional Event (MouseMoveOnItem, to address Hover-Areas within a given Item)

    Olaf
    Last edited by Schmidt; Jul 22nd, 2018 at 11:41 AM.

  2. #2
    Frenzied Member gibra's Avatar
    Join Date
    Oct 2009
    Location
    ITALY
    Posts
    1,574

    Re: VB6 Simple Virtual ComboBox (OwnerDrawn)

    Why, regardless of the setting of MinVisibleItems, always and only 4 items are displayed?

    Both on IDE and compiled EXE.

  3. #3

    Thread Starter
    PowerPoster
    Join Date
    Jun 2013
    Posts
    3,779

    Re: VB6 Simple Virtual ComboBox (OwnerDrawn)

    Quote Originally Posted by gibra View Post
    Why, regardless of the setting of MinVisibleItems, always and only 4 items are displayed?

    Both on IDE and compiled EXE.
    It's a feature of the (newer) CommonControls...

    Meaning, as soon as you run your IDE with appropriate "manifest-support",
    or (for the compiled Binary) include a CommonControls-covering *.res file into your Project,
    everything should look as in the ScreenShot...

    Edit: I've now included two lines, which should ensure the feature in roughly the same way also in non-manifested environments.
    ... have uploaded a new Zip...


    HTH

    Olaf
    Last edited by Schmidt; Jul 2nd, 2018 at 04:08 AM.

  4. #4
    Frenzied Member gibra's Avatar
    Join Date
    Oct 2009
    Location
    ITALY
    Posts
    1,574

    Re: VB6 Simple Virtual ComboBox (OwnerDrawn)

    Quote Originally Posted by Schmidt View Post
    Edit: I've now included two lines, which should ensure the feature in roughly the same way also in non-manifested environments.
    ... have uploaded a new Zip...
    Thank, now work good.

  5. #5
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    4,595

    Re: VB6 Simple Virtual ComboBox (OwnerDrawn)

    Very nice Olaf. Not quite as full-featured as PGBSoft's, but far less code to get it done. Definitely two thumbs up from me.

    Take Care,
    Elroy
    Any software I post in these forums written by me is provided “AS IS” without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that I’ve been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a “VB6 random code folder” that is overflowing. I’ve been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  6. #6
    Frenzied Member
    Join Date
    Jan 2010
    Posts
    1,103

    Re: VB6 Simple Virtual ComboBox (OwnerDrawn)

    fast scrolling cause weird behavior (mouse on an item and click, but highlight and select anothet item).

    Edited: look like it is Listbox standard behavior. We need a mouse move after fast scrolling.
    Attached Images Attached Images  
    Last edited by Jonney; Jul 16th, 2018 at 10:08 PM.

  7. #7

    Thread Starter
    PowerPoster
    Join Date
    Jun 2013
    Posts
    3,779

    Re: VB6 Simple Virtual ComboBox (OwnerDrawn)

    Quote Originally Posted by Jonney View Post
    fast scrolling cause weird behavior (mouse on an item and click, but highlight and select anothet item).

    Edited: look like it is Listbox standard behavior. We need a mouse move after fast scrolling.
    This behaviour is now addressed (the hovered-Item is now reflected, also in MouseWheel-scrollings, where the Mouse is not moved otherwise).

    Olaf

  8. #8

    Thread Starter
    PowerPoster
    Join Date
    Jun 2013
    Posts
    3,779

    Re: VB6 Simple Virtual ComboBox (OwnerDrawn)

    Quote Originally Posted by Elroy View Post
    Very nice Olaf. Not quite as full-featured as PGBSoft's, but far less code to get it done. Definitely two thumbs up from me.
    Well, at the moment I cannot think of a scenario which won't be possible with that virtual Control
    (and a whole lot of scenarios, which are impossible with non-virtual Controls, that do not support OwnerDrawing).

    Not many VB6-Users are familiar with the concept of an external DataContainer - perhaps that's the reason, why so much stuff gets "crammed" into the Controls itself.

    To give a few examples...:
    - Sorting (if you choose e.g. an ADO-Rs as your external DataContainer, you have multiple-column-sorts easily available - stuff like that does not belong into a Control IMO)
    - Searching (same thing as with Sorting - just use your own Find- or Filter-routines on your external DataContainer - e.g. an ADO-Rs already comes with appropriate methods)
    - Grid-like, or even TreeView-like real Multi-Colum-rendering is easily possible - and only depends on your external DataSource and how you manage the States there...

    Virtual Controls are far underused by the community IMO.
    They not only offer advantages implementation-wise (smaller, easier maintainable codebase) - but usage- (or UserCode-)wise as well.

    Olaf

  9. #9
    Lively Member
    Join Date
    May 2016
    Location
    China
    Posts
    122

    Re: VB6 Simple Virtual ComboBox (OwnerDrawn)

    I added a button support, let's see if it is needed: while supporting F4, you can press the down arrow to open the list.

    Private Sub oCB_KeyDown(KeyCode As Integer, Shift As Integer)
    If KeyCode = vbKeyDown And Not DroppedDownState Then
    KeyCode = vbKeyF4
    End If
    End Sub
    QQ: 289778005

  10. #10
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    4,595

    Re: VB6 Simple Virtual ComboBox (OwnerDrawn)

    Say Olaf,

    I took a run at cutting this thing down to be more like the typical ComboBox (but with the addition of multi-select). However, somewhere in the process, I did something that started causing crashes. I'd show it to you, but I got frustrated and deleted it all, thinking I'd just start again.

    For me, I'm not interested in the icons. However, I am interested in being able to AddNew and Delete items after things are initially setup. That seems to be where I got hung up before.

    This whole thing is almost certainly in your head more than mine. If you were so motivated, it'd be cool if you provided a version that would do this. If not, I certainly get it, but it doesn't hurt to ask.

    Take Care,
    Elroy
    Any software I post in these forums written by me is provided “AS IS” without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that I’ve been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a “VB6 random code folder” that is overflowing. I’ve been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  11. #11
    Frenzied Member
    Join Date
    Feb 2017
    Posts
    1,181

    Re: VB6 Simple Virtual ComboBox (OwnerDrawn)

    Quote Originally Posted by Elroy View Post
    Say Olaf,

    I took a run at cutting this thing down to be more like the typical ComboBox (but with the addition of multi-select). However, somewhere in the process, I did something that started causing crashes. I'd show it to you, but I got frustrated and deleted it all, thinking I'd just start again.

    For me, I'm not interested in the icons. However, I am interested in being able to AddNew and Delete items after things are initially setup. That seems to be where I got hung up before.

    This whole thing is almost certainly in your head more than mine. If you were so motivated, it'd be cool if you provided a version that would do this. If not, I certainly get it, but it doesn't hurt to ask.

    Take Care,
    Elroy
    Something like this?
    vbExtra: Print preview for VB6, print FlexGrids and more.
    MSDN online for VB6, Language reference.

  12. #12

    Thread Starter
    PowerPoster
    Join Date
    Jun 2013
    Posts
    3,779

    Re: VB6 Simple Virtual ComboBox (OwnerDrawn)

    Quote Originally Posted by Elroy View Post
    I took a run at cutting this thing down to be more like the typical ComboBox (but with the addition of multi-select).
    However, somewhere in the process, I did something that started causing crashes.
    Hmm, not sure about the crashes (didn't experience any whilst developing the demo, so Tricks SubClasser seems indeed quite IDE-safe).

    Quote Originally Posted by Elroy View Post
    For me, I'm not interested in the icons. However, I am interested in being able to AddNew and Delete items after things are initially setup.
    That seems to be where I got hung up before.
    An important thing with Virtual-Controls (which throw an OwnerDraw-Event at you, that comes with a "Record-Index") is,
    to ensure that the "DataCount" of your external DataSource is "made known" to the virtual Control, as soon as you change it.
    (no matter if the external DataSource is an Array or a Recordset, or a Collection - always tell the Control the new Count as soon as you change it).

    Quote Originally Posted by Elroy View Post
    This whole thing is almost certainly in your head more than mine. If you were so motivated, it'd be cool if you provided a version that would do this. If not, I certainly get it, but it doesn't hurt to ask.
    Ok, what about using a 4-Column ADO-Recordset as the external DataSource, which:
    - is inversed-sorted by ID (just to show how easy that is, without implementing any Sorting-stuff inside the Control)
    - which gets a new Record dynamically added on each Combo-DropDown-Event
    - then supporting MultiSelects whilst being in a "Dropped-Down-Session"
    - dynamically deleting all selected Records in the Combo-RollUp-Event
    - rendering its output in a Grid-like 3-Column-View (with differing TextColors in each Grid-Cell and different Alignments)
    - looking like that?



    To bring this to life in your own Form - the easiest way is:
    - to download and unzip the latest Combo-Project "as it is" in Post #1.
    - then adding an additional empty Form1
    - changing the Project-Startup-Form to that Form1
    - adding a new Virtual Combo to it, with its default-name ucVirtualCombo1
    - finally adding an ADO-Reference to the Project - and paste the following code:

    Code:
    Option Explicit
    
    Private Rs As New ADODB.Recordset 'our external DataSource for this little scenario
    
    Private Sub Form_Load()
      'prepare a free-standing (yet empty) ADO-Rs with four fields)
      Rs.Fields.Append "ID", adInteger
      Rs.Fields.Append "FirstName", adVarWChar, 4096
      Rs.Fields.Append "LastName", adVarWChar, 4096
      Rs.Fields.Append "Checked", adBoolean
      Rs.Open
      'prepare the Virtual Combo for Multi-Select-Mode
      ucVirtualCombo1.MultiSelect = True
      ucVirtualCombo1.ItemHeight = 23
    End Sub
    
    Private Sub AddRecord(ID, FirstName, LastName) 'small Helper, to add a new Record to the Rs
      Rs.AddNew
        Rs!ID.Value = ID
        Rs!FirstName.Value = FirstName
        Rs!LastName.Value = LastName
      Rs.UpdateBatch
    End Sub
    
    Private Sub ucVirtualCombo1_DropDown() 'here is, where we add Items dynamically (to the external DataSource)
      Static ID As Long: ID = ID + 1
      AddRecord ID, "FirstName " & ID, "LastName " & ID
      Rs.Sort = "ID Desc" 'just to show that this works, we apply an inverse Sorting on the external DataSource
      ucVirtualCombo1.ListCount = Rs.RecordCount 'always make the new RecordCount known to the virtual Control, as soon as it changes
    End Sub
    
    Private Sub ucVirtualCombo1_RollUp() 'here is, where we delete Items (from the external DataSource)
      Dim i As Long
      For i = Rs.RecordCount To 1 Step -1
        Rs.AbsolutePosition = i
        If Rs!Checked Then Rs.Delete
      Next
      ucVirtualCombo1.ListCount = Rs.RecordCount 'again, make the new RecordCount known to the virtual Control
    End Sub
    
    Private Sub ucVirtualCombo1_ListMultiClick() 'here is, where we synchronize the checked-state (marking Records for deletion during a "Drop-Down-Session")
      Rs.AbsolutePosition = ucVirtualCombo1.ListIndex + 1 '<- synchronize the Rs to the current (zerobased) Item-Index
      Rs!Checked.Value = Not Rs!Checked.Value
    End Sub
    
    Private Sub ucVirtualCombo1_OwnerDraw(ByVal Index As Long, ByVal IsSelected As Boolean, ByVal IsComboItem As Boolean, Canvas As PictureBox, ByVal dx As Long, ByVal dy As Long)
      Canvas.FontName = "Arial": Canvas.FontSize = 10
      Canvas.Line (0, 0)-(dx, dy), IIf(IsSelected, RGB(212, 232, 255), Canvas.BackColor), BF
    
      If Index = -1 Or IsComboItem Then 'draw the Combo-Item
        ucVirtualCombo1.TextOut 2, 2, "Select Items to delete"
      Else 'draw the current List-Item
        Rs.AbsolutePosition = Index + 1 '<- synchronize the Rs to the current (zerobased) Item-Index
        DrawTextCell Canvas, Rs!ID, vbRightJustify, 0, 0.2, vbRed, dx
        DrawTextCell Canvas, Rs!FirstName, vbRightJustify, 0.2, 0.6, vbBlue, dx
        DrawTextCell Canvas, Rs!LastName, vbLeftJustify, 0.6, 1, vbMagenta, dx
        
        Canvas.Line (4, 4)-(dy - 5, dy - 5), vbBlack, B
        If Rs!Checked Then Canvas.FontName = "WebDings": Canvas.FontSize = 13: ucVirtualCombo1.TextOut 3, 0, "a"
      End If
    End Sub
    
    'a small helper, to render "Text within a given Table-Cell"
    Private Sub DrawTextCell(Canvas As PictureBox, ByVal Txt$, Align As AlignmentConstants, ByVal xPerc1#, ByVal xPerc2#, ByVal Color&, ByVal dx&)
      Const InnerSpace = 3
      Dim CW As Long: CW = (xPerc2 - xPerc1) * dx - 2 * InnerSpace
      Dim TW As Long: TW = Canvas.TextWidth(Txt)
      Dim x0 As Long: x0 = xPerc1 * dx + InnerSpace + Choose(Align + 1, 0, CW - TW, (CW - TW) / 2)
      Canvas.ForeColor = Color
      ucVirtualCombo1.TextOut x0, InnerSpace, Txt
      Canvas.Line (xPerc2 * dx, 0)-(xPerc2 * dx, ucVirtualCombo1.ItemHeight), &HDDDDDD
      Canvas.ForeColor = vbBlack
    End Sub
    HTH

    Olaf

  13. #13
    Fanatic Member
    Join Date
    Apr 2015
    Location
    Finland
    Posts
    614

    Re: VB6 Simple Virtual ComboBox (OwnerDrawn)

    Added keyboard DropDown functionality.

    Not sure is this right way to do it, by exposing vb intrinsic combobox hwnd publicly? However code below.

    ucVirtualCombo.ctl add keydown event to declaration section
    Code:
    Event KeyDown(KeyCode As Integer, Shift As Integer)
    'and long variable for the oCB.hwnd
    Code:
    Private mcboHwnd As Long
    Private Sub UserControl_Initialize... add following line after 'hWndLB = hComboLBox' line.
    Code:
    mcboHwnd = oCB.hWnd 'expose vb intrinsic combobox hwnd publicly.
    ...add following subroutine for the Keydown event.
    Code:
    Private Sub UserControl_KeyDown(KeyCode As Integer, Shift As Integer)
      RaiseEvent KeyDown(KeyCode, Shift)
      Me.Refresh
    End Sub
    ..add public property for the Hwnd
    Code:
    Public Property Get cboHwnd() As Long
    cboHwnd = mcboHwnd
    End Property
    fTest form... add to declaration section

    Code:
    Private Const CB_SHOWDROPDOWN  As Long = &H14F
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageW" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
    ...add KeyDown routine.
    Code:
    Private Sub cboV_KeyDown(KeyCode As Integer, Shift As Integer)
    If KeyCode = vbKeySpace Then
        If cboV.DroppedDownState = False Then
    	KeyCode = 0 'eat keycode, item is not selected when dropped down.
            Call SendMessage(cboV.cboHwnd, CB_SHOWDROPDOWN, 1&, ByVal 0&)
        End If
    End If
    End Sub
    Now space key opens selection list.
    Last edited by Tech99; Sep 5th, 2018 at 07:28 AM.

  14. #14
    Fanatic Member wqweto's Avatar
    Join Date
    May 2011
    Posts
    737

    Re: VB6 Simple Virtual ComboBox (OwnerDrawn)

    FYI, F4 is the official keyb shortcut for dropdown in std comboboxes.

    cheers,
    </wqw>

  15. #15
    Fanatic Member
    Join Date
    Apr 2015
    Location
    Finland
    Posts
    614

    Re: VB6 Simple Virtual ComboBox (OwnerDrawn)

    Quote Originally Posted by wqweto View Post
    FYI, F4 is the official keyb shortcut for dropdown in std comboboxes.

    cheers,
    </wqw>
    Thanks, i know - but didn't thought that so ctl needs keydown event only and handler. Idea for this is to getting focus by tabbing to it in a 'standard keyboard data entry way', then same space key can be used for dropdown and item selection.

    [ECHO]
    Event KeyDown(KeyCode As Integer, Shift As Integer)

    Private Sub UserControl_KeyDown(KeyCode As Integer, Shift As Integer)
    RaiseEvent KeyDown(KeyCode, Shift)
    Me.Refresh
    End Sub
    [/ECHO]

    [ECHO]
    Private Sub cboV_KeyDown(KeyCode As Integer, Shift As Integer)
    'Space key dropdown support
    If KeyCode = vbKeySpace And cboV.DroppedDownState = False Then
    KeyCode = vbKeyF4 'translate key to F4, for combobox dropdown.
    End If
    End Sub
    [/ECHO]

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width