--Class:NativeMethods.vb--
Imports System.Collections.Generic
Imports System.Text
Imports System.Runtime.InteropServices
Imports System.Drawing
Namespace Demo
Friend Class NativeMethods
#Region "WindowsMessage"
Public Enum WindowsMessage
WM_SETFOCUS = &H7
WM_KILLFOCUS = &H8
WM_PAINT = &HF
WM_SETFONT = &H30
' keyboard
WM_KEYDOWN = &H100
WM_KEYUP = &H101
WM_CHAR = &H102
' mouse
WM_MOUSEMOVE = &H200
WM_LBUTTONDOWN = &H201
WM_LBUTTONUP = &H202
WM_LBUTTONDBLCLK = &H203
WM_RBUTTONDOWN = &H204
WM_RBUTTONUP = &H205
WM_RBUTTONDBLCLK = &H206
WM_MBUTTONDOWN = &H207
WM_MBUTTONUP = &H208
WM_MBUTTONDBLCLK = &H209
End Enum
#End Region
#Region "ImageLisFlags"
<Flags()> _
Public Enum ImageListDrawFlags As Integer
ILD_NORMAL = &H0
ILD_TRANSPARENT = &H1
ILD_BLEND25 = &H2
ILD_FOCUS = &H2
ILD_BLEND50 = &H4
ILD_SELECTED = &H4
ILD_BLEND = &H4
ILD_MASK = &H10
ILD_IMAGE = &H20
ILD_ROP = &H40
ILD_OVERLAYMASK = &HF00
ILD_PRESERVEALPHA = &H1000
ILD_SCALE = &H2000
ILD_DPISCALE = &H4000
ILD_ASYNC = &H8000
End Enum
#End Region
#Region "RECT"
<StructLayout(LayoutKind.Sequential)> _
Public Structure RECT
Public Left As Integer
Public Top As Integer
Public Right As Integer
Public Bottom As Integer
Public Sub New(ByVal left__1 As Integer, ByVal top__2 As Integer, ByVal right__3 As Integer, ByVal bottom__4 As Integer)
Left = left__1
Top = top__2
Right = right__3
Bottom = bottom__4
End Sub
Public Sub New(ByVal rect As Rectangle)
Left = rect.Left
Top = rect.Top
Right = rect.Right
Bottom = rect.Bottom
End Sub
Public ReadOnly Property Rect() As Rectangle
Get
Return New Rectangle(Left, Top, Right - Left, Bottom - Top)
End Get
End Property
Public ReadOnly Property Size() As Size
Get
Return New Size(Right - Left, Bottom - Top)
End Get
End Property
Public Shared Function FromXYWH(ByVal x As Integer, ByVal y As Integer, ByVal width As Integer, ByVal height As Integer) As RECT
Return New RECT(x, y, x + width, y + height)
End Function
Public Shared Function FromRectangle(ByVal rect As Rectangle) As RECT
Return New RECT(rect.Left, rect.Top, rect.Right, rect.Bottom)
End Function
End Structure
#End Region
#Region "API Methods"
<DllImport("user32.dll")> _
Public Shared Function SendMessage(ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
End Function
<DllImport("user32.dll", CharSet:=CharSet.Auto, ExactSpelling:=True)> _
Public Shared Function GetClientRect(ByVal hWnd As IntPtr, <[In](), Out()> ByRef rect As NativeMethods.RECT) As Boolean
End Function
<DllImport("user32.dll")> _
Public Shared Function GetDC(ByVal ptr As IntPtr) As IntPtr
End Function
<DllImport("user32.dll")> _
Public Shared Function ReleaseDC(ByVal hwnd As IntPtr, ByVal hDC As IntPtr) As Integer
End Function
<DllImport("comctl32.dll", SetLastError:=True)> _
Public Shared Function ImageList_GetIcon(ByVal himl As IntPtr, ByVal i As Integer, ByVal flags As Integer) As IntPtr
End Function
<DllImport("user32.dll", SetLastError:=True)> _
Public Shared Function DestroyIcon(ByVal hIcon As IntPtr) As Boolean
End Function
#End Region
End Class
End Namespace
--Class:ImageComboBoxItem.vb--
Imports System.ComponentModel
Imports System.Drawing
Imports System.Windows.Forms
Imports System.Runtime.Serialization
Imports System.Security.Permissions
Imports System.Drawing.Design
Namespace Demo
<Serializable()> _
<DefaultProperty("Text")> _
<TypeConverter(GetType(ExpandableObjectConverter))> _
Public Class ImageComboBoxItem
Implements IDisposable
Implements ISerializable
#Region "Fields"
Public Const IMAGEINDEXEDITOR As String = "System.Windows.Forms.Design.ImageIndexEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
Private _imageComboBox As ImageComboBox
Private _value As String = String.Empty
Private _imageIndexer As ImageComboBoxItemImageIndexer
Private _tag As Object
Private _level As Integer
#End Region
#Region "Constructors"
Public Sub New()
End Sub
'public ImageComboBoxItem(string text)
' : this(text, -1, 0)
'{
'}
'public ImageComboBoxItem(
' string text, int imageIndex)
' : this(text, imageIndex, 0)
'{
'}
'public ImageComboBoxItem(
' string text, string imageKey)
' : this(text, imageKey, 0)
'{
'}
'public ImageComboBoxItem(
' string text, int imageIndex, int level)
' : this()
'{
' _text = text;
' ImageIndexer.Index = imageIndex;
' _level = level;
'}
'public ImageComboBoxItem(
' string text, string imageKey, int level)
' : this()
'{
' _text = text;
' ImageIndexer.Key = imageKey;
' _level = level;
'}
Protected Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
Me.New()
Deserialize(info, context)
End Sub
#End Region
#Region "Properties"
<Localizable(True)> _
Public Property Value() As String
Get
Return _value
End Get
Set(ByVal value As String)
_value = value
End Set
End Property
<Bindable(True)> _
<Localizable(False)> _
<DefaultValue("")> _
<TypeConverter(GetType(StringConverter))> _
<DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
Public Property Tag() As Object
Get
Return _tag
End Get
Set(ByVal value As Object)
_tag = value
End Set
End Property
<DefaultValue(0)> _
<Localizable(True)> _
<RefreshProperties(RefreshProperties.Repaint)> _
<DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
Public Property Level() As Integer
Get
Return _level
End Get
Set(ByVal value As Integer)
If _level < 0 Then
Throw New ArgumentOutOfRangeException("level")
End If
_level = value
End Set
End Property
<DefaultValue(-1)> _
<Localizable(True)> _
<RelatedImageList("ImageComboBox.ImageList")> _
<Editor(IMAGEINDEXEDITOR, GetType(UITypeEditor))> _
<RefreshProperties(RefreshProperties.Repaint)> _
<DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
<TypeConverter(GetType(NoneExcludedImageIndexConverter))> _
Public Property ImageIndex() As Integer
Get
If ((ImageIndexer.Index <> -1) AndAlso (ImageList IsNot Nothing)) AndAlso (ImageIndexer.Index >= ImageList.Images.Count) Then
Return ImageList.Images.Count - 1
End If
Return ImageIndexer.Index
End Get
Set(ByVal value As Integer)
If value < -1 Then
Throw New ArgumentOutOfRangeException("ImageIndex")
End If
ImageIndexer.Index = value
End Set
End Property
<DefaultValue("")> _
<Localizable(True)> _
<RelatedImageList("ImageComboBox.ImageList")> _
<RefreshProperties(RefreshProperties.Repaint)> _
<Editor(IMAGEINDEXEDITOR, GetType(UITypeEditor))> _
<DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
<TypeConverter(GetType(ImageKeyConverter))> _
Public Property ImageKey() As String
Get
Return ImageIndexer.Key
End Get
Set(ByVal value As String)
ImageIndexer.Key = value
End Set
End Property
<Browsable(False)> _
Public ReadOnly Property ImageComboBox() As ImageComboBox
Get
Return _imageComboBox
End Get
End Property
Friend ReadOnly Property Image() As Image
Get
Dim actualIndex As Integer = ImageIndexer.ActualIndex
If ImageList IsNot Nothing AndAlso ImageList.Images.Count > 0 AndAlso actualIndex <> -1 Then
Return ImageList.Images(actualIndex)
End If
Return Nothing
End Get
End Property
<Browsable(False)> _
Friend ReadOnly Property ImageList() As ImageList
Get
If ImageComboBox IsNot Nothing Then
Return ImageComboBox.ImageList
End If
Return Nothing
End Get
End Property
Friend ReadOnly Property ImageIndexer() As ImageComboBoxItemImageIndexer
Get
If _imageIndexer Is Nothing Then
_imageIndexer = New ImageComboBoxItemImageIndexer(Me)
End If
Return _imageIndexer
End Get
End Property
#End Region
#Region "Methods"
'public override string ToString()
'{
' return _text;
'}
Friend Sub Host(ByVal parent As ImageComboBox)
_imageComboBox = parent
End Sub
<SecurityPermission(SecurityAction.Demand, Flags:=SecurityPermissionFlag.SerializationFormatter), SecurityPermission(SecurityAction.InheritanceDemand, Flags:=SecurityPermissionFlag.SerializationFormatter)> _
Protected Overridable Sub Serialize(ByVal info As SerializationInfo, ByVal context As StreamingContext)
info.AddValue("Value", Value)
info.AddValue("Level", Level)
info.AddValue("ImageIndex", ImageIndexer.Index)
If Not String.IsNullOrEmpty(ImageIndexer.Key) Then
info.AddValue("ImageKey", ImageIndexer.Key)
End If
End Sub
Protected Overridable Sub Deserialize(ByVal info As SerializationInfo, ByVal context As StreamingContext)
Dim imageKey__1 As String = Nothing
Dim imageIndex__2 As Integer = -1
Dim enumerator As SerializationInfoEnumerator = info.GetEnumerator()
While enumerator.MoveNext()
Dim current As SerializationEntry = enumerator.Current
If current.Name = "Value" Then
Value = info.GetString(current.Name)
ElseIf current.Name = "Level" Then
Level = info.GetInt32(current.Name)
Else
If current.Name = "ImageIndex" Then
imageIndex__2 = info.GetInt32(current.Name)
Continue While
End If
If current.Name = "ImageKey" Then
imageKey__1 = info.GetString(current.Name)
Continue While
End If
End If
End While
If imageKey__1 IsNot Nothing Then
ImageKey = imageKey__1
ElseIf imageIndex__2 <> -1 Then
ImageIndex = imageIndex__2
End If
End Sub
#End Region
#Region "ISerializable 成员"
<SecurityPermission(SecurityAction.LinkDemand, Flags:=SecurityPermissionFlag.SerializationFormatter)> _
Private Sub ISerializable_GetObjectData(ByVal info As SerializationInfo, ByVal context As StreamingContext) Implements ISerializable.GetObjectData
Serialize(info, context)
End Sub
#End Region
#Region "IDisposable 成员"
Public Sub Dispose() Implements IDisposable.Dispose
_imageComboBox = Nothing
_imageIndexer = Nothing
_tag = Nothing
End Sub
#End Region
#Region "ImageComboBoxItemImageIndexer Class"
Friend Class ImageComboBoxItemImageIndexer
Inherits ImageIndexer
Private _owner As ImageComboBoxItem
Public Sub New(ByVal owner As ImageComboBoxItem)
_owner = owner
End Sub
Public Overrides Property ImageList() As ImageList
Get
If _owner IsNot Nothing Then
Return _owner.ImageList
End If
Return Nothing
End Get
Set(ByVal value As ImageList)
End Set
End Property
End Class
#End Region
End Class
Friend Class ImageIndexer
Private _imageList As ImageList
Private _index As Integer = -1
Private _key As String = String.Empty
Private _useIntegerIndex As Boolean = True
Public Overridable ReadOnly Property ActualIndex() As Integer
Get
If _useIntegerIndex Then
Return Index
End If
If ImageList IsNot Nothing Then
Return ImageList.Images.IndexOfKey(Key)
End If
Return -1
End Get
End Property
Public Overridable Property ImageList() As ImageList
Get
Return _imageList
End Get
Set(ByVal value As ImageList)
_imageList = value
End Set
End Property
Public Overridable Property Index() As Integer
Get
Return _index
End Get
Set(ByVal value As Integer)
_key = String.Empty
_index = value
_useIntegerIndex = True
End Set
End Property
Public Overridable Property Key() As String
Get
Return _key
End Get
Set(ByVal value As String)
_index = -1
_key = IIf((value Is Nothing), String.Empty, value)
_useIntegerIndex = False
End Set
End Property
End Class
Friend NotInheritable Class NoneExcludedImageIndexConverter
Inherits ImageIndexConverter
Protected Overrides ReadOnly Property IncludeNoneAsStandardValue() As Boolean
Get
Return False
End Get
End Property
End Class
End Namespace
--Class:ImageComboBox.vb--
Imports System.Collections.Generic
Imports System.Text
Imports System.Windows.Forms
Imports System.ComponentModel
Imports System.Collections
Imports System.Drawing
Imports System.Drawing.Drawing2D
Namespace Demo
<ToolboxBitmap(GetType(ComboBox))> _
Public Class ImageComboBox
Inherits ComboBox
#Region "Fields"
Private _imageList As ImageList
Private _items As ImageComboBoxItemCollection
Private _indent As Integer = 10
Private _defaultImage As Image
Private _defaultImageList As ImageList
Private _emptyTextTip As String = String.Empty
Private _emptyTextTipColor As Color = Color.DarkGray
Private _nativeWimdow As EditorNativeWimdow
#End Region
#Region "Constructors"
Public Sub New()
MyBase.New()
MyBase.DrawMode = DrawMode.OwnerDrawFixed
MyBase.ItemHeight = 14
_items = New ImageComboBoxItemCollection(Me)
End Sub
#End Region
#Region "Properties"
<Localizable(True)> _
<MergableProperty(False)> _
<DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _
Public Shadows ReadOnly Property Items() As ImageComboBoxItemCollection
Get
Return _items
End Get
End Property
<DefaultValue(DirectCast(Nothing, String))> _
Public Property ImageList() As ImageList
Get
Return _imageList
End Get
Set(ByVal value As ImageList)
If _imageList IsNot value Then
_imageList = value
End If
End Set
End Property
<DefaultValue(GetType(Image), "")> _
Public Property DefaultImage() As Image
Get
Return _defaultImage
End Get
Set(ByVal value As Image)
If _defaultImage IsNot value Then
_defaultImage = value
If _defaultImage Is Nothing AndAlso _defaultImageList IsNot Nothing Then
_defaultImageList.Dispose()
_defaultImageList = Nothing
End If
If _defaultImage IsNot Nothing Then
_defaultImageList = New ImageList()
_defaultImageList.ColorDepth = ColorDepth.Depth24Bit
_defaultImageList.ImageSize = New Size(ItemHeight, ItemHeight)
_defaultImageList.Images.Add(_defaultImage)
End If
If DropDownStyle <> ComboBoxStyle.DropDownList Then
Invalidate(True)
End If
End If
End Set
End Property
'[DefaultValue("")]
'public string EmptyTextTip
'{
' get { return _emptyTextTip; }
' set
' {
' if (DropDownStyle == ComboBoxStyle.DropDown)
' {
' _emptyTextTip = value;
' base.Invalidate(true);
' }
' }
'}
'[DefaultValue(typeof(Color), "DarkGray")]
'public Color EmptyTextTipColor
'{
' get { return _emptyTextTipColor; }
' set
' {
' if (DropDownStyle == ComboBoxStyle.DropDown)
' {
' _emptyTextTipColor = value;
' base.Invalidate(true);
' }
' }
'}
<DefaultValue(10)> _
Public Property Indent() As Integer
Get
Return _indent
End Get
Set(ByVal value As Integer)
If _indent <> value Then
_indent = value
MyBase.RefreshItems()
End If
End Set
End Property
<DefaultValue(14)> _
Public Shadows Property ItemHeight() As Integer
Get
Return MyBase.ItemHeight
End Get
Set(ByVal value As Integer)
MyBase.ItemHeight = value
End Set
End Property
<Browsable(False)> _
<EditorBrowsable(EditorBrowsableState.Never)> _
<DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
Public Shadows Property DrawMode() As DrawMode
Get
Return MyBase.DrawMode
End Get
Set(ByVal value As DrawMode)
MyBase.DrawMode = DrawMode.OwnerDrawFixed
End Set
End Property
<Browsable(False)> _
<Bindable(True)> _
<DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
Public Shadows Property SelectedItem() As ImageComboBoxItem
Get
If MyBase.SelectedItem Is Nothing Then
Return Nothing
End If
Return TryCast(MyBase.SelectedItem, ImageComboBoxItem)
End Get
Set(ByVal value As ImageComboBoxItem)
MyBase.SelectedItem = value
End Set
End Property
Public Shadows Property DropDownStyle() As ComboBoxStyle
Get
Return MyBase.DropDownStyle
End Get
Set(ByVal value As ComboBoxStyle)
If MyBase.DropDownStyle <> value Then
If value = ComboBoxStyle.DropDownList Then
If _nativeWimdow IsNot Nothing Then
_nativeWimdow.Dispose()
_nativeWimdow = Nothing
End If
End If
MyBase.DropDownStyle = value
End If
End Set
End Property
Protected Friend ReadOnly Property OldItems() As ComboBox.ObjectCollection
Get
Return MyBase.Items
End Get
End Property
Friend ReadOnly Property DefaultImageList() As ImageList
Get
Return _defaultImageList
End Get
End Property
'public new string SelectedValue
'{
' get
' {
' if (base.SelectedValue == null)
' {
' return string.Empty;
' }
' return base.SelectedValue.ToString();
' }
' set
' {
' base.SelectedValue = value;
' }
'}
#End Region
#Region "Ovveride Methods"
Protected Overrides Sub OnCreateControl()
MyBase.OnCreateControl()
If DropDownStyle <> ComboBoxStyle.DropDownList AndAlso Not DesignMode Then
If _nativeWimdow Is Nothing Then
_nativeWimdow = New EditorNativeWimdow(Me)
End If
End If
End Sub
Protected Overrides Sub OnHandleDestroyed(ByVal e As EventArgs)
If _nativeWimdow IsNot Nothing Then
_nativeWimdow.Dispose()
_nativeWimdow = Nothing
End If
MyBase.OnHandleDestroyed(e)
End Sub
Protected Overrides Sub OnDropDown(ByVal e As EventArgs)
MyBase.OnDropDown(e)
Dim ddWidth As Integer = 0
'int textWidth = 0;
Dim itemWidth As Integer = 0
Dim scrollBarWidth As Integer = IIf(Items.Count > MaxDropDownItems, SystemInformation.VerticalScrollBarWidth, 0)
Dim g As Graphics = CreateGraphics()
For Each item As ImageComboBoxItem In Items
'textWidth = g.MeasureString(
' item.Text, Font).ToSize().Width;
itemWidth = ItemHeight + 8 + _indent * item.Level + scrollBarWidth
If itemWidth > ddWidth Then
ddWidth = itemWidth
End If
Next
DropDownWidth = IIf((ddWidth > Width), ddWidth, Width)
g.Dispose()
End Sub
Protected Overrides Sub OnDrawItem(ByVal e As DrawItemEventArgs)
If e.Index <> -1 Then
Dim item As ImageComboBoxItem = Items(e.Index)
Dim g As Graphics = e.Graphics
Dim bounds As Rectangle = e.Bounds
Dim indentOffset As Integer = Indent * item.Level
If (e.State And DrawItemState.ComboBoxEdit) = DrawItemState.ComboBoxEdit Then
indentOffset = 0
End If
Dim imageWidth As Integer = bounds.Height
Dim imageRect As Rectangle
'Rectangle textRect;
'TextFormatFlags format =
' TextFormatFlags.VerticalCenter |
' TextFormatFlags.SingleLine |
' TextFormatFlags.WordBreak;
imageRect = New Rectangle(bounds.Left + indentOffset + 2, bounds.Top, imageWidth, imageWidth)
'textRect = new Rectangle(
' imageRect.Right + 3,
' bounds.Y,
' bounds.Width - imageRect.Width - indentOffset - 5,
' bounds.Height);
'Rectangle backRect = new Rectangle(
' textRect.X,
' textRect.Y + 1,
' textRect.Width,
' textRect.Height - 2);
'backRect.Width = TextRenderer.MeasureText(
' item.Text, e.Font, textRect.Size, format).Width;
'if (base.RightToLeft == RightToLeft.Yes)
'{
' imageRect.X = bounds.Right - imageRect.Right;
' textRect.X = bounds.Right - textRect.Right;
' backRect.X = textRect.Right - backRect.Width;
'}
Dim selected As Boolean = ((e.State And DrawItemState.Selected) = DrawItemState.Selected)
Dim backColor As Color = IIf(selected, SystemColors.Highlight, MyBase.BackColor)
Using backBrush As Brush = New SolidBrush(backColor)
g.FillRectangle(backBrush, bounds)
End Using
If selected Then
ControlPaint.DrawFocusRectangle(g, bounds)
End If
Dim image As Image = item.Image
If image IsNot Nothing Then
Using graphics As New InterpolationModeGraphics(g, InterpolationMode.HighQualityBicubic)
If selected Then
Dim hIcon As IntPtr = NativeMethods.ImageList_GetIcon(ImageList.Handle, item.ImageIndexer.ActualIndex, CInt(NativeMethods.ImageListDrawFlags.ILD_SELECTED))
g.DrawIcon(Icon.FromHandle(hIcon), imageRect)
NativeMethods.DestroyIcon(hIcon)
Else
g.DrawImage(image, imageRect, 0, 0, image.Width, image.Height, _
GraphicsUnit.Pixel)
End If
End Using
'TextRenderer.DrawText(
' g,
' item.Text,
' e.Font,
' textRect,
' base.ForeColor,
' format);
End If
End If
End Sub
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
MyBase.Dispose(disposing)
If disposing Then
_imageList = Nothing
_defaultImage = Nothing
_defaultImageList = Nothing
_items = Nothing
End If
End Sub
#End Region
#Region "EditorNativeWimdow Class"
Private Class EditorNativeWimdow
Inherits NativeWindow
Implements IDisposable
#Region "Fields"
Private _owner As ImageComboBox
Private Const EC_LEFTMARGIN As Integer = &H1
Private Const EC_RIGHTMARGIN As Integer = &H2
Private Const EC_USEFONTINFO As Integer = &HFFFF
Private Const EM_SETMARGINS As Integer = &HD3
Private Const EM_GETMARGINS As Integer = &HD4
#End Region
#Region "Constructors"
Public Sub New(ByVal owner As ImageComboBox)
MyBase.New()
_owner = owner
Attach()
End Sub
#End Region
#Region "Private Methods"
Private Sub Attach()
If Not Handle.Equals(IntPtr.Zero) Then
ReleaseHandle()
End If
'AssignHandle(_owner.EditHandle);
SetMargin()
End Sub
Protected Overrides Sub WndProc(ByRef m As Message)
MyBase.WndProc(m)
Select Case m.Msg
Case CInt(NativeMethods.WindowsMessage.WM_SETFONT)
SetMargin()
Exit Select
Case CInt(NativeMethods.WindowsMessage.WM_PAINT)
RePaint()
Exit Select
Case CInt(NativeMethods.WindowsMessage.WM_SETFOCUS), CInt(NativeMethods.WindowsMessage.WM_KILLFOCUS)
RePaint()
Exit Select
Case CInt(NativeMethods.WindowsMessage.WM_LBUTTONDOWN), CInt(NativeMethods.WindowsMessage.WM_RBUTTONDOWN), CInt(NativeMethods.WindowsMessage.WM_MBUTTONDOWN)
RePaint()
Exit Select
Case CInt(NativeMethods.WindowsMessage.WM_LBUTTONUP), CInt(NativeMethods.WindowsMessage.WM_RBUTTONUP), CInt(NativeMethods.WindowsMessage.WM_MBUTTONUP)
RePaint()
Exit Select
Case CInt(NativeMethods.WindowsMessage.WM_LBUTTONDBLCLK), CInt(NativeMethods.WindowsMessage.WM_RBUTTONDBLCLK), CInt(NativeMethods.WindowsMessage.WM_MBUTTONDBLCLK)
RePaint()
Exit Select
Case CInt(NativeMethods.WindowsMessage.WM_KEYDOWN), CInt(NativeMethods.WindowsMessage.WM_CHAR), CInt(NativeMethods.WindowsMessage.WM_KEYUP)
RePaint()
Exit Select
Case CInt(NativeMethods.WindowsMessage.WM_MOUSEMOVE)
If Not m.WParam.Equals(IntPtr.Zero) Then
RePaint()
End If
Exit Select
End Select
End Sub
Friend Sub SetMargin()
NearMargin(Handle, _owner.ItemHeight + 5)
End Sub
Private Shared Function IsRightToLeft(ByVal handle As IntPtr) As Boolean
'int style = NativeMethods.GetWindowLong(
' handle, (int)NativeMethods.GWL.GWL_EXSTYLE);
'return (
' ((style & (int)NativeMethods.WS_EX.WS_EX_RIGHT)
' == (int)NativeMethods.WS_EX.WS_EX_RIGHT) ||
' ((style & (int)NativeMethods.WS_EX.WS_EX_RTLREADING)
' == (int)NativeMethods.WS_EX.WS_EX_RTLREADING) ||
' ((style & (int)NativeMethods.WS_EX.WS_EX_LEFTSCROLLBAR)
' == (int)NativeMethods.WS_EX.WS_EX_LEFTSCROLLBAR));
Return False
End Function
Private Shared Sub FarMargin(ByVal handle As IntPtr, ByVal margin As Integer)
Dim message As Integer = IIf(IsRightToLeft(handle), EC_LEFTMARGIN, EC_RIGHTMARGIN)
If message = EC_LEFTMARGIN Then
margin = margin And &HFFFF
Else
margin = margin * &H10000
End If
NativeMethods.SendMessage(handle, EM_SETMARGINS, message, margin)
End Sub
Friend Shared Sub NearMargin(ByVal handle As IntPtr, ByVal margin As Integer)
Dim message As Integer = IIf(IsRightToLeft(handle), EC_RIGHTMARGIN, EC_LEFTMARGIN)
If message = EC_LEFTMARGIN Then
margin = margin And &HFFFF
Else
margin = margin * &H10000
End If
NativeMethods.SendMessage(handle, EM_SETMARGINS, message, margin)
End Sub
Private Sub RePaint()
Dim item As ImageComboBoxItem = _owner.SelectedItem
Dim rcClient As New NativeMethods.RECT()
NativeMethods.GetClientRect(Handle, rcClient)
'bool rightToLeft = IsRightToLeft(Handle);
Dim handle__1 As IntPtr = Handle
Dim hdc As IntPtr = NativeMethods.GetDC(handle__1)
If hdc = IntPtr.Zero Then
Return
End If
Try
Using g As Graphics = Graphics.FromHdc(hdc)
Dim itemSize As Integer = _owner.ItemHeight
Dim imageRect As New Rectangle(2, rcClient.Top + (rcClient.Bottom - itemSize) / 2, itemSize, itemSize)
'Rectangle textRect = new Rectangle(
' 0,
' 0,
' rcClient.Right - itemSize - 6,
' rcClient.Bottom);
'if (rightToLeft)
'{
' imageRect.X = rcClient.Right - itemSize - 2;
' //textRect.X = 2;
'}
'else
'{
'imageRect.X = 2;
'textRect.X = imageRect.Right + 2;
'}
'if (_owner.Text.Length == 0)
'{
' DrawImage(
' g,
' imageRect,
' _owner.DefaultImage,
' _owner.DefaultImageList,
' 0,
' _owner.Focused);
' //if (_owner.Text.Length == 0 &&
' // !string.IsNullOrEmpty(_owner.EmptyTextTip) &&
' // !_owner.Focused)
' //{
' // TextFormatFlags format =
' // TextFormatFlags.EndEllipsis |
' // TextFormatFlags.VerticalCenter;
' // if (_owner.RightToLeft == RightToLeft.Yes)
' // {
' // format |=
' // (TextFormatFlags.RightToLeft |
' // TextFormatFlags.Right);
' // }
' // TextRenderer.DrawText(
' // g,
' // _owner.EmptyTextTip,
' // _owner.Font,
' // textRect,
' // _owner.EmptyTextTipColor,
' // format);
' //}
' return;
'}
'if (_owner.Text.Length > 0)
'{
' using (SolidBrush brush =
' new SolidBrush(_owner.BackColor))
' {
' g.FillRectangle(brush, imageRect);
' }
'}
'if (_owner.Items.Count == 0)
'{
' DrawImage(
' g,
' imageRect,
' _owner.DefaultImage,
' _owner.DefaultImageList,
' 0,
' _owner.Focused);
' return;
'}
If item Is Nothing Then
Return
End If
DrawImage(g, imageRect, item.Image, _owner.ImageList, item.ImageIndexer.ActualIndex, _owner.Focused)
End Using
Finally
NativeMethods.ReleaseDC(handle__1, hdc)
End Try
End Sub
Private Sub DrawImage(ByVal g As Graphics, ByVal imageRect As Rectangle, ByVal image As Image, ByVal imageList As ImageList, ByVal imageIndex As Integer, ByVal focus As Boolean)
Using brush As New SolidBrush(_owner.BackColor)
g.FillRectangle(brush, imageRect)
End Using
If image Is Nothing Then
Return
End If
Using graphics As New InterpolationModeGraphics(g, InterpolationMode.HighQualityBicubic)
If focus Then
Dim hIcon As IntPtr = NativeMethods.ImageList_GetIcon(imageList.Handle, imageIndex, CInt(NativeMethods.ImageListDrawFlags.ILD_SELECTED))
g.DrawIcon(Icon.FromHandle(hIcon), imageRect)
NativeMethods.DestroyIcon(hIcon)
Else
g.DrawImage(image, imageRect, 0, 0, image.Width, image.Height, _
GraphicsUnit.Pixel)
End If
End Using
End Sub
#End Region
#Region "IDisposable 成员"
Public Sub Dispose() Implements IDisposable.Dispose
_owner = Nothing
MyBase.ReleaseHandle()
End Sub
#End Region
End Class
#End Region
#Region "ImageComboBoxItemCollection Class"
<ListBindable(False)> _
Public Class ImageComboBoxItemCollection
Implements IList
Implements ICollection
Implements IEnumerable
#Region "Fields"
Private _owner As ImageComboBox
#End Region
#Region "Constructors"
Public Sub New(ByVal owner As ImageComboBox)
_owner = owner
End Sub
#End Region
#Region "Properties"
Friend ReadOnly Property Owner() As ImageComboBox
Get
Return _owner
End Get
End Property
Default Public Property Item(ByVal index As Integer) As ImageComboBoxItem
Get
Return TryCast(Owner.OldItems(index), ImageComboBoxItem)
End Get
Set(ByVal value As ImageComboBoxItem)
Owner.OldItems(index) = value
End Set
End Property
Public ReadOnly Property Count() As Integer
Get
Return Owner.OldItems.Count
End Get
End Property
Public ReadOnly Property IsReadOnly() As Boolean
Get
Return Owner.OldItems.IsReadOnly
End Get
End Property
#End Region
#Region "Public Methods"
Public Function Add(ByVal item As ImageComboBoxItem) As Integer
If item Is Nothing Then
Throw New ArgumentNullException("item")
End If
item.Host(Owner)
Return Owner.OldItems.Add(item)
End Function
Public Sub AddRange(ByVal value As ImageComboBoxItemCollection)
For Each item As ImageComboBoxItem In value
Add(item)
Next
End Sub
Public Sub AddRange(ByVal items As ImageComboBoxItem())
For Each item As ImageComboBoxItem In items
Add(item)
Next
End Sub
Public Sub Clear()
Owner.OldItems.Clear()
End Sub
Public Function Contains(ByVal item As ImageComboBoxItem) As Boolean
Return Owner.OldItems.Contains(item)
End Function
Public Sub CopyTo(ByVal destination As ImageComboBoxItem(), ByVal arrayIndex As Integer)
Owner.OldItems.CopyTo(destination, arrayIndex)
End Sub
Public Function IndexOf(ByVal item As ImageComboBoxItem) As Integer
Return Owner.OldItems.IndexOf(item)
End Function
Public Sub Insert(ByVal index As Integer, ByVal item As ImageComboBoxItem)
If item Is Nothing Then
Throw New ArgumentNullException("item")
End If
item.Host(Owner)
Owner.OldItems.Insert(index, item)
End Sub
Public Sub Remove(ByVal item As ImageComboBoxItem)
Owner.OldItems.Remove(item)
End Sub
Public Sub RemoveAt(ByVal index As Integer)
Owner.OldItems.RemoveAt(index)
End Sub
Public Function GetEnumerator() As IEnumerator
Return Owner.OldItems.GetEnumerator()
End Function
#End Region
#Region "IList 成员"
Private Function IList_Add(ByVal value As Object) As Integer Implements IList.Add
If Not (TypeOf value Is ImageComboBoxItem) Then
Throw New ArgumentException()
End If
Return Add(TryCast(value, ImageComboBoxItem))
End Function
Private Sub IList_Clear() Implements IList.Clear
Clear()
End Sub
Private Function IList_Contains(ByVal value As Object) As Boolean Implements IList.Contains
Return Contains(TryCast(value, ImageComboBoxItem))
End Function
Private Function IList_IndexOf(ByVal value As Object) As Integer Implements IList.IndexOf
Return IndexOf(TryCast(value, ImageComboBoxItem))
End Function
Private Sub IList_Insert(ByVal index As Integer, ByVal value As Object) Implements IList.Insert
If Not (TypeOf value Is ImageComboBoxItem) Then
Throw New ArgumentException()
End If
Insert(index, TryCast(value, ImageComboBoxItem))
End Sub
Private ReadOnly Property IList_IsFixedSize() As Boolean Implements IList.IsFixedSize
Get
Return False
End Get
End Property
Private ReadOnly Property IList_IsReadOnly() As Boolean Implements IList.IsReadOnly
Get
Return IsReadOnly
End Get
End Property
Private Sub IList_Remove(ByVal value As Object) Implements IList.Remove
Remove(TryCast(value, ImageComboBoxItem))
End Sub
Private Sub IList_RemoveAt(ByVal index As Integer) Implements IList.RemoveAt
RemoveAt(index)
End Sub
Property IList_Item(ByVal index As Integer) As Object Implements IList.Item
Get
Return Me(index)
End Get
Set(ByVal value As Object)
If Not (TypeOf value Is ImageComboBoxItem) Then
Throw New ArgumentException()
End If
Me(index) = TryCast(value, ImageComboBoxItem)
End Set
End Property
#End Region
#Region "ICollection 成员"
Private Sub ICollection_CopyTo(ByVal array As Array, ByVal index As Integer) Implements ICollection.CopyTo
CopyTo(DirectCast(array, ImageComboBoxItem()), index)
End Sub
Private ReadOnly Property ICollection_Count() As Integer Implements ICollection.Count
Get
Return Count
End Get
End Property
Private ReadOnly Property ICollection_IsSynchronized() As Boolean Implements ICollection.IsSynchronized
Get
Return False
End Get
End Property
Private ReadOnly Property ICollection_SyncRoot() As Object Implements ICollection.SyncRoot
Get
Return Me
End Get
End Property
#End Region
#Region "IEnumerable 成员"
Private Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
Return GetEnumerator()
End Function
#End Region
End Class
#End Region
End Class
Public Class InterpolationModeGraphics
Implements IDisposable
Private _oldMode As InterpolationMode
Private _graphics As Graphics
Public Sub New(ByVal graphics As Graphics)
Me.New(graphics, InterpolationMode.HighQualityBicubic)
End Sub
Public Sub New(ByVal graphics As Graphics, ByVal newMode As InterpolationMode)
_graphics = graphics
_oldMode = graphics.InterpolationMode
graphics.InterpolationMode = newMode
End Sub
#Region "IDisposable 成员"
Public Sub Dispose() Implements IDisposable.Dispose
_graphics.InterpolationMode = _oldMode
End Sub
#End Region
End Class
End Namespace