There are several ways to Custom Paint a form, but each has their flaw.
This method starts with a standard Form that has its BorderStyle set to None.
We also create a WindowMenu class which pops up in place of the standard WindowMenu. We do this because restoring the standard WindowMenu causes the standard Window Size options to be lost and these cannot be restored without adding the sizable border which we do not want to see.
To get the standard Size and Move options we simply create GraphicsPaths that react to the mouse in the same way as the standard Non-Client form parts do. To achieve this we simply intercept and manipulate a few standard Windows messages. For this article I have not used any Interop calls, but you may get more flexible results by using SendMessage() and SetMenuItemBitmaps() rather than sending WndProc() calls and OwnerDrawing the custom WindowMenu.
The example here simply paints the defined paths in order that you can physically see how this method works, it is not meant to be pretty. You are not restricted to where the paths are placed or what shape they are, you dont even have to stick to them exactly when painting, the paths are simply there for mouse interaction.
The only real problem with this method is that if you set AutoScroll to true then Scrollbars will appear on top of the fake NonClientArea. A simple fix for this is to dock a Panel to the form (set the forms margins as appropiate) and use this as the Form Client.
You'll need to add images to your projects resources for the buttons. You can download the images that I used here...
by: Mick Dohertys'
This method starts with a standard Form that has its BorderStyle set to None.
We also create a WindowMenu class which pops up in place of the standard WindowMenu. We do this because restoring the standard WindowMenu causes the standard Window Size options to be lost and these cannot be restored without adding the sizable border which we do not want to see.
To get the standard Size and Move options we simply create GraphicsPaths that react to the mouse in the same way as the standard Non-Client form parts do. To achieve this we simply intercept and manipulate a few standard Windows messages. For this article I have not used any Interop calls, but you may get more flexible results by using SendMessage() and SetMenuItemBitmaps() rather than sending WndProc() calls and OwnerDrawing the custom WindowMenu.
The example here simply paints the defined paths in order that you can physically see how this method works, it is not meant to be pretty. You are not restricted to where the paths are placed or what shape they are, you dont even have to stick to them exactly when painting, the paths are simply there for mouse interaction.
The only real problem with this method is that if you set AutoScroll to true then Scrollbars will appear on top of the fake NonClientArea. A simple fix for this is to dock a Panel to the form (set the forms margins as appropiate) and use this as the Form Client.
You'll need to add images to your projects resources for the buttons. You can download the images that I used here...
VB net Sample:
Imports System.Drawing.Drawing2D
Imports System.Security.Permissions
Public Class Form1
Inherits System.Windows.Forms.Form
'Form overrides dispose to clean up the component list.
<System.Diagnostics.DebuggerNonUserCode()> _
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
Me.Panel1 = New System.Windows.Forms.Panel
Me.SuspendLayout()
'
'Panel1
'
Me.Panel1.AutoScroll = True
Me.Panel1.AutoScrollMinSize = New System.Drawing.Size(340, 300)
Me.Panel1.Dock = System.Windows.Forms.DockStyle.Fill
Me.Panel1.Location = New System.Drawing.Point(7, 6)
Me.Panel1.Margin = New System.Windows.Forms.Padding(4)
Me.Panel1.Name = "Panel1"
Me.Panel1.Size = New System.Drawing.Size(375, 319)
Me.Panel1.TabIndex = 0
'
'Form1
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(8.0!, 16.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.BackColor = System.Drawing.Color.LemonChiffon
Me.ClientSize = New System.Drawing.Size(389, 331)
Me.Controls.Add(Me.Panel1)
Me.DoubleBuffered = True
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None
Me.MinimumSize = New System.Drawing.Size(133, 62)
Me.Name = "Form1"
Me.Padding = New System.Windows.Forms.Padding(7, 6, 7, 6)
Me.Text = "CustomForm"
Me.ResumeLayout(False)
End Sub
Friend WithEvents Panel1 As System.Windows.Forms.Panel
Private leftEdge, topEdge, bottomEdge, rightEdge, _
topLeftEdge, topRightEdge, bottomLeftEdge, bottomRightEdge, _
titleBar, closeButton, maxButton, minButton, iconButton As GraphicsPath
Private formActive As Boolean = True
Private ButtonTip As ToolTip
Private SystemMenu As WindowMenu
Public Sub New()
' This call is required by the Windows Form Designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Me.leftEdge = New GraphicsPath()
Me.topEdge = New GraphicsPath()
Me.rightEdge = New GraphicsPath()
Me.bottomEdge = New GraphicsPath()
Me.topLeftEdge = New GraphicsPath()
Me.topRightEdge = New GraphicsPath()
Me.bottomLeftEdge = New GraphicsPath()
Me.bottomRightEdge = New GraphicsPath()
Me.titleBar = New GraphicsPath()
Me.closeButton = New GraphicsPath()
Me.maxButton = New GraphicsPath()
Me.minButton = New GraphicsPath()
Me.iconButton = New GraphicsPath()
BuildPaths()
Me.MaximizedBounds = Screen.GetWorkingArea(Me)
Me.Padding = New Padding(5, titleBar.GetBounds().Height + 7, 5, 5)
Me.SystemMenu = New WindowMenu(Me)
AddHandler Me.SystemMenu.SystemEvent, AddressOf SystemMenu_SystemEvent
ButtonTip = New ToolTip()
End Sub
Protected Overrides ReadOnly Property CreateParams() As System.Windows.Forms.CreateParams
Get
Const WS_MINIMIZEBOX As Int32 = &H20000
Dim cParams As System.Windows.Forms.CreateParams = MyBase.CreateParams
cParams.Style = cParams.Style Or WS_MINIMIZEBOX
Return cParams
End Get
End Property
Private Sub Form1_Resize(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Resize
If (Me.Created) Then
BuildPaths()
Me.Invalidate()
Me.ButtonTip.SetToolTip(Me, "")
End If
End Sub
Private Sub Form1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
e.Graphics.FillPath(Brushes.Orange, leftEdge)
e.Graphics.FillPath(Brushes.Orange, topEdge)
e.Graphics.FillPath(Brushes.Orange, rightEdge)
e.Graphics.FillPath(Brushes.Orange, bottomEdge)
e.Graphics.FillPath(Brushes.Coral, topLeftEdge)
e.Graphics.FillPath(Brushes.Coral, topRightEdge)
e.Graphics.FillPath(Brushes.Coral, bottomLeftEdge)
e.Graphics.FillPath(Brushes.Coral, bottomRightEdge)
If (Not Me.formActive) Then
e.Graphics.FillRectangle(Brushes.Silver, Rectangle.Round(titleBar.GetBounds()))
End If
Dim rc As Rectangle = Rectangle.Round(iconButton.GetBounds())
Using bm As Bitmap = IIf(Me.TopMost, My.Resources.Pin, My.Resources.UnPin)
bm.MakeTransparent(Color.Magenta)
e.Graphics.DrawImage(bm, rc)
End Using
rc = Rectangle.Round(minButton.GetBounds())
Using bm As Bitmap = My.Resources.Min
bm.MakeTransparent(Color.Magenta)
e.Graphics.DrawImage(bm, rc)
End Using
rc = Rectangle.Round(maxButton.GetBounds())
Using bm As Bitmap = IIf(Me.WindowState = FormWindowState.Normal, My.Resources.Max, My.Resources.Restore)
bm.MakeTransparent(Color.Magenta)
e.Graphics.DrawImage(bm, rc)
End Using
rc = Rectangle.Round(closeButton.GetBounds())
Using bm As Bitmap = My.Resources.Close
bm.MakeTransparent(Color.Magenta)
e.Graphics.DrawImage(bm, rc)
End Using
Using myPen As Pen = New Pen(Color.Orange, 2)
rc = Me.DisplayRectangle
e.Graphics.DrawLine(myPen, rc.Left, rc.Top - 2, rc.Right, rc.Top - 2)
End Using
Dim textRect As RectangleF = titleBar.GetBounds()
textRect.X += iconButton.GetBounds().Width + 3
textRect.Width = minButton.GetBounds().Left - textRect.Left
TextRenderer.DrawText(e.Graphics, Me.Text, SystemFonts.CaptionFont, Rectangle.Round(textRect), Color.DarkGoldenrod, TextFormatFlags.EndEllipsis Or TextFormatFlags.VerticalCenter)
End Sub
Protected Overrides Sub OnTextChanged(ByVal e As System.EventArgs)
MyBase.OnTextChanged(e)
Me.Invalidate()
End Sub
Private Sub BuildPaths()
Dim edgeSize As Int32 = SystemInformation.CaptionHeight + 2
Dim buttonSize As Int32 = SystemFonts.CaptionFont.Height
Dim buttonPadding As Int32 = 2
'Left Sizing Edge
leftEdge.Reset()
leftEdge.AddRectangle(New Rectangle(0, edgeSize, 5, Me.Height - (edgeSize * 2)))
'Top Sizing Edge
topEdge.Reset()
topEdge.AddRectangle(New Rectangle(edgeSize, 0, Me.Width - (edgeSize * 2), 5))
'Right Sizing Edge
rightEdge.Reset()
rightEdge.AddRectangle(New Rectangle(Me.Width - 5, edgeSize, 5, Me.Height - (edgeSize * 2)))
'Bottom Sizing Edge
bottomEdge.Reset()
bottomEdge.AddRectangle(New Rectangle(edgeSize, Me.Height - 5, Me.Width - (edgeSize * 2), 5))
'Top-Left Sizing Edge
topLeftEdge.Reset()
topLeftEdge.AddRectangle(New Rectangle(0, 0, edgeSize, edgeSize))
topLeftEdge.AddRectangle(New Rectangle(5, 5, edgeSize - 5, edgeSize - 5))
'Top-Right Sizing Edge
topRightEdge.Reset()
topRightEdge.AddRectangle(New Rectangle(Me.Width - edgeSize, 0, edgeSize, edgeSize))
topRightEdge.AddRectangle(New Rectangle(Me.Width - edgeSize, 5, edgeSize - 5, edgeSize - 5))
'Bottom-Left Sizing Edge
bottomLeftEdge.Reset()
bottomLeftEdge.AddRectangle(New Rectangle(0, Me.Height - edgeSize, edgeSize, edgeSize))
bottomLeftEdge.AddRectangle(New Rectangle(5, Me.Height - edgeSize, edgeSize - 5, edgeSize - 5))
'Bottom-Right Sizing Edge
bottomRightEdge.Reset()
bottomRightEdge.AddRectangle(New Rectangle(Me.Width - edgeSize, Me.Height - edgeSize, edgeSize, edgeSize))
bottomRightEdge.AddRectangle(New Rectangle(Me.Width - edgeSize, Me.Height - edgeSize, edgeSize - 5, edgeSize - 5))
'Close Button
closeButton.Reset()
closeButton.AddRectangle(New Rectangle(Me.Width - 5 - (buttonSize + buttonPadding), 8, buttonSize, buttonSize))
'Maximize Button
maxButton.Reset()
maxButton.AddRectangle(New Rectangle(Me.Width - 5 - ((buttonSize + buttonPadding) * 2), 8, buttonSize, buttonSize))
'Minimize Button
minButton.Reset()
minButton.AddRectangle(New Rectangle(Me.Width - 5 - ((buttonSize + buttonPadding) * 3), 8, buttonSize, buttonSize))
'Window Menu Button (Icon)
iconButton.Reset()
iconButton.AddRectangle(New Rectangle(8, 8, buttonSize, buttonSize))
'TitleBar
titleBar.Reset()
titleBar.AddRectangle(New Rectangle(5, 5, Me.Width - 10, edgeSize - 5))
'Remove Titlebar Buttons from TitleBar Path
titleBar.AddPath(closeButton, False)
titleBar.AddPath(maxButton, False)
titleBar.AddPath(minButton, False)
titleBar.AddPath(iconButton, False)
End Sub
<PermissionSet(SecurityAction.Demand, Name:="FullTrust")> _
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If (Me.WindowState = FormWindowState.Maximized) Then
If (m.Msg = User32.WM_SYSCOMMAND AndAlso _
m.WParam.ToInt32() = User32.SysCommand.SC_MOVE OrElse _
m.Msg = User32.NCMouseMessage.WM_NCLBUTTONDOWN AndAlso _
m.WParam.ToInt32() = User32.NCHitTestResult.HTCAPTION) Then
m.Msg = User32.WM_NULL
End If
End If
MyBase.WndProc(m)
Select Case (m.Msg)
Case User32.WM_GETSYSMENU
Me.SystemMenu.Show(Me, Me.PointToClient(New Point(m.LParam.ToInt32())))
Case User32.WM_NCACTIVATE
Me.formActive = m.WParam.ToInt32() <> 0
Me.Invalidate()
Case User32.WM_NCHITTEST
m.Result = OnNonClientHitTest(m.LParam)
Case User32.NCMouseMessage.WM_NCLBUTTONUP
OnNonClientLButtonUp(m.LParam)
Case User32.NCMouseMessage.WM_NCRBUTTONUP
OnNonClientRButtonUp(m.LParam)
Case User32.NCMouseMessage.WM_NCMOUSEMOVE
OnNonClientMouseMove(m.LParam)
End Select
End Sub
Private Sub OnNonClientLButtonUp(ByVal lParam As IntPtr)
Dim code As User32.SysCommand = User32.SysCommand.SC_DEFAULT
Dim point As Point = Me.PointToClient(New Point(lParam.ToInt32()))
If (Me.iconButton.IsVisible(point)) Then
Me.TopMost = Not Me.TopMost
Me.Invalidate()
Else
If (Me.closeButton.IsVisible(point)) Then
code = User32.SysCommand.SC_CLOSE
ElseIf (Me.maxButton.IsVisible(point)) Then
code = IIf(Me.WindowState = FormWindowState.Normal, User32.SysCommand.SC_MAXIMIZE, User32.SysCommand.SC_RESTORE)
ElseIf (Me.minButton.IsVisible(point)) Then
code = User32.SysCommand.SC_MINIMIZE
End If
SendNCWinMessage(User32.WM_SYSCOMMAND, New IntPtr(code), IntPtr.Zero)
End If
End Sub
Private Sub OnNonClientRButtonUp(ByVal lParam As IntPtr)
If (Me.titleBar.IsVisible(Me.PointToClient(New Point(lParam.ToInt32())))) Then
SendNCWinMessage(User32.WM_GETSYSMENU, IntPtr.Zero, lParam)
End If
End Sub
Private Sub OnNonClientMouseMove(ByVal lParam As IntPtr)
Dim point As Point = Me.PointToClient(New Point(lParam.ToInt32()))
Dim tooltip As String
If (Me.closeButton.IsVisible(point)) Then
tooltip = "Close"
ElseIf (Me.maxButton.IsVisible(point)) Then
tooltip = IIf(Me.WindowState = FormWindowState.Normal, "Maximize", "Restore")
ElseIf (Me.minButton.IsVisible(point)) Then
tooltip = "Minimize"
ElseIf (Me.iconButton.IsVisible(point)) Then
tooltip = IIf(Me.TopMost, "Un-Pin", "Pin")
Else
tooltip = String.Empty
End If
If (ButtonTip.GetToolTip(Me) <> tooltip) Then
ButtonTip.SetToolTip(Me, tooltip)
End If
End Sub
Private Function OnNonClientHitTest(ByVal lParam As IntPtr) As IntPtr
Dim result As User32.NCHitTestResult = User32.NCHitTestResult.HTCLIENT
Dim point As Point = Me.PointToClient(New Point(lParam.ToInt32()))
If (Me.titleBar.IsVisible(point)) Then
result = User32.NCHitTestResult.HTCAPTION
End If
If (Me.WindowState = FormWindowState.Normal) Then
If (Me.topLeftEdge.IsVisible(point)) Then
result = User32.NCHitTestResult.HTTOPLEFT
ElseIf (Me.topEdge.IsVisible(point)) Then
result = User32.NCHitTestResult.HTTOP
ElseIf (Me.topRightEdge.IsVisible(point)) Then
result = User32.NCHitTestResult.HTTOPRIGHT
ElseIf (Me.leftEdge.IsVisible(point)) Then
result = User32.NCHitTestResult.HTLEFT
ElseIf (Me.rightEdge.IsVisible(point)) Then
result = User32.NCHitTestResult.HTRIGHT
ElseIf (Me.bottomLeftEdge.IsVisible(point)) Then
result = User32.NCHitTestResult.HTBOTTOMLEFT
ElseIf (Me.bottomEdge.IsVisible(point)) Then
result = User32.NCHitTestResult.HTBOTTOM
ElseIf (Me.bottomRightEdge.IsVisible(point)) Then
result = User32.NCHitTestResult.HTBOTTOMRIGHT
End If
End If
If (Me.closeButton.IsVisible(point)) Then
result = User32.NCHitTestResult.HTBORDER
ElseIf (Me.maxButton.IsVisible(point)) Then
result = User32.NCHitTestResult.HTBORDER
ElseIf (Me.minButton.IsVisible(point)) Then
result = User32.NCHitTestResult.HTBORDER
ElseIf (Me.iconButton.IsVisible(point)) Then
result = User32.NCHitTestResult.HTBORDER
End If
Return New IntPtr(result)
End Function
Private Sub SendNCWinMessage(ByVal msg As Int32, ByVal wParam As IntPtr, ByVal lParam As IntPtr)
Dim message As Message = message.Create(Me.Handle, msg, wParam, lParam)
Me.WndProc(message)
End Sub
Protected Sub SystemMenu_SystemEvent(ByVal sender As Object, ByVal ev As WindowMenuEventArgs)
SendNCWinMessage(User32.WM_SYSCOMMAND, New IntPtr(ev.SystemCommand), IntPtr.Zero)
End Sub
End Class
Friend NotInheritable Class User32
Private Sub New()
MyBase.New()
'Non-Instantiable class
End Sub
Public Enum SysCommand
SC_SIZE = &HF000
SC_MOVE = &HF010
SC_MINIMIZE = &HF020
SC_MAXIMIZE = &HF030
SC_NEXTWINDOW = &HF040
SC_PREVWINDOW = &HF050
SC_CLOSE = &HF060
SC_VSCROLL = &HF070
SC_HSCROLL = &HF080
SC_MOUSEMENU = &HF090
SC_KEYMENU = &HF100
SC_ARRANGE = &HF110
SC_RESTORE = &HF120
SC_TASKLIST = &HF130
SC_SCREENSAVE = &HF140
SC_HOTKEY = &HF150
SC_DEFAULT = &HF160
SC_MONITORPOWER = &HF170
SC_CONTEXTHELP = &HF180
SC_SEPARATOR = &HF00F
End Enum
Public Enum NCHitTestResult
HTERROR = (-2)
HTTRANSPARENT
HTNOWHERE
HTCLIENT
HTCAPTION
HTSYSMENU
HTGROWBOX
HTMENU
HTHSCROLL
HTVSCROLL
HTMINBUTTON
HTMAXBUTTON
HTLEFT
HTRIGHT
HTTOP
HTTOPLEFT
HTTOPRIGHT
HTBOTTOM
HTBOTTOMLEFT
HTBOTTOMRIGHT
HTBORDER
HTOBJECT
HTCLOSE
HTHELP
End Enum
Public Enum NCMouseMessage
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_NCXBUTTONDOWN = &HAB
WM_NCXBUTTONUP = &HAC
WM_NCXBUTTONDBLCLK = &HAD
End Enum
Public Const WM_NULL As Int32 = &H0
Public Const WM_NCHITTEST As Int32 = &H84
Public Const WM_NCACTIVATE As Int32 = &H86
Public Const WM_SYSCOMMAND As Int32 = &H112
Public Const WM_ENTERMENULOOP As Int32 = &H211
Public Const WM_EXITMENULOOP As Int32 = &H212
'********** Undocumented message **********
Public Const WM_GETSYSMENU As Int32 = &H313
'*****************************************
Public Shared Function MakeLParam(ByVal LoWord As Int32, ByVal HiWord As Int32) As IntPtr
Return New IntPtr((HiWord << 16) Or (LoWord And &HFFFF))
End Function
End Class
Friend NotInheritable Class WindowMenu
Inherits ContextMenu
Private Owner As Form
Private menuRestore, menuMove, menuSize, menuMin, menuMax, menuSep, menuClose As MenuItem
Public Event SystemEvent As WindowMenuEventHandler
Public Sub New(ByVal owner As Form)
MyBase.New()
Me.Owner = owner
menuRestore = CreateMenuItem("Restore")
menuMove = CreateMenuItem("Move")
menuSize = CreateMenuItem("Size")
menuMin = CreateMenuItem("Minimize")
menuMax = CreateMenuItem("Maximize")
menuSep = CreateMenuItem("-")
menuClose = CreateMenuItem("Close", Shortcut.AltF4)
Me.MenuItems.AddRange(New MenuItem() {menuRestore, menuMove, menuSize, menuMin, menuMax, menuSep, menuClose})
menuClose.DefaultItem = True
End Sub
Protected Overrides Sub OnPopup(ByVal e As EventArgs)
Select Case Owner.WindowState
Case FormWindowState.Normal
menuRestore.Enabled = False
menuMax.Enabled = True
menuMin.Enabled = True
menuMove.Enabled = True
menuSize.Enabled = True
Case FormWindowState.Minimized
menuRestore.Enabled = True
menuMax.Enabled = True
menuMin.Enabled = False
menuMove.Enabled = False
menuSize.Enabled = False
Case FormWindowState.Maximized
menuRestore.Enabled = True
menuMax.Enabled = False
menuMin.Enabled = True
menuMove.Enabled = False
menuSize.Enabled = False
End Select
MyBase.OnPopup(e)
End Sub
Private Sub OnWindowMenuClick(ByVal sender As Object, ByVal e As EventArgs)
Select Case Me.MenuItems.IndexOf(DirectCast(sender, MenuItem))
Case 0
SendSysCommand(User32.SysCommand.SC_RESTORE)
Case 1
SendSysCommand(User32.SysCommand.SC_MOVE)
Case 2
SendSysCommand(User32.SysCommand.SC_SIZE)
Case 3
SendSysCommand(User32.SysCommand.SC_MINIMIZE)
Case 4
SendSysCommand(User32.SysCommand.SC_MAXIMIZE)
Case 6
SendSysCommand(User32.SysCommand.SC_CLOSE)
End Select
End Sub
Private Function CreateMenuItem(ByVal text As String) As MenuItem
Return CreateMenuItem(text, Shortcut.None)
End Function
Private Function CreateMenuItem(ByVal text As String, ByVal shortcut As Shortcut) As MenuItem
Dim item As MenuItem = New MenuItem(text, AddressOf OnWindowMenuClick, shortcut)
item.OwnerDraw = True
AddHandler item.MeasureItem, AddressOf item_MeasureItem
AddHandler item.DrawItem, AddressOf item_DrawItem
Return item
End Function
Private Sub item_MeasureItem(ByVal sender As Object, ByVal e As MeasureItemEventArgs)
Dim item As MenuItem = Me.MenuItems(e.Index)
Dim itemText As String = item.Text
itemText += "/tAlt+F4"
Dim itemSize As Size = TextRenderer.MeasureText(itemText, SystemFonts.MenuFont)
e.ItemHeight = IIf(e.Index = 5, 8, itemSize.Height + 7)
e.ItemWidth = itemSize.Width + itemSize.Height + 23
End Sub
Private Sub item_DrawItem(ByVal sender As Object, ByVal e As DrawItemEventArgs)
Dim item As MenuItem = Me.MenuItems(e.Index)
If item.Enabled Then
e.DrawBackground()
Else
e.Graphics.FillRectangle(SystemBrushes.Menu, e.Bounds)
End If
If e.Index = 5 Then
e.Graphics.DrawLine(SystemPens.GrayText, e.Bounds.Left + 2, e.Bounds.Top + 3, e.Bounds.Right - 2, e.Bounds.Top + 3)
Else
Dim format As TextFormatFlags = TextFormatFlags.HorizontalCenter Or TextFormatFlags.VerticalCenter Or TextFormatFlags.NoPadding
Dim textColor As Color = IIf(item.Enabled, SystemColors.MenuText, SystemColors.GrayText)
Using marlettFont As New Font("Marlett", 10)
Dim GlyphRect As Rectangle = e.Bounds
GlyphRect.Width = GlyphRect.Height
If item Is menuRestore Then
TextRenderer.DrawText(e.Graphics, "2", marlettFont, GlyphRect, textColor, format)
ElseIf item Is menuMin Then
TextRenderer.DrawText(e.Graphics, "0", marlettFont, GlyphRect, textColor, format)
ElseIf item Is menuMax Then
TextRenderer.DrawText(e.Graphics, "1", marlettFont, GlyphRect, textColor, format)
ElseIf item Is menuClose Then
TextRenderer.DrawText(e.Graphics, "r", marlettFont, GlyphRect, textColor, format)
End If
End Using
format = format And (TextFormatFlags.Left Or Not TextFormatFlags.HorizontalCenter)
Dim textRect As Rectangle = New Rectangle(e.Bounds.Left + e.Bounds.Height + 3, e.Bounds.Top, e.Bounds.Width - e.Bounds.Height - 3, e.Bounds.Height)
TextRenderer.DrawText(e.Graphics, item.Text, SystemFonts.MenuFont, textRect, textColor, format)
If (item Is menuClose) Then
Dim shortcut As String = "Alt+F4"
Dim shortcutSize As Size = TextRenderer.MeasureText(shortcut, SystemFonts.MenuFont)
textRect.X = textRect.Right - shortcutSize.Width - 13
TextRenderer.DrawText(e.Graphics, shortcut, SystemFonts.MenuFont, textRect, textColor, format)
End If
End If
End Sub
Private Sub SendSysCommand(ByVal command As User32.SysCommand)
Dim ev As WindowMenuEventArgs = New WindowMenuEventArgs(DirectCast(command, Int32))
RaiseEvent SystemEvent(Me, ev)
End Sub
End Class
Public Class WindowMenuEventArgs
Inherits EventArgs
Private sysCommand As Int32
Public ReadOnly Property SystemCommand() As Int32
Get
Return Me.sysCommand
End Get
End Property
Public Sub New(ByVal command As Int32)
MyBase.new()
Me.sysCommand = command
End Sub
End Class
Public Delegate Sub WindowMenuEventHandler(ByVal sender As Object, ByVal ev As WindowMenuEventArgs)
CSharp Sample:
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using CustomForm.Properties;
using System.Security.Permissions;
namespace CustomForm
{
public class Form1 : Form
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
this.panel1 = new System.Windows.Forms.Panel();
this.SuspendLayout();
//
// panel1
//
this.panel1.AutoScroll = true;
this.panel1.AutoScrollMinSize = new System.Drawing.Size(340, 300);
this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.panel1.Location = new System.Drawing.Point(7, 6);
this.panel1.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(375, 319);
this.panel1.TabIndex = 0;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.LemonChiffon;
this.ClientSize = new System.Drawing.Size(389, 331);
this.Controls.Add(this.panel1);
this.DoubleBuffered = true;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
this.MinimumSize = new System.Drawing.Size(133, 62);
this.Name = "Form1";
this.Padding = new System.Windows.Forms.Padding(7, 6, 7, 6);
this.Text = "CustomForm";
this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form1_Paint);
this.Resize += new System.EventHandler(this.Form1_Resize);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Panel panel1;
private GraphicsPath leftEdge, topEdge ,bottomEdge, rightEdge,
topLeftEdge, topRightEdge, bottomLeftEdge, bottomRightEdge,
titleBar, closeButton, maxButton, minButton, iconButton;
private bool formActive = true;
private ToolTip ButtonTip;
private WindowMenu SystemMenu;
public Form1()
{
InitializeComponent();
this.leftEdge = new GraphicsPath();
this.topEdge = new GraphicsPath();
this.rightEdge = new GraphicsPath();
this.bottomEdge = new GraphicsPath();
this.topLeftEdge = new GraphicsPath();
this.topRightEdge = new GraphicsPath();
this.bottomLeftEdge = new GraphicsPath();
this.bottomRightEdge = new GraphicsPath();
this.titleBar = new GraphicsPath();
this.closeButton = new GraphicsPath();
this.maxButton = new GraphicsPath();
this.minButton = new GraphicsPath();
this.iconButton = new GraphicsPath();
BuildPaths();
this.MaximizedBounds = Screen.GetWorkingArea(this);
this.Padding = new Padding(5,(int)titleBar.GetBounds().Height+7, 5, 5);
this.SystemMenu = new WindowMenu(this);
this.SystemMenu.SystemEvent += new WindowMenuEventHandler(SystemMenu_SystemEvent);
ButtonTip = new ToolTip();
}
protected override CreateParams CreateParams
{
get
{
const int WS_MINIMIZEBOX = 0x20000;
System.Windows.Forms.CreateParams cParams = base.CreateParams;
cParams.Style |= WS_MINIMIZEBOX;
return cParams;
}
}
private void Form1_Resize(object sender, EventArgs e)
{
if (this.Created)
{
BuildPaths();
this.Invalidate();
this.ButtonTip.SetToolTip(this, "");
}
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.FillPath(Brushes.Orange, leftEdge);
e.Graphics.FillPath(Brushes.Orange, topEdge);
e.Graphics.FillPath(Brushes.Orange, rightEdge);
e.Graphics.FillPath(Brushes.Orange, bottomEdge);
e.Graphics.FillPath(Brushes.Coral, topLeftEdge);
e.Graphics.FillPath(Brushes.Coral, topRightEdge);
e.Graphics.FillPath(Brushes.Coral, bottomLeftEdge);
e.Graphics.FillPath(Brushes.Coral, bottomRightEdge);
if (!this.formActive)
{
e.Graphics.FillRectangle(Brushes.Silver, Rectangle.Round(titleBar.GetBounds()));
}
Rectangle rc = Rectangle.Round(iconButton.GetBounds());
using (Bitmap bm = this.TopMost ? Resources.Pin : Resources.UnPin)
{
bm.MakeTransparent(Color.Magenta);
e.Graphics.DrawImage(bm, rc);
}
rc = Rectangle.Round(minButton.GetBounds());
using (Bitmap bm = Resources.Min)
{
bm.MakeTransparent(Color.Magenta);
e.Graphics.DrawImage(bm, rc);
}
rc = Rectangle.Round(maxButton.GetBounds());
using (Bitmap bm = this.WindowState == FormWindowState.Normal ? Resources.Max : Resources.Restore)
{
bm.MakeTransparent(Color.Magenta);
e.Graphics.DrawImage(bm, rc);
}
rc = Rectangle.Round(closeButton.GetBounds());
using (Bitmap bm = Resources.Close)
{
bm.MakeTransparent(Color.Magenta);
e.Graphics.DrawImage(bm, rc);
}
using (Pen myPen = new Pen(Color.Orange, 2))
{
rc = this.DisplayRectangle;
e.Graphics.DrawLine(myPen, rc.Left, rc.Top - 2, rc.Right, rc.Top - 2);
}
RectangleF textRect = titleBar.GetBounds();
textRect.X += iconButton.GetBounds().Width + 3;
textRect.Width = minButton.GetBounds().Left - textRect.Left;
TextRenderer.DrawText(e.Graphics, this.Text, SystemFonts.CaptionFont, Rectangle.Round(textRect), Color.DarkGoldenrod, TextFormatFlags.EndEllipsis | TextFormatFlags.VerticalCenter);
}
protected override void OnTextChanged(EventArgs e)
{
base.OnTextChanged(e);
this.Invalidate();
}
private void BuildPaths()
{
int edgeSize = SystemInformation.CaptionHeight + 2;
int buttonSize = SystemFonts.CaptionFont.Height;
int buttonPadding = 2;
//Left Sizing Edge
leftEdge.Reset();
leftEdge.AddRectangle(new Rectangle(0, edgeSize, 5, this.Height - (edgeSize*2)));
//Top Sizing Edge
topEdge.Reset();
topEdge.AddRectangle(new Rectangle(edgeSize, 0, this.Width - (edgeSize * 2), 5));
//Right Sizing Edge
rightEdge.Reset();
rightEdge.AddRectangle(new Rectangle(this.Width - 5, edgeSize, 5, this.Height - (edgeSize * 2)));
//Bottom Sizing Edge
bottomEdge.Reset();
bottomEdge.AddRectangle(new Rectangle(edgeSize, this.Height - 5, this.Width - (edgeSize * 2), 5));
//Top-Left Sizing Edge
topLeftEdge.Reset();
topLeftEdge.AddRectangle(new Rectangle(0, 0, edgeSize, edgeSize));
topLeftEdge.AddRectangle(new Rectangle(5, 5, edgeSize - 5, edgeSize - 5));
//Top-Right Sizing Edge
topRightEdge.Reset();
topRightEdge.AddRectangle(new Rectangle(this.Width - edgeSize, 0, edgeSize, edgeSize));
topRightEdge.AddRectangle(new Rectangle(this.Width - edgeSize, 5, edgeSize - 5, edgeSize - 5));
//Bottom-Left Sizing Edge
bottomLeftEdge.Reset();
bottomLeftEdge.AddRectangle(new Rectangle(0, this.Height - edgeSize, edgeSize, edgeSize));
bottomLeftEdge.AddRectangle(new Rectangle(5, this.Height - edgeSize, edgeSize - 5, edgeSize - 5));
//Bottom-Right Sizing Edge
bottomRightEdge.Reset();
bottomRightEdge.AddRectangle(new Rectangle(this.Width - edgeSize, this.Height - edgeSize, edgeSize, edgeSize));
bottomRightEdge.AddRectangle(new Rectangle(this.Width - edgeSize, this.Height - edgeSize, edgeSize - 5, edgeSize - 5));
//Close Button
closeButton.Reset();
closeButton.AddRectangle(new Rectangle(this.Width - 5 - (buttonSize + buttonPadding), 8, buttonSize, buttonSize));
//Maximize Button
maxButton.Reset();
maxButton.AddRectangle(new Rectangle(this.Width - 5 -((buttonSize + buttonPadding)*2), 8, buttonSize, buttonSize));
//Minimize Button
minButton.Reset();
minButton.AddRectangle(new Rectangle(this.Width - 5 -((buttonSize + buttonPadding)*3), 8, buttonSize, buttonSize));
//Window Menu Button (Icon)
iconButton.Reset();
iconButton.AddRectangle(new Rectangle(8, 8, buttonSize, buttonSize));
//TitleBar
titleBar.Reset();
titleBar.AddRectangle(new Rectangle(5, 5, this.Width - 10, edgeSize-5));
//Remove Titlebar Buttons from TitleBar Path
titleBar.AddPath(closeButton, false);
titleBar.AddPath(maxButton, false);
titleBar.AddPath(minButton, false);
titleBar.AddPath(iconButton, false);
}
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
protected override void WndProc(ref Message m)
{
if (this.WindowState == FormWindowState.Maximized)
{
if (m.Msg == USER32.WM_SYSCOMMAND &&
m.WParam.ToInt32() == (int)USER32.SysCommand.SC_MOVE ||
m.Msg == (int)USER32.NCMouseMessage.WM_NCLBUTTONDOWN &&
m.WParam.ToInt32() == (int)USER32.NCHitTestResult.HTCAPTION)
{
m.Msg = USER32.WM_NULL;
}
}
base.WndProc(ref m);
switch (m.Msg)
{
case (int)USER32.WM_GETSYSMENU:
this.SystemMenu.Show(this, this.PointToClient(new Point(m.LParam.ToInt32())));
break;
case USER32.WM_NCACTIVATE:
this.formActive = m.WParam.ToInt32() != 0;
this.Invalidate();
break;
case USER32.WM_NCHITTEST:
m.Result = OnNonClientHitTest(m.LParam);
break;
case (int) USER32.NCMouseMessage.WM_NCLBUTTONUP:
OnNonClientLButtonUp(m.LParam);
break;
case (int)USER32.NCMouseMessage.WM_NCRBUTTONUP:
OnNonClientRButtonUp(m.LParam);
break;
case (int)USER32.NCMouseMessage.WM_NCMOUSEMOVE:
OnNonClientMouseMove(m.LParam);
break;
default:
break;
}
}
private void OnNonClientLButtonUp(IntPtr lParam)
{
USER32.SysCommand code = USER32.SysCommand.SC_DEFAULT;
Point point = this.PointToClient(new Point(lParam.ToInt32()));
if (this.iconButton.IsVisible(point))
{
this.TopMost = !this.TopMost;
this.Invalidate();
}
else
{
if (this.closeButton.IsVisible(point))
code = USER32.SysCommand.SC_CLOSE;
else if (this.maxButton.IsVisible(point))
code = this.WindowState == FormWindowState.Normal ? USER32.SysCommand.SC_MAXIMIZE : USER32.SysCommand.SC_RESTORE;
else if (this.minButton.IsVisible(point))
code = USER32.SysCommand.SC_MINIMIZE;
SendNCWinMessage(USER32.WM_SYSCOMMAND, (IntPtr)code, IntPtr.Zero);
}
}
private void OnNonClientRButtonUp(IntPtr lParam)
{
if (this.titleBar.IsVisible(this.PointToClient(new Point(lParam.ToInt32()))))
SendNCWinMessage(USER32.WM_GETSYSMENU, IntPtr.Zero, lParam);
}
private void OnNonClientMouseMove(IntPtr lParam)
{
Point point = this.PointToClient(new Point(lParam.ToInt32()));
String tooltip;
if (this.closeButton.IsVisible(point))
tooltip = "Close";
else if (this.maxButton.IsVisible(point))
tooltip = this.WindowState == FormWindowState.Normal ? "Maximize" : "Restore";
else if (this.minButton.IsVisible(point))
tooltip = "Minimize";
else if (this.iconButton.IsVisible(point))
tooltip = this.TopMost ? "Un-Pin" : "Pin";
else
tooltip = string.Empty;
if (ButtonTip.GetToolTip(this) != tooltip)
ButtonTip.SetToolTip(this, tooltip);
}
private IntPtr OnNonClientHitTest(IntPtr lParam)
{
USER32.NCHitTestResult result = USER32.NCHitTestResult.HTCLIENT;
Point point = this.PointToClient(new Point(lParam.ToInt32()));
if (this.titleBar.IsVisible(point))
{
result = USER32.NCHitTestResult.HTCAPTION;
}
if (this.WindowState == FormWindowState.Normal)
{
if (this.topLeftEdge.IsVisible(point))
result = USER32.NCHitTestResult.HTTOPLEFT;
else if (this.topEdge.IsVisible(point))
result = USER32.NCHitTestResult.HTTOP;
else if (this.topRightEdge.IsVisible(point))
result = USER32.NCHitTestResult.HTTOPRIGHT;
else if (this.leftEdge.IsVisible(point))
result = USER32.NCHitTestResult.HTLEFT;
else if (this.rightEdge.IsVisible(point))
result = USER32.NCHitTestResult.HTRIGHT;
else if (this.bottomLeftEdge.IsVisible(point))
result = USER32.NCHitTestResult.HTBOTTOMLEFT;
else if (this.bottomEdge.IsVisible(point))
result = USER32.NCHitTestResult.HTBOTTOM;
else if (this.bottomRightEdge.IsVisible(point))
result = USER32.NCHitTestResult.HTBOTTOMRIGHT;
}
if (this.closeButton.IsVisible(point))
result = USER32.NCHitTestResult.HTBORDER;
else if (this.maxButton.IsVisible(point))
result = USER32.NCHitTestResult.HTBORDER;
else if (this.minButton.IsVisible(point))
result = USER32.NCHitTestResult.HTBORDER;
else if (this.iconButton.IsVisible(point))
result = USER32.NCHitTestResult.HTBORDER;
return (IntPtr)result;
}
private void SendNCWinMessage(int msg, IntPtr wParam, IntPtr lParam)
{
Message message = Message.Create(this.Handle, msg, wParam, lParam);
this.WndProc(ref message);
}
protected void SystemMenu_SystemEvent(object sender, WindowMenuEventArgs ev)
{
SendNCWinMessage(USER32.WM_SYSCOMMAND, (IntPtr)ev.SystemCommand, IntPtr.Zero);
}
}
internal sealed class USER32
{
private USER32()
: base()
{
//Non-Instantiable class
}
public enum SysCommand
{
SC_SIZE = 0xF000,
SC_MOVE = 0xF010,
SC_MINIMIZE = 0xF020,
SC_MAXIMIZE = 0xF030,
SC_NEXTWINDOW = 0xF040,
SC_PREVWINDOW = 0xF050,
SC_CLOSE = 0xF060,
SC_VSCROLL = 0xF070,
SC_HSCROLL = 0xF080,
SC_MOUSEMENU = 0xF090,
SC_KEYMENU = 0xF100,
SC_ARRANGE = 0xF110,
SC_RESTORE = 0xF120,
SC_TASKLIST = 0xF130,
SC_SCREENSAVE = 0xF140,
SC_HOTKEY = 0xF150,
SC_DEFAULT = 0xF160,
SC_MONITORPOWER = 0xF170,
SC_CONTEXTHELP = 0xF180,
SC_SEPARATOR = 0xF00F
}
public enum NCHitTestResult
{
HTERROR = (-2),
HTTRANSPARENT,
HTNOWHERE,
HTCLIENT,
HTCAPTION,
HTSYSMENU,
HTGROWBOX,
HTMENU,
HTHSCROLL,
HTVSCROLL,
HTMINBUTTON,
HTMAXBUTTON,
HTLEFT,
HTRIGHT,
HTTOP,
HTTOPLEFT,
HTTOPRIGHT,
HTBOTTOM,
HTBOTTOMLEFT,
HTBOTTOMRIGHT,
HTBORDER,
HTOBJECT,
HTCLOSE,
HTHELP
}
public enum NCMouseMessage
{
WM_NCMOUSEMOVE = 0xA0,
WM_NCLBUTTONDOWN = 0xA1,
WM_NCLBUTTONUP = 0xA2,
WM_NCLBUTTONDBLCLK = 0xA3,
WM_NCRBUTTONDOWN = 0xA4,
WM_NCRBUTTONUP = 0xA5,
WM_NCRBUTTONDBLCLK = 0xA6,
WM_NCMBUTTONDOWN = 0xA7,
WM_NCMBUTTONUP = 0xA8,
WM_NCMBUTTONDBLCLK = 0xA9,
WM_NCXBUTTONDOWN = 0xAB,
WM_NCXBUTTONUP = 0xAC,
WM_NCXBUTTONDBLCLK = 0xAD
}
public const int WM_NULL = 0x0;
public const int WM_NCHITTEST = 0x84;
public const int WM_NCACTIVATE = 0x86;
public const int WM_SYSCOMMAND = 0x112;
public const int WM_ENTERMENULOOP = 0x211;
public const int WM_EXITMENULOOP = 0x212;
//********** Undocumented message **********
public const int WM_GETSYSMENU = 0x313;
//*****************************************
public static IntPtr MakeLParam(int LoWord, int HiWord)
{
return (IntPtr)(((HiWord << 16) | (LoWord & 0xFFFF)));
}
}
internal sealed class WindowMenu : ContextMenu
{
private Form Owner;
private MenuItem menuRestore, menuMove, menuSize, menuMin, menuMax, menuSep, menuClose;
public event WindowMenuEventHandler SystemEvent;
public WindowMenu(Form owner)
: base()
{
Owner = owner;
menuRestore = CreateMenuItem("Restore");
menuMove = CreateMenuItem("Move");
menuSize = CreateMenuItem("Size");
menuMin = CreateMenuItem("Minimize");
menuMax = CreateMenuItem("Maximize");
menuSep = CreateMenuItem("-");
menuClose = CreateMenuItem("Close", Shortcut.AltF4);
this.MenuItems.AddRange(new MenuItem[] { menuRestore, menuMove, menuSize, menuMin, menuMax, menuSep, menuClose });
menuClose.DefaultItem = true;
}
protected override void OnPopup(EventArgs e)
{
switch (Owner.WindowState)
{
case FormWindowState.Normal:
menuRestore.Enabled = false;
menuMax.Enabled = true;
menuMin.Enabled = true;
menuMove.Enabled = true;
menuSize.Enabled = true;
break;
case FormWindowState.Minimized:
menuRestore.Enabled = true;
menuMax.Enabled = true;
menuMin.Enabled = false;
menuMove.Enabled = false;
menuSize.Enabled = false;
break;
case FormWindowState.Maximized:
menuRestore.Enabled = true;
menuMax.Enabled = false;
menuMin.Enabled = true;
menuMove.Enabled = false;
menuSize.Enabled = false;
break;
}
base.OnPopup(e);
}
private void OnWindowMenuClick(object sender, EventArgs e)
{
switch (this.MenuItems.IndexOf((MenuItem)sender))
{
case 0:
SendSysCommand(USER32.SysCommand.SC_RESTORE);
break;
case 1:
SendSysCommand(USER32.SysCommand.SC_MOVE);
break;
case 2:
SendSysCommand(USER32.SysCommand.SC_SIZE);
break;
case 3:
SendSysCommand(USER32.SysCommand.SC_MINIMIZE);
break;
case 4:
SendSysCommand(USER32.SysCommand.SC_MAXIMIZE);
break;
case 6:
SendSysCommand(USER32.SysCommand.SC_CLOSE);
break;
}
}
private MenuItem CreateMenuItem(string text)
{
return CreateMenuItem(text, Shortcut.None);
}
private MenuItem CreateMenuItem(string text, Shortcut shortcut)
{
MenuItem item = new MenuItem(text, OnWindowMenuClick, shortcut);
item.OwnerDraw = true;
item.MeasureItem += new MeasureItemEventHandler(item_MeasureItem);
item.DrawItem += new DrawItemEventHandler(item_DrawItem);
return item;
}
void item_MeasureItem(object sender, MeasureItemEventArgs e)
{
MenuItem item = this.MenuItems[e.Index];
String itemText = item.Text;
itemText += "/tAlt+F4";
Size itemSize = TextRenderer.MeasureText(itemText, SystemFonts.MenuFont);
e.ItemHeight = e.Index == 5 ? 8 : itemSize.Height + 7;
e.ItemWidth = itemSize.Width + itemSize.Height + 23;
}
void item_DrawItem(object sender, DrawItemEventArgs e)
{
MenuItem item = this.MenuItems[e.Index];
if (item.Enabled)
e.DrawBackground();
else
e.Graphics.FillRectangle(SystemBrushes.Menu, e.Bounds);
if (e.Index == 5)
e.Graphics.DrawLine(SystemPens.GrayText, e.Bounds.Left + 2, e.Bounds.Top + 3, e.Bounds.Right - 2, e.Bounds.Top + 3);
else
{
TextFormatFlags format = TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter | TextFormatFlags.NoPadding;
Color textColor = item.Enabled ? SystemColors.MenuText : SystemColors.GrayText;
using (Font marlettFont = new Font("Marlett", 10))
{
Rectangle GlyphRect = e.Bounds;
GlyphRect.Width = GlyphRect.Height;
if (item == menuRestore)
TextRenderer.DrawText(e.Graphics, "2", marlettFont, GlyphRect, textColor, format);
else if (item == menuMin)
TextRenderer.DrawText(e.Graphics, "0", marlettFont, GlyphRect, textColor, format);
else if (item == menuMax)
TextRenderer.DrawText(e.Graphics, "1", marlettFont, GlyphRect, textColor, format);
else if (item == menuClose)
TextRenderer.DrawText(e.Graphics, "r", marlettFont, GlyphRect, textColor, format);
}
format &= TextFormatFlags.Left | ~TextFormatFlags.HorizontalCenter;
Rectangle textRect = new Rectangle(e.Bounds.Left + e.Bounds.Height + 3, e.Bounds.Top, e.Bounds.Width - e.Bounds.Height - 3, e.Bounds.Height);
TextRenderer.DrawText(e.Graphics, item.Text, SystemFonts.MenuFont, textRect, textColor, format);
if (item == menuClose)
{
String shortcut = "Alt+F4";
Size shortcutSize = TextRenderer.MeasureText(shortcut, SystemFonts.MenuFont);
textRect.X = textRect.Right - shortcutSize.Width - 13;
TextRenderer.DrawText(e.Graphics, shortcut, SystemFonts.MenuFont, textRect, textColor, format);
}
}
}
private void SendSysCommand(USER32.SysCommand command)
{
if (this.SystemEvent != null)
{
WindowMenuEventArgs ev = new WindowMenuEventArgs((int)command);
this.SystemEvent(this, ev);
}
}
}
public class WindowMenuEventArgs : EventArgs
{
private int systemCommand;
public int SystemCommand
{
get { return (int)this.systemCommand; }
}
public WindowMenuEventArgs(int command)
: base()
{
this.systemCommand = command;
}
}
public delegate void WindowMenuEventHandler(object sender, WindowMenuEventArgs ev);
}
by: Mick Dohertys'













0 comments:
Post a Comment