私はこのコードを使用して埋め込みフォントを取得しています:
/// <summary>
/// Returns an Embedded Font
/// </summary>
/// <param name="ImagePath">String begins with namespace e.g MyProgram.Image.png</param>
/// <returns></returns>
public static Font GetEmbeddedFont(string FontPath, float Size)
{
Font _font = null;
Thread getFontThread = new Thread(() => GetFont(FontPath, Size, out _font));
getFontThread.Start();
getFontThread.Join();
return _font;
}
#region GetFont
private static void GetFont(string FontPath, float Size, out Font FontOut)
{
Font fnt = null;
Assembly asm = Assembly.GetExecutingAssembly();
Stream resStream = asm.GetManifestResourceStream(FontPath);
if (null != resStream)
{
//
// GDI+ wants a pointer to memory, GDI wants the memory.
// We will make them both happy.
//
// First read the font into a buffer
byte[] rgbyt = new Byte[resStream.Length];
resStream.Read(rgbyt, 0, rgbyt.Length);
resStream.Close();
// Then do the unmanaged font (Windows 2000 and later)
// The reason this works is that GDI+ will create a font object for
// controls like the RichTextBox and this call will make sure that GDI
// recognizes the font name, later.
uint cFonts;
AddFontMemResourceEx(rgbyt, rgbyt.Length, IntPtr.Zero, out cFonts);
// Now do the managed font
IntPtr pbyt = Marshal.AllocCoTaskMem(rgbyt.Length);
if (null != pbyt)
{
Marshal.Copy(rgbyt, 0, pbyt, rgbyt.Length);
m_pfc = new PrivateFontCollection();
m_pfc.AddMemoryFont(pbyt, rgbyt.Length);
Marshal.FreeCoTaskMem(pbyt);
}
}
if (m_pfc.Families.Length > 0)
{
// Handy how one of the Font constructors takes a
// FontFamily object, huh? :-)
fnt = new Font(m_pfc.Families[0], Size);
}
m_pfc.Dispose();
FontOut = fnt;
}
このメソッドが短時間に複数回呼び出されると、エラーが発生するように見えるため、スレッドを使用してスレッドが終了するのを待機しようとしています。
このエラーの発生をどのように防ぐことができますか。これは、メソッドが互いにすばやく連続して呼び出されることに関係していると思います。
ここで例外が発生します:
_font = value;
using (Graphics g = _parent.CreateGraphics())
{
SizeF soize = g.MeasureString(_text, _font);
_size = new Size((int)soize.Width, (int)soize.Height);
_width = _size.Width;
_height = _size.Height;
}
行g.MeasureString(_text、_font);
ただし、フォントがGetEmbeddedFontメソッドを使用して設定されている場合にのみエラーがスローされるため、エラーがGetEmbeddedFontメソッドにあることはわかっています。
1回は正常に動作しますが、2回目に使用して、最初の直後に使用すると、エラーがスローされます。
そして、コードをデバッグすると、_fontはこれを返します。
{Name = '((System.Drawing.Font)(_font)).fontFamily.Name' threw an exception of type 'System.ArgumentException' Size=15.0}