Как установить RichTextBox.SelectionFont FontFamily без изменения стиля? - PullRequest
0 голосов
/ 27 октября 2009

Один из элементов управления в моем приложении ограничивает возможности пользователя изменять только стиль шрифта (B, I, U) и цвет текста. Я создал собственный элемент управления, который наследуется от RichTextBox для этой цели. Я могу перехватить CTRL-V и установить шрифт вставленного текста на SystemFonts.DefaultFont. Проблема, с которой я сейчас сталкиваюсь, заключается в том, что вставленный текст содержит, например, полужирный, наполовину обычный стиль - жирный шрифт теряется.

т.е. «Foo Bar » будет просто вставлен как «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();
}

}

Кто-нибудь может придумать более чистое (и более быстрое) решение?

Ответы [ 2 ]

0 голосов
/ 03 марта 2010

Для тех, кто хочет получить ответ Delphi, выдержка, которая даст вам основную идею:

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;
0 голосов
/ 28 октября 2009

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