如何在 vb.net 中更改表单标题栏的外观
How to change appearance of the form titlebar in vb.net
如何在 vb.net 中为表格边框颜色着色?
我想要 color formborder 等于 backcolor 45、66、50。
下面截图中的黄色圆圈是什么意思?
注意:我使用 visual studio 2010
谢谢
罗伊
正如我在评论中提到的,这不是一件小事。它涉及处理原生 windows 消息,如 WM_NCPAINT
和调用原生 windows API 函数,以及绘制标题栏和自己处理不同的情况。
如果您使用无边框表单并自己显示自定义标题栏,可能会更容易。作为自定义标题栏的想法,您可以使用 MenuStrip。
Whosebug 中有很多类似的问题,但我找不到自定义标题栏的示例(特别是在 VB.NET 中),所以我在这里发布了使用 VB.NET 的自定义标题栏。
使用 ManuStrip 自定义标题栏
在此示例中,我创建了一个基于菜单条的自定义标题栏 class,它支持以下功能:
- 它有关闭、Maximize/Restore 和最小化按钮
- 显示表单的图标和文本
- 双击标题栏有效,它最大化或恢复表单
- 右击标题栏有效并显示系统菜单
- 双击图标有效并关闭表单
- 它是可移动的;您可以通过拖动标题栏来移动表格
我不能说这是一个 full-fledge 标题栏,但它是一个很好的概念证明:
您可以根据需要修改外观和行为。这是代码:
Imports System.Runtime.InteropServices
Public Class CustomTitleBar
Inherits MenuStrip
Private CloseButton As ToolStripMenuItem
Private MaximizeButton As ToolStripMenuItem
Private MinimizeButton As ToolStripMenuItem
Private IconLabel As ToolStripLabel
Private TextLabel As ToolStripLabel
Public Sub New()
MyBase.New()
CloseButton = New ToolStripMenuItem()
MaximizeButton = New ToolStripMenuItem()
MinimizeButton = New ToolStripMenuItem()
IconLabel = New ToolStripLabel()
TextLabel = New ToolStripLabel()
'IconLabel
IconLabel.Alignment = ToolStripItemAlignment.Left
IconLabel.AutoSize = False
IconLabel.Name = "IconLabel"
IconLabel.Size = New Size(64, 64)
IconLabel.Text = ""
'TextLabel
TextLabel.Alignment = ToolStripItemAlignment.Left
TextLabel.AutoSize = True
TextLabel.Name = "TextLabel"
TextLabel.Text = ""
'CloseButton
CloseButton.Alignment = ToolStripItemAlignment.Right
CloseButton.AutoSize = False
CloseButton.Name = "CloseButton"
CloseButton.Size = New Size(64, 64)
CloseButton.Text = "✕"
AddHandler CloseButton.Click, AddressOf CloseButton_Click
'MaximizeButton
MaximizeButton.Alignment = ToolStripItemAlignment.Right
MaximizeButton.AutoSize = False
MaximizeButton.Name = "MaximizeButton"
MaximizeButton.Size = New Size(64, 64)
MaximizeButton.Text = "⬜"
AddHandler MaximizeButton.Click, AddressOf MaximizeButton_Click
'MinimizeButton
MinimizeButton.Alignment = ToolStripItemAlignment.Right
MinimizeButton.AutoSize = False
MinimizeButton.Name = "MinimizeButton"
MinimizeButton.Size = New Size(64, 64)
MinimizeButton.Text = "―"
AddHandler MinimizeButton.Click, AddressOf MinimizeButton_Click
GripStyle = ToolStripGripStyle.Hidden
Me.Padding = New Padding(1)
ImageScalingSize = New System.Drawing.Size(32, 32)
Me.AutoSize = True
Me.Dock = DockStyle.Top
Me.TabStop=False
Items.Add(IconLabel)
Items.Add(TextLabel)
Items.Add(CloseButton)
Items.Add(MaximizeButton)
Items.Add(MinimizeButton)
End Sub
private sub MinimizeButton_Click(sender As Object, e As EventArgs)
Dim f = FindForm()
If (f Is Nothing) Then Return
f.WindowState = FormWindowState.Minimized
End sub
private sub MaximizeButton_Click(sender As Object, e As EventArgs)
Dim f = FindForm()
If (f Is Nothing) Then Return
If (f.WindowState = FormWindowState.Normal) Then
f.WindowState = FormWindowState.Maximized
ElseIf f.WindowState = FormWindowState.Maximized Then
f.WindowState = FormWindowState.Normal
End If
End sub
private sub CloseButton_Click(sender As Object, e As EventArgs)
Dim f = FindForm()
If (f Is Nothing) Then Return
f.Close()
End sub
Protected Overrides Sub OnMouseDown(e As MouseEventArgs)
MyBase.OnMouseDown(e)
Dim f = FindForm()
If (f Is Nothing) Then Return
If (e.Button = MouseButtons.Left) Then
If (e.Clicks = 1 AndAlso _
e.Location.X < MinimizeButton.Bounds.X AndAlso _
e.Location.X > IconLabel.Bounds.Right) Then
ReleaseCapture()
SendMessage(f.Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0)
End If
ElseIf (e.Button = MouseButtons.Right) Then
Dim menu = GetSystemMenu(f.Handle, False)
Dim command = TrackPopupMenu(menu, _
TPM_RETURNCMD + TPM_LEFTBUTTON + TPM_RIGHTBUTTON, _
MousePosition.X, MousePosition.Y, IntPtr.Zero, _
f.Handle, IntPtr.Zero)
If (command > 0) Then
SendMessage(f.Handle, _
WM_SYSCOMMAND, command, IntPtr.Zero)
End If
End If
End Sub
Protected Overrides Sub OnMouseDoubleClick(e As MouseEventArgs)
MyBase.OnMouseDoubleClick(e)
Dim f = FindForm()
If (f Is Nothing) Then Return
If (e.X < IconLabel.Bounds.Right) Then
f.Close()
ElseIf (f.WindowState = FormWindowState.Normal) Then
f.WindowState = FormWindowState.Maximized
ElseIf f.WindowState = FormWindowState.Maximized Then
f.WindowState = FormWindowState.Normal
End If
End Sub
Protected Overrides Sub OnParentChanged(e As EventArgs)
MyBase.OnParentChanged(e)
Dim f = FindForm()
If (f Is Nothing) Then Return
UpdateIcon()
UpdateText()
AddHandler f.TextChanged, AddressOf Parent_TextChanged
End Sub
Protected Overrides Sub OnHandleCreated(e As EventArgs)
MyBase.OnHandleCreated(e)
UpdateIcon()
UpdateText()
End Sub
Private sub Parent_TextChanged(sender As Object, e As EventArgs)
UpdateText()
End sub
Private sub UpdateIcon()
Dim f = FindForm()
If (f Is Nothing) Then Return
If(f.Icon IsNot Nothing)
IconLabel.Image = f.Icon.ToBitmap()
End If
End sub
Private sub UpdateText()
Dim f = FindForm()
If (f Is Nothing) Then Return
TextLabel.Text = f.Text
End sub
Private Const TPM_LEFTBUTTON As Integer = &H0
Private Const TPM_RIGHTBUTTON As Integer = &H2
Private Const TPM_RETURNCMD As Integer = &H100
Private Const WM_SYSCOMMAND As Integer = &H112
<DllImport("user32.dll")> _
Private Shared Function GetSystemMenu(hWnd As IntPtr, _
bRevert As Boolean) As IntPtr
End Function
<DllImport("user32.dll")> _
Private Shared Function TrackPopupMenu( _
hMenu As IntPtr, uFlags As Integer, _
x As Integer, y As Integer, nReserved As Integer, _
hWnd As IntPtr, prcRect As IntPtr) As Integer
End Function
Private Const WM_NCLBUTTONDOWN As Integer = &HA1
Private Const HT_CAPTION As Integer = &H2
<DllImport("User32")> _
Private Shared Function SendMessage(hWnd As IntPtr, msg As Integer, _
wParam As Integer, lParam As Integer) As Integer
End Function
<DllImport("User32")> _
Private Shared Function ReleaseCapture() As Boolean
End Function
End Class
构建项目后,您可以将 CustomTitleBar 的实例拖放到窗体中。要支持显示系统上下文菜单,您需要在表单中添加以下代码:
Public Class Form1
Private Const WS_SYSMENU As Integer = &H80000
Private Const WS_MINIMIZEBOX As Integer = &H20000
Private Const WS_MAXIMIZEBOX As Integer = &H10000
Protected Overrides ReadOnly Property CreateParams _
As System.Windows.Forms.CreateParams
Get
Dim p = MyBase.CreateParams
p.Style = WS_SYSMENU + WS_MINIMIZEBOX + WS_MAXIMIZEBOX
Return p
End Get
End Property
End Class
如何在 vb.net 中为表格边框颜色着色?
我想要 color formborder 等于 backcolor 45、66、50。
下面截图中的黄色圆圈是什么意思?
正如我在评论中提到的,这不是一件小事。它涉及处理原生 windows 消息,如 WM_NCPAINT
和调用原生 windows API 函数,以及绘制标题栏和自己处理不同的情况。
如果您使用无边框表单并自己显示自定义标题栏,可能会更容易。作为自定义标题栏的想法,您可以使用 MenuStrip。
Whosebug 中有很多类似的问题,但我找不到自定义标题栏的示例(特别是在 VB.NET 中),所以我在这里发布了使用 VB.NET 的自定义标题栏。
使用 ManuStrip 自定义标题栏
在此示例中,我创建了一个基于菜单条的自定义标题栏 class,它支持以下功能:
- 它有关闭、Maximize/Restore 和最小化按钮
- 显示表单的图标和文本
- 双击标题栏有效,它最大化或恢复表单
- 右击标题栏有效并显示系统菜单
- 双击图标有效并关闭表单
- 它是可移动的;您可以通过拖动标题栏来移动表格
我不能说这是一个 full-fledge 标题栏,但它是一个很好的概念证明:
您可以根据需要修改外观和行为。这是代码:
Imports System.Runtime.InteropServices
Public Class CustomTitleBar
Inherits MenuStrip
Private CloseButton As ToolStripMenuItem
Private MaximizeButton As ToolStripMenuItem
Private MinimizeButton As ToolStripMenuItem
Private IconLabel As ToolStripLabel
Private TextLabel As ToolStripLabel
Public Sub New()
MyBase.New()
CloseButton = New ToolStripMenuItem()
MaximizeButton = New ToolStripMenuItem()
MinimizeButton = New ToolStripMenuItem()
IconLabel = New ToolStripLabel()
TextLabel = New ToolStripLabel()
'IconLabel
IconLabel.Alignment = ToolStripItemAlignment.Left
IconLabel.AutoSize = False
IconLabel.Name = "IconLabel"
IconLabel.Size = New Size(64, 64)
IconLabel.Text = ""
'TextLabel
TextLabel.Alignment = ToolStripItemAlignment.Left
TextLabel.AutoSize = True
TextLabel.Name = "TextLabel"
TextLabel.Text = ""
'CloseButton
CloseButton.Alignment = ToolStripItemAlignment.Right
CloseButton.AutoSize = False
CloseButton.Name = "CloseButton"
CloseButton.Size = New Size(64, 64)
CloseButton.Text = "✕"
AddHandler CloseButton.Click, AddressOf CloseButton_Click
'MaximizeButton
MaximizeButton.Alignment = ToolStripItemAlignment.Right
MaximizeButton.AutoSize = False
MaximizeButton.Name = "MaximizeButton"
MaximizeButton.Size = New Size(64, 64)
MaximizeButton.Text = "⬜"
AddHandler MaximizeButton.Click, AddressOf MaximizeButton_Click
'MinimizeButton
MinimizeButton.Alignment = ToolStripItemAlignment.Right
MinimizeButton.AutoSize = False
MinimizeButton.Name = "MinimizeButton"
MinimizeButton.Size = New Size(64, 64)
MinimizeButton.Text = "―"
AddHandler MinimizeButton.Click, AddressOf MinimizeButton_Click
GripStyle = ToolStripGripStyle.Hidden
Me.Padding = New Padding(1)
ImageScalingSize = New System.Drawing.Size(32, 32)
Me.AutoSize = True
Me.Dock = DockStyle.Top
Me.TabStop=False
Items.Add(IconLabel)
Items.Add(TextLabel)
Items.Add(CloseButton)
Items.Add(MaximizeButton)
Items.Add(MinimizeButton)
End Sub
private sub MinimizeButton_Click(sender As Object, e As EventArgs)
Dim f = FindForm()
If (f Is Nothing) Then Return
f.WindowState = FormWindowState.Minimized
End sub
private sub MaximizeButton_Click(sender As Object, e As EventArgs)
Dim f = FindForm()
If (f Is Nothing) Then Return
If (f.WindowState = FormWindowState.Normal) Then
f.WindowState = FormWindowState.Maximized
ElseIf f.WindowState = FormWindowState.Maximized Then
f.WindowState = FormWindowState.Normal
End If
End sub
private sub CloseButton_Click(sender As Object, e As EventArgs)
Dim f = FindForm()
If (f Is Nothing) Then Return
f.Close()
End sub
Protected Overrides Sub OnMouseDown(e As MouseEventArgs)
MyBase.OnMouseDown(e)
Dim f = FindForm()
If (f Is Nothing) Then Return
If (e.Button = MouseButtons.Left) Then
If (e.Clicks = 1 AndAlso _
e.Location.X < MinimizeButton.Bounds.X AndAlso _
e.Location.X > IconLabel.Bounds.Right) Then
ReleaseCapture()
SendMessage(f.Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0)
End If
ElseIf (e.Button = MouseButtons.Right) Then
Dim menu = GetSystemMenu(f.Handle, False)
Dim command = TrackPopupMenu(menu, _
TPM_RETURNCMD + TPM_LEFTBUTTON + TPM_RIGHTBUTTON, _
MousePosition.X, MousePosition.Y, IntPtr.Zero, _
f.Handle, IntPtr.Zero)
If (command > 0) Then
SendMessage(f.Handle, _
WM_SYSCOMMAND, command, IntPtr.Zero)
End If
End If
End Sub
Protected Overrides Sub OnMouseDoubleClick(e As MouseEventArgs)
MyBase.OnMouseDoubleClick(e)
Dim f = FindForm()
If (f Is Nothing) Then Return
If (e.X < IconLabel.Bounds.Right) Then
f.Close()
ElseIf (f.WindowState = FormWindowState.Normal) Then
f.WindowState = FormWindowState.Maximized
ElseIf f.WindowState = FormWindowState.Maximized Then
f.WindowState = FormWindowState.Normal
End If
End Sub
Protected Overrides Sub OnParentChanged(e As EventArgs)
MyBase.OnParentChanged(e)
Dim f = FindForm()
If (f Is Nothing) Then Return
UpdateIcon()
UpdateText()
AddHandler f.TextChanged, AddressOf Parent_TextChanged
End Sub
Protected Overrides Sub OnHandleCreated(e As EventArgs)
MyBase.OnHandleCreated(e)
UpdateIcon()
UpdateText()
End Sub
Private sub Parent_TextChanged(sender As Object, e As EventArgs)
UpdateText()
End sub
Private sub UpdateIcon()
Dim f = FindForm()
If (f Is Nothing) Then Return
If(f.Icon IsNot Nothing)
IconLabel.Image = f.Icon.ToBitmap()
End If
End sub
Private sub UpdateText()
Dim f = FindForm()
If (f Is Nothing) Then Return
TextLabel.Text = f.Text
End sub
Private Const TPM_LEFTBUTTON As Integer = &H0
Private Const TPM_RIGHTBUTTON As Integer = &H2
Private Const TPM_RETURNCMD As Integer = &H100
Private Const WM_SYSCOMMAND As Integer = &H112
<DllImport("user32.dll")> _
Private Shared Function GetSystemMenu(hWnd As IntPtr, _
bRevert As Boolean) As IntPtr
End Function
<DllImport("user32.dll")> _
Private Shared Function TrackPopupMenu( _
hMenu As IntPtr, uFlags As Integer, _
x As Integer, y As Integer, nReserved As Integer, _
hWnd As IntPtr, prcRect As IntPtr) As Integer
End Function
Private Const WM_NCLBUTTONDOWN As Integer = &HA1
Private Const HT_CAPTION As Integer = &H2
<DllImport("User32")> _
Private Shared Function SendMessage(hWnd As IntPtr, msg As Integer, _
wParam As Integer, lParam As Integer) As Integer
End Function
<DllImport("User32")> _
Private Shared Function ReleaseCapture() As Boolean
End Function
End Class
构建项目后,您可以将 CustomTitleBar 的实例拖放到窗体中。要支持显示系统上下文菜单,您需要在表单中添加以下代码:
Public Class Form1
Private Const WS_SYSMENU As Integer = &H80000
Private Const WS_MINIMIZEBOX As Integer = &H20000
Private Const WS_MAXIMIZEBOX As Integer = &H10000
Protected Overrides ReadOnly Property CreateParams _
As System.Windows.Forms.CreateParams
Get
Dim p = MyBase.CreateParams
p.Style = WS_SYSMENU + WS_MINIMIZEBOX + WS_MAXIMIZEBOX
Return p
End Get
End Property
End Class