7

This question has been asked in practically every forum, including here but there are no acceptable answers anywhere that I can find. I'm beginning to think that there is actually no solution and I just have to wrap my code in a try/catch block and apologise to the user and ask them to pick another font.

I want to show a FontDialog so that a user can change the fonts on a Chart, however if the user selects a non-TrueType font, then an exception is thrown. GDI+ can only handle TrueType fonts.

How can I filter the fonts from the FontDialog which cannot be used with GDI+?

Community
  • 1
  • 1
Ozzah
  • 10,631
  • 16
  • 77
  • 116

4 Answers4

5

The FontDialog class already does this, it uses the ChooseFont() API call with the CF_TTONLY option. Which forces the dialog to only display fonts that advertise themselves as TrueType fonts. The links suggests there are fonts around that fool the dialog, never heard of it before until today. Which makes it quite rare but certainly not unexpected, there are lots of junk fonts around with bad metadata.

There isn't anything you can do to catch the exception, it is raised in a callback function that's baked into the .NET framework. Rewriting the class is an option but not a pleasant one. Uninstalling the troublemaker font is certainly the easy solution.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • 2
    Thanks Hans. I'm running Win7 x64 with Adobe Photoshop and Mathematica fonts installed only; the rest are all stock fonts. About half of my fonts lead to this exception, so uninstalling the troublesome font(s) is not an option, sadly. – Ozzah Jun 13 '11 at 23:27
1

You can use the custom FontDialog available here to overcome this exception. It is developed in C#.Net.

Umar
  • 11
  • 1
  • MS didn't solve this bug, up to now. The exception triggers with some TTF fonts, telling they are not TTF. This Custom FontDialog is much better than the default FontDialog! It not only solves that problem, but it also can properly handle long font names like "Noto Sans SemCond SemBd". The default FontDialog will forget such name when reopening it. It has Checkboxes for Italic, Bold, and Strikeout. I had to add a flag for the button OK, though, so I could see I didn't hit Cancel. – Jack Jun 21 '21 at 15:00
1

No real nice way around this one except to try/catch block it

try
{
    if (m_FontDialog.ShowDialog(frmMain.mainForm) == DialogResult.OK)
    {
        //Successful
    }
}
catch (Exception ex)
{
    //Not a truetype font
    MessageBox.Show(frmMain.mainForm, ex.Message + Environment.NewLine + "Font not changed.", "Font Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
Astro29
  • 11
  • 1
  • Except that this is not a catchable exception! – Ozzah Jul 22 '11 at 06:33
  • @Ozzah: What do you mean by "not a catchable exception"? The catch works fine. Does it mean you are not supposed to catch it? – Binus Oct 24 '11 at 12:08
  • @Binus The exception cannot be caught: just like StackOverflowException. If you put the code inside a try/catch, nothing happens - the exception still happens and the program still crashes. – Ozzah Oct 24 '11 at 21:49
  • @Ozzah: Maybe there is more than one similar issue out there. I was able to reproduce described behavior today using following font: [Galette](http://www.dafont.com/galette.font). I obtained _ArgumendException_, which can be caught without problems. It is only kind of silly to notify the user that the selected font does not work. It would be much better filter those fonts out before selection. – Binus Oct 24 '11 at 22:53
0

I'm not sure whether it will work, but try to set FontDialog.AllowSimulations to false.

Centro
  • 3,892
  • 2
  • 25
  • 31