如何在不丢失格式的情况下更改富文本框所有内容的字体?
我正在尝试使用
rtb.SelectAll();
rtb.SelectionFont = new Font(fontName,...);
但是字体构造函数除了字体类型之外还必须采用字体样式(粗体、斜体、...)或字体大小。所以使用它会改变richtextbox所有内容的样式/大小。
当然,这同样适用于富文本框中的任何选择。
如何在不丢失格式的情况下更改富文本框所有内容的字体?
我正在尝试使用
rtb.SelectAll();
rtb.SelectionFont = new Font(fontName,...);
但是字体构造函数除了字体类型之外还必须采用字体样式(粗体、斜体、...)或字体大小。所以使用它会改变richtextbox所有内容的样式/大小。
当然,这同样适用于富文本框中的任何选择。
这是我过去使用的 RichTextBox。它是从 Stack Overflow 和整个互联网上的代码拼接在一起的:
public class RichBox : RichTextBox {
private const UInt32 CFM_BOLD = 0x00000001;
private const UInt32 CFM_ITALIC = 0x00000002;
private const UInt32 CFM_UNDERLINE = 0x00000004;
private const UInt32 CFM_STRIKE = 0x00000008;
private const UInt32 CFM_FACE = 0x20000000;
private const UInt32 CFM_SIZE = 0x80000000;
private const int WM_PAINT = 0xF;
private const int WM_SETREDRAW = 0xB;
private const int WM_USER = 0x400;
private const int EM_SETCHARFORMAT = (WM_USER + 68);
private const int SCF_SELECTION = 0x0001;
private const int EM_GETEVENTMASK = WM_USER + 59;
private const int EM_SETEVENTMASK = WM_USER + 69;
private const int EM_GETSCROLLPOS = WM_USER + 221;
private const int EM_SETSCROLLPOS = WM_USER + 222;
[StructLayout(LayoutKind.Sequential)]
private struct CHARFORMAT {
public int cbSize;
public uint dwMask;
public uint dwEffects;
public int yHeight;
public int yOffset;
public int crTextColor;
public byte bCharSet;
public byte bPitchAndFamily;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public char[] szFaceName;
public short wWeight;
public short sSpacing;
public int crBackColor;
public int LCID;
public uint dwReserved;
public short sStyle;
public short wKerning;
public byte bUnderlineType;
public byte bAnimation;
public byte bRevAuthor;
}
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr LoadLibrary(string lpFileName);
[DllImport("user32", CharSet = CharSet.Auto)]
private static extern int SendMessage(IntPtr hWnd, int msg, int wParam, ref CHARFORMAT lParam);
[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, Int32 wMsg, Int32 wParam, ref Point lParam);
[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, Int32 wMsg, Int32 wParam, IntPtr lParam);
private bool frozen = false;
private Point lastScroll = Point.Empty;
private IntPtr lastEvent = IntPtr.Zero;
private int lastIndex = 0;
private int lastWidth = 0;
protected override CreateParams CreateParams {
get {
var cp = base.CreateParams;
if (LoadLibrary("msftedit.dll") != IntPtr.Zero) {
cp.ClassName = "RICHEDIT50W";
}
return cp;
}
}
[Browsable(false)]
[DefaultValue(typeof(bool), "False")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool FreezeDrawing {
get { return frozen; }
set {
if (value != frozen) {
frozen = value;
if (frozen) {
this.SuspendLayout();
SendMessage(this.Handle, WM_SETREDRAW, 0, IntPtr.Zero);
SendMessage(this.Handle, EM_GETSCROLLPOS, 0, ref lastScroll);
lastEvent = SendMessage(this.Handle, EM_GETEVENTMASK, 0, IntPtr.Zero);
lastIndex = this.SelectionStart;
lastWidth = this.SelectionLength;
} else {
this.Select(lastIndex, lastWidth);
SendMessage(this.Handle, EM_SETEVENTMASK, 0, lastEvent);
SendMessage(this.Handle, EM_SETSCROLLPOS, 0, ref lastScroll);
SendMessage(this.Handle, WM_SETREDRAW, 1, IntPtr.Zero);
this.Invalidate();
this.ResumeLayout();
}
}
}
}
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Font CurrentFont {
get {
Font result = this.Font;
if (this.SelectionLength == 0) {
result = SelectionFont;
} else {
using (RichBox rb = new RichBox()) {
rb.FreezeDrawing = true;
rb.SelectAll();
rb.SelectedRtf = this.SelectedRtf;
rb.Select(0, 1);
result = rb.SelectionFont;
}
}
return result;
}
}
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public string SelectionFontName {
get { return CurrentFont.FontFamily.Name; }
set {
CHARFORMAT cf = new CHARFORMAT();
cf.cbSize = Marshal.SizeOf(cf);
cf.szFaceName = new char[32];
cf.dwMask = CFM_FACE;
value.CopyTo(0, cf.szFaceName, 0, Math.Min(31, value.Length));
IntPtr lParam = Marshal.AllocCoTaskMem(Marshal.SizeOf(cf));
Marshal.StructureToPtr(cf, lParam, false);
SendMessage(this.Handle, EM_SETCHARFORMAT, SCF_SELECTION, lParam);
}
}
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public float SelectionFontSize {
get { return CurrentFont.Size; }
set {
CHARFORMAT cf = new CHARFORMAT();
cf.cbSize = Marshal.SizeOf(cf);
cf.dwMask = CFM_SIZE;
cf.yHeight = Convert.ToInt32(value * 20);
IntPtr lParam = Marshal.AllocCoTaskMem(Marshal.SizeOf(cf));
Marshal.StructureToPtr(cf, lParam, false);
SendMessage(this.Handle, EM_SETCHARFORMAT, SCF_SELECTION, lParam);
}
}
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool SelectionBold {
get { return CurrentFont.Bold; }
set {
CHARFORMAT cf = new CHARFORMAT();
cf.cbSize = Marshal.SizeOf(cf);
cf.dwMask = CFM_BOLD;
cf.dwEffects = value ? CFM_BOLD : 0;
IntPtr lParam = Marshal.AllocCoTaskMem(Marshal.SizeOf(cf));
Marshal.StructureToPtr(cf, lParam, false);
SendMessage(this.Handle, EM_SETCHARFORMAT, SCF_SELECTION, lParam);
}
}
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool SelectionItalic {
get { return CurrentFont.Italic; }
set {
CHARFORMAT cf = new CHARFORMAT();
cf.cbSize = Marshal.SizeOf(cf);
cf.dwMask = CFM_ITALIC;
cf.dwEffects = value ? CFM_ITALIC : 0;
IntPtr lParam = Marshal.AllocCoTaskMem(Marshal.SizeOf(cf));
Marshal.StructureToPtr(cf, lParam, false);
SendMessage(this.Handle, EM_SETCHARFORMAT, SCF_SELECTION, lParam);
}
}
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool SelectionStrikeout {
get { return CurrentFont.Strikeout; }
set {
CHARFORMAT cf = new CHARFORMAT();
cf.cbSize = Marshal.SizeOf(cf);
cf.dwMask = CFM_STRIKE;
cf.dwEffects = value ? CFM_STRIKE : 0;
IntPtr lParam = Marshal.AllocCoTaskMem(Marshal.SizeOf(cf));
Marshal.StructureToPtr(cf, lParam, false);
SendMessage(this.Handle, EM_SETCHARFORMAT, SCF_SELECTION, lParam);
}
}
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool SelectionUnderline {
get { return CurrentFont.Underline; }
set {
CHARFORMAT cf = new CHARFORMAT();
cf.cbSize = Marshal.SizeOf(cf);
cf.dwMask = CFM_UNDERLINE;
cf.dwEffects = value ? CFM_UNDERLINE : 0;
IntPtr lParam = Marshal.AllocCoTaskMem(Marshal.SizeOf(cf));
Marshal.StructureToPtr(cf, lParam, false);
SendMessage(this.Handle, EM_SETCHARFORMAT, SCF_SELECTION, lParam);
}
}
}
它添加了新的属性,例如 SelectionBold、SelectionItalic 等,您可以在其中应用属性而不会丢失文本的其他格式。
您可以使用现有的 Richtextbox 字体属性传递新字体名称,同时保持其他值不变。要仅更改所选文本的字体名称,您需要执行以下操作:
if (rtb.SelectionFont !=null)
rtb.SelectionFont = new Font(fontName, rtb.SelectionFont.Size, rtb.SelectionFont.Style);
请注意,仅当所有选定文本具有相同的格式(字体大小、样式等)时,上述代码才有效。这是通过首先检查 SelectionFont 属性来检测的,如果选择包含混合样式,它将为 null。
现在要更改richtextbox所有内容的字体名称,同时保持其他格式不变,您需要遍历richtextbox的所有字符并一一应用字体名称。
for (int i = 0; i < rtb.TextLength; i++)
{
rtb.Select(i, 1);
rtb.SelectionFont = new Font(fontName, rtb.SelectionFont.Size, rtb.SelectionFont.Style);
}
您可以为所需的任何参数传入新值,并使用rtb
属性来保留其他值。例如,如果您想更改 ,font family
但想保留font size
,这就是您要做的:
rtb.SelectionFont = new Font(fontName, rtb.Font.Size);
这会将SelectionFont
系列更改为fontName
但保留字体大小。您可以对其他重载遵循相同的模式。
Private Sub changeFont(ByVal fontz As FontStyle, getStr As RichTextBox)
Dim currentFont As System.Drawing.Font = txt.SelectionFont
Dim newFontStyle As System.Drawing.FontStyle
newFontStyle = fontz
getStr.SelectionFont = New Font(currentFont.FontFamily, currentFont.Size, newFontStyle)
End Sub
这将更改所选文本的字体属性。
样本:
changeFont(FontStyle.Italic, [textbox_name])
更改richtextbox的字体而不丢失格式
private void Change_RichTextBox_FontName(string fontName )
{
if (richTextBox1.TextLength ==0)
{
return;
}
richTextBox1.Select(0, 1);
var lastTextColor = richTextBox1.SelectionColor;
var lastFontStyle = richTextBox1.SelectionFont.Style;
var lastFontSize = richTextBox1.SelectionFont.Size;
var lastSelectionStart = 0;
for (int i=1; i < richTextBox1.TextLength;i++)
{
richTextBox1.Select(i, 1);
var selColor = richTextBox1.SelectionColor;
var selStyle = richTextBox1.SelectionFont.Style;
var selSize = richTextBox1.SelectionFont.Size;
if (selColor != lastTextColor ||
selStyle != lastFontStyle ||
selSize != lastFontSize ||
i== richTextBox1.TextLength-1)
{
richTextBox1.Select(lastSelectionStart, i - lastSelectionStart);
richTextBox1.SelectionColor = lastTextColor;
richTextBox1.SelectionFont =
new Font(fontName, lastFontSize, lastFontStyle);
lastTextColor = selColor;
lastFontStyle = selStyle;
lastFontSize = selSize;
lastSelectionStart = i;
}
}
}