2010-03-06 6 views
3

У меня возникли проблемы с многочисленными пользователями, не имеющими один из шрифтов Windows Core, установленных на их машине (например, Courier New, Comic Sans MS, Arial). Всякий раз, когда я пытаюсь построить один из них, он выдает ошибку, а не возвращается к соответствующему, или действительно, любому другому шрифту.Шрифты с жестким кодированием в DotNET

Каков наилучший способ создания шрифта, если я хочу, чтобы он был курьером, но я не особенно привязан к нему?

ответ

4

Вы можете вставлять шрифты в качестве ресурсов и использовать ключевое слово unsafe (и его необходимо скомпилировать с помощью «небезопасно») для получения шрифтов ... Вот пример кода, который я использовал для установки пользовательского элемента управления шрифтом типа «OCR»

 
private PrivateFontCollection pfc = new PrivateFontCollection(); 
private Font _fntOCRFont = null; 
private enum FontEnum{ 
    OCR = 0 
}; 

что объявляет частную коллекцию шрифтов ... шрифт «OCR» встраивается в качестве ресурса, используя соглашение об именовании, где «Foo» является пространством имен, следовательно, имя ресурса будет «Foo .ocraext.ttf '... Посмотрите на «InitOCRFont» здесь, который загружает шрифт и добавляет его в коллекцию:

 
private void InitOCRFont(){ 
    try{ 
     System.IO.Stream streamFont = this.GetType().Assembly.GetManifestResourceStream("foo.ocraext.ttf"); 
     if (streamFont != null){ 
      byte[] fontData = new byte[streamFont.Length]; 
      streamFont.Read(fontData, 0, (int)streamFont.Length); 
      streamFont.Close(); 
      unsafe{ 
       fixed(byte *pFontData = fontData){ 
        this.pfc.AddMemoryFont((System.IntPtr)pFontData, fontData.Length); 
       } 
      } 
     }else{ 
      throw new Exception("Error! Could not read built-in Font."); 
     } 
    }catch(Exception eX){ 
     throw new Exception("InitOCRFont Method - Exception occurred!\nException was: " + eX.Message); 
    } 
} 

Здесь я установил элементы управления в элементе управления пользователя, чтобы установить шрифт на этот шрифт «OCR», итерируя через коллекцию, см. «InitializeCtlFont», размер шрифта равен 10 и является жирным шрифтом «тип»:

 
private void InitializeCtlFont(){ 
    this._fntOCRFont = new Font(this.pfc.Families[0], 10.0F, System.Drawing.FontStyle.Bold); 
    if (this._fntOCRFont != null){ 
     foreach(Control ctl in this.Controls){ 
      if (ctl != null && ((ctl is Label) || (ctl is TextBox))){ 
         ctl.Font = this._fntOCRFont; 
        } 
     } 
    } 
} 

Когда пользовательский элемент управление получает утилизировать, то необходимо, чтобы высвободить ресурсы, занятый шрифт, как показано здесь, в методе Dispose:

 
try{ 
    if (this._fntOCRFont != null) this._fntOCRFont.Dispose(); 
}catch{ 
} 
try{ 
    if (this.pfc != null) this.pfc.Dispose(); 
}catch{ 
} 

Надеется, что это помогает, с наилучшими пожеланиями, Том.

+0

Tommie, спасибо за прекрасный ответ. Боюсь, что это не принесет мне много пользы. Нам не разрешено распространять все эти шрифты, мое приложение должно быть бит-глухим агностиком, и даже предполагается, что он будет работать на Mac через Mono. Я искренне надеюсь, что мне не придётся прибегать к решению довольно этого жесткого ядра ... –

+0

@David: Я не уверен, что Mono под Mac будет иметь PrivateFontCollection .... поскольку это зависит от Windows, так или иначе, Я бы подумал, что это бесполезно ....если нет более общего способа сделать это ... для того, чтобы чистая кросс-платформа работала, никаких pinvokes и никаких API-интерфейсов Win32 ... – t0mm13b

2

Ну, вы могли бы использовать, чтобы получить FontFamily.GenericMonospaceв моноширинный шрифт, а не конкретно Courier:

Font f = new Font(FontFamily.GenericMonospace, 12, FontStyle.Regular); 

Есть a few more such generic font families as well.

Вы также можете использовать это в качестве последнего средства после того, как попробовали свой предпочтительный шрифт и запутались в исключение.

+0

Спасибо, Йоханнес, мне нужно исследовать это немного больше, чтобы узнать, смогу ли я его применить. –

2

Это очень необычно. Диспетчер шрифтов Windows всегда будет предоставлять заменяющий шрифт, когда ваша программа запрашивает шрифт, недоступный на целевой машине. Этот заменяющий шрифт обычно будет Microsoft Sans Serif на XP, Segoe UI в более поздних версиях. Ни один из них никогда не должен вызывать проблемы.

Опять же, если машина настолько перепутана, что у нее нет доступных основных шрифтов, она может вообще не иметь шрифта TrueType. Да, это будет бомбить вашу программу. Честно говоря, это не то, с чем вам придется иметь дело, если это не очень ценный клиент. Это иначе тривиально решает команда поддержки вашего клиента.

+0

Привет, nobugz, это уже много раз, но, похоже, оно ограничено для людей с «странными» локализациями (турецкий, китайский, корейский и т. д.). У меня действительно сложилось впечатление, что логика Windows с ошибкой Windows должна предотвращать ее сбой, но это явно не так. Спасибо за ответ, хотя, это может быть просто лучший подход, чтобы игнорировать это на данный момент ... –

+0

Ух, они даже используют лицензионную копию Windows? Может быть, что-то вроде Вина. Не твоя проблема. –

+0

nobugz, я понятия не имею. И если я спрошу их, они, вероятно, будут лгать об этом, если бы они были. Точка, независимо от того, украли ли они Windows, они * являются законными нашими клиентами. Исправить не все, что трудно, конечно («Просто установите Font X»), но это вызвало мое любопытство о том, почему код вообще рушится. –

 Смежные вопросы

  • Нет связанных вопросов^_^