代码之家  ›  专栏  ›  技术社区  ›  Philip Wallace

如何在不更改样式的情况下设置RichTextBox.SelectionFont FontFamily?

  •  0
  • Philip Wallace  · 技术社区  · 16 年前

    我的应用程序中的一个控件限制用户只能更改文本的字体样式(B、I、U)和颜色。为此,我创建了一个从RichTextBox继承的自定义控件。我可以截取CTRL-V,并将粘贴文本的字体设置为 SystemFonts.DefaultFont . 我目前面临的问题是,如果粘贴的文本包含,例如,半粗体半常规样式-粗体丢失。

    即“Foo” 酒吧

    我目前唯一的想法是逐字阅读这篇文章( 然后执行以下操作:

    public class MyRichTextBox : RichTextBox
    {
    
    private RichTextBox hiddenBuffer = new RichTextBox();
    
    /// <summary>
    /// This paste will strip the font size, family and alignment from the text being pasted.
    /// </summary>
    public void PasteUnformatted()
    {
        this.hiddenBuffer.Clear();
        this.hiddenBuffer.Paste();
    
        for (int x = 0; x < this.hiddenBuffer.TextLength; x++)
        {
            // select the next character
            this.hiddenBuffer.Select(x, 1);
    
            // Set the font family and size to default
            this.hiddenBuffer.SelectionFont = new Font(SystemFonts.DefaultFont.FontFamily, SystemFonts.DefaultFont.Size, this.hiddenBuffer.SelectionFont.Style);
        }
    
        // Reset the alignment
        this.hiddenBuffer.SelectionAlignment = HorizontalAlignment.Left;
    
        base.SelectedRtf = this.hiddenBuffer.SelectedRtf;
        this.hiddenBuffer.Clear();
    }
    

    }

    有人能想出一个更干净(更快)的解决方案吗?

    2 回复  |  直到 12 年前
        1
  •  0
  •   Philip Wallace    16 年前

    MSDN论坛上的“nobugz”帮我回答了这个问题(我很快就需要一个答案,所以在经历了差不多一天的风滚草风滚草之后,我不得不去别处看看——不要评判我!)

    using System.Runtime.InteropServices;
    ...
            public static bool SetRtbFace(RichTextBox rtb, Font font, bool selectionOnly) {
                CHARFORMATW fmt = new CHARFORMATW();
                fmt.cbSize = Marshal.SizeOf(fmt);
                fmt.szFaceName = font.FontFamily.Name;
                fmt.dwMask = 0x20000000;  // CFM_FACE
                return IntPtr.Zero != SendMessage(rtb.Handle, 0x444, (IntPtr)(selectionOnly ? 1 : 4), fmt);
            }
            [StructLayout(LayoutKind.Sequential, Pack = 4)]
            private class CHARFORMATW {
                public int cbSize;
                public int dwMask;
                public int dwEffects;
                public int yHeight;
                public int yOffset;
                public int crTextColor;
                public byte bCharSet;
                public byte bPitchAndFamily;
                [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x40)]
                public string szFaceName;
            }
    
            [DllImport("user32.dll", CharSet = CharSet.Auto)]
            private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, CHARFORMATW lParam);
    
        2
  •  0
  •   bosvos    16 年前

    对于那些想要德尔菲答案的人,请提供一份摘录,让您了解基本想法:

    using RichEdit; //reqd. for the constants and types
    
    var
      chformat : TCharFormat2;
      fontname : string;
    
    begin
      FillChar(chformat,sizeof(chformat),0);
      chformat.cbSize := sizeof(chformat);
      //only modify the szFaceName field, height etc. left alone
      chformat.dwMask :=  CFM_FACE; 
      //get the fontname set by the user
      fontname := AdvFontSelector1.Text;
      strpcopy(chformat.szFaceName,fontname);
      RichEdit1.Perform(EM_SETCHARFORMAT, SCF_SELECTION, lparam(@chformat));
    end;
    
    推荐文章