Imports System.Security
Imports System.Runtime.InteropServices
''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Author: Stacey Brown (ibanezowner@yahoo.com)
' Date: June, 2002
' Reason: Bored
' URL: staceybrown.hispeed.com (I gave up on this site back around 1998)
'
' Overview:
' In .NET, Microsoft has given us many things to work
' with. It's nice how they standardized properties like
' Text and Name on most controls. owever, what's the story
' with the Flat look?
'
' Some controls have a flat look as a property, either
' through the FlatStyle property or the Border property.
' I love the flat look and have been using it for all my
' controls, except one. The combobox. Do you know how funny
' a data entry form looks when all its text boxes, checkboxes,
' radio buttons, command buttons, etc are flat, but its
' combo boxes are 3D? You probably do, and that's why
' you're looking here...
'
' This project is nothing more than a simple combobox that
' inherits from combobox. All events and properties of the
' regular combo box are there. It even does databinding. The
' great thing is that it's flat.
'
' I didn't exactly write this code. I'm a VB developer mostly,
' and at work we're almost 100% VB. I needed to find a combobox
' control with a flat look written in VB. What did I find? I
' found the coolest code on CodeProject.com in an article named,
' "VSNetToolbar (flat toolbar with embedded combo boxes) written in C#"
' by Carlos H. Perez. It's a incredibly awesome project to have.
' However, it's not in VB. I ported his code, line for line,
' coming up with my own VB equivalents for things like bit
' shifting, etc. I converted all the API calls and structures
' needed, also. This was a lot of fun to convert.
'
' If you like the code, thank Carlos. If you like the fact
' that it's in VB, thank me! Enjoy..
''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Public Class FlatComboBase
'''''''''''''''''''''''''''''''''''''
' This class serves as a base class
' handling most of the events from
' combobox. It can be further inherited
' and extended. In fact, in Carlos'
' C# project, he creates flat dropdowns
' with bitmaps in them!
'''''''''''''''''''''''''''''''''''''
Inherits System.Windows.Forms.ComboBox
Private eraseDropDownHightLight As Boolean = False
Private mouseHookHandle As IntPtr = IntPtr.Zero
Private mouseProcHandle As GCHandle
Public toolBarUse As Boolean = False
Private hooked As Boolean = False
Public Const ARROW_WIDTH As Integer = 13
Private editHook As EditCtrlHook = Nothing
Friend forceUpdate As Boolean = False
Friend highlighted As Boolean = False
#Region " Public methods"
Public Sub New(ByVal toolBarUse As Boolean)
'// Flag to indicate that combo box will be used
'// in a toolbar --which means we will use some window hooks
'// to reset the focus of the combobox--
Me.toolBarUse = toolBarUse
DrawMode = DrawMode.OwnerDrawFixed
SetStyle(ControlStyles.AllPaintingInWmPaint Or ControlStyles.UserPaint Or ControlStyles.Opaque, True)
'// Use Menu font so that the combobox uses the same font as the toolbar buttons
Font = SystemInformation.MenuFont
'// When use in a toolbar we don't need tab stop
TabStop = False
End Sub
Public Sub New()
DrawMode = DrawMode.OwnerDrawFixed
SetStyle(ControlStyles.AllPaintingInWmPaint Or ControlStyles.UserPaint Or ControlStyles.Opaque, True)
End Sub
Public Sub SetFontHeight(ByVal newHeight As Integer)
FontHeight = newHeight
End Sub
#End Region
#Region " Protected methods"
Protected Overrides Sub OnHandleCreated(ByVal e As EventArgs)
MyBase.OnHandleCreated(e)
'// Hook the edit control
If DropDownStyle = ComboBoxStyle.DropDown Then
Dim hEditControl As IntPtr = Win32API.GetDlgItem(Handle, &H3E9)
Debug.Assert(Not hEditControl.ToInt64 = IntPtr.Zero.ToInt64, "Fail to get ComboBox's Edit Control Handle...")
editHook = New EditCtrlHook(Me)
editHook.AssignHandle(hEditControl)
End If
End Sub
Protected Overrides Sub OnDrawItem(ByVal e As DrawItemEventArgs)
'// Draw bitmap strech to the size of the size of the combobox
Dim g As Graphics = e.Graphics
Dim bounds As Rectangle = e.Bounds
Dim selected As Boolean = (e.State And DrawItemState.Selected) > 0
Dim editSel As Boolean = (e.State & DrawItemState.ComboBoxEdit) > 0
If e.Index <> -1 Then
DrawComboBoxItem(g, bounds, e.Index, selected, editSel)
End If
End Sub
Protected Overrides Sub OnPaint(ByVal pe As PaintEventArgs)
'// This on paint is only going to happen for the combobox if
'// the combobox has been set the style to do all painting
'// in the OnPaint event
PaintComboBoxBackground(pe.Graphics, SystemColors.Window)
MyBase.OnPaint(pe)
If DropDownStyle = ComboBoxStyle.DropDown Then
'// We will handle the painting from WM_PAINT
Exit Sub
End If
If Not Enabled Then
DrawDisableState()
Exit Sub
End If
Dim rc As Rectangle = ClientRectangle
If SelectedIndex = -1 Then
If Items.Count > 0 Then
'// Select first item as the current item
SelectedIndex = 0
End If
End If
DrawComboBoxItemEx(pe.Graphics, rc, SelectedIndex, False, True)
If Not ContainsFocus Then
DrawComboBoxBorder(pe.Graphics, SystemColors.Window)
DrawComboBoxArrowNormal(pe.Graphics, True)
Else
DrawComboBoxBorder(pe.Graphics, SystemColors.Highlight)
End If
End Sub
Protected Overrides Sub WndProc(ByRef m As Message)
Dim doPainting As Boolean = False
Select Case m.Msg
Case Win32API.Msg.WM_PAINT
doPainting = True
Exit Select
Case Else
Exit Select
End Select
MyBase.WndProc(m)
'// Now let's do our own painting
'// we have to do it after the combox
'// does its own painting so that we can
'// let the edit control in the combobox
'// take care of the text
If doPainting Then ForcePaint(m)
End Sub
Protected Overrides Sub OnMouseEnter(ByVal e As EventArgs)
MyBase.OnMouseEnter(e)
Dim g As Graphics = CreateGraphics()
DrawComboBoxBorder(g, SystemColors.Highlight)
DrawComboBoxArrowSelected(g, False)
g.Dispose()
End Sub
Protected Overrides Sub OnMouseLeave(ByVal e As EventArgs)
MyBase.OnMouseLeave(e)
If Not ContainsFocus Then
Dim g As Graphics = CreateGraphics()
DrawComboBoxBorder(g, SystemColors.Window)
DrawComboBoxArrowNormal(g, False)
g.Dispose()
End If
End Sub
Protected Overrides Sub OnLostFocus(ByVal e As EventArgs)
MyBase.OnLostFocus(e)
Dim g As Graphics = CreateGraphics()
DrawComboBoxBorder(g, SystemColors.Window)
DrawComboBoxArrowNormal(g, False)
g.Dispose()
If toolBarUse And hooked Then
hooked = False
EndHook()
End If
End Sub
Protected Overrides Sub OnGotFocus(ByVal e As EventArgs)
MyBase.OnGotFocus(e)
Dim g As Graphics = CreateGraphics()
DrawComboBoxBorder(g, SystemColors.Highlight)
DrawComboBoxArrowSelected(g, False)
g.Dispose()
If toolBarUse And Not hooked Then
hooked = True
StartHook()
End If
End Sub
Protected Overrides Sub OnDropDown(ByVal e As EventArgs)
eraseDropDownHightLight = True
MyBase.OnDropDown(e)
End Sub
Protected Overrides Sub OnSelectedIndexChanged(ByVal e As EventArgs)
MyBase.OnSelectedIndexChanged(e)
If eraseDropDownHightLight Then
Dim g As Graphics = CreateGraphics()
DrawComboBoxArrowSelected(g, False)
eraseDropDownHightLight = False
g.Dispose()
End If
End Sub
Protected Overridable Sub DrawComboBoxItem(ByVal g As Graphics, ByVal bounds As Rectangle, ByVal Index As Integer, ByVal selected As Boolean, ByVal editSel As Boolean)
'// Draw the the combo item
g.FillRectangle(New SolidBrush(SystemColors.Window), bounds.Left, bounds.Top, bounds.Width, bounds.Height)
If selected And Not editSel Then
'// Draw highlight rectangle
g.FillRectangle(New SolidBrush(SystemColors.Highlight), bounds.Left, bounds.Top, bounds.Width, bounds.Height)
Else
'// Erase highlight rectangle
g.FillRectangle(New SolidBrush(SystemColors.Window), bounds.Left, bounds.Top, bounds.Width, bounds.Height)
If editSel And ContainsFocus Then
'// Draw higlighted arrow
DrawComboBoxArrowSelected(g, False)
End If
End If
End Sub
Protected Overridable Sub DrawComboBoxItemEx(ByVal g As Graphics, ByVal bounds As Rectangle, ByVal Index As Integer, ByVal selected As Boolean, ByVal editSel As Boolean)
'// This function is only called form the OnPaint handler and the Graphics object passed is the one
'// for the combobox itself as opossed to the one for the edit control in the combobox
'// doing this allows us to be able to avoid clipping problems with text strings
'// Draw the the combo item
bounds.Inflate(-3, -3)
g.FillRectangle(New SolidBrush(SystemColors.Window), bounds.Left, bounds.Top, bounds.Width, bounds.Height)
If selected And Not editSel Then
'// Draw highlight rectangle
g.FillRectangle(New SolidBrush(SystemColors.Highlight), bounds.Left, bounds.Top, bounds.Width, bounds.Height)
Else
'// Erase highlight rectangle
g.FillRectangle(New SolidBrush(SystemColors.Window), bounds.Left, bounds.Top, bounds.Width, bounds.Height)
If editSel And ContainsFocus Then
'// Draw higlighted arrow
DrawComboBoxArrowSelected(g, False)
End If
End If
End Sub
#End Region
#Region " Friend methods"
Friend Sub DrawComboBoxBorder(ByVal g As Graphics, ByVal color As Color)
'// Keep track of what we painted last
If color.Equals(SystemColors.Highlight) Then
highlighted = True
Else
highlighted = False
End If
Dim pen As Pen = New Pen(New SolidBrush(color), 1)
g.DrawRectangle(pen, ClientRectangle.Left, ClientRectangle.Top, ClientRectangle.Width - 1, ClientRectangle.Height - 1)
'// We need to draw an extra "inner" border to erase the ugly 3D look of the combobox
g.DrawRectangle(Pens.White, ClientRectangle.Left + 1, _
ClientRectangle.Top + 1, _
ClientRectangle.Width - SystemInformation.VerticalScrollBarWidth - 1, _
ClientRectangle.Height - 3)
End Sub
Friend Sub DrawComboBoxArrowNormal(ByVal g As Graphics, ByVal disable As Boolean)
Dim left As Integer
Dim top As Integer
Dim arrowWidth As Integer
Dim height As Integer
CalculateArrowBoxCoordinates(left, top, arrowWidth, height)
'// We are not going to draw the arrow background using the total
'// width of the arrow button in the combobox because it too wide
'// and it does not look nice. However, we need to paint over the section
'// that correspond to the "original" arrow button dimension to avoid
'// clipping or painting problems
Dim stripeColorBrush As Brush = New SolidBrush(ColorUtil.VSNetStripeColor)
If Enabled Then
Dim Width As Integer = SystemInformation.VerticalScrollBarWidth - ARROW_WIDTH
g.FillRectangle(Brushes.White, _
New Rectangle(left - Width, _
top, _
SystemInformation.VerticalScrollBarWidth, _
height))
End If
If Not disable Then
'// Erase previous selected rectangle first
DrawComboBoxArrowSelected(g, True)
'// Now draw the unselected background
g.FillRectangle(stripeColorBrush, left, top, arrowWidth, height)
Else
'// Now draw the unselected background
g.FillRectangle(stripeColorBrush, left - 1, top - 1, arrowWidth + 2, height + 2)
End If
DrawArrowGlyph(g, disable)
End Sub
Friend Sub DrawComboBoxArrowSelected(ByVal g As Graphics, ByVal bErase As Boolean)
Dim left As Integer
Dim top As Integer
Dim arrowWidth As Integer
Dim height As Integer
CalculateArrowBoxCoordinates(left, top, arrowWidth, height)
'// We are not going to draw the arrow background using the total
'// width of the arrow button in the combobox because it too wide
'// and it does not look nice. However, we need to paint over the section
'// that correspond to the "original" arrow button dimension to avoid
'// clipping or painting problems
If Enabled Then
Dim width As Integer = SystemInformation.VerticalScrollBarWidth - ARROW_WIDTH
g.FillRectangle(Brushes.White, _
New Rectangle(left - width, _
top, _
SystemInformation.VerticalScrollBarWidth, _
height))
End If
If Not bErase Then
If (DroppedDown) Then
'// If showing the list portion of the combo box, draw the arrow portion background using
'// the highlight color with some transparency
'// Don't use the graphics object that we get passed because that is associated
'// to the edit control of the combobox and we actually want to paint on the combobox area
'// and not be clipped only to the edit control client area
Dim cbg As Graphics = CreateGraphics()
cbg.FillRectangle(New SolidBrush(ColorUtil.VSNetPressedColor), left - 1, top - 1, arrowWidth + 2, height + 2)
cbg.DrawRectangle(New Pen(New SolidBrush(SystemColors.Highlight), 1), left - 1, top - 1, arrowWidth + 2, height + 3)
cbg.Dispose()
forceUpdate = True
Else
g.FillRectangle(New SolidBrush(ColorUtil.VSNetSelectionColor), left - 1, top - 1, arrowWidth + 2, height + 2)
g.DrawRectangle(New Pen(New SolidBrush(SystemColors.Highlight), 1), left - 1, top - 2, arrowWidth + 2, height + 3)
End If
Else
g.FillRectangle(Brushes.White, left - 1, top - 1, arrowWidth + 2, height + 2)
End If
DrawArrowGlyph(g, False)
End Sub
Friend Sub DrawDisableState()
Dim g As Graphics = CreateGraphics()
PaintComboBoxBackground(g, SystemColors.Window)
DrawComboBoxBorder(g, SystemColors.ControlDark)
DrawComboBoxArrowNormal(g, True)
g.Dispose()
End Sub
Friend Sub ForceTheUpdate()
Dim g As Graphics = CreateGraphics()
If ContainsFocus Then DrawComboBoxArrowSelected(g, False)
End Sub
#End Region
#Region " Private methods"
Private Sub PaintComboBoxBackground(ByVal g As Graphics, ByVal backColor As Color)
Dim rc As Rectangle = ClientRectangle
rc.Inflate(-1, -1)
g.FillRectangle(New SolidBrush(backColor), rc)
End Sub
Private Sub CalculateArrowBoxCoordinates(ByRef left As Integer, ByRef top As Integer, ByRef width As Integer, ByRef height As Integer)
Dim rc As Rectangle = ClientRectangle
width = ARROW_WIDTH
left = rc.Right - width - 2
top = rc.Top + 2
height = rc.Height - 4
End Sub
Private Sub DrawArrowGlyph(ByVal g As Graphics, ByVal disable As Boolean)
Dim left As Integer
Dim top As Integer
Dim arrowWidth As Integer
Dim height As Integer
CalculateArrowBoxCoordinates(left, top, arrowWidth, height)
'// Draw arrow glyph
Dim pts(2) As Point
pts(0) = New Point(left + arrowWidth / 2 - 2, top + height / 2 - 1)
pts(1) = New Point(left + arrowWidth / 2 + 3, top + height / 2 - 1)
pts(2) = New Point(left + arrowWidth / 2, (top + height / 2 - 1) + 3)
If disable Then
g.FillPolygon(New SolidBrush(SystemColors.ControlDark), pts)
Else
g.FillPolygon(Brushes.Black, pts)
End If
End Sub
Private Sub ForcePaint(ByRef m As Message)
'// Similar code to the OnPaint handler
Dim g As Graphics = Graphics.FromHwnd(Handle)
If Not Enabled Then
DrawDisableState()
Exit Sub
End If
Dim rc As Rectangle = ClientRectangle
If SelectedIndex = -1 Then
If Items.Count > 0 Then
SelectedIndex = 0
End If
DrawComboBoxItemEx(g, rc, SelectedIndex, False, True)
If Not ContainsFocus Then
DrawComboBoxBorder(g, SystemColors.Window)
DrawComboBoxArrowNormal(g, False)
End If
Else
DrawComboBoxBorder(g, SystemColors.Highlight)
End If
End Sub
Private Sub StartHook()
'// Mouse hook
Dim mouseHookProc As Win32API.HookProc = New Win32API.HookProc(AddressOf MouseHook)
mouseProcHandle = GCHandle.Alloc(mouseHookProc)
mouseHookHandle = Win32API.SetWindowsHookEx(Win32API.WindowsHookCodes.WH_MOUSE, mouseHookProc, IntPtr.Zero, Win32API.GetCurrentThreadId())
If mouseHookHandle.ToInt64 = IntPtr.Zero.ToInt64 Then
Throw New SecurityException()
End If
End Sub
Private Sub EndHook()
'// Unhook
Win32API.UnhookWindowsHookEx(mouseHookHandle)
mouseProcHandle.Free()
mouseHookHandle = IntPtr.Zero
End Sub
Private Function MouseHook(ByVal code As Integer, ByVal wparam As IntPtr, ByVal lparam As IntPtr) As IntPtr
Dim mh As Win32API.MOUSEHOOKSTRUCT = Marshal.PtrToStructure(lparam, GetType(Win32API.MOUSEHOOKSTRUCT))
If mh.hwnd.ToInt64 <> Handle.ToInt64 And Not DroppedDown And (wparam.ToInt64 = Convert.ToInt64(Win32API.Msg.WM_LBUTTONDOWN) Or wparam.ToInt64 = Convert.ToInt64(Win32API.Msg.WM_RBUTTONDOWN)) Or wparam.ToInt64 = Convert.ToInt64(Win32API.Msg.WM_NCLBUTTONDOWN) Then
'// Loose focus
Win32API.SetFocus(IntPtr.Zero)
ElseIf mh.hwnd.ToInt64 <> Handle.ToInt64 And Not DroppedDown And (wparam.ToInt64 = Convert.ToInt64(Win32API.Msg.WM_LBUTTONUP) Or wparam.ToInt64 = Convert.ToInt64(Win32API.Msg.WM_RBUTTONUP)) Or wparam.ToInt64 = Convert.ToInt64(Win32API.Msg.WM_NCLBUTTONUP) Then
Win32API.SetFocus(IntPtr.Zero)
End If
Return Win32API.CallNextHookEx(mouseHookHandle, code, wparam, lparam)
End Function
#End Region
End Class
Public Class FlatTextComboBox
'''''''''''''''''''''''''''''''''''''
' This is the actual class to implement
'''''''''''''''''''''''''''''''''''''
Inherits FlatComboBase
'// For use when hosted by a toolbar
Public Sub New(ByVal toolBarUse As Boolean)
'// Override parent, we don't want to do all the painting ourselves
'// since we want to let the edit control deal with the text for editing
'// the parent class ComboBoxBase knows to do the right stuff with
'// non-editable comboboxes as well as editable comboboxes as long
'// as we change these flags below
SetStyle(ControlStyles.AllPaintingInWmPaint Or ControlStyles.UserPaint Or ControlStyles.Opaque, False)
End Sub
Public Sub New()
'// Override parent, we don't want to do all the painting ourselves
'// since we want to let the edit control deal with the text for editing
'// the parent class ComboBoxBase knows to do the right stuff with
'// non-editable comboboxes as well as editable comboboxes as long
'// as we change these flags below
SetStyle(ControlStyles.AllPaintingInWmPaint Or ControlStyles.UserPaint Or ControlStyles.Opaque, False)
End Sub
Protected Overrides Sub OnPaint(ByVal pe As PaintEventArgs)
MyBase.OnPaint(pe)
End Sub
Protected Overrides Sub OnDrawItem(ByVal e As DrawItemEventArgs)
'// Call base class to do the "Flat ComboBox" drawing
MyBase.OnDrawItem(e)
'// Draw text
Dim g As Graphics = e.Graphics
Dim bounds As Rectangle = e.Bounds
Dim selected As Boolean = (e.State And DrawItemState.Selected) > 0
Dim editSel As Boolean = (e.State And DrawItemState.ComboBoxEdit) > 0
If e.Index <> -1 Then
DrawComboBoxItem(g, bounds, e.Index, selected, editSel)
End If
End Sub
Protected Overrides Sub DrawComboBoxItem(ByVal g As Graphics, ByVal bounds As Rectangle, ByVal Index As Integer, ByVal selected As Boolean, ByVal editSel As Boolean)
'// Call base class to do the "Flat ComboBox" drawing
MyBase.DrawComboBoxItem(g, bounds, Index, selected, editSel)
If Index <> -1 Then
Dim brush As SolidBrush
If selected And editSel Then
brush = New SolidBrush(SystemColors.MenuText)
ElseIf (selected) Then
brush = New SolidBrush(SystemColors.HighlightText)
Else
brush = New SolidBrush(SystemColors.MenuText)
End If
Dim textSize As Size = GetTextSize(g, Items(Index).ToString(), Font)
Dim top As Integer = bounds.Top + (bounds.Height - textSize.Height) / 2
g.DrawString(Items(Index).ToString(), Font, brush, New Drawing.PointF(bounds.Left + 1, top))
End If
End Sub
Protected Overrides Sub DrawComboBoxItemEx(ByVal g As Graphics, ByVal bounds As Rectangle, ByVal Index As Integer, ByVal selected As Boolean, ByVal editSel As Boolean)
'// This "hack" is necessary to avoid a clipping bug that comes from the fact that sometimes
'// we are drawing using the Graphics object for the edit control in the combobox and sometimes
'// we are using the graphics object for the combobox itself. If we use the same function to do our custom
'// drawing it is hard to adjust for the clipping because of what was said about
MyBase.DrawComboBoxItemEx(g, bounds, Index, selected, editSel)
If Index <> -1 Then
Dim brush As SolidBrush
If selected And editSel Then
brush = New SolidBrush(SystemColors.MenuText)
ElseIf (selected) Then
brush = New SolidBrush(SystemColors.HighlightText)
Else
brush = New SolidBrush(SystemColors.MenuText)
Dim textSize As Size = GetTextSize(g, Items(Index).ToString(), Font)
Dim top As Integer = bounds.Top + (bounds.Height - textSize.Height) / 2
'// Clipping rectangle
Dim clipRect As RectangleF = New RectangleF(bounds.Left + 4, top, bounds.Width - ARROW_WIDTH - 4, top + textSize.Height)
g.DrawString(Items(Index).ToString(), Font, brush, clipRect)
End If
End If
End Sub
Public Shared Function GetTextSize(ByVal graphics As Graphics, ByVal text As String, ByVal font As Font) As Size
Dim hdc As IntPtr = graphics.GetHdc()
Dim fontHandle As IntPtr = font.ToHfont()
Dim currentFontHandle As IntPtr = Win32API.SelectObject(hdc, fontHandle)
Dim rect As Win32API.RECT = New Win32API.RECT()
rect.left = 0
rect.right = 0
rect.top = 0
rect.bottom = 0
Win32API.DrawText(hdc, text, text.Length, rect, _
(Win32API.DrawTextFormatFlags.DT_SINGLELINE Or Win32API.DrawTextFormatFlags.DT_LEFT Or Win32API.DrawTextFormatFlags.DT_CALCRECT))
Win32API.SelectObject(hdc, currentFontHandle)
Win32API.DeleteObject(fontHandle)
graphics.ReleaseHdc(hdc)
Return New Size(rect.right - rect.left, rect.bottom - rect.top)
End Function
End Class
Friend Class ColorUtil
'''''''''''''''''''''''''''''''''''''
' This is a helper class for converting
' color data around
'''''''''''''''''''''''''''''''''''''
Public Sub New()
'// No need to construct this object
End Sub
#Region " Members"
'// Knowncolor names
Public Shared KnownColorNames() As String = _
{"Transparent", "Black", "DimGray", "Gray", "DarkGray", "Silver", "LightGray", "Gainsboro", "WhiteSmoke", "White", _
"RosyBrown", "IndianRed", "Brown", "Firebrick", "LightCoral", "Maroon", "DarkRed", "Red", "Snow", "MistyRose", _
"Salmon", "Tomato", "DarkSalmon", "Coral", "OrangeRed", "LightSalmon", "Sienna", "SeaShell", "Chocalate", _
"SaddleBrown", "SandyBrown", "PeachPuff", "Peru", "Linen", "Bisque", "DarkOrange", "BurlyWood", "Tan", "AntiqueWhite", _
"NavajoWhite", "BlanchedAlmond", "PapayaWhip", "Mocassin", "Orange", "Wheat", "OldLace", "FloralWhite", "DarkGoldenrod", _
"Cornsilk", "Gold", "Khaki", "LemonChiffon", "PaleGoldenrod", "DarkKhaki", "Beige", "LightGoldenrod", "Olive", _
"Yellow", "LightYellow", "Ivory", "OliveDrab", "YellowGreen", "DarkOliveGreen", "GreenYellow", "Chartreuse", "LawnGreen", _
"DarkSeaGreen", "ForestGreen", "LimeGreen", "PaleGreen", "DarkGreen", "Green", "Lime", "Honeydew", "SeaGreen", "MediumSeaGreen", _
"SpringGreen", "MintCream", "MediumSpringGreen", "MediumAquaMarine", "YellowAquaMarine", "Turquoise", "LightSeaGreen", _
"MediumTurquoise", "DarkSlateGray", "PaleTurquoise", "Teal", "DarkCyan", "Aqua", "Cyan", "LightCyan", "Azure", "DarkTurquoise", _
"CadetBlue", "PowderBlue", "LightBlue", "DeepSkyBlue", "SkyBlue", "LightSkyBlue", "SteelBlue", "AliceBlue", "DodgerBlue", _
"SlateGray", "LightSlateGray", "LightSteelBlue", "CornflowerBlue", "RoyalBlue", "MidnightBlue", "Lavender", "Navy", _
"DarkBlue", "MediumBlue", "Blue", "GhostWhite", "SlateBlue", "DarkSlateBlue", "MediumSlateBlue", "MediumPurple", _
"BlueViolet", "Indigo", "DarkOrchid", "DarkViolet", "MediumOrchid", "Thistle", "Plum", "Violet", "Purple", "DarkMagenta", _
"Magenta", "Fuchsia", "Orchid", "MediumVioletRed", "DeepPink", "HotPink", "LavenderBlush", "PaleVioletRed", "Crimson", _
"Pink", "LightPink"}
'// Systemcolors names
Public Shared SystemColorNames() As String = { _
"ActiveBorder", "ActiveCaption", "ActiveCaptionText", "AppWorkspace", "Control", "ControlDark", "ControlDarkDark", _
"ControlLight", "ControlLightLight", "ControlText", "Desktop", "GrayText", "HighLight", "HighLightText", _
"HotTrack", "InactiveBorder", "InactiveCaption", "InactiveCaptionText", "Info", "InfoText", "Menu", "MenuText", _
"ScrollBar", "Window", "WindowFrame", "WindowText"}
#End Region
'// Conversion between RGB and Hue, Saturation and Luminosity function helpers
Public Shared Sub HSLToRGB(ByVal h As Single, ByVal s As Single, ByVal l As Single, ByRef r As Single, ByRef g As Single, ByRef b As Single)
'// given h,s,l,[240 and r,g,b [0-255]
'// convert h [0-360], s,l,r,g,b [0-1]
h = (h / 240.0F) * 360.0F
s /= 240
l /= 240
r /= 255
g /= 255
b /= 255
'// Begin Foley
Dim m1 As Single
Dim m2 As Single
'// Calc m2
If l <= 0.5 Then
'//m2=(l*(l+s)); seems to be typo in Foley??, replace l for 1
m2 = (l * (1 + s))
Else
m2 = (l + s - l * s)
End If
'//calc m1
m1 = 2.0F * l - m2
'//calc r,g,b in [0-1]
If s = 0 Then
' // Achromatic: There is no hue
' // leave out the UNDEFINED part, h will always have value
r = g = b = l
Else
' // Chromatic: There is a hue
r = getRGBValue(m1, m2, h + 120.0F)
g = getRGBValue(m1, m2, h)
b = getRGBValue(m1, m2, h - 120.0F)
End If
'// End Foley
'// convert to 0-255 ranges
r *= 255.0F
g *= 255.0F
b *= 255.0F
End Sub
Private Shared Function getRGBValue(ByVal n1 As Single, ByVal n2 As Single, ByVal hue As Single) As Single
'// Helper function for the HSLToRGB function above
If hue > 360.0F Then
hue -= 360.0F
ElseIf hue < 0 Then
hue += 360.0F
End If
If hue < 60.0F Then
Return n1 + (n2 - n1) * hue / 60.0F
ElseIf hue < 180.0F Then
Return n2
ElseIf hue < 240.0F Then
Return n1 + (n2 - n1) * (240.0F - hue) / 60.0F
Else
Return n1
End If
End Function
Public Shared Sub RGBToHSL(ByVal r As Integer, ByVal g As Integer, ByVal b As Integer, ByRef h As Single, ByRef s As Single, ByRef l As Single)
'//Computer Graphics - Foley p.595
Dim delta As Single
Dim fr As Single = r / 255.0F
Dim fg As Single = g / 255.0F
Dim fb As Single = b / 255.0F
Dim max As Single = Math.Max(fr, Math.Max(fg, fb))
Dim min As Single = Math.Min(fr, Math.Min(fg, fb))
'//calc the lightness
l = (max + min) / 2
If max = min Then
'//should be undefined but this works for what we need
s = 0.0F
h = 240.0F
Else
delta = max - min
'//calc the Saturation
If l < 0.5F Then
s = delta / (max + min)
Else
s = delta / (2.0F - (max + min))
End If
'//calc the hue
If fr = max Then
h = (fg - fb) / delta
ElseIf fg = max Then
h = 2.0F + (fb - fr) / delta
ElseIf fb = max Then
h = 4.0F + (fr - fg) / delta
End If
'//convert hue to degrees
h *= 60.0F
If h < 0.0F Then
h += 360.0F
End If
'//end foley
End If
'//convert to 0-255 ranges
'//h [0-360], h,l [0-1]
l *= 240.0F
s *= 240.0F
h = (h / 360.0F) * 240.0F
End Sub
'// Visual Studio .NET colors calculation helpers
Public Shared ReadOnly Property VSNetBackgroundColor() As Color
Get
Return CalculateColor(SystemColors.Window, SystemColors.Control, 220)
End Get
End Property
Public Shared ReadOnly Property VSNetSelectionColor() As Color
Get
Return CalculateColor(SystemColors.Highlight, SystemColors.Window, 70)
End Get
End Property
Public Shared ReadOnly Property VSNetStripeColor() As Color
Get
Return CalculateColor(SystemColors.Control, VSNetBackgroundColor, 195)
End Get
End Property
Public Shared ReadOnly Property VSNetPressedColor() As Color
Get
Return CalculateColor(SystemColors.Highlight, ColorUtil.VSNetSelectionColor, 70)
End Get
End Property
Public Shared ReadOnly Property VSNetToggleColor() As Color
Get
Return CalculateColor(SystemColors.Highlight, SystemColors.Window, 30)
End Get
End Property
Private Shared Function CalculateColor(ByVal front As Color, ByVal back As Color, ByVal alpha As Integer) As Color
'// Use alpha blending to brigthen the colors but don't use it
'// directly. Instead derive an opaque color that we can use.
'// -- if we use a color with alpha blending directly we won't be able
'// to paint over whatever color was in the background and there
'// would be shadows of that color showing through
Dim frontColor As Color = Color.FromArgb(255, front)
Dim backColor As Color = Color.FromArgb(255, back)
Dim frontRed As Single = frontColor.R
Dim frontGreen As Single = frontColor.G
Dim frontBlue As Single = frontColor.B
Dim backRed As Single = backColor.R
Dim backGreen As Single = backColor.G
Dim backBlue As Single = backColor.B
Dim fRed As Single = frontRed * alpha / 255 + backRed * Convert.ToSingle((255 - alpha) / 255)
Dim newRed As Byte = Convert.ToByte(fRed)
Dim fGreen As Single = frontGreen * alpha / 255 + backGreen * Convert.ToSingle((255 - alpha) / 255)
Dim newGreen As Byte = Convert.ToByte(fGreen)
Dim fBlue As Single = frontBlue * alpha / 255 + backBlue * Convert.ToSingle((255 - alpha) / 255)
Dim newBlue As Byte = Convert.ToByte(fBlue)
Return Color.FromArgb(255, newRed, newGreen, newBlue)
End Function
'// General functions
Public Shared Function ColorFromPoint(ByVal g As Graphics, ByVal x As Integer, ByVal y As Integer) As Color
Dim hDC As IntPtr = g.GetHdc()
'// Get the color of the pixel first
Dim colorref As UInt32 = Win32API.GetPixel(hDC, x, y)
Dim Red As Byte = GetRValue(colorref)
Dim Green As Byte = GetGValue(colorref)
Dim Blue As Byte = GetBValue(colorref)
g.ReleaseHdc(hDC)
Return Color.FromArgb(Red, Green, Blue)
End Function
Public Shared Function IsKnownColor(ByVal color As Color, ByRef knownColor As Color, ByVal useTransparent As Boolean) As Boolean
'// Using the Color structrure "FromKnowColor" does not work if
'// we did not create the color as a known color to begin with
'// we need to compare the rgbs of both color
Dim currentColor As Color = color.Empty
Dim badColor As Boolean = False
Dim enumValue As KnownColor
For enumValue = 0 To knownColor.YellowGreen.ToKnownColor
currentColor = color.FromKnownColor(enumValue)
Dim colorName As String = currentColor.Name
If Not useTransparent Then
badColor = (colorName = "Transparent")
If (color.A = currentColor.A And color.R = currentColor.R And color.G = currentColor.G _
And color.B = currentColor.B And Not currentColor.IsSystemColor _
And Not badColor) Then
knownColor = currentColor
Return True
End If
End If
Next enumValue
Return False
End Function
Public Shared Function IsSystemColor(ByVal color As Color, ByRef knownColor As Color) As Boolean
'// Using the Color structrure "FromKnowColor" does not work if
'// we did not create the color as a known color to begin with
'// we need to compare the rgbs of both color
Dim currentColor As Color = color.Empty
Dim enumValue As KnownColor
For enumValue = 0 To knownColor.YellowGreen.ToKnownColor
currentColor = color.FromKnownColor(enumValue)
Dim colorName As String = currentColor.Name
If (color.R = currentColor.R And color.G = currentColor.G _
And color.B = currentColor.B And currentColor.IsSystemColor) Then
knownColor = currentColor
Return True
End If
Next enumValue
Return False
End Function
Public Shared Function GetCOLORREF(ByVal color As Color) As UInt32
Return RGB(color.R, color.G, color.B)
End Function
'// Windows RGB related macros
Public Shared Function GetRValue(ByVal color As UInt32) As Byte
Dim i As Integer = 0
Dim iBinaryNumber As Integer = 0
Dim retVal As Byte = 0
For i = 0 To 7
iBinaryNumber = (2 ^ i)
If (Convert.ToInt32(color) And iBinaryNumber) = iBinaryNumber Then
Dim iShiftedBinaryNumber As Byte = (2 ^ i)
retVal = retVal Or iShiftedBinaryNumber
End If
Next
Return retVal
End Function
Public Shared Function GetGValue(ByVal color As UInt32) As Byte
Dim i As Integer = 0
Dim iBinaryNumber As Integer = 0
Dim retVal As Byte = 0
For i = 8 To 15
iBinaryNumber = (2 ^ i)
If (Convert.ToInt32(color) And iBinaryNumber) = iBinaryNumber Then
Dim iShiftedBinaryNumber As Byte = (2 ^ (i - 8))
retVal = retVal Or iShiftedBinaryNumber
End If
Next
Return retVal
End Function
Public Shared Function GetBValue(ByVal color As UInt32) As Byte
Dim i As Integer = 0
Dim iBinaryNumber As Integer = 0
Dim retVal As Byte = 0
For i = 16 To 23
iBinaryNumber = (2 ^ i)
If (Convert.ToInt32(color) And iBinaryNumber) = iBinaryNumber Then
Dim iShiftedBinaryNumber As Byte = (2 ^ (i - 16))
retVal = retVal Or iShiftedBinaryNumber
End If
Next
Return retVal
End Function
Public Shared Function RGB(ByVal r As Integer, ByVal g As Integer, ByVal b As Integer) As UInt32
Dim i As Integer = 0
Dim iBinaryNumber As Integer = 0
Dim retVal As Integer
For i = 0 To 7
iBinaryNumber = (2 ^ i)
If (r And iBinaryNumber) = iBinaryNumber Then
Dim iShiftedBinaryNumber As Byte = (2 ^ i)
retVal = retVal Or iShiftedBinaryNumber
End If
Next
iBinaryNumber = 0
For i = 0 To 7
iBinaryNumber = (2 ^ i)
If (g And iBinaryNumber) = iBinaryNumber Then
Dim iShiftedBinaryNumber As Integer = (2 ^ (i + 8))
retVal = retVal Or iShiftedBinaryNumber
End If
Next
iBinaryNumber = 0
For i = 0 To 7
iBinaryNumber = (2 ^ i)
If (b And iBinaryNumber) = iBinaryNumber Then
Dim iShiftedBinaryNumber As Integer = (2 ^ (i + 16))
retVal = retVal Or iShiftedBinaryNumber
End If
Next
Return Convert.ToUInt32(retVal)
End Function
End Class
Friend Class EditCtrlHook
'''''''''''''''''''''''''''''''''''''
' This class is used by the combobox classes
' to hook into some windows events.
'''''''''''''''''''''''''''''''''''''
Inherits System.Windows.Forms.NativeWindow
Dim comboBox As FlatComboBase = Nothing
Dim ignoreNextPaintMessage As Boolean = False
Public Sub New(ByVal cb As FlatComboBase)
comboBox = cb
End Sub
Protected Overrides Sub WndProc(ByRef m As Message)
Dim currentMessage As Win32API.Msg = m.Msg
Select Case m.Msg
Case Win32API.Msg.WM_PAINT
If ignoreNextPaintMessage Then
ignoreNextPaintMessage = False
Exit Sub
End If
If comboBox.forceUpdate And Not comboBox.DroppedDown Then
comboBox.forceUpdate = False
comboBox.ForceTheUpdate()
End If
If Not comboBox.Enabled Then
'// Let the edit control do its thing first
MyBase.WndProc(m)
'// This is going to generate another paint message
'// ignore it
ignoreNextPaintMessage = True
DrawDisableState()
Exit Sub
End If
Exit Select
Case Win32API.Msg.WM_MOUSEMOVE
RequestMouseLeaveMessage(m.HWnd)
If Not comboBox.highlighted Then
Dim g As Graphics = Graphics.FromHwnd(comboBox.Handle)
comboBox.DrawComboBoxBorder(g, SystemColors.Highlight)
comboBox.DrawComboBoxArrowSelected(g, False)
End If
Exit Select
Case Win32API.Msg.WM_MOUSELEAVE
If comboBox.highlighted And Not comboBox.ContainsFocus Then
Dim g As Graphics = Graphics.FromHwnd(comboBox.Handle)
comboBox.DrawComboBoxBorder(g, SystemColors.Window)
comboBox.DrawComboBoxArrowNormal(g, False)
End If
Exit Select
Case Else
Exit Select
End Select
MyBase.WndProc(m)
End Sub
Private Sub DrawDisableState()
'// we are just going to fill the edit area
'// with a white background, the combobox
'// already does the hard part
Dim g As Graphics = Graphics.FromHwnd(Handle)
Dim rc As Win32API.RECT = New Win32API.RECT()
Win32API.GetClientRect(Handle, rc)
Dim clientSize As Rectangle = New Rectangle(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top)
g.FillRectangle(Brushes.White, clientSize)
End Sub
Private Sub RequestMouseLeaveMessage(ByVal hWnd As IntPtr)
'// Crea the structure needed for WindowsAPI call
Dim tme As Win32API.TRACKMOUSEEVENTS = New Win32API.TRACKMOUSEEVENTS()
'// Fill in the structure
tme.cbSize = Convert.ToUInt32(16)
tme.dwFlags = Convert.ToUInt32(Win32API.TrackerEventFlags.TME_LEAVE)
tme.hWnd = hWnd
tme.dwHoverTime = Convert.ToUInt32(0)
'// Request that a message gets sent when mouse leaves this window
Win32API.TrackMouseEvent(tme)
End Sub
End Class
Friend Class Win32API
'''''''''''''''''''''''''''''''''''''
' this class is full of useful, re-usable
' VB ports of common Win32API stuff...
'''''''''''''''''''''''''''''''''''''
Public Delegate Function HookProc(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
#Region " Enums and structs"
Public Enum WindowsHookCodes
WH_MSGFILTER = -1
WH_JOURNALRECORD = 0
WH_JOURNALPLAYBACK = 1
WH_KEYBOARD = 2
WH_GETMESSAGE = 3
WH_CALLWNDPROC = 4
WH_CBT = 5
WH_SYSMSGFILTER = 6
WH_MOUSE = 7
WH_HARDWARE = 8
WH_DEBUG = 9
WH_SHELL = 10
WH_FOREGROUNDIDLE = 11
WH_CALLWNDPROCRET = 12
WH_KEYBOARD_LL = 13
WH_MOUSE_LL = 14
End Enum
Public Enum TrackerEventFlags As Integer
TME_HOVER = &H1
TME_LEAVE = &H2
TME_QUERY = &H40000000
TME_CANCEL = &H80000000
End Enum
Public Enum Msg
WM_NULL = &H0
WM_CREATE = &H1
WM_DESTROY = &H2
WM_MOVE = &H3
WM_SIZE = &H5
WM_ACTIVATE = &H6
WM_SETFOCUS = &H7
WM_KILLFOCUS = &H8
WM_ENABLE = &HA
WM_SETREDRAW = &HB
WM_SETTEXT = &HC
WM_GETTEXT = &HD
WM_GETTEXTLENGTH = &HE
WM_PAINT = &HF
WM_CLOSE = &H10
WM_QUERYENDSESSION = &H11
WM_QUIT = &H12
WM_QUERYOPEN = &H13
WM_ERASEBKGND = &H14
WM_SYSCOLORCHANGE = &H15
WM_ENDSESSION = &H16
WM_SHOWWINDOW = &H18
WM_CTLCOLOR = &H19
WM_WININICHANGE = &H1A
WM_SETTINGCHANGE = &H1A
WM_DEVMODECHANGE = &H1B
WM_ACTIVATEAPP = &H1C
WM_FONTCHANGE = &H1D
WM_TIMECHANGE = &H1E
WM_CANCELMODE = &H1F
WM_SETCURSOR = &H20
WM_MOUSEACTIVATE = &H21
WM_CHILDACTIVATE = &H22
WM_QUEUESYNC = &H23
WM_GETMINMAXINFO = &H24
WM_PAINTICON = &H26
WM_ICONERASEBKGND = &H27
WM_NEXTDLGCTL = &H28
WM_SPOOLERSTATUS = &H2A
WM_DRAWITEM = &H2B
WM_MEASUREITEM = &H2C
WM_DELETEITEM = &H2D
WM_VKEYTOITEM = &H2E
WM_CHARTOITEM = &H2F
WM_SETFONT = &H30
WM_GETFONT = &H31
WM_SETHOTKEY = &H32
WM_GETHOTKEY = &H33
WM_QUERYDRAGICON = &H37
WM_COMPAREITEM = &H39
WM_GETOBJECT = &H3D
WM_COMPACTING = &H41
WM_COMMNOTIFY = &H44
WM_WINDOWPOSCHANGING = &H46
WM_WINDOWPOSCHANGED = &H47
WM_POWER = &H48
WM_COPYDATA = &H4A
WM_CANCELJOURNAL = &H4B
WM_NOTIFY = &H4E
WM_INPUTLANGCHANGEREQUEST = &H50
WM_INPUTLANGCHANGE = &H51
WM_TCARD = &H52
WM_HELP = &H53
WM_USERCHANGED = &H54
WM_NOTIFYFORMAT = &H55
WM_CONTEXTMENU = &H7B
WM_STYLECHANGING = &H7C
WM_STYLECHANGED = &H7D
WM_DISPLAYCHANGE = &H7E
WM_GETICON = &H7F
WM_SETICON = &H80
WM_NCCREATE = &H81
WM_NCDESTROY = &H82
WM_NCCALCSIZE = &H83
WM_NCHITTEST = &H84
WM_NCPAINT = &H85
WM_NCACTIVATE = &H86
WM_GETDLGCODE = &H87
WM_SYNCPAINT = &H88
WM_NCMOUSEMOVE = &HA0
WM_NCLBUTTONDOWN = &HA1
WM_NCLBUTTONUP = &HA2
WM_NCLBUTTONDBLCLK = &HA3
WM_NCRBUTTONDOWN = &HA4
WM_NCRBUTTONUP = &HA5
WM_NCRBUTTONDBLCLK = &HA6
WM_NCMBUTTONDOWN = &HA7
WM_NCMBUTTONUP = &HA8
WM_NCMBUTTONDBLCLK = &HA9
WM_KEYDOWN = &H100
WM_KEYUP = &H101
WM_CHAR = &H102
WM_DEADCHAR = &H103
WM_SYSKEYDOWN = &H104
WM_SYSKEYUP = &H105
WM_SYSCHAR = &H106
WM_SYSDEADCHAR = &H107
WM_KEYLAST = &H108
WM_IME_STARTCOMPOSITION = &H10D
WM_IME_ENDCOMPOSITION = &H10E
WM_IME_COMPOSITION = &H10F
WM_IME_KEYLAST = &H10F
WM_INITDIALOG = &H110
WM_COMMAND = &H111
WM_SYSCOMMAND = &H112
WM_TIMER = &H113
WM_HSCROLL = &H114
WM_VSCROLL = &H115
WM_INITMENU = &H116
WM_INITMENUPOPUP = &H117
WM_MENUSELECT = &H11F
WM_MENUCHAR = &H120
WM_ENTERIDLE = &H121
WM_MENURBUTTONUP = &H122
WM_MENUDRAG = &H123
WM_MENUGETOBJECT = &H124
WM_UNINITMENUPOPUP = &H125
WM_MENUCOMMAND = &H126
WM_CTLCOLORMSGBOX = &H132
WM_CTLCOLOREDIT = &H133
WM_CTLCOLORLISTBOX = &H134
WM_CTLCOLORBTN = &H135
WM_CTLCOLORDLG = &H136
WM_CTLCOLORSCROLLBAR = &H137
WM_CTLCOLORSTATIC = &H138
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
WM_MOUSEWHEEL = &H20A
WM_PARENTNOTIFY = &H210
WM_ENTERMENULOOP = &H211
WM_EXITMENULOOP = &H212
WM_NEXTMENU = &H213
WM_SIZING = &H214
WM_CAPTURECHANGED = &H215
WM_MOVING = &H216
WM_DEVICECHANGE = &H219
WM_MDICREATE = &H220
WM_MDIDESTROY = &H221
WM_MDIACTIVATE = &H222
WM_MDIRESTORE = &H223
WM_MDINEXT = &H224
WM_MDIMAXIMIZE = &H225
WM_MDITILE = &H226
WM_MDICASCADE = &H227
WM_MDIICONARRANGE = &H228
WM_MDIGETACTIVE = &H229
WM_MDISETMENU = &H230
WM_ENTERSIZEMOVE = &H231
WM_EXITSIZEMOVE = &H232
WM_DROPFILES = &H233
WM_MDIREFRESHMENU = &H234
WM_IME_SETCONTEXT = &H281
WM_IME_NOTIFY = &H282
WM_IME_CONTROL = &H283
WM_IME_COMPOSITIONFULL = &H284
WM_IME_SELECT = &H285
WM_IME_CHAR = &H286
WM_IME_REQUEST = &H288
WM_IME_KEYDOWN = &H290
WM_IME_KEYUP = &H291
WM_MOUSEHOVER = &H2A1
WM_MOUSELEAVE = &H2A3
WM_CUT = &H300
WM_COPY = &H301
WM_PASTE = &H302
WM_CLEAR = &H303
WM_UNDO = &H304
WM_RENDERFORMAT = &H305
WM_RENDERALLFORMATS = &H306
WM_DESTROYCLIPBOARD = &H307
WM_DRAWCLIPBOARD = &H308
WM_PAINTCLIPBOARD = &H309
WM_VSCROLLCLIPBOARD = &H30A
WM_SIZECLIPBOARD = &H30B
WM_ASKCBFORMATNAME = &H30C
WM_CHANGECBCHAIN = &H30D
WM_HSCROLLCLIPBOARD = &H30E
WM_QUERYNEWPALETTE = &H30F
WM_PALETTEISCHANGING = &H310
WM_PALETTECHANGED = &H311
WM_HOTKEY = &H312
WM_PRINT = &H317
WM_PRINTCLIENT = &H318
WM_HANDHELDFIRST = &H358
WM_HANDHELDLAST = &H35F
WM_AFXFIRST = &H360
WM_AFXLAST = &H37F
WM_PENWINFIRST = &H380
WM_PENWINLAST = &H38F
WM_APP = &H8000
WM_USER = &H400
WM_REFLECT = WM_USER + &H1C00
End Enum
Public Enum DrawTextFormatFlags As Integer
DT_TOP = &H0
DT_LEFT = &H0
DT_CENTER = &H1
DT_RIGHT = &H2
DT_VCENTER = &H4
DT_BOTTOM = &H8
DT_WORDBREAK = &H10
DT_SINGLELINE = &H20
DT_EXPANDTABS = &H40
DT_TABSTOP = &H80
DT_NOCLIP = &H100
DT_EXTERNALLEADING = &H200
DT_CALCRECT = &H400
DT_NOPREFIX = &H800
DT_INTERNAL = &H1000
DT_EDITCONTROL = &H2000
DT_PATH_ELLIPSIS = &H4000
DT_END_ELLIPSIS = &H8000
DT_MODIFYSTRING = &H10000
DT_RTLREADING = &H20000
DT_WORD_ELLIPSIS = &H40000
End Enum
<StructLayout(LayoutKind.Sequential)> _
Public Structure POINT
Public x As Integer
Public y As Integer
End Structure
<StructLayout(LayoutKind.Sequential)> _
Public Structure RECT
Public left As Integer
Public top As Integer
Public right As Integer
Public bottom As Integer
End Structure
<StructLayout(LayoutKind.Sequential)> _
Public Structure TRACKMOUSEEVENTS
Public cbSize As UInt32
Public dwFlags As UInt32
Public hWnd As IntPtr
Public dwHoverTime As UInt32
End Structure
Public Structure MOUSEHOOKSTRUCT
Public pt As POINT
Public hwnd As IntPtr
Public wHitTestCode As Integer
Public dwExtraInfo As IntPtr
End Structure
#End Region
#Region " Methods"
#Region " Kernel32"
<DllImport("kernel32.dll")> _
Public Shared Function GetCurrentThreadId() As Integer
End Function
#End Region
#Region " User32"
<DllImport("user32.dll")> _
Public Shared Function GetDlgItem(ByVal hDlg As IntPtr, ByVal nControlID As Integer) As IntPtr
End Function
<DllImport("user32.dll")> _
Public Shared Function SetWindowsHookEx(ByVal hookid As Integer, ByVal pfnhook As HookProc, ByVal hinst As IntPtr, ByVal threadid As Integer) As IntPtr
End Function
<DllImport("user32.dll")> _
Public Shared Function UnhookWindowsHookEx(ByVal hhook As IntPtr) As Boolean
End Function
<DllImport("user32.dll")> _
Public Shared Function SetFocus(ByVal hWnd As IntPtr) As IntPtr
End Function
<DllImport("user32.dll")> _
Public Shared Function CallNextHookEx(ByVal hhook As IntPtr, ByVal code As Integer, ByVal wparam As IntPtr, ByVal lparam As IntPtr) As IntPtr
End Function
<DllImport("User32.dll")> _
Public Shared Function TrackMouseEvent(ByRef tme As TRACKMOUSEEVENTS) As Boolean
End Function
<DllImport("user32.dll")> _
Public Shared Function GetClientRect(ByVal hWnd As IntPtr, ByRef rc As RECT) As Integer
End Function
<DllImport("user32.dll")> _
Public Shared Function DrawText(ByVal hdc As IntPtr, ByVal lpString As String, ByVal nCount As Integer, ByRef lpRect As RECT, ByVal uFormat As Integer) As Integer
End Function
#End Region
#Region " GDI32"
<DllImport("gdi32.dll")> _
Public Shared Function SelectObject(ByVal hDC As IntPtr, ByVal hObject As IntPtr) As IntPtr
End Function
<DllImport("gdi32.dll")> _
Public Shared Function DeleteObject(ByVal hObject As IntPtr) As Boolean
End Function
<DllImport("gdi32.dll")> _
Public Shared Function GetPixel(ByVal hDC As IntPtr, ByVal XPos As Integer, ByVal YPos As Integer) As UInt32
End Function
#End Region
#End Region
End Class