I'm trying to create a custom ComboBox with rounded corners where i'm still able to edit the text through user input. The solution i have so far allows me to have a decent ComboBox but only in DropDownList style, i want to go the extra mile and try to paint the embedded EditControl that appears when the combobox is set to DropDown. The solution i have so far is
Public Sub New()
' Esta llamada es exigida por el diseñador.
InitializeComponent()
' Agregue cualquier inicialización después de la llamada a InitializeComponent().
Me.SetStyle(ControlStyles.UserPaint _
Or ControlStyles.AllPaintingInWmPaint _
Or ControlStyles.Opaque _
Or ControlStyles.ResizeRedraw, True)
Me.m_ControlBuffer = New Bitmap(Me.Width, Me.Height)
Me.m_ControlGraphics = Graphics.FromImage(m_ControlBuffer)
Me.m_BackBuffer = New Bitmap(Me.Width, Me.Height)
Me.m_BackGraphics = Graphics.FromImage(m_BackBuffer)
Dim backcolor As Color = If(Enabled, m_UITheme.TextBoxColor, Color.White)
BackgroundBrush = New SolidBrush(backcolor)
Me.BackColor = backcolor
End Sub
and Paint method is
Public Sub CustomPaint(screenGraphics As Graphics)
' If there is body to be drawn.
If Me.Width > 0 AndAlso Me.Height > 0 Then
' Clear the background image graphics
If Me.m_backImage Is Nothing Then
' Cached Background Image
Me.m_backImage = New Bitmap(Me.Width, Me.Height)
Dim backGraphics As Graphics = Graphics.FromImage(Me.m_backImage)
backGraphics.Clear(Color.Transparent)
Me.PaintTransparentBackground(backGraphics, Me.ClientRectangle)
End If
m_BackGraphics.Clear(Color.Transparent)
m_BackGraphics.DrawImageUnscaled(Me.m_backImage, 0, 0)
m_ControlGraphics.Clear(Color.Transparent)
m_ControlGraphics.SmoothingMode = SmoothingMode.HighQuality
' Begin drawing
Dim path As GraphicsPath = GetBoxBorder()
m_ControlGraphics.FillPath(BackgroundBrush, path)
PaintArrowAndLine(m_ControlGraphics)
' Draw text
DrawText(m_ControlGraphics)
m_ControlGraphics.Flush()
m_BackGraphics.DrawImage(m_ControlBuffer,
New Rectangle(0, 0,
m_ControlBuffer.Width,
m_ControlBuffer.Height),
0, 0,
m_ControlBuffer.Width,
m_ControlBuffer.Height,
GraphicsUnit.Pixel)
m_BackGraphics.Flush()
' Now paint this to the screen
screenGraphics.DrawImageUnscaled(m_BackBuffer, 0, 0)
End If
End Sub
The problem is that for DropDown style a white EditControl appears on top of my drawing. Searching on other forums i received the idea of getting a handle of that control and maybe i could change the color. I then found the WM_CTLCOLOREDIT which i think would help me in what i have to do. It says,
If an application processes this message, it must return the handle of a brush. The system uses the brush to paint the background of the edit control.
So what i tried was to catch that message on the WndProc of my ComboBox and alter result of the message (which as i understand is the return value for the WM_CTLCOLOREDIT) to be the pointer to the brush i'm creating.
<DllImport("gdi32.dll")>
Public Shared Function CreateSolidBrush(ByVal color As Integer) As IntPtr
End Function
Protected Overrides Sub WndProc(ByRef m As Message)
If (m.Msg = &H133) Then
Dim brush As IntPtr = CreateSolidBrush(RGB(255, 0, 0))
m.Result = brush
End If
MyBase.WndProc(m)
End Sub
I'm not sure how to use the WndProc and this code above still does not work. Any help will be aprecciated.
EDIT: After changing the WndProc,
Private hBrush As IntPtr = CreateSolidBrush(RGB(255, 0, 0))
Protected Overrides Sub WndProc(ByRef m As Message)
If (m.Msg = &H133) Then
m.Result = hBrush
Else
MyBase.WndProc(m)
End If
End Sub
It does paints the red rectangle except when i have the focus on the control. See Images below,
I feel so far and so close to the solution at the same time.