Reputation: 2636
Using Visual Studio 2012 Ultimate C#.NET4.5
Well this one has rotted my brain, I've got some code I tweaked a little to embed a font onto my application. So far so good it works, so my client machine no longer needs the font.
Here's my code so far:
//add font
[DllImport("gdi32.dll", ExactSpelling = true)]
private static extern IntPtr AddFontMemResourceEx(byte[] pbFont, int cbFont, IntPtr pdv, out uint pcFonts);
/****/
//Dispose Font
[DllImport("gdi32.dll", ExactSpelling = true)]
internal static extern bool RemoveFontMemResourceEx(IntPtr fh);
/****/
static private IntPtr m_fh = IntPtr.Zero;
static private PrivateFontCollection m_pfc = null;
public Font GtSpecialFont(float size)
{
Font fnt = null;
if (null == m_pfc)
{
Stream stmFnt = Assembly.GetExecutingAssembly().GetManifestResourceStream("NewLabelPrinter.Resources.FREE3OF9.TTF"); // always returns null?
if (null != stmFnt)
{
byte[] rgbyt = new byte[stmFnt.Length];
stmFnt.Read(rgbyt, 0, rgbyt.Length);
uint cFonts;
AddFontMemResourceEx(rgbyt, rgbyt.Length, IntPtr.Zero, out cFonts);
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);
}
}
}
try
{
if (m_pfc.Families.Length > 0)
{
fnt = new Font(m_pfc.Families[0], size);
}
}
catch (Exception rdf)
{
MessageBox.Show("", rdf.ToString());
}
return fnt;
}
private void myFont()
{
txtBarCal.Font = GtSpecialFont(48.0f);
txtBarCodeOLD.Font = GtSpecialFont(48.0f);
txtBarCV.Font = GtSpecialFont(48.0f);
txtBarBK.Font = GtSpecialFont(48.0f);
txtNewBar.Font = GtSpecialFont(48.0f);
}
As you can see this code is pretty nice, I'm loving it works perfectly. Now my form finally can have fonts without my clients needing them.
there is one small problem, how in the world do I use this to set a visual studio report textbox font???? there is no code for the report so I'm at an utter loss!
well I'm hoping someone somewhere knows something, the Only thing I can think of, is something to do with using expressions and/or possibly parameters.
many thanks guys!
Upvotes: 4
Views: 1842
Reputation: 941347
You have some odds to make this work. Your code makes the font available both to any code that renders with GDI as well as any code that renders with GDI+. With GDI being the likely one that ReportViewer uses to render the report, it is a pretty old chunk of code. The only real requirement is that you ensure that this code runs before you ever display the report.
The one thing you however cannot rely on is the Font that's returned by your code, for obvious reasons. To fix that, you'll have to refer to the font in your report by the family name. To make that work, you'll have to actually install the font on your dev machine so you can select it in the report designer. On the user's machine, that font name should then be good enough to get the font selected from the memory font.
No guarantees, just decent odds.
Do make sure you fix a bug in this code, also possibly the reason you've got a problem with the report, releasing the memory for the font after calling AddMemoryFont() is not correct. You must keep it allocated as long as the app can use the font. The failure mode is very flaky since it has such good odds of not being noticed, background answer is here. In a nutshell: just don't call FreeCoTaskMem(). Windows will clean up.
Upvotes: 1