This is by no means a complete solution, just an idea for creating custom shaped forms with custom Titlebars.
The form can be dragged by its fake titlebar, and if right clicked the fake Titlebar will popup the WindowMenu.
The CreateParams property has been modified to add a System Menu (with Min,Move and Close items) to a borderless form.
The Titlebar button are not controls, they are simply drawn in the fake title bar and they react to hittesting.
The MainMenu is actually labels that popup Contextmenus.
The form can be resized only by its resizegrip, but you could define regions for each of the sides and corners and allow sizing by dragging the edge. The example requires a little work to be useable, but it should give you an idea of how to achieve this solution.
With a little InterOp you can draw a standard TitleBar onto which you can place custom buttons, and this solution is much simpler than that of OwnerDrawing the NonClient Area to achieve the same effect.
by: Mick Dohertys'
The form can be dragged by its fake titlebar, and if right clicked the fake Titlebar will popup the WindowMenu.
The CreateParams property has been modified to add a System Menu (with Min,Move and Close items) to a borderless form.
The Titlebar button are not controls, they are simply drawn in the fake title bar and they react to hittesting.
The MainMenu is actually labels that popup Contextmenus.
The form can be resized only by its resizegrip, but you could define regions for each of the sides and corners and allow sizing by dragging the edge. The example requires a little work to be useable, but it should give you an idea of how to achieve this solution.
With a little InterOp you can draw a standard TitleBar onto which you can place custom buttons, and this solution is much simpler than that of OwnerDrawing the NonClient Area to achieve the same effect.
VB net Sample:
Imports System.Drawing.Drawing2D
Public Class MainForm
Inherits System.Windows.Forms.Form
#Region " Windows Form Designer generated code "
<System.STAThread()> _
Public Shared Sub Main()
Application.EnableVisualStyles()
Application.DoEvents()
Application.Run(New MainForm)
End Sub
Public Sub New()
MyBase.New()
'This call is required by the Windows Form Designer.
InitializeComponent()
'Add any initialization after the InitializeComponent() call
setstyle(ControlStyles.AllPaintingInWmPaint Or ControlStyles.DoubleBuffer Or ControlStyles.ResizeRedraw Or ControlStyles.UserPaint, True)
End Sub
'Form overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
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.
Friend WithEvents ContextMenu1 As System.Windows.Forms.ContextMenu
Friend WithEvents MenuItem1 As System.Windows.Forms.MenuItem
Friend WithEvents MenuItem2 As System.Windows.Forms.MenuItem
Friend WithEvents ContextMenu2 As System.Windows.Forms.ContextMenu
Friend WithEvents MenuExit As System.Windows.Forms.MenuItem
Friend WithEvents MenuAbout As System.Windows.Forms.MenuItem
Friend WithEvents ToolTip1 As System.Windows.Forms.ToolTip
Friend WithEvents LabelFile As System.Windows.Forms.Label
Friend WithEvents LabelResize As System.Windows.Forms.Label
Friend WithEvents LabelHelp As System.Windows.Forms.Label
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
Me.components = New System.ComponentModel.Container
Me.ContextMenu1 = New System.Windows.Forms.ContextMenu
Me.MenuItem1 = New System.Windows.Forms.MenuItem
Me.MenuItem2 = New System.Windows.Forms.MenuItem
Me.MenuExit = New System.Windows.Forms.MenuItem
Me.ContextMenu2 = New System.Windows.Forms.ContextMenu
Me.MenuAbout = New System.Windows.Forms.MenuItem
Me.ToolTip1 = New System.Windows.Forms.ToolTip(Me.components)
Me.LabelFile = New System.Windows.Forms.Label
Me.LabelHelp = New System.Windows.Forms.Label
Me.LabelResize = New System.Windows.Forms.Label
Me.SuspendLayout()
'
'ContextMenu1
'
Me.ContextMenu1.MenuItems.AddRange(New System.Windows.Forms.MenuItem() {Me.MenuItem1, Me.MenuItem2, Me.MenuExit})
'
'MenuItem1
'
Me.MenuItem1.Index = 0
Me.MenuItem1.Text = "MenuItem1"
'
'MenuItem2
'
Me.MenuItem2.Index = 1
Me.MenuItem2.Text = "-"
'
'MenuExit
'
Me.MenuExit.Index = 2
Me.MenuExit.Text = "Exit"
'
'ContextMenu2
'
Me.ContextMenu2.MenuItems.AddRange(New System.Windows.Forms.MenuItem() {Me.MenuAbout})
'
'MenuAbout
'
Me.MenuAbout.Index = 0
Me.MenuAbout.Text = "About"
'
'ToolTip1
'
Me.ToolTip1.ShowAlways = True
'
'LabelFile
'
Me.LabelFile.BackColor = System.Drawing.Color.Transparent
Me.LabelFile.ForeColor = System.Drawing.SystemColors.MenuText
Me.LabelFile.Location = New System.Drawing.Point(8, 24)
Me.LabelFile.Name = "LabelFile"
Me.LabelFile.Size = New System.Drawing.Size(32, 19)
Me.LabelFile.TabIndex = 0
Me.LabelFile.Text = "File"
Me.LabelFile.TextAlign = System.Drawing.ContentAlignment.MiddleCenter
'
'LabelHelp
'
Me.LabelHelp.BackColor = System.Drawing.Color.Transparent
Me.LabelHelp.ForeColor = System.Drawing.SystemColors.MenuText
Me.LabelHelp.Location = New System.Drawing.Point(64, 24)
Me.LabelHelp.Name = "LabelHelp"
Me.LabelHelp.Size = New System.Drawing.Size(32, 19)
Me.LabelHelp.TabIndex = 1
Me.LabelHelp.Text = "Help"
Me.LabelHelp.TextAlign = System.Drawing.ContentAlignment.MiddleCenter
'
'LabelResize
'
Me.LabelResize.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
Me.LabelResize.AutoSize = True
Me.LabelResize.BackColor = System.Drawing.Color.Transparent
Me.LabelResize.Font = New System.Drawing.Font("Marlett", 8.25!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(2, Byte))
Me.LabelResize.Location = New System.Drawing.Point(272, 138)
Me.LabelResize.Name = "LabelResize"
Me.LabelResize.Size = New System.Drawing.Size(16, 14)
Me.LabelResize.TabIndex = 2
Me.LabelResize.Text = "o"
'
'MainForm
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(288, 152)
Me.Controls.Add(Me.LabelResize)
Me.Controls.Add(Me.LabelHelp)
Me.Controls.Add(Me.LabelFile)
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None
Me.Name = "MainForm"
Me.Text = "Shaped Form Example"
Me.ResumeLayout(False)
End Sub
#End Region
Private ReadOnly Property TitleBar() As Region
Get
Return New Region(New Rectangle(0, 0, Width, 26))
End Get
End Property
Private ReadOnly Property CloseButton() As GraphicsPath
Get
Dim gp As New GraphicsPath
gp.AddEllipse(New Rectangle(Width - 26, 3, 18, 18))
Return gp
End Get
End Property
Private ReadOnly Property MinButton() As GraphicsPath
Get
Dim gp As New GraphicsPath
gp.AddEllipse(New Rectangle(Width - 49, 3, 18, 18))
Return gp
End Get
End Property
Private ReadOnly Property FormShape() As GraphicsPath
Get
Dim gp As GraphicsPath = New GraphicsPath
Dim r As Rectangle = ClientRectangle
Dim radius As Int32 = 12
gp.AddArc(r.Left, r.Top + 24, radius, radius, 180, 90)
gp.AddArc(r.Left + 80 - radius, r.Top + 24 - radius, radius, radius, -270, -90)
gp.AddArc(r.Left + 80, r.Top, radius, radius, 180, 90)
gp.AddArc(r.Right - radius, r.Top, radius, radius, 270, 90)
gp.AddArc(r.Right - radius, r.Bottom - radius, radius, radius, 0, 90)
gp.AddArc(r.Left, r.Bottom - radius, radius, radius, 90, 90)
gp.CloseFigure()
Return gp
End Get
End Property
Private ClosePress As Boolean = False
Private MinPress As Boolean = False
Private FormDrag As Boolean = False
Private FileActive As Boolean = False
Private HelpActive As Boolean = False
Private FileHot As Boolean = False
Private HelpHot As Boolean = False
Private Const WM_NCLBUTTONDOWN As Integer = &HA1
Private Const HT_CAPTION As Integer = &H2
Protected Overrides ReadOnly Property CreateParams() As System.Windows.Forms.CreateParams
Get
Dim cp As CreateParams = MyBase.CreateParams
Const WS_CLIPCHILDREN As Integer = &H2000000
Const WS_MINIMIZEBOX As Integer = &H20000
'Const WS_MAXIMIZEBOX As Integer = &H10000
Const WS_SYSMENU As Integer = &H80000
Const CS_DBLCLKS As Integer = &H8
Const CS_DROPSHADOW As Integer = &H20000
Dim ClassFlags As Integer = CS_DBLCLKS
Dim OSVER As Integer = Environment.OSVersion.Version.Major * 10
OSVER += Environment.OSVersion.Version.Minor
If OSVER >= 51 Then ClassFlags = CS_DBLCLKS Or CS_DROPSHADOW
cp.Style = WS_CLIPCHILDREN Or WS_MINIMIZEBOX Or WS_SYSMENU 'Or WS_MAXIMIZEBOX
cp.ClassStyle = ClassFlags
Return cp
End Get
End Property
Private Sub MainForm_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.LabelFile.Location = New Point(2, 26)
Me.LabelHelp.Location = New Point(LabelFile.Right, 26)
Me.LabelFile.Font = SystemInformation.MenuFont
Me.LabelHelp.Font = SystemInformation.MenuFont
Me.Region = New Region(FormShape)
End Sub
Private Sub MainForm_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
e.Graphics.FillRegion(Brushes.Green, TitleBar)
e.Graphics.FillRectangle(SystemBrushes.Menu, New Rectangle(0, 26, Width, 19))
If FileHot Then e.Graphics.FillRectangle(SystemBrushes.Highlight, LabelFile.Bounds)
If HelpHot Then e.Graphics.FillRectangle(SystemBrushes.Highlight, LabelHelp.Bounds)
Dim BorderPen As New Pen(Color.Green, 2)
BorderPen.Alignment = PenAlignment.Inset
e.Graphics.DrawPath(BorderPen, FormShape)
BorderPen.Dispose()
e.Graphics.SmoothingMode = SmoothingMode.HighQuality
Dim sf As New StringFormat(StringFormatFlags.NoWrap)
sf.Trimming = StringTrimming.EllipsisCharacter
sf.Alignment = StringAlignment.Center
sf.LineAlignment = StringAlignment.Center
e.Graphics.DrawString(Me.Text, Control.DefaultFont, Brushes.White, RectangleF.FromLTRB(84, 0, MinButton.GetBounds.X, 24), sf)
If ClosePress Then
e.Graphics.FillPath(Brushes.Blue, CloseButton)
Else
e.Graphics.FillPath(Brushes.Red, CloseButton)
End If
If MinPress Then
e.Graphics.FillPath(Brushes.Red, MinButton)
Else
e.Graphics.FillPath(Brushes.Yellow, MinButton)
End If
Dim GlyphFont As New Font("marlett", Font.SizeInPoints, FontStyle.Bold, GraphicsUnit.Point)
e.Graphics.DrawString("0", GlyphFont, Brushes.Black, MinButton.GetBounds, sf)
e.Graphics.DrawString("r", GlyphFont, Brushes.Black, CloseButton.GetBounds, sf)
GlyphFont.Dispose()
End Sub
Private Sub MainForm_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseDown
ClosePress = CloseButton.IsVisible(e.X, e.Y) AndAlso e.Button = MouseButtons.Left
MinPress = MinButton.IsVisible(e.X, e.Y) AndAlso e.Button = MouseButtons.Left
FormDrag = TitleBar.IsVisible(e.X, e.Y) AndAlso _
e.Button = MouseButtons.Left AndAlso _
ClosePress = False AndAlso MinPress = False
If FormDrag Then
Me.Capture = False
WndProc(Message.Create(Handle, WM_NCLBUTTONDOWN, IntPtr.op_Explicit(HT_CAPTION), IntPtr.Zero))
End If
Invalidate()
End Sub
Private Sub MainForm_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseMove
Dim OverClose, OverMin As Boolean
OverClose = CloseButton.IsVisible(e.X, e.Y)
OverMin = MinButton.IsVisible(e.X, e.Y)
ClosePress = OverClose AndAlso e.Button = MouseButtons.Left
MinPress = OverMin AndAlso e.Button = MouseButtons.Left
If OverClose AndAlso ClosePress = False Then
ToolTip1.SetToolTip(Me, "Close")
ElseIf OverMin AndAlso MinPress = False Then
ToolTip1.SetToolTip(Me, "Minimize")
Else
ToolTip1.SetToolTip(Me, "")
End If
Invalidate()
End Sub
Private Sub MainForm_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseUp
Dim OverClose, OverMin As Boolean
OverClose = CloseButton.IsVisible(e.X, e.Y)
OverMin = MinButton.IsVisible(e.X, e.Y)
If OverClose AndAlso ClosePress AndAlso e.Button = MouseButtons.Left Then
Me.Close()
End If
If OverMin AndAlso MinPress AndAlso e.Button = MouseButtons.Left Then
Me.WindowState = FormWindowState.Minimized
End If
If e.Button = MouseButtons.Right AndAlso TitleBar.IsVisible(e.X, e.Y) Then
If OverClose = False AndAlso OverMin = False Then
Const WM_GETSYSMENU As Integer = &H313
If e.Button = MouseButtons.Right Then
Dim pos As Point = Me.PointToScreen(New Point(e.X, e.Y))
Dim hPos As IntPtr = IntPtr.op_Explicit(CInt((pos.Y * &H10000) Or (pos.X And &HFFFF&)))
WndProc(Message.Create(Handle, WM_GETSYSMENU, IntPtr.Zero, hPos))
End If
End If
End If
ClosePress = False
MinPress = False
FormDrag = False
Invalidate()
End Sub
Private Sub MenuAbout_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles MenuAbout.Click
MessageBox.Show("Shaped Form Example!" & vbCrLf & "By Mick Doherty (http://dotnetrix.co.uk)", "About...", MessageBoxButtons.OK)
End Sub
Private Sub MenuExit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuExit.Click
Application.Exit()
End Sub
Private Sub LabelHelp_MouseEnter(ByVal sender As Object, ByVal e As System.EventArgs) Handles LabelHelp.MouseEnter
HelpHot = True
LabelHelp.ForeColor = SystemColors.HighlightText
Invalidate()
End Sub
Private Sub LabelHelp_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles LabelHelp.MouseUp
HelpActive = True
ContextMenu2.Show(LabelHelp, New Point(0, LabelHelp.Height))
HelpActive = False
LabelHelp.ForeColor = SystemColors.MenuText
Invalidate()
End Sub
Private Sub LabelHelp_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles LabelHelp.MouseLeave
If HelpActive = False Then
HelpHot = False
LabelHelp.ForeColor = SystemColors.MenuText
End If
Invalidate()
End Sub
Private Sub LabelFile_MouseEnter(ByVal sender As Object, ByVal e As System.EventArgs) Handles LabelFile.MouseEnter
FileHot = True
LabelFile.ForeColor = SystemColors.HighlightText
Invalidate()
End Sub
Private Sub LabelFile_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles LabelFile.MouseUp
FileActive = True
ContextMenu1.Show(LabelFile, New Point(0, LabelFile.Height))
FileActive = False
LabelFile.ForeColor = SystemColors.MenuText
Invalidate()
End Sub
Private Sub LabelFile_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles LabelFile.MouseLeave
If FileActive = False Then
FileHot = False
LabelFile.ForeColor = SystemColors.MenuText
End If
Invalidate()
End Sub
Private Sizing As Boolean = False
Private SizeOffset As Point = Point.Empty
Private Sub LabelResize_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles LabelResize.MouseDown
Sizing = True
SizeOffset = New Point(Me.Right - Cursor.Position.X, Me.Bottom - Cursor.Position.Y)
End Sub
Private Sub LabelResize_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles LabelResize.MouseMove
If Sizing = True Then
'Clip cursor to dissallow sizing of form below 250x100
Dim ClipRectangle As Rectangle = RectangleToScreen(New Rectangle(250, 100, Width, Height))
ClipRectangle.Offset(SizeOffset)
Cursor.Clip = ClipRectangle
Me.Size = New Size(Cursor.Position.X + SizeOffset.X - Location.X, Cursor.Position.Y + SizeOffset.Y - Location.Y)
End If
End Sub
Private Sub LabelResize_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles LabelResize.MouseUp
Sizing = False
Cursor.Clip = Nothing
End Sub
Private Sub MainForm_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Resize
Me.Region = New Region(FormShape)
End Sub
End Class
CSharp Sample:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Drawing.Drawing2D;
namespace ShapedForm
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class MainForm : System.Windows.Forms.Form
{
private System.ComponentModel.IContainer components;
public MainForm()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
this.SetStyle(ControlStyles.AllPaintingInWmPaint| ControlStyles.DoubleBuffer|ControlStyles.UserPaint|ControlStyles.ResizeRedraw,true);
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (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()
{
this.components = new System.ComponentModel.Container();
this.labelFile = new System.Windows.Forms.Label();
this.labelHelp = new System.Windows.Forms.Label();
this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
this.contextMenu1 = new System.Windows.Forms.ContextMenu();
this.menuItem1 = new System.Windows.Forms.MenuItem();
this.menuItem2 = new System.Windows.Forms.MenuItem();
this.menuExit = new System.Windows.Forms.MenuItem();
this.contextMenu2 = new System.Windows.Forms.ContextMenu();
this.menuAbout = new System.Windows.Forms.MenuItem();
this.labelResize = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// labelFile
//
this.labelFile.BackColor = System.Drawing.Color.Transparent;
this.labelFile.ForeColor = System.Drawing.SystemColors.MenuText;
this.labelFile.Location = new System.Drawing.Point(8, 24);
this.labelFile.Name = "labelFile";
this.labelFile.Size = new System.Drawing.Size(32, 19);
this.labelFile.TabIndex = 0;
this.labelFile.Text = "File";
this.labelFile.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
this.labelFile.MouseEnter += new System.EventHandler(this.labelFile_MouseEnter);
this.labelFile.MouseUp += new System.Windows.Forms.MouseEventHandler(this.labelFile_MouseUp);
this.labelFile.MouseLeave += new System.EventHandler(this.labelFile_MouseLeave);
//
// labelHelp
//
this.labelHelp.BackColor = System.Drawing.Color.Transparent;
this.labelHelp.ForeColor = System.Drawing.SystemColors.MenuText;
this.labelHelp.Location = new System.Drawing.Point(64, 24);
this.labelHelp.Name = "labelHelp";
this.labelHelp.Size = new System.Drawing.Size(32, 19);
this.labelHelp.TabIndex = 1;
this.labelHelp.Text = "Help";
this.labelHelp.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
this.labelHelp.MouseEnter += new System.EventHandler(this.labelHelp_MouseEnter);
this.labelHelp.MouseUp += new System.Windows.Forms.MouseEventHandler(this.labelHelp_MouseUp);
this.labelHelp.MouseLeave += new System.EventHandler(this.labelHelp_MouseLeave);
//
// contextMenu1
//
this.contextMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.menuItem1,
this.menuItem2,
this.menuExit});
//
// menuItem1
//
this.menuItem1.Index = 0;
this.menuItem1.Text = "menuItem1";
//
// menuItem2
//
this.menuItem2.Index = 1;
this.menuItem2.Text = "-";
//
// menuExit
//
this.menuExit.Index = 2;
this.menuExit.Text = "Exit";
this.menuExit.Click += new System.EventHandler(this.menuExit_Click);
//
// contextMenu2
//
this.contextMenu2.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.menuAbout});
//
// menuAbout
//
this.menuAbout.Index = 0;
this.menuAbout.Text = "About";
this.menuAbout.Click += new System.EventHandler(this.menuAbout_Click);
//
// labelResize
//
this.labelResize.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.labelResize.AutoSize = true;
this.labelResize.BackColor = System.Drawing.Color.Transparent;
this.labelResize.Font = new System.Drawing.Font("Marlett", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(2)));
this.labelResize.Location = new System.Drawing.Point(272, 138);
this.labelResize.Name = "labelResize";
this.labelResize.Size = new System.Drawing.Size(16, 14);
this.labelResize.TabIndex = 2;
this.labelResize.Text = "o";
this.labelResize.MouseUp += new System.Windows.Forms.MouseEventHandler(this.labelResize_MouseUp);
this.labelResize.MouseMove += new System.Windows.Forms.MouseEventHandler(this.labelResize_MouseMove);
this.labelResize.MouseDown += new System.Windows.Forms.MouseEventHandler(this.labelResize_MouseDown);
//
// MainForm
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(288, 152);
this.Controls.Add(this.labelResize);
this.Controls.Add(this.labelHelp);
this.Controls.Add(this.labelFile);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Name = "Form1";
this.Text = "Shaped Form Example";
this.Resize += new System.EventHandler(this.MainForm_Resize);
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Form1_MouseDown);
this.Load += new System.EventHandler(this.Form1_Load);
this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.Form1_MouseUp);
this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form1_Paint);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.Form1_MouseMove);
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new MainForm());
}
private Region TitleBar
{
get{return new Region(new Rectangle(0, 0, Width, 26));}
}
private GraphicsPath CloseButton
{
get
{
GraphicsPath gp = new GraphicsPath();
gp.AddEllipse(new Rectangle(Width - 26, 3, 18, 18));
return gp;
}
}
private GraphicsPath MinButton
{
get
{
GraphicsPath gp = new GraphicsPath();
gp.AddEllipse(new Rectangle(Width - 49, 3, 18, 18));
return gp;
}
}
private GraphicsPath FormShape
{
get
{
GraphicsPath gp = new GraphicsPath();
Rectangle r = ClientRectangle;
int radius = 12;
gp.AddArc(r.Left, r.Top + 24, radius, radius, 180, 90);
gp.AddArc(r.Left + 80 - radius, r.Top + 24 - radius, radius, radius, -270, -90);
gp.AddArc(r.Left + 80, r.Top, radius, radius, 180, 90);
gp.AddArc(r.Right - radius, r.Top, radius, radius, 270, 90);
gp.AddArc(r.Right - radius, r.Bottom - radius, radius, radius, 0, 90);
gp.AddArc(r.Left, r.Bottom - radius, radius, radius, 90, 90);
gp.CloseFigure();
return gp;
}
}
private bool ClosePress = false;
private bool MinPress = false;
private bool FormDrag = false;
private bool FileActive = false;
private bool HelpActive = false;
private bool FileHot = false;
private bool HelpHot = false;
private const int WM_NCLBUTTONDOWN = 0xA1;
private System.Windows.Forms.Label labelFile;
private System.Windows.Forms.Label labelHelp;
private System.Windows.Forms.ToolTip toolTip1;
private System.Windows.Forms.ContextMenu contextMenu1;
private System.Windows.Forms.ContextMenu contextMenu2;
private System.Windows.Forms.MenuItem menuItem1;
private System.Windows.Forms.MenuItem menuItem2;
private System.Windows.Forms.MenuItem menuAbout;
private System.Windows.Forms.MenuItem menuExit;
private System.Windows.Forms.Label labelResize;
private const int HT_CAPTION = 0x2;
protected override System.Windows.Forms.CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
const int WS_CLIPCHILDREN = 0x2000000;
const int WS_MINIMIZEBOX = 0x20000;
//const int WS_MAXIMIZEBOX = 0x10000;
const int WS_SYSMENU = 0x80000;
const int CS_DBLCLKS = 0x8;
const int CS_DROPSHADOW = 0x20000;
int ClassFlags = CS_DBLCLKS;
int OSVER = Environment.OSVersion.Version.Major * 10;
OSVER += Environment.OSVersion.Version.Minor;
if (OSVER >= 51) ClassFlags = CS_DBLCLKS | CS_DROPSHADOW;
cp.Style = WS_CLIPCHILDREN | WS_MINIMIZEBOX | WS_SYSMENU; //| WS_MAXIMIZEBOX
cp.ClassStyle = ClassFlags;
return cp;
}
}
private void Form1_Load(object sender, System.EventArgs e)
{
this.labelFile.Location = new Point(2, 26);
this.labelHelp.Location = new Point(labelFile.Right, 26);
this.labelFile.Font = SystemInformation.MenuFont;
this.labelHelp.Font = SystemInformation.MenuFont;
this.Region = new Region(FormShape);
}
private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
e.Graphics.FillRegion(Brushes.Green, TitleBar);
e.Graphics.FillRectangle(SystemBrushes.Menu, new Rectangle(0, 26, Width, 19));
if (FileHot) e.Graphics.FillRectangle(SystemBrushes.Highlight, labelFile.Bounds);
if (HelpHot) e.Graphics.FillRectangle(SystemBrushes.Highlight, labelHelp.Bounds);
Pen BorderPen = new Pen(Color.Green, 2);
BorderPen.Alignment = PenAlignment.Inset;
e.Graphics.DrawPath(BorderPen, FormShape);
BorderPen.Dispose();
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
StringFormat sf= new StringFormat(StringFormatFlags.NoWrap);
sf.Trimming = StringTrimming.EllipsisCharacter;
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
e.Graphics.DrawString(this.Text, Control.DefaultFont, Brushes.White, RectangleF.FromLTRB(84, 0, MinButton.GetBounds().X, 24), sf);
if (ClosePress)
e.Graphics.FillPath(Brushes.Blue, CloseButton);
else
e.Graphics.FillPath(Brushes.Red, CloseButton);
if (MinPress)
e.Graphics.FillPath(Brushes.Red, MinButton);
else
e.Graphics.FillPath(Brushes.Yellow, MinButton);
Font GlyphFont = new Font("marlett", Font.SizeInPoints, FontStyle.Bold, GraphicsUnit.Point);
e.Graphics.DrawString("0", GlyphFont, Brushes.Black, MinButton.GetBounds(), sf);
e.Graphics.DrawString("r", GlyphFont, Brushes.Black, CloseButton.GetBounds(), sf);
GlyphFont.Dispose();
}
private void Form1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
ClosePress = CloseButton.IsVisible(e.X, e.Y) && e.Button == MouseButtons.Left;
MinPress = MinButton.IsVisible(e.X, e.Y) && e.Button == MouseButtons.Left;
FormDrag = TitleBar.IsVisible(e.X, e.Y) &&
e.Button == MouseButtons.Left &&
ClosePress == false && MinPress == false;
if (FormDrag)
{
this.Capture = false;
Message msg = Message.Create(Handle, WM_NCLBUTTONDOWN, (IntPtr)HT_CAPTION, IntPtr.Zero);
WndProc(ref msg);
}
Invalidate();
}
private void Form1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
bool OverClose, OverMin;
OverClose = CloseButton.IsVisible(e.X, e.Y);
OverMin = MinButton.IsVisible(e.X, e.Y);
ClosePress = OverClose && e.Button == MouseButtons.Left;
MinPress = OverMin && e.Button == MouseButtons.Left;
if (OverClose && ClosePress == false)
toolTip1.SetToolTip(this, "Close");
else if (OverMin && MinPress == false)
toolTip1.SetToolTip(this, "Minimize");
else
toolTip1.SetToolTip(this, "");
Invalidate();
}
private void Form1_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
bool OverClose, OverMin;
OverClose = CloseButton.IsVisible(e.X, e.Y);
OverMin = MinButton.IsVisible(e.X, e.Y);
if (OverClose && ClosePress && e.Button == MouseButtons.Left)
this.Close();
if (OverMin && MinPress && e.Button == MouseButtons.Left)
this.WindowState = FormWindowState.Minimized;
if (e.Button == MouseButtons.Right && TitleBar.IsVisible(e.X, e.Y))
{
if (OverClose == false && OverMin == false)
{
const int WM_GETSYSMENU = 0x313;
if (e.Button == MouseButtons.Right)
{
Point pos = this.PointToScreen(new Point(e.X, e.Y));
IntPtr hPos = (IntPtr)((int)((pos.Y * 0x10000) | (pos.X & 0xFFFF)));
Message msg = Message.Create(this.Handle, WM_GETSYSMENU, IntPtr.Zero, hPos);
WndProc(ref msg);
}
}
}
ClosePress = false;
MinPress = false;
FormDrag = false;
Invalidate();
}
private void menuAbout_Click(object sender, System.EventArgs e)
{
MessageBox.Show("Shaped Form Example!\nBy Mick Doherty (http://dotnetrix.co.uk)", "About...", MessageBoxButtons.OK);
}
private void menuExit_Click(object sender, System.EventArgs e)
{
Application.Exit();
}
private void labelHelp_MouseEnter(object sender, System.EventArgs e)
{
HelpHot = true;
labelHelp.ForeColor = SystemColors.HighlightText;
Invalidate();
}
private void labelHelp_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
HelpActive = true;
contextMenu2.Show(labelHelp, new Point(0, labelHelp.Height));
HelpActive = false;
labelHelp.ForeColor = SystemColors.MenuText;
Invalidate();
}
private void labelHelp_MouseLeave(object sender, System.EventArgs e)
{
if (HelpActive == false)
{
HelpHot = false;
labelHelp.ForeColor = SystemColors.MenuText;
}
Invalidate();
}
private void labelFile_MouseEnter(object sender, System.EventArgs e)
{
FileHot = true;
labelFile.ForeColor = SystemColors.HighlightText;
Invalidate();
}
private void labelFile_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
FileActive = true;
contextMenu1.Show(labelFile, new Point(0, labelFile.Height));
FileActive = false;
labelFile.ForeColor = SystemColors.MenuText;
Invalidate();
}
private void labelFile_MouseLeave(object sender, System.EventArgs e)
{
if (FileActive == false)
{
FileHot = false;
labelFile.ForeColor = SystemColors.MenuText;
}
Invalidate();
}
private bool Sizing = false;
private Point SizeOffset = Point.Empty;
private void labelResize_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
Sizing = true;
SizeOffset = new Point(this.Right - Cursor.Position.X, this.Bottom - Cursor.Position.Y);
}
private void labelResize_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (Sizing)
{
//Clip cursor to dissallow sizing of form below 250x100
Rectangle ClipRectangle = RectangleToScreen(new Rectangle(250, 100, Width, Height));
ClipRectangle.Offset(SizeOffset);
Cursor.Clip = ClipRectangle;
this.Size = new Size(Cursor.Position.X + SizeOffset.X - Location.X, Cursor.Position.Y + SizeOffset.Y - Location.Y);
}
}
private void labelResize_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
Sizing = false;
Cursor.Clip = Rectangle.Empty;
}
private void MainForm_Resize(object sender, System.EventArgs e)
{
this.Region=new Region(FormShape);
}
}
}
by: Mick Dohertys'













1 comments:
Hello
This is a very good solution for shaped form! Much more better than if we use the 'transparency key'. With that the form cannot visible with screenshot tools on XP.
Thank you for the code.
Post a Comment