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


| Name | Description |