更改 RichTextBox 的字体而不丢失格式

2024-03-01

如何在不丢失格式的情况下更改richtextbox所有内容的字体?

我正在尝试使用

rtb.SelectAll();
rtb.SelectionFont = new Font(fontName,...);

但字体构造函数除了字体类型之外还必须采用字体样式(粗体、斜体等)或字体大小。 因此,使用它会改变富文本框所有内容的样式/大小。

当然,这同样适用于富文本框中的任何选择。


这是我过去使用过的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 等,您可以在其中应用该属性,而不会丢失文本的其他格式。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

更改 RichTextBox 的字体而不丢失格式 的相关文章

随机推荐

  • 如何使用Vagrant box打包文件?

    所以我使用以下命令创建了一个 Vagrant 框 vagrant package base box name here vagrantfile Vagrantfile include manifests manifests 是一个包含 pu
  • ASP.NET MVC Url.Action 和路由名称值

    我正在使用 asp net mvc 2 并根据路由创建本地化 我的路线如下 culture controller action 我转到我的家庭控制器 en Home Index 我的家庭控制器视图有到其他控制器的链接 a href Prod
  • 数组在内存中是如何存储的?

    我有一个简单的程序 它将数组初始化为 int a 10 20 30 40 50 char p p char a 现在我想通过指针访问每个字节的值p 为此我需要知道 数组如何存储在内存中 是存储在栈上还是堆上 数组将其元素存储在连续的内存位置
  • 如何使用 Google Maps API v3 从地图获取 MapOptions 对象

    在 Google Maps api v2 中 您可以直接从地图对象获取地图类型 缩放等参数 在版本 3 中 您可以使用 setOptions 方法来设置某些参数 但没有 getOptions 或选项来检索它们 您还可以使用以下命令访问选项g
  • 对“_GetAdaptersAddresses@20”的未定义引用 - 但我包含了 -liphlpapi

    我在用着gcc under cygwin编写一些调用的代码GetAdaptersAddresses from iphlpapi h在我的代码中我设置了 WIN32 WINNT高于要求的0x0501在我添加的链接器行上 liphlpapi但链
  • 来自 createFileAtPath 的更详细错误?

    无论如何 是否可以从 createFileAtPath 获取更详细的错误数据 我有点期待 NSError 目前我正在使用 BOOL 返回值 success fileMan createFileAtPath fileOnDisk conten
  • XSD:大型模式验证

    我正在尝试使用 JAXP 和 SAX 解析器根据非常大的工业模式验证 xml 文件 问题是 验证即使是很小的 XML 文件也需要很长时间 我正在运行 Apache Tomcat 6 0 我尝试将堆大小增加到 1024 但这没有多大帮助 我还
  • 在 Visual Studio 中调试可执行文件

    想要在调试器下调试可执行文件 如何在视觉工作室中做到这一点 Windbg 有一个打开可执行文件的选项 但我发现 VS 2010 中缺少这一点 这个问题并不完全相同在 Visual Studio 2010 中调试 exe https stac
  • 字符串的长度超过了 maxJsonLength 属性上设置的值

    我正在通过 jQuery 加载选项卡内容数据ajax通过 web 方法发布方法 大约有 200 300 条记录 并在控制台中出现以下错误 错误 Sys Net WebServiceFailedException Sys Net WebSer
  • 在 JMockit 中模拟被测类的私有方法

    在我的被 测类 CUT 中 一个 ejb 我有一个私有方法 getConnection 我想测试另一种 CUT 方法 但这种方法会提前失败 我尝试了如下所示 但 调用 是错误的 我不想调用该方法 我想存根它 但如何呢 连接 是一个存根 ne
  • 如何在主机之间迁移 Docker 卷?

    码头工人的文档 https docs docker com engine admin volumes volumes 指出卷可以 迁移 我假设这意味着我应该能够将卷从一台主机移动到另一台主机 非常乐意在这一点上得到纠正 但是 同一文档页面没
  • 获取单元 apache poi 的名称

    我有一个 Cell 对象 如何获取该单元格的名称 想要一个函数 例如 String name myCell getName 在Excel中 我已在名称框中对其进行命名 因此我不想获得 B4 我想获得诸如 InterestRate 之类的名称
  • 元素不会重定向到另一个页面并且不可点击

    我创建了一个 Web 组件 在其中声明了创建版权字符串的方法 p Copyright 2020 Krzysztof Kaczy ski a href https www google com Policy terms a p 然后我把这个字
  • 如何为 Mac OS X 编写启动脚本?

    我用java创建了一个jar文件 我想让应用程序在系统启动时自动启动 我发现我必须为此编写一个 shell 脚本 shell 脚本应该是什么样子 我还需要做些什么才能使应用程序在启动时自动启动吗 在 OS X 启动时启动程序的首选方法是创建
  • Altair Ridgeline 不会创建具有名义组的绘图

    我尝试在 Altair 中创建山脊线图 假设我的数据框由 str 和 float 列组成 a object b float64 dtype object 具有像这样的值 a b 0 25 2303 0 1 29 2676 0 2 18 29
  • 问:如何在多个设备上运行单个测试?

    我试图了解如何在多个设备中启动自动化测试 但我无法真正找到我想要的东西 我每个类有大约 5 个测试 我只想在所有连接的设备中执行一个测试 例如登录的端到端测试 我尝试使用连接的设备 但它不仅仅启动我想要的测试 我正在使用 Espresso
  • 如何在量角器测试中单击选择框中的选项?

    我正在使用 Protractor 在 Angular 应用程序中进行端到端测试 我试图单击选择框中的选项 但出现以下错误元素当前不可见 并且可能无法操作 我有这部分html
  • AuthenticationCredentialsNotFoundException:安全上下文不包含身份验证令牌

    我收到以下错误 AuthenticationCredentialsNotFoundException 安全上下文 不包含身份验证令牌 一个可能的原因可能是 没有为此 URL 配置防火墙 我尝试过解决方案 因为我知道当没有为路由配置安全防火墙
  • 在不同的目录中创建共享部分包结构的多个Python模块

    我正在开发一个包含单个应用程序的 Django 项目 该应用程序将在 GPL 下发布 因此我想将其与项目分开开发 使用该应用程序的个人网站 我试图对项目和应用程序使用基于我的域名的包结构 这就是我遇到问题的地方 这是我的文件结构 在适当的情
  • 更改 RichTextBox 的字体而不丢失格式

    如何在不丢失格式的情况下更改richtextbox所有内容的字体 我正在尝试使用 rtb SelectAll rtb SelectionFont new Font fontName 但字体构造函数除了字体类型之外还必须采用字体样式 粗体 斜