我正在开发一个WinForms智能客户端应用程序,其中使用了许多RichTextBox控件 - 由于各种原因,有些替代了常规的文本框。不幸的是,RichTextBox会绘制丑陋的Win95 3D边框,而不是主题化的XP或Vista风格边框。
请问是否有方法可以将主题化的边框应用到RichTextBox?我不介意为此目的子类化它们。
谢谢!
我正在开发一个WinForms智能客户端应用程序,其中使用了许多RichTextBox控件 - 由于各种原因,有些替代了常规的文本框。不幸的是,RichTextBox会绘制丑陋的Win95 3D边框,而不是主题化的XP或Vista风格边框。
请问是否有方法可以将主题化的边框应用到RichTextBox?我不介意为此目的子类化它们。
谢谢!
这确实是一个技巧,但是你可以在页面上放置一个面板控件。将其BorderStyle设置为FixedSingle(默认情况下为None)。
将RichTextBox放入面板中,并将BorderStyle设置为无。然后将RichTextBox的Dock属性设置为Fill。
这将给您一个带有平坦边框的RichTextBox。
以前我必须使用一个面板来解决这个问题,其中文本框是组件内部的,设置了3或4像素的DockPadding。然后我会将该面板样式设置为单个像素。
我一直觉得这很烦人!
这里是VB.NET代码,它将非客户区充气为-1,然后填充非客户区与淡蓝色。可以使用SharpDevelop 4.4将其转换为C#。我从这篇文章中得出了该代码:
http://www.codeproject.com/Articles/13723/Themed-RichTextBox-A-RichTextBox-with-XP-styled-bo
Imports System.Runtime.InteropServices
Imports System.Windows.Forms
Imports System.Windows.Forms.VisualStyles
Imports System.Drawing
Imports System.Diagnostics
Public Class FlatRichTextBox
Inherits RichTextBox
Private BorderRect As RECT
Sub New()
If VisualStyleInformation.IsEnabledByUser Then
BorderStyle = BorderStyle.None
End If
End Sub
Protected Overrides Sub WndProc(ByRef m As Message)
Const WM_NCPAINT = &H85
Const WM_NCCALCSIZE = &H83
Const WM_THEMECHANGED = &H31A
Select Case m.Msg
Case WM_NCPAINT
WmNcpaint(m)
Case WM_NCCALCSIZE
WmNccalcsize(m)
Case WM_THEMECHANGED
UpdateStyles()
Case Else
MyBase.WndProc(m)
End Select
End Sub
Private Sub WmNccalcsize(ByRef m As Message)
MyBase.WndProc(m)
If Not VisualStyleInformation.IsEnabledByUser Then Return
Dim par As New NCCALCSIZE_PARAMS()
Dim windowRect As RECT
If m.WParam <> IntPtr.Zero Then
par = CType(Marshal.PtrToStructure(m.LParam, GetType(NCCALCSIZE_PARAMS)), NCCALCSIZE_PARAMS)
windowRect = par.rgrc0
End If
Dim clientRect = windowRect
clientRect.Left += 1
clientRect.Top += 1
clientRect.Right -= 1
clientRect.Bottom -= 1
BorderRect = New RECT(clientRect.Left - windowRect.Left,
clientRect.Top - windowRect.Top,
windowRect.Right - clientRect.Right,
windowRect.Bottom - clientRect.Bottom)
If m.WParam = IntPtr.Zero Then
Marshal.StructureToPtr(clientRect, m.LParam, False)
Else
par.rgrc0 = clientRect
Marshal.StructureToPtr(par, m.LParam, False)
End If
Const WVR_HREDRAW = &H100
Const WVR_VREDRAW = &H200
Const WVR_REDRAW = (WVR_HREDRAW Or WVR_VREDRAW)
m.Result = New IntPtr(WVR_REDRAW)
End Sub
Private Sub WmNcpaint(ByRef m As Message)
MyBase.WndProc(m)
If Not VisualStyleInformation.IsEnabledByUser Then Return
Dim r As RECT
GetWindowRect(Handle, r)
r.Right -= r.Left
r.Bottom -= r.Top
r.Top = 0
r.Left = 0
r.Left += BorderRect.Left
r.Top += BorderRect.Top
r.Right -= BorderRect.Right
r.Bottom -= BorderRect.Bottom
Dim hDC = GetWindowDC(Handle)
ExcludeClipRect(hDC, r.Left, r.Top, r.Right, r.Bottom)
Using g = Graphics.FromHdc(hDC)
g.Clear(Color.CadetBlue)
End Using
ReleaseDC(Handle, hDC)
m.Result = IntPtr.Zero
End Sub
<DllImport("user32.dll")>
Public Shared Function GetWindowRect(hWnd As IntPtr, ByRef lpRect As RECT) As Boolean
End Function
<DllImport("user32.dll")>
Public Shared Function GetWindowDC(hWnd As IntPtr) As IntPtr
End Function
<DllImport("user32.dll")>
Public Shared Function ReleaseDC(hWnd As IntPtr, hDC As IntPtr) As Integer
End Function
<DllImport("gdi32.dll")>
Public Shared Function ExcludeClipRect(hdc As IntPtr, nLeftRect As Integer, nTopRect As Integer, nRightRect As Integer, nBottomRect As Integer) As Integer
End Function
<StructLayout(LayoutKind.Sequential)>
Public Structure NCCALCSIZE_PARAMS
Public rgrc0, rgrc1, rgrc2 As RECT
Public lppos As IntPtr
End Structure
<StructLayout(LayoutKind.Sequential)>
Public Structure RECT
Public Left As Integer
Public Top As Integer
Public Right As Integer
Public Bottom As Integer
Public Sub New(left As Integer, top As Integer, right As Integer, bottom As Integer)
Me.Left = left
Me.Top = top
Me.Right = right
Me.Bottom = bottom
End Sub
End Structure
End Class
我猜这可能有点晚了,但还是要说一下。
你可以随时使用P/Invoke并使用UXTheme API对RichEdit进行子类化,这样你就可以根据需要禁用/启用它。
我想CodeProject有一个使用UXTheme/Visual Styles API的richedit控件。
Label backcolor = System.Drawing.Color.Transparent
Label.BorderStyle = BorderStyle.FixedSingle
myRichTextBox.BringToFront
Label.Width= myRichTextbox.Width + 4
Label.Height = myRichTextbox.Height + 4
Label.left = myRichTextBox.left -2
Label.Top = myRichTextboxTop -2
richTextBox.BorderStyle = BorderStyle.FixedSingle;
FixedSingle
边框样式是最接近例如按钮的 FlatStyle
的样式。