Answered by:
Customize Titlebar
Question
-
I want to remove title bar and replace it with custom title Bar that:
- I can put custom controls(like text,label,button,...) to it
- No change in Os Style
- Not remove control box
- The form must be sizable
Is this possible?
thanks
Monday, January 19, 2015 6:39 AM
Answers
-
Hello,
Check this Code Project article for one method of doing buttons in the title bar.
Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem.
- Marked as answer by vb2015 Tuesday, January 20, 2015 2:50 PM
Tuesday, January 20, 2015 11:54 AM -
Hi birjand,
In addition to Aggelos gkoutis's reply, when you set the formBorderStyle property to none, the form will be not sizable with mouse.
You could override the WndProc() method to make the form sizable when formBorderStyle is none.
Private Const cGrip As Integer = 16 ' Grip size Private Const cCaption As Integer = 32 ' Caption bar height; Protected Overrides Sub WndProc(ByRef m As Message) If m.Msg = &H84 Then ' Trap WM_NCHITTEST Dim pos As New Point(m.LParam.ToInt32() And &HFFFF, m.LParam.ToInt32() >> 16) pos = Me.PointToClient(pos) If pos.Y < cCaption Then m.Result = IntPtr.op_Explicit(2) ' HTCAPTION Return End If If pos.X >= Me.ClientSize.Width - cGrip AndAlso pos.Y >= Me.ClientSize.Height - cGrip Then m.Result = IntPtr.op_Explicit(17) ' HTBOTTOMRIGHT Return End If End If MyBase.WndProc(m) End SubIf you have any other concern regarding this issue, please feel free to let me know.
Best regards,
Youjun Tang
We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
Click HERE to participate the survey.This works great! I also used Agg's button. Now all it needs is Monkey's glass.
Public Class Form6 Private WithEvents button1 As New Button With {.Parent = Me, .Width = 32, .Text = "X", .BackColor = Color.White, .ForeColor = Color.Red} Private flagbmp As New Bitmap("c:\bitmaps\us flag2.jpg") Private Sub Form6_Load(sender As Object, e As EventArgs) Handles MyBase.Load Me.FormBorderStyle = Windows.Forms.FormBorderStyle.None Me.BackColor = Color.Teal Me.DoubleBuffered = True AddHandler Button1.Click, AddressOf CloseForm End Sub Private Const cGrip As Integer = 16 ' Grip size Private Const cCaption As Integer = 32 ' Caption bar height; Protected Overrides Sub WndProc(ByRef m As Message) If m.Msg = &H84 Then ' Trap WM_NCHITTEST Dim pos As New Point(m.LParam.ToInt32() And &HFFFF, m.LParam.ToInt32() >> 16) pos = Me.PointToClient(pos) If pos.Y < cCaption Then m.Result = IntPtr.op_Explicit(2) ' HTCAPTION Return End If If pos.X >= Me.ClientSize.Width - cGrip AndAlso pos.Y >= Me.ClientSize.Height - cGrip Then m.Result = IntPtr.op_Explicit(17) ' HTBOTTOMRIGHT Return End If End If MyBase.WndProc(m) End Sub Private Sub Form6_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint e.Graphics.DrawRectangle(New Pen(Brushes.SteelBlue, 6), Me.ClientRectangle) e.Graphics.DrawString("My Form", New Font("Tahoma", 14), Brushes.White, 100, 0) e.Graphics.DrawImage(flagbmp, 1, 1) End Sub Private Sub Form6_Resize(sender As Object, e As EventArgs) Handles Me.Resize button1.Left = Me.ClientSize.Width - button1.Width Me.Refresh() End Sub Private Sub CloseForm() Me.Close() End Sub End Class
- Edited by tommytwotrain Tuesday, January 20, 2015 2:17 PM
- Marked as answer by vb2015 Tuesday, January 20, 2015 3:04 PM
Tuesday, January 20, 2015 2:15 PM
All replies
-
Hello, I think this is possible if you set the formBoarderStyle properties to none and set your custom items on top of the form, like close button.
You will need to add handlers on load of the form.
Example for the close button :
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
AddHandler Button1.Click, AddressOf CloseForm
End SubPrivate Sub CloseForm()
Me.Close()
End Sub- Edited by Aggelos gkoutis Monday, January 19, 2015 7:02 AM
- Proposed as answer by Youjun Tang Tuesday, January 20, 2015 3:10 AM
Monday, January 19, 2015 7:01 AM -
Hi birjand,
In addition to Aggelos gkoutis's reply, when you set the formBorderStyle property to none, the form will be not sizable with mouse.
You could override the WndProc() method to make the form sizable when formBorderStyle is none.
Private Const cGrip As Integer = 16 ' Grip size Private Const cCaption As Integer = 32 ' Caption bar height; Protected Overrides Sub WndProc(ByRef m As Message) If m.Msg = &H84 Then ' Trap WM_NCHITTEST Dim pos As New Point(m.LParam.ToInt32() And &HFFFF, m.LParam.ToInt32() >> 16) pos = Me.PointToClient(pos) If pos.Y < cCaption Then m.Result = IntPtr.op_Explicit(2) ' HTCAPTION Return End If If pos.X >= Me.ClientSize.Width - cGrip AndAlso pos.Y >= Me.ClientSize.Height - cGrip Then m.Result = IntPtr.op_Explicit(17) ' HTBOTTOMRIGHT Return End If End If MyBase.WndProc(m) End SubIf you have any other concern regarding this issue, please feel free to let me know.
Best regards,
Youjun Tang
We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
Click HERE to participate the survey.- Proposed as answer by tommytwotrain Tuesday, January 20, 2015 2:15 PM
Tuesday, January 20, 2015 3:16 AM -
I want to remove title bar and replace it with custom title Bar that:
- I can put custom controls(like text,label,button,...) to it
- No change in Os Style
- Not remove control box
- The form must be sizable
Is this possible?
thanks
Yes. If you know what to do.
La vida loca
Tuesday, January 20, 2015 6:46 AM -
Hi birjand,
In addition to Aggelos gkoutis's reply, when you set the formBorderStyle property to none, the form will be not sizable with mouse.
You could override the WndProc() method to make the form sizable when formBorderStyle is none.
Private Const cGrip As Integer = 16 ' Grip size Private Const cCaption As Integer = 32 ' Caption bar height; Protected Overrides Sub WndProc(ByRef m As Message) If m.Msg = &H84 Then ' Trap WM_NCHITTEST Dim pos As New Point(m.LParam.ToInt32() And &HFFFF, m.LParam.ToInt32() >> 16) pos = Me.PointToClient(pos) If pos.Y < cCaption Then m.Result = IntPtr.op_Explicit(2) ' HTCAPTION Return End If If pos.X >= Me.ClientSize.Width - cGrip AndAlso pos.Y >= Me.ClientSize.Height - cGrip Then m.Result = IntPtr.op_Explicit(17) ' HTBOTTOMRIGHT Return End If End If MyBase.WndProc(m) End SubIf you have any other concern regarding this issue, please feel free to let me know.
Best regards,
Youjun Tang
We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
Click HERE to participate the survey.Ok
But Where I can run this command?
Into sub form_Load???
sub form_load()
WndProc(m=???)
End Sub
Tuesday, January 20, 2015 9:33 AM -
I want to remove title bar and replace it with custom title Bar that:
- I can put custom controls(like text,label,button,...) to it
- No change in Os Style
- Not remove control box
- The form must be sizable
Is this possible?
thanks
Yes. If you know what to do.
La vida loca
Thank you
I want to create a form exactly like this.
But How I can do this?
Tuesday, January 20, 2015 9:35 AM -
Hello,
Check this Code Project article for one method of doing buttons in the title bar.
Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem.
- Marked as answer by vb2015 Tuesday, January 20, 2015 2:50 PM
Tuesday, January 20, 2015 11:54 AM -
Hi birjand,
In addition to Aggelos gkoutis's reply, when you set the formBorderStyle property to none, the form will be not sizable with mouse.
You could override the WndProc() method to make the form sizable when formBorderStyle is none.
Private Const cGrip As Integer = 16 ' Grip size Private Const cCaption As Integer = 32 ' Caption bar height; Protected Overrides Sub WndProc(ByRef m As Message) If m.Msg = &H84 Then ' Trap WM_NCHITTEST Dim pos As New Point(m.LParam.ToInt32() And &HFFFF, m.LParam.ToInt32() >> 16) pos = Me.PointToClient(pos) If pos.Y < cCaption Then m.Result = IntPtr.op_Explicit(2) ' HTCAPTION Return End If If pos.X >= Me.ClientSize.Width - cGrip AndAlso pos.Y >= Me.ClientSize.Height - cGrip Then m.Result = IntPtr.op_Explicit(17) ' HTBOTTOMRIGHT Return End If End If MyBase.WndProc(m) End SubIf you have any other concern regarding this issue, please feel free to let me know.
Best regards,
Youjun Tang
We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
Click HERE to participate the survey.This works great! I also used Agg's button. Now all it needs is Monkey's glass.
Public Class Form6 Private WithEvents button1 As New Button With {.Parent = Me, .Width = 32, .Text = "X", .BackColor = Color.White, .ForeColor = Color.Red} Private flagbmp As New Bitmap("c:\bitmaps\us flag2.jpg") Private Sub Form6_Load(sender As Object, e As EventArgs) Handles MyBase.Load Me.FormBorderStyle = Windows.Forms.FormBorderStyle.None Me.BackColor = Color.Teal Me.DoubleBuffered = True AddHandler Button1.Click, AddressOf CloseForm End Sub Private Const cGrip As Integer = 16 ' Grip size Private Const cCaption As Integer = 32 ' Caption bar height; Protected Overrides Sub WndProc(ByRef m As Message) If m.Msg = &H84 Then ' Trap WM_NCHITTEST Dim pos As New Point(m.LParam.ToInt32() And &HFFFF, m.LParam.ToInt32() >> 16) pos = Me.PointToClient(pos) If pos.Y < cCaption Then m.Result = IntPtr.op_Explicit(2) ' HTCAPTION Return End If If pos.X >= Me.ClientSize.Width - cGrip AndAlso pos.Y >= Me.ClientSize.Height - cGrip Then m.Result = IntPtr.op_Explicit(17) ' HTBOTTOMRIGHT Return End If End If MyBase.WndProc(m) End Sub Private Sub Form6_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint e.Graphics.DrawRectangle(New Pen(Brushes.SteelBlue, 6), Me.ClientRectangle) e.Graphics.DrawString("My Form", New Font("Tahoma", 14), Brushes.White, 100, 0) e.Graphics.DrawImage(flagbmp, 1, 1) End Sub Private Sub Form6_Resize(sender As Object, e As EventArgs) Handles Me.Resize button1.Left = Me.ClientSize.Width - button1.Width Me.Refresh() End Sub Private Sub CloseForm() Me.Close() End Sub End Class
- Edited by tommytwotrain Tuesday, January 20, 2015 2:17 PM
- Marked as answer by vb2015 Tuesday, January 20, 2015 3:04 PM
Tuesday, January 20, 2015 2:15 PM -
Hi,
Here is another example. You can change the Titlebar color, border color, and the caption text color. You just need to change these lines to create the colors you want for everything.
Private ClientBrush As New SolidBrush(Color.WhiteSmoke) 'Color of client area Private CaptionColor As Color = Color.Green 'Color of the Caption area Private CaptionTextBrush As New SolidBrush(Color.White) 'Color of the Caption Text Private BorderPen As New Pen(Color.Black) 'Color of the BorderHere is the full code i have made so far. I did not get to the Icon, Minimize button, or Maximize button yet though. It is resizable too.
Imports System.Drawing.Drawing2D Public Class Form1 Private Const WM_LBUTTONDOWN As Integer = &H201 Private Const WM_NCHITTEST As Integer = &H84 Private Const HTCAPTION As Integer = &H2 Private Const HTLEFT As Integer = &HA Private Const HTRIGHT As Integer = &HB Private Const HTTOP As Integer = &HC Private Const HTBOTTOM As Integer = &HF Private Const HTBOTTOMLEFT As Integer = &H10 Private Const HTBOTTOMRIGHT As Integer = &H11 Private ClientBrush As New SolidBrush(Color.WhiteSmoke) 'Color of client area Private CaptionColor As Color = Color.Green 'Color of the Caption area Private CaptionTextBrush As New SolidBrush(Color.White) 'Color of the Caption Text Private BorderPen As New Pen(Color.Black) 'Color of the Border Private CloseBtnBounds As New Rectangle(Me.Width - SystemInformation.CaptionHeight, CInt(SystemInformation.CaptionHeight / 2) - CInt((SystemInformation.CaptionHeight - 8) / 2), SystemInformation.CaptionHeight - 8, SystemInformation.CaptionHeight - 8) Private bBlend As New Blend Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Me.DoubleBuffered = True Me.FormBorderStyle = Windows.Forms.FormBorderStyle.None Me.BackColor = Color.Lime Me.TransparencyKey = Color.Lime bBlend.Positions = New Single() {0.0F, 0.1F, 0.2F, 0.3F, 0.4F, 0.5F, 0.6F, 0.7F, 0.8F, 0.9F, 1.0F} End Sub Protected Overrides Sub OnFormClosing(ByVal e As System.Windows.Forms.FormClosingEventArgs) ClientBrush.Dispose() CaptionTextBrush.Dispose() BorderPen.Dispose() MyBase.OnFormClosing(e) End Sub Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) MyBase.OnPaint(e) Dim FrmBnds As Rectangle = New Rectangle(0, 0, Me.Width - 1, Me.Height - 1) Dim ClntBnds As New Rectangle(0, SystemInformation.CaptionHeight, Me.Width - 1, FrmBnds.Height) e.Graphics.FillRectangle(ClientBrush, ClntBnds) Using CapBrdrPath As New GraphicsPath CapBrdrPath.AddArc(FrmBnds.X, FrmBnds.Y, 14, 14, 180, 90) CapBrdrPath.AddArc(FrmBnds.Right - 14, FrmBnds.Y, 14, 14, 270, 90) CapBrdrPath.AddLine(FrmBnds.Width, SystemInformation.CaptionHeight, FrmBnds.X, SystemInformation.CaptionHeight) CapBrdrPath.CloseFigure() bBlend.Factors = New Single() {0.5F, 0.6F, 0.7F, 0.7F, 0.6F, 0.5F, 0.4F, 0.3F, 0.2F, 0.1F, 0.0F} Using capbrush As New LinearGradientBrush(Point.Empty, New Point(0, SystemInformation.CaptionHeight), CaptionColor, Color.White) capbrush.Blend = bBlend e.Graphics.FillPath(capbrush, CapBrdrPath) End Using CapBrdrPath.StartFigure() CapBrdrPath.AddLine(ClntBnds.X, ClntBnds.Y, ClntBnds.X, ClntBnds.Height) CapBrdrPath.AddLine(ClntBnds.Width, ClntBnds.Height, ClntBnds.Width, ClntBnds.Y) e.Graphics.DrawPath(BorderPen, CapBrdrPath) End Using Using fnt As New Font(Me.Font.FontFamily, Me.Font.Size + 2, FontStyle.Bold) Dim txtpnt As New Point(10, CInt(SystemInformation.CaptionHeight / 2) - CInt(fnt.GetHeight / 2)) e.Graphics.DrawString(Me.Text, fnt, CaptionTextBrush, txtpnt) End Using Using ClsBtnPath As New GraphicsPath Dim rad As Integer = 6 ClsBtnPath.AddArc(CloseBtnBounds.Right - rad, CloseBtnBounds.Y, rad, rad, 270, 90) ClsBtnPath.AddArc(CloseBtnBounds.Right - rad, CloseBtnBounds.Bottom - rad, rad, rad, 0, 90) ClsBtnPath.AddArc(CloseBtnBounds.X, CloseBtnBounds.Bottom - rad, rad, rad, 90, 90) ClsBtnPath.AddArc(CloseBtnBounds.X, CloseBtnBounds.Y, rad, rad, 180, 90) ClsBtnPath.CloseFigure() bBlend.Factors = New Single() {0.4F, 0.5F, 0.6F, 0.6F, 0.5F, 0.4F, 0.3F, 0.2F, 0.1F, 0.0F, 0.0F} Using cbbrush As New LinearGradientBrush(Point.Empty, New Point(0, SystemInformation.CaptionHeight), Color.Red, Color.White) cbbrush.Blend = bBlend e.Graphics.FillPath(cbbrush, ClsBtnPath) End Using e.Graphics.DrawPath(Pens.Black, ClsBtnPath) End Using Using xpen As New Pen(Color.White, 2) e.Graphics.DrawLine(xpen, CloseBtnBounds.X + 4, CloseBtnBounds.Y + 4, CloseBtnBounds.Right - 4, CloseBtnBounds.Bottom - 4) e.Graphics.DrawLine(xpen, CloseBtnBounds.Right - 4, CloseBtnBounds.Y + 4, CloseBtnBounds.X + 4, CloseBtnBounds.Bottom - 4) End Using End Sub Protected Overrides Sub OnResize(ByVal e As System.EventArgs) CloseBtnBounds = New Rectangle(Me.Width - SystemInformation.CaptionHeight, CInt(SystemInformation.CaptionHeight / 2) - CInt((SystemInformation.CaptionHeight - 8) / 2), SystemInformation.CaptionHeight - 8, SystemInformation.CaptionHeight - 8) MyBase.OnResize(e) End Sub Protected Overrides Sub WndProc(ByRef m As Message) If m.Msg = WM_LBUTTONDOWN Then If CloseBtnBounds.Contains(Me.PointToClient(MousePosition)) Then Me.Close() m.Result = CType(0, IntPtr) Return End If ElseIf m.Msg = WM_NCHITTEST Then Dim loc As Point = Me.PointToClient(MousePosition) Dim bTop As Boolean = (loc.Y < 4) Dim bLeft As Boolean = (loc.X < 4) Dim bRight As Boolean = (loc.X > Me.ClientSize.Width - 4) Dim bBottom As Boolean = (loc.Y > Me.ClientSize.Height - 4) Dim bCaption As Boolean = (loc.Y > 3 And loc.Y < SystemInformation.CaptionHeight And loc.X < Me.Width - 3) Dim bClose As Boolean = CloseBtnBounds.Contains(loc) If bCaption And Not bClose Then m.Result = CType(HTCAPTION, IntPtr) Return ElseIf bBottom And bLeft Then m.Result = CType(HTBOTTOMLEFT, IntPtr) Return ElseIf bBottom And bRight Then m.Result = CType(HTBOTTOMRIGHT, IntPtr) Return ElseIf bLeft Then m.Result = CType(HTLEFT, IntPtr) Return ElseIf bTop Then m.Result = CType(HTTOP, IntPtr) Return ElseIf bRight Then m.Result = CType(HTRIGHT, IntPtr) Return ElseIf bBottom Then m.Result = CType(HTBOTTOM, IntPtr) Return End If End If MyBase.WndProc(m) End Sub End ClassIn the image you can see on the left what the form looks like in the vb [Design] tab and on the right is the form when the app is running. You will notice it may take a little messing around to get your controls in the correct spot.
If you say it can`t be done then i`ll try it
- Edited by IronRazerz Tuesday, January 20, 2015 8:21 PM
Tuesday, January 20, 2015 7:57 PM -
Ahha! Now I see what you are doing. Using Razerz and Monkey methods I came up with this.
Imports System.Runtime.InteropServices Public Class Form7 Private WithEvents button1 As New Button With {.Parent = Me, .Width = 32, .Height = 24, .Top = 2, .Text = "X", .Font = New Font("Microsoft Sans Serif", 9, FontStyle.Bold), .ForeColor = Color.Firebrick, .BackColor = SystemColors.Control} Private WithEvents checkbox1 As New CheckBox With {.Parent = Me, .Width = 70, .Height = 18, .Left = 170, .Top = 4, .Text = "Glassy", .Font = New Font("Microsoft Sans Serif", 9, FontStyle.Bold), .BackColor = SystemColors.ActiveCaption} Private WithEvents checkbox2 As New CheckBox With {.Parent = Me, .Width = 100, .Height = 18, .Left = 170, .Top = 50, .Text = "CheckBox", .Font = New Font("Microsoft Sans Serif", 9, FontStyle.Bold), .BackColor = SystemColors.InactiveCaption} Private WithEvents groupbox1 As New GroupBox With {.Parent = Me, .Width = 130, .Height = 100, .Left = 10, .Top = 40, .Text = "GroupBox", .BackColor = SystemColors.InactiveCaption} Private WithEvents textbox1 As New TextBox With {.Parent = Me, .Width = 100, .Height = 24, .Left = 170, .Top = 80, .Text = "TextBox"} <StructLayout(LayoutKind.Sequential)> _ Public Structure MARGINS Public cxLeftWidth As Integer Public cxRightWidth As Integer Public cyTopHeight As Integer Public cyBottomHeight As Integer End Structure <DllImport("DwmApi.dll")> _ Public Shared Function DwmExtendFrameIntoClientArea(hwnd As IntPtr, ByRef pMarInset As MARGINS) As Integer End Function Private flagbmp As New Bitmap("c:\bitmaps\us flag2.jpg") Private MouseDownX, MouseDownY As Integer Private draggingEnabled As Boolean Private headerheight As Integer = 30 Private Sub Form7_Load(sender As Object, e As EventArgs) Handles MyBase.Load Me.Text = String.Empty Me.ControlBox = False Me.TransparencyKey = Color.Silver Me.DoubleBuffered = True End Sub Private Sub Form7_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint e.Graphics.FillRectangle(New SolidBrush(SystemColors.ActiveCaption), Me.ClientRectangle.Left + 1, Me.ClientRectangle.Top + 1, Me.ClientRectangle.Width - 2, headerheight - 4) e.Graphics.DrawString("My Form", New Font("Tacoma", 16), SystemBrushes.ActiveCaptionText, 50, 0) e.Graphics.DrawString("My Form", New Font("Tacoma", 16), Brushes.White, 51, 1) e.Graphics.DrawImage(flagbmp, 1, 1, CInt(1.3 * headerheight), headerheight - 4) End Sub Private Sub Form3_MouseDown(sender As Object, e As MouseEventArgs) Handles Me.MouseDown If e.Y < headerheight Then draggingEnabled = True MouseDownX = e.X MouseDownY = e.Y End If End Sub Private Sub Form3_MouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove If draggingEnabled Then Dim movePoint As Point = New Point(e.X, e.Y) movePoint = Me.PointToScreen(movePoint) Me.Left = movePoint.X - MouseDownX Me.Top = movePoint.Y - MouseDownY End If End Sub Private Sub Form3_MouseUp(sender As Object, e As MouseEventArgs) Handles Me.MouseUp draggingEnabled = False End Sub Private Sub Form7_Resize(sender As Object, e As EventArgs) Handles Me.Resize button1.Left = Me.ClientSize.Width - (button1.Width + 1) SetGlassEffect() Me.Refresh() End Sub Private Sub button1_Click(sender As Object, e As EventArgs) Handles button1.Click Me.Close() End Sub Private Sub checkbox1_CheckedChanged(sender As Object, e As EventArgs) Handles checkbox1.CheckedChanged SetGlassEffect() Me.Refresh() End Sub Private Sub SetGlassEffect() Dim BordersWidth As Integer = 3 Dim margins As New MARGINS() margins.cxLeftWidth = BordersWidth margins.cxRightWidth = BordersWidth margins.cyBottomHeight = BordersWidth If checkbox1.Checked Then margins.cyTopHeight = Me.ClientRectangle.Height Me.BackColor = Color.Silver Else margins.cyTopHeight = 0 Me.BackColor = SystemColors.Control End If DwmExtendFrameIntoClientArea(Me.Handle, margins) End Sub End Class
- Edited by tommytwotrain Wednesday, January 21, 2015 4:40 AM add glassy
Tuesday, January 20, 2015 10:10 PM -
Well, duh, this is easy. You can just turn off the form header in the IDE by setting the ControlBox False and Text to nothing. Then you can add controls as normal using the IDE. This has no code. The borders resize. But you would need to add dragging the form to move it.
Wednesday, January 21, 2015 5:03 AM -
Apparently from the posts above this one there's a variety of ways to do this.
Unfortunately controls in the glass area seem affected with regard to displayed text. So I drew the text in the Button and had to use a Double Buffered TextBox in order to draw text in it also. Other methods may be able to overcome those issues. But I didn't try any others. Also the TextBox class could probably have an overrides paint event within it rather than the TextBox having a paint event outside of the class for the TextBox.
The new ControlBox is just 3 buttons with no text. And their background images have transparent pixels in areas of the images so you can see through them. The minimize button has an image of a Ghost in it that doesn't look that great. It's white background was altered to transparent pixels using GIMP. As were the background colors of the crescent moon and full moon used in the normal/maximize button (normal = crescent and maximized = full) and the white in the crossbones image. You can see through those areas and therefore through the glass in those areas.
You could also set the alpha channel on a ControlBox buttons mouse hover or mouse down like Color.FromArgb(40, 255, 255, 0) which would be a semi transparent yellowish color.
Option Strict On Imports System.Runtime.InteropServices Public Class Form1 <StructLayout(LayoutKind.Sequential)> Public Structure MARGINS Public cxLeftWidth As Integer Public cxRightWidth As Integer Public cyTopHeight As Integer Public cyBottomHeight As Integer End Structure <DllImport("DwmApi.dll")> Public Shared Function DwmExtendFrameIntoClientArea(hwnd As IntPtr, ByRef pMarInset As MARGINS) As Integer End Function Dim TextBox1 As New DoubleBufferedTextBox Dim margins1 As New MARGINS() Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Me.Text = "" Me.ControlBox = False Me.FormBorderStyle = FormBorderStyle.SizableToolWindow Me.Location = New Point(CInt((Screen.PrimaryScreen.WorkingArea.Width / 2) - (Me.Width / 2)), CInt((Screen.PrimaryScreen.WorkingArea.Height / 2) - (Me.Height / 2))) Me.DoubleBuffered = True TextBox1.Left = Button1.Right + 30 TextBox1.Top = Button1.Top TextBox1.Text = "Custom Titlebar" TextBox1.Font = New Font("Book Antiqua", 11, FontStyle.Bold) TextBox1.Width = 150 AddHandler TextBox1.TextChanged, AddressOf TextBox1_TextChanged AddHandler TextBox1.Paint, AddressOf TextBox1_Paint Me.Controls.Add(TextBox1) Button2.Text = "" Button2.BackColor = Color.Transparent Button2.BackgroundImageLayout = ImageLayout.Stretch Button2.BackgroundImage = My.Resources.Ghost Button2.FlatStyle = FlatStyle.Flat Button2.FlatAppearance.BorderColor = Me.BackColor Button2.FlatAppearance.MouseDownBackColor = Color.Aqua Button2.FlatAppearance.MouseOverBackColor = Color.Yellow Button3.Text = "" Button3.BackColor = Color.Transparent Button3.BackgroundImageLayout = ImageLayout.Stretch Button3.BackgroundImage = My.Resources.Crescent2 Button3.FlatStyle = FlatStyle.Flat Button3.FlatAppearance.BorderColor = Me.BackColor Button3.FlatAppearance.MouseDownBackColor = Color.Gold Button3.FlatAppearance.MouseOverBackColor = Color.HotPink Button4.Text = "" Button4.BackColor = Color.Transparent Button4.BackgroundImageLayout = ImageLayout.Stretch Button4.BackgroundImage = My.Resources.Crossbones_Clear Button4.FlatStyle = FlatStyle.Flat Button4.FlatAppearance.BorderColor = Me.BackColor Button4.FlatAppearance.MouseDownBackColor = Color.Red Button4.FlatAppearance.MouseOverBackColor = Color.Lime Button3.Left = Button2.Right Button3.Top = Button2.Top Button4.Left = Button3.Right Button4.Top = Button3.Top Button2.Anchor = CType(AnchorStyles.Right + AnchorStyles.Top, AnchorStyles) Button3.Anchor = CType(AnchorStyles.Right + AnchorStyles.Top, AnchorStyles) Button4.Anchor = CType(AnchorStyles.Right + AnchorStyles.Top, AnchorStyles) Try margins1.cxLeftWidth = 0 margins1.cxRightWidth = 0 margins1.cyTopHeight = 36 margins1.cyBottomHeight = 0 If Environment.OSVersion.Version.Major >= 6 Then DwmExtendFrameIntoClientArea(Me.Handle, margins1) End If Catch ex As Exception End Try End Sub Private Sub Form1_Resize(sender As Object, e As EventArgs) Handles Me.Resize Button2.BringToFront() Button3.BringToFront() Button4.BringToFront() Me.Refresh() End Sub Dim MoveForm As Boolean = False Dim InitialX As Integer = 0 Dim InitialY As Integer = 0 Private Sub Form1_MouseDown(sender As Object, e As MouseEventArgs) Handles Me.MouseDown If e.Button = MouseButtons.Left Then Dim MoveArea As New Rectangle(Me.ClientRectangle.Top, Me.ClientRectangle.Left, Me.ClientRectangle.Width, 36) If MoveArea.Contains(e.Location) Then MoveForm = True InitialX = e.X InitialY = e.Y End If End If End Sub Private Sub Form1_MouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove If MoveForm = True Then Me.Location = New Point(Me.Left + e.X - InitialX, Me.Top + e.Y - InitialY) End If End Sub Private Sub Form1_Up(sender As Object, e As MouseEventArgs) Handles Me.MouseUp If MoveForm = True Then MoveForm = False End Sub Protected Overrides Sub OnPaintBackground(e As PaintEventArgs) MyBase.OnPaint(e) e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias e.Graphics.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAlias e.Graphics.Clear(Color.Transparent) Dim clientArea As New Rectangle(margins1.cxLeftWidth, margins1.cyTopHeight, Me.ClientRectangle.Width - margins1.cxLeftWidth - margins1.cxRightWidth, Me.ClientRectangle.Height - margins1.cyTopHeight - margins1.cyBottomHeight) Using b As Brush = New SolidBrush(Me.BackColor) e.Graphics.FillRectangle(b, clientArea) End Using e.Graphics.DrawString("Custom Form1", New Font("Book Antiqua", 12), Brushes.Black, 0, 4) End Sub Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click Me.WindowState = FormWindowState.Minimized End Sub Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click If Me.WindowState = FormWindowState.Maximized Then Button3.BackgroundImage = My.Resources.Crescent2 Me.WindowState = FormWindowState.Normal Else Button3.BackgroundImage = My.Resources.Moon2 Me.WindowState = FormWindowState.Maximized End If End Sub Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click Application.Exit() End Sub Private Sub Button1_Paint(sender As Object, e As PaintEventArgs) Handles Button1.Paint e.Graphics.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAlias Dim StrWidth As Integer = CInt(e.Graphics.MeasureString("Button1", New Font("Book Antiqua", 11)).Width / 2) e.Graphics.DrawString("Button1", New Font("Book Antiqua", 11), Brushes.Black, New Point(CInt((Button1.Width / 2) - StrWidth), 2)) End Sub Private Sub TextBox1_Paint(sender As Object, e As PaintEventArgs) e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias e.Graphics.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAlias e.Graphics.DrawString(TextBox1.Text, New Font("Book Antiqua", 11, FontStyle.Bold), Brushes.Black, 2, 2) End Sub Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) End Sub Public Class DoubleBufferedTextBox Inherits TextBox Public Sub New() Me.SetStyle(ControlStyles.OptimizedDoubleBuffer, True) Me.SetStyle(ControlStyles.UserPaint, True) Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True) End Sub End Class End Class
La vida loca
- Edited by Mr. Monkeyboy Wednesday, January 21, 2015 5:27 AM
Wednesday, January 21, 2015 5:11 AM -
Ha, ha, ha, Monkey. It took all day to figure out how you did it.Wednesday, January 21, 2015 5:19 AM
-
Ha, ha, ha, Monkey. It took all day to figure out how you did it.
:)
I'm sorry. I've been busy all day with other things and alot of yesterday too or I would've posted the code. But I had to figure out the issues with the controls displayed in the glass area. A DateTimePicker in it is really ugly!
La vida loca
Wednesday, January 21, 2015 5:29 AM -
Ha, ha, ha, Monkey. It took all day to figure out how you did it.
:)
I'm sorry. I've been busy all day with other things and alot of yesterday too or I would've posted the code. But I had to figure out the issues with the controls displayed in the glass area. A DateTimePicker in it is really ugly!
La vida loca
Oh, I meant I enjoyed it. The basic solution is so simple using the IDE just his me an hour ago. Adding the glass is something else. I first realized turn off the control and text looking at Razerz but was still in code.
Yes the glassy has some gotchas. Since its transparent you cant click it so dragging the header to move is more difficult. Any transparent control with text is a problem due to the background coming through.
Wednesday, January 21, 2015 5:39 AM -
Ha, ha, ha, Monkey. It took all day to figure out how you did it.
:)
I'm sorry. I've been busy all day with other things and alot of yesterday too or I would've posted the code. But I had to figure out the issues with the controls displayed in the glass area. A DateTimePicker in it is really ugly!
La vida loca
Oh, I meant I enjoyed it. The basic solution is so simple using the IDE just his me an hour ago. Adding the glass is something else. I first realized turn off the control and text looking at Razerz but was still in code.
Yes the glassy has some gotchas. Since its transparent you cant click it so dragging the header to move is more difficult. Any transparent control with text is a problem due to the background coming through.
Yeah the glass is something to work with regarding having controls in it.
I had some old code I modified for dragging the Form if the cursor is in the glass area but not the border area of the Form. It seems to work when the Form is resized also.
One thing I notice is when I set the Form to Maximized (at least when running it in Visual Studio 2015 preview) it fills the entire screen covering the TaskBar. I don't know why though. Perhaps because the Forms border style is tool window for all I know.
Dim MoveForm As Boolean = False Dim InitialX As Integer = 0 Dim InitialY As Integer = 0 Private Sub Form1_MouseDown(sender As Object, e As MouseEventArgs) Handles Me.MouseDown If e.Button = MouseButtons.Left Then Dim MoveArea As New Rectangle(Me.ClientRectangle.Top, Me.ClientRectangle.Left, Me.ClientRectangle.Width, 36) If MoveArea.Contains(e.Location) Then MoveForm = True InitialX = e.X InitialY = e.Y End If End If End Sub Private Sub Form1_MouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove If MoveForm = True Then Me.Location = New Point(Me.Left + e.X - InitialX, Me.Top + e.Y - InitialY) End If End Sub Private Sub Form1_Up(sender As Object, e As MouseEventArgs) Handles Me.MouseUp If MoveForm = True Then MoveForm = False End Sub
La vida loca
- Edited by Mr. Monkeyboy Wednesday, January 21, 2015 7:01 AM
Wednesday, January 21, 2015 7:00 AM -
Ha, ha, ha, Monkey. It took all day to figure out how you did it.
:)
I'm sorry. I've been busy all day with other things and alot of yesterday too or I would've posted the code. But I had to figure out the issues with the controls displayed in the glass area. A DateTimePicker in it is really ugly!
La vida loca
Oh, I meant I enjoyed it. The basic solution is so simple using the IDE just his me an hour ago. Adding the glass is something else. I first realized turn off the control and text looking at Razerz but was still in code.
Yes the glassy has some gotchas. Since its transparent you cant click it so dragging the header to move is more difficult. Any transparent control with text is a problem due to the background coming through.
Yeah the glass is something to work with regarding having controls in it.
I had some old code I modified for dragging the Form if the cursor is in the glass area but not the border area of the Form. It seems to work when the Form is resized also.
One thing I notice is when I set the Form to Maximized (at least when running it in Visual Studio 2015 preview) it fills the entire screen covering the TaskBar. I don't know why though. Perhaps because the Forms border style is tool window for all I know.
Dim MoveForm As Boolean = False Dim InitialX As Integer = 0 Dim InitialY As Integer = 0 Private Sub Form1_MouseDown(sender As Object, e As MouseEventArgs) Handles Me.MouseDown If e.Button = MouseButtons.Left Then Dim MoveArea As New Rectangle(Me.ClientRectangle.Top, Me.ClientRectangle.Left, Me.ClientRectangle.Width, 36) If MoveArea.Contains(e.Location) Then MoveForm = True InitialX = e.X InitialY = e.Y End If End If End Sub Private Sub Form1_MouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove If MoveForm = True Then Me.Location = New Point(Me.Left + e.X - InitialX, Me.Top + e.Y - InitialY) End If End Sub Private Sub Form1_Up(sender As Object, e As MouseEventArgs) Handles Me.MouseUp If MoveForm = True Then MoveForm = False End Sub
La vida loca
In my last example if you dont draw the header a different color then the mousedown event does not fire on the glass because of the transparancy. The glassy does not work without the transparancy. Does it work on yours? Im using 2013.
Wednesday, January 21, 2015 2:34 PM -
Hi,
Thanks for the code, it was just what I needed. Once I got that title bar customized, I realized that I need it to be in a separate class that I can call from each form. Is that possible? And if so, how would I go about accomplishing this? I've tried variations of the following code, but I all do is throw exceptions. Thank you
Public Class Form1
Protected Friend p As PaintEventArgsPrivate Sub FormLoad(sender As Object, e As EventArgs) Handles MyBase.Load
Public Class TitleBar
'Link to homemade CSS file
SetMenuFormStyle(Me)
Me.DoubleBuffered = True
Me.FormBorderStyle = Windows.Forms.FormBorderStyle.None
Me.TransparencyKey = Color.FromKnownColor(KnownColor.Control)
bBlend.Positions = New Single() {0.0F, 0.1F, 0.2F, 0.3F, 0.4F, 0.5F, 0.6F, 0.7F, 0.8F, 0.9F, 1.0F}
' MyBase.OnPaint(p)
Try
Using l As New TitleBar
Dim newName As Object = Me.Name
l.OnPaint(newName, e)
End Using
Catch ex As Exception
MessageBox.Show(ex.ToString, "From Form Load", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
End Class
Inherits Control
Private Const WM_LBUTTONDOWN As Integer = &H201
Private Const WM_NCHITTEST As Integer = &H84
Private Const HTCAPTION As Integer = &H2
Private Const HTLEFT As Integer = &HA
Private Const HTRIGHT As Integer = &HB
Private Const HTTOP As Integer = &HC
Private Const HTBOTTOM As Integer = &HF
Private Const HTBOTTOMLEFT As Integer = &H10
Private Const HTBOTTOMRIGHT As Integer = &H11
Private ReadOnly CaptionColor As Color = Color.FromArgb(31, 78, 121) 'Color of the Caption area
Private CaptionTextBrush As New SolidBrush(Color.White) ' 'Color of the Caption Text
Private ClientBrush As New SolidBrush(Color.WhiteSmoke) 'Color of client area
Private MinimizeBtnBounds As New Rectangle(Me.Width - SystemInformation.CaptionHeight, CInt(SystemInformation.CaptionHeight / 2) - CInt((SystemInformation.CaptionHeight - 8) / 2), SystemInformation.CaptionHeight - 8, SystemInformation.CaptionHeight - 8)
Private bBlend As New Blend
Public Sub OnPaint(sender As Object, ByVal e As PaintEventArgs)
'For TitleBar
Try
sender.OnPaint(e)
Catch ex As Exception
MessageBox.Show(ex.ToString, "It's right here", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
- Edited by MistyHobson Saturday, August 29, 2020 5:59 PM
Saturday, August 29, 2020 5:54 PM