I am trying to get the font size of a running instance of WordPad (based on
Rich Edit). When I called the following function in my Windows Form which is
shown but not activated (SW_SHOWNOACTIVATE), WordPad crashed with the dialog
message - "WordPad MFC Application has encountered a problem and needs
to close. We are sorry for the inconvenience". I also found out that if I
run a test Windows Forms application containing a RichTextBox, then the same
problem
(crashing) occurs as with WordPad. The problem has to do with the Rich Edit
control when it receives the message EM_GETCHARFORMAT through interop. I'd be
very grateful for any advices on how to resolve this issue.
/// <summary>
/// Get the height of the font currently being used in the RichEdit control
/// <summary>
private int GetFontHeightFromRichEditControl()
{
int fontHeight = 0;
IntPtr idAttached = User32.GetWindowThreadProcessId(this.Handle,
IntPtr.Zero);
IntPtr idAttachedTo =
User32.GetWindowThreadProcessId(User32.GetForegroundWindow(), IntPtr.Zero);
// Attached
if (User32.AttachThreadInput(idAttached, idAttachedTo, 1) == IntPtr.Zero)
{
return fontHeight;
}
CHARFORMAT cf = new CHARFORMAT();
cf.cbSize = Marshal.SizeOf(cf);
// Get the focus window
IntPtr focusWindow = User32.GetFocus();
SendMessage(focusWindow, User32.EM_GETCHARFORMAT, SCF_SELECTION, ref cf);
if ((cf.dwMask & CFM_SIZE) == CFM_SIZE)
{
fontHeight = cf.yHeight / 20; // yHeight is in 1/20 pt
}
// Deattached
User32.AttachThreadInput(idAttached, idAttachedTo, 0);
return fontHeight;
}
[DllImport("user32")] public static extern IntPtr
GetWindowThreadProcessId(IntPtr hWnd, IntPtr lpdwProcessId);
[DllImport("user32")] public static extern IntPtr AttachThreadInput(IntPtr
idAttach, IntPtr idAttachTo, int fAttach);
[DllImport("user32")] public static extern int SendMessage(IntPtr hWnd, int
wMsg, int wParam, ref CHARFORMAT lParam);
[StructLayout( LayoutKind.Sequential )]
public 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;
}
Chris Taylor - 10 Jun 2005 20:12 GMT
Hi,
The crux of the problem is that the pointer (ref cf) that you are passing to
WordPad is not a valid pointer within the WordPad process.
When the RichTextBox hosted within WordPad attempts to write to to that
address to fill the structure an access violation is raised.
In the following post I describe a way to handle this situation, the post is
for a ListView control, but the same principal should apply for
other controls.
http://dotnetjunkies.com/WebLog/chris.taylor/archive/2004/05/31/14828.aspx
Hope this helps

Signature
Chris Taylor
http://dotnetjunkies.com/weblog/chris.taylor
>I am trying to get the font size of a running instance of WordPad (based on
> Rich Edit). When I called the following function in my Windows Form which
[quoted text clipped - 77 lines]
> public char[] szFaceName;
> }