如何让RichTextBox看起来平整?

时间:2021-02-18 07:20:37

I'm working on a WinForms SmartClient application, which uses a lot of RichTextBox controls - some in place of the regular TextBox for various reasons. Unfortunately the RichTextBox draws the ugly Win95 3D border instead of the themed XP or Vista style border.

我正在使用WinForms SmartClient应用程序,该应用程序使用了许多RichTextBox控件 - 由于各种原因,有些代替常规TextBox。不幸的是,RichTextBox绘制了丑陋的Win95 3D边框,而不是主题的XP或Vista风格边框。

Does anyone know of a way to apply the themed border to the RichTextBox? I don't mind subclassing them for this purpose.

有谁知道将主题边框应用于RichTextBox的方法?我不介意为此目的对它们进行子类化。

Thanks!

5 个解决方案

#1


This is really a hack but one thing you can do is drop a Panel control onto the page. Give it a BorderStyle of FixedSingle (it will be None by default.)

这真的是一个黑客,但你可以做的一件事是将一个Panel控件放到页面上。给它一个FixedSingle的BorderStyle(默认情况下它将是None。)

Drop your RichTextBox into the panel and set the BorderStyle to none. Then set the Dock property of the RichTextBox to Fill.

将RichTextBox放入面板并将BorderStyle设置为none。然后将RichTextBox的Dock属性设置为Fill。

This will give you a RichTextBox with a flat border.

这将为您提供具有平面边框的RichTextBox。

#2


Back in the day I had to solve this with a panel where the text box is a component inside and had DockPadding set to 3 or 4 pixels. I'd then style that panel to a single pixel.

回到那一天,我不得不用一个面板来解决这个问题,其中文本框是内部组件,并且DockPadding设置为3或4像素。然后我将该面板设置为单个像素。

I always found this really annoying!

我总觉得这真烦人!

#3


I guess this is a little too late, but nonetheless.

我想这有点太晚了,但仍然如此。

You can always use P/Invoke and subclass your RichEdit with UXTheme API that way you can disable/enable it as you wish.

您可以随时使用P / Invoke并将RichEdit子类化为UXTheme API,以便您可以根据需要禁用/启用它。

I think CodeProject had an richedit control which used UXTheme/Visual Styles API

我认为CodeProject有一个使用UXTheme / Visual Styles API的richedit控件

Visual Styles UXTheme API may become obsolete or deprecated as Windows 8 is rolling out

视觉样式UXTheme API可能会在Windows 8推出时过时或弃用

#4


Here is VB.NET code, it inflates the nonclient area with -1 and then fills the nonclient area with caded blue. It can be converted to C# using SharpDevelop 4.4. I derived the code from this article:

这是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

#5


The easiest way to get rid of the 3D-border is to set another one:

摆脱3D边界的最简单方法是设置另一个:

richTextBox.BorderStyle = BorderStyle.FixedSingle;

The FixedSingle-BorderStyle is the closest to the FlatStyle of e.g. Button

FixedSingle-BorderStyle最接近例如FlatStyle。按键

#1


This is really a hack but one thing you can do is drop a Panel control onto the page. Give it a BorderStyle of FixedSingle (it will be None by default.)

这真的是一个黑客,但你可以做的一件事是将一个Panel控件放到页面上。给它一个FixedSingle的BorderStyle(默认情况下它将是None。)

Drop your RichTextBox into the panel and set the BorderStyle to none. Then set the Dock property of the RichTextBox to Fill.

将RichTextBox放入面板并将BorderStyle设置为none。然后将RichTextBox的Dock属性设置为Fill。

This will give you a RichTextBox with a flat border.

这将为您提供具有平面边框的RichTextBox。

#2


Back in the day I had to solve this with a panel where the text box is a component inside and had DockPadding set to 3 or 4 pixels. I'd then style that panel to a single pixel.

回到那一天,我不得不用一个面板来解决这个问题,其中文本框是内部组件,并且DockPadding设置为3或4像素。然后我将该面板设置为单个像素。

I always found this really annoying!

我总觉得这真烦人!

#3


I guess this is a little too late, but nonetheless.

我想这有点太晚了,但仍然如此。

You can always use P/Invoke and subclass your RichEdit with UXTheme API that way you can disable/enable it as you wish.

您可以随时使用P / Invoke并将RichEdit子类化为UXTheme API,以便您可以根据需要禁用/启用它。

I think CodeProject had an richedit control which used UXTheme/Visual Styles API

我认为CodeProject有一个使用UXTheme / Visual Styles API的richedit控件

Visual Styles UXTheme API may become obsolete or deprecated as Windows 8 is rolling out

视觉样式UXTheme API可能会在Windows 8推出时过时或弃用

#4


Here is VB.NET code, it inflates the nonclient area with -1 and then fills the nonclient area with caded blue. It can be converted to C# using SharpDevelop 4.4. I derived the code from this article:

这是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

#5


The easiest way to get rid of the 3D-border is to set another one:

摆脱3D边界的最简单方法是设置另一个:

richTextBox.BorderStyle = BorderStyle.FixedSingle;

The FixedSingle-BorderStyle is the closest to the FlatStyle of e.g. Button

FixedSingle-BorderStyle最接近例如FlatStyle。按键