Imports System.ComponentModel
Imports System.Runtime.InteropServices
Public Class ComboBoxEx
Inherits ComboBox
Sub New()
MyBase.DrawMode = Windows.Forms.DrawMode.OwnerDrawFixed
End Sub
Protected Overrides Sub OnHandleCreated(ByVal e As System.EventArgs)
MyBase.OnHandleCreated(e)
Helpers.CenterComboText(Me)
End Sub
Protected Overrides Sub OnTextChanged(ByVal e As System.EventArgs)
Helpers.CenterComboText(Me)
MyBase.OnTextChanged(e)
End Sub
'We hide this property from the intellisense and property grid
'to prevent anyone from changing it.
<Browsable(False), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never)> _
Public Shadows ReadOnly Property DrawMode() As DrawMode
Get
'This property is declared merely so we can
'hide it
Return MyBase.DrawMode
End Get
End Property
Protected Overrides Sub OnDrawItem(ByVal e As System.Windows.Forms.DrawItemEventArgs)
Dim txt As String = MyBase.Items(e.Index).ToString
Dim sf As New StringFormat
e.DrawBackground()
sf.Alignment = StringAlignment.Center
e.Graphics.DrawString(txt, e.Font, New SolidBrush(e.ForeColor), e.Bounds, sf)
e.DrawFocusRectangle()
End Sub
End Class
Friend Class Win32API
<StructLayout(LayoutKind.Sequential)> _
Public Structure RECT
Public Left As Integer
Public Top As Integer
Public Right As Integer
Public Bottom As Integer
End Structure
Public Const EM_SETMARGINS As Integer = &HD3
Public Const EC_LEFTMARGIN = &H1
Public Declare Function FindWindowEx Lib "User32.dll" Alias "FindWindowExA" (ByVal hWnd As IntPtr, ByVal hwndChildAfter As IntPtr, ByVal lpszClass As String, ByVal lpszWindow As String) As IntPtr
Public Declare Function GetWindowRect Lib "User32.dll" (ByVal hWnd As IntPtr, ByRef lpRect As RECT) As Boolean
Public Declare Function SendMessage Lib "User32.dll" Alias "SendMessageA" (ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
End Class
Friend Class Helpers
Public Shared Sub CenterComboText(ByVal cbo As ComboBox)
' combo must be set to DropDown style!
If Not cbo.DropDownStyle = ComboBoxStyle.DropDown Then Return
' get handle to Edit box in combo
Dim cboEdit_hWnd As IntPtr = Win32API.FindWindowEx(cbo.Handle, IntPtr.Zero, "Edit", Nothing)
' if handle found set combo edit box text left margin
If Not cboEdit_hWnd = IntPtr.Zero Then
' Determine width of string displayed
Dim textWidth As Integer
Using g As System.Drawing.Graphics = cbo.CreateGraphics()
textWidth = CInt(g.MeasureString(cbo.Text, cbo.Font).Width)
End Using
' get combo's Edit window size
Dim rct As Win32API.RECT
Win32API.GetWindowRect(cboEdit_hWnd, rct)
' figure left margin so text appears centered in combo's edit box area.
Dim leftMargin As Integer = ((rct.Right - rct.Left) - textWidth) \ 2
' set left margin of combo's Edit box
Win32API.SendMessage(cboEdit_hWnd, Win32API.EM_SETMARGINS, Win32API.EC_LEFTMARGIN, leftMargin)
End If
End Sub
End Class