OwnerDrawHandler object

The OwnerDrawHandler interface provides an elegant way to let user paints the cell. The CellOwnerDraw property requires an object that implements the OwnerDrawHandler interface. Use the Def(exCellOwneDraw) property to assign an owner draw object for the entire column. The control calls DrawCell method when an owner draw cell requires painting. The interface definition is like follows:

    [
        uuid(29301C67-ABB7-4E36-9C4D-C4DB8479D893),
        pointer_default(unique)
    ]
    interface IOwnerDrawHandler : IUnknown
    {
        [id(1), helpstring("The source paints the cell.")] HRESULT DrawCell( long hDC, long left, long top, long right, long bottom, long Item, long Column, IDispatch* Source );
    }

The following VB sample shows how to paint a gradient color into the cells:

Option Explicit
Implements EXCOMBOBOXLibCtl.IOwnerDrawHandler       ' The form implements the IOwnerDrawHandler interface

Private Type RECT
    left As Long
    top As Long
    right As Long
    bottom As Long
End Type
Private Const ETO_OPAQUE = 2
Private Declare Sub InflateRect Lib "user32" (lpRect As RECT, ByVal x As Long, ByVal Y As Long)
Private Declare Function ExtTextOut Lib "gdi32" Alias "ExtTextOutA" (ByVal hDC As Long, ByVal x As Long, ByVal Y As Long, ByVal wOptions As Long, lpRect As RECT, ByVal lpString As String, ByVal nCount As Long, lpDx As Long) As Long
Private Declare Function SetBkColor Lib "gdi32" (ByVal hDC As Long, ByVal crColor As Long) As Long
Private Declare Function DrawText Lib "user32" Alias "DrawTextA" (ByVal hDC As Long, ByVal lpStr As String, ByVal nCount As Long, lpRect As RECT, ByVal wFormat As Long) As Long
Private Declare Function SetTextColor Lib "gdi32" (ByVal hDC As Long, ByVal crColor As Long) As Long
Private Declare Function OleTranslateColor Lib "olepro32" (ByVal c As Long, ByVal p As Long, c As Long) As Long
Private Const DT_VCENTER = &H4
Private Const DT_CENTER = &H1
Private Const DT_NOPREFIX = &H800

Private Sub DrawGradient(ByVal hDC As Long, ByVal left As Long, ByVal top As Long, ByVal right As Long, ByVal bottom As Long, ByVal c1 As Long, ByVal c2 As Long)
    On Error Resume Next
    Dim x As Long, rg, gg, bg, r1, r2, g1, g2, b1, b2
    Dim rc As RECT
    With rc
        .left = left
        .right = right
        .top = top
        .bottom = bottom
    End With
    OleTranslateColor c1, 0, c1
    OleTranslateColor c2, 0, c2
    r1 = c1 Mod 256
    r2 = c2 Mod 256
    b1 = Int(c1 / 65536)
    b2 = Int(c2 / 65536)
    g1 = Int(c1 / 256) Mod 256
    g2 = Int(c2 / 256) Mod 256
    For x = left To right Step 2
        rc.left = x
        SetBkColor hDC, RGB(r1 + (x - left) * (r2 - r1) / (right - left), g1 + (x - left) * (g2 - g1) / (right - left), b1 + (x - left) * (b2 - b1) / (right - left))
        ExtTextOut hDC, rc.left, rc.top, ETO_OPAQUE, rc, " ", 1, x
    Next
End Sub

Private Sub ComboBox1_InsertItem(Index As Integer, ByVal Item As EXCOMBOBOXLibCtl.HITEM)
    With ComboBox1(Index).Items
        Set .CellOwnerDraw(Item, 2) = Me         ' The form implements the IOwnerDrawHandler interface
    End With
End Sub

Private Sub IOwnerDrawHandler_DrawCell(ByVal hDC As Long, ByVal left As Long, ByVal top As Long, ByVal right As Long, ByVal bottom As Long, ByVal Item As Long, ByVal Column As Long, ByVal Source As Object)
    With Source.Items
        DrawGradient hDC, left, top, right / 2, bottom, .CellCaption(Item, 0), .CellCaption(Item, 1)
        DrawGradient hDC, right / 2, top, right, bottom, .CellCaption(Item, 1), .CellCaption(Item, 0)
        Dim rc As RECT
        With rc
            .left = left + 16
            .right = right - 1
            .top = top + 1
            .bottom = bottom - 1
        End With
    Dim c As Long, r, g, b
    c = .CellCaption(Item, 1)
    r = c Mod 256
    b = Int(c / 65536)
    g = Int(c / 256) Mod 256
    Dim str As String
    str = IIf(r > 0, r, IIf(g > 0, g, IIf(b > 0, b, 0)))
    SetTextColor hDC, vbWhite
    DrawText hDC, str, Len(str), rc, DT_VCENTER Or DT_NOPREFIX Or DT_CENTER
    End With
End Sub

Private Sub Form_Load()
    Dim j As Long
    For j = 0 To 2
        With ComboBox1(j)
            .BeginUpdate
            .ColumnAutoResize = True
            With .Columns
                With .Add("From")
                    .Visible = False
                End With
                With .Add("To")
                    .Visible = False
                End With
                With .Add("Gradient")
                    .Width = 128
                End With
            End With

            With .Items
                Dim i As Long, h As HITEM
                For i = 255 To 0 Step -1
                    h = .AddItem(vbWhite)
                    .CellCaption(h, 1) = RGB(i * IIf(j = 0, 1, 0), i * IIf(j = 1, 1, 0), i * IIf(j = 2, 1, 0))
                Next
                .SelectItem(.ItemByIndex(0)) = True
            End With

             .EndUpdate
        End With
    Next
End Sub

NameDescription