locked
Customize Titlebar RRS feed

  • 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 Sub

    If 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 Sub

      Private Sub CloseForm()
            Me.Close()
        End Sub


    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 Sub

    If 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 Sub

    If 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 Sub

    If 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 Border
     

     Here 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 Class
     

     In 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

    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

    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 PaintEventArgs 

       Private Sub FormLoad(sender As Object, e As EventArgs) Handles MyBase.Load
            '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

    Public Class TitleBar
        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