views:

62

answers:

2

Hi,

When a selection in WindowsForms RichTextbox uses two or more different font sizes (eg. you select text with font size 9 and some other text with font size 16 in the same selection), SelectionFont.Size always returns 13. Is there any way to detect that two different sizes are selected?

A: 

I'm not 100% sure but I think that the only way of doing that is to loop through and check the font size of every single character separately.

ho1
A: 

If a range is selected which contains items that have the same font, but different sizes, the control incorrectly reports that the selection contains a font with size 13. I'm not certain this can be fixed. Perhaps it's always 13 in this case, perhaps not, I don't know.

But i use the follow Solution ...
Found via Reflection in Methode

public class RichTextBox : TextBoxBase ...
  private Font GetCharFormatFont(bool selectionOnly)**

Example Code:
Content => The RichTextBox-Control

// var lSize = Content.SelectionSize;
var lSize = RichTextBoxHelper.GetSelectionSize(Content);

if (lSize.HasValue)
  ComboBoxFontSize.Text = Convert.ToString(lSize.Value);
else
  // Multible Sizes ...
  ComboBoxFontSize.Text = string.Empty;

Helper Methode (Class):

using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace UnimatrixOne
{
  public class RichTextBoxHelper
  {
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr SendMessage(HandleRef hWnd, int msg, int wParam, [In, Out, MarshalAs(UnmanagedType.LPStruct)] CHARFORMATA lParam);

    private const long CFM_SIZE = 0x80000000;
    private const int EM_GETCHARFORMAT = 0x043A;
    private const int SCF_SELECTION = 0x01;

    /// <summary> 
    /// Contains information about character formatting in a rich edit control. 
    /// </summary> 
    /// <remarks><see cref="CHARFORMAT"/>works with all Rich Edit versions.</remarks> 
    [StructLayout(LayoutKind.Sequential, Pack = 4)]
    public class CHARFORMATA
    {
      public int cbSize = Marshal.SizeOf(typeof(CHARFORMATA));
      public int dwMask;
      public int dwEffects;
      public int yHeight;
      public int yOffset;
      public int crTextColor;
      public byte bCharSet;
      public byte bPitchAndFamily;
      [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
      public byte[] szFaceName = new byte[32];
    }

    /// <summary> 
    /// Gets or sets the underline size off the current selection. 
    /// </summary>
    [Browsable(false),
    DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
    public static float? GetSelectionSize(RichTextBox control)
    {
      var lParam = new CHARFORMATA();
      lParam.cbSize = Marshal.SizeOf(lParam);

      // Get the underline style 
      SendMessage(new HandleRef(control, control.Handle), EM_GETCHARFORMAT, SCF_SELECTION, lParam);
      if ((lParam.dwMask & -CFM_SIZE) != 0)
      {
        float emSize = ((float)lParam.yHeight) / 20f;

        if ((emSize == 0f) && (lParam.yHeight > 0))
          emSize = 1f;

        return emSize;
      }
      else
        return null;
    }
  }
}
Donald Peter