كيف أقوم بتعيين RichTextBox.SelectionFont FontFamily دون تغيير النمط؟

StackOverflow https://stackoverflow.com/questions/1632951

  •  06-07-2019
  •  | 
  •  

سؤال

أحد عناصر التحكم في تطبيقي يحد من قدرة المستخدم على تغيير نمط الخط فقط (B، I، U) ولون النص.لقد قمت بإنشاء عنصر تحكم مخصص يرث من RichTextBox لهذا الغرض.أنا قادر على اعتراض CTRL-V، وتعيين خط النص الملصق عليه SystemFonts.DefaultFont.المشكلة التي أواجهها حاليًا هي إذا كان النص الملصق يحتوي، على سبيل المثال، على نمط نصف غامق ونصف عادي - يتم فقدان الخط الغامق.

أي."فو حاجِز" سيتم لصقه فقط كـ "Foo Bar".

فكرتي الوحيدة حاليًا هي تصفح النص حرفًا بحرف (جداً بطيء)، وافعل شيئًا مثل:

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();
}

}

هل يمكن لأي شخص أن يفكر في حل أنظف (وأسرع)؟

هل كانت مفيدة؟

المحلول

"nobugz" في منتديات MSDN أجابني عن هذا (كنت بحاجة إلى إجابة بسرعة، لذلك بعد يوم تقريبًا من التشويش من SO، كان علي أن أبحث في مكان آخر - لا تحكم علي!):

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);

نصائح أخرى

بالنسبة لأولئك الذين يريدون إجابة دلفي، مقتطف ليعطيك الفكرة الأساسية:

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;
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top