Форум программистов, компьютерный форум, киберфорум
Visual Basic .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.76/25: Рейтинг темы: голосов - 25, средняя оценка - 4.76
129 / 108 / 24
Регистрация: 11.07.2017
Сообщений: 274

Шрифт из ресурсов

25.06.2019, 22:53. Показов 5817. Ответов 20
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Приветствую, уважаемые форумчане!

Такой вопрос. Есть шрифт ГОСТ в ресурсах. В Form1_Load его загружаю
VB.NET
1
2
3
4
5
6
7
            Dim buffer() As Byte
            buffer = My.Resources.gost 'Шрифт GOST Type A .tft
            Dim ip As IntPtr = Runtime.InteropServices.Marshal.AllocHGlobal(Runtime.InteropServices.Marshal.SizeOf(GetType(Byte)) * buffer.Length)
            Runtime.InteropServices.Marshal.Copy(buffer, 0, ip, buffer.Length)
            fnt.AddMemoryFont(ip, buffer.Length)
            lblKF_A4.Font = New Font(fnt.Families(0), 9, FontStyle.Italic)
            lblKF_A3.Font = New Font(fnt.Families(0), 9, FontStyle.Italic)
На компе, где уже установлен данный шрифт, все норм. На другом, где его нет, все, что прописано в Form1_Load не проходит, остается шрифт по умолчанию. Но в другом методе, который используется после загрузки формы
VB.NET
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    Private Sub PrintReversNumber()
        Try
            Dim fs As New FontStyle
            fs = FontStyle.Italic Or FontStyle.Bold
            Dim font As New Font(fnt.Families(0), 14, fs)
            Dim g As Graphics = pbNumber.CreateGraphics
            g.Clear(Me.BackColor)
            g.TranslateTransform(200, 22)
            g.RotateTransform(180)
            g.DrawString(f.number, font, New SolidBrush(Color.Black), New PointF(0, 0))
            g.Dispose()
        Catch ex As Exception
            'не получилось что-то, и хсним
        End Try
    End Sub
все рисует нужным шрифтом, используется тот же fnt.Families(0).
Почему так? И как это пофиксить?
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
25.06.2019, 22:53
Ответы с готовыми решениями:

Шрифт из ресурсов
Всем привет! Добавил в ресурсы программы (через Project -> Resources and Image) шрифт. Шрифт называется NeoSansPro.ttf. Ему присвоился...

Шрифт из ресурсов (окно, HDC)
Всем привет! Появился вопрос, как применить своей программе шрифт из ресурсов? Для начала как его применить HDC (именно из ресурсов) ...

Загрузить свой шрифт из ресурсов
Задача - вставить свой шрифт в программу, чтобы получился только ехе-шник без лишних файлов\папок со шрифтами. Закинул shtrixmicro.ttf в...

20
Лень — мое второе и
 Аватар для Orlangur
3228 / 2416 / 687
Регистрация: 28.11.2014
Сообщений: 3,601
Записей в блоге: 3
26.06.2019, 08:40
rvs_dk, попробуйте прописать это не в Form.Load, а в Form.Shown
Порядок событий в формах Windows Forms
1
129 / 108 / 24
Регистрация: 11.07.2017
Сообщений: 274
27.06.2019, 01:40  [ТС]
Orlangur1991, не помогло. Шрифт в ресурсах есть, а в контролах его нет. И это только на одном из компьютеров.

Добавлено через 8 минут
Причем, если сделать загрузку шрифта из файла
VB.NET
1
fnt.AddFontFile(Application.StartupPath + "\resourses\gost.ttf")
то все работает.
0
Модератор
Эксперт .NET
 Аватар для Yury Komar
4358 / 3428 / 512
Регистрация: 27.01.2014
Сообщений: 6,258
27.06.2019, 14:01
rvs_dk, посмотри вот этот вариант. Извиняюсь за код на C#, нету возможности и времени сейчас его перевести:

you'll need to use the PrivateFontCollection.AddMemoryFont() method. For example, I added a font file named "test.ttf" as a resource and used it like this:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
using System.Drawing.Text;
using System.Runtime.InteropServices;
...
public partial class Form1 : Form {
    private static PrivateFontCollection myFonts;
    private static IntPtr fontBuffer;
 
    public Form1() {
        InitializeComponent();
        if (myFonts == null) {
            myFonts = new PrivateFontCollection();
            byte[] font = Properties.Resources.test;
            fontBuffer = Marshal.AllocCoTaskMem(font.Length);
            Marshal.Copy(font, 0, fontBuffer, font.Length);
            myFonts.AddMemoryFont(fontBuffer, font.Length);
        }
    }
 
    protected override void OnPaint(PaintEventArgs e) {
        FontFamily fam = myFonts.Families[0];
        using (Font fnt = new Font(fam, 16)) {
            TextRenderer.DrawText(e.Graphics, "Private font", fnt, Point.Empty, Color.Black);
            //e.Graphics.DrawString("Private font", fnt, Brushes.Black, 0, 0);
        }
    }
}
Do note that the fontBuffer variable is static intentionally. Memory management is difficult when you use AddMemoryFont(), the memory needs to remain valid as long as the font can be used and the PrivateFontCollection is not yet disposed. Be sure not to call Marshal.FreeCoTaskMem() if you don't have that guarantee, it is a very common bug that causes very hard to diagnose text corruption. You only get an AccessViolationException when you are lucky. Keeping it valid for the life of the program is the simple solution.
Добавлено через 1 минуту
ты используешь AllocHGlobal, а следует использовать AllocCoTaskMem
1
129 / 108 / 24
Регистрация: 11.07.2017
Сообщений: 274
27.06.2019, 19:02  [ТС]
Yury Komar, спасибо, на другом компе проверю только вечером.
Но странно то, что в процессе работы программы шрифт то используется, но для рисования. Рисует тем самым ГОСТовским шрифтом. А вот лабелы и текстбоксы его не принимают. Уж не знаю, может из-за того, что через гитхаб передаю туда обратно, что то из ресурсов отваливается.

Добавлено через 4 часа 9 минут
Yury Komar, изменил на
VB.NET
1
            Dim ip As IntPtr = Runtime.InteropServices.Marshal.AllocCoTaskMem(Runtime.InteropServices.Marshal.SizeOf(GetType(Byte)) * buffer.Length)
ничего не меняется. Видимо так и придется таскать с собой шрифт.
0
2282 / 1598 / 400
Регистрация: 26.06.2017
Сообщений: 4,732
Записей в блоге: 1
27.06.2019, 22:39
Мне кажется правильнее будет сделать пакет инсталляции Вашей софтины, в который включить установку необходимых шрифтов в систему. Так шрифт будет доступен везде и всегда.
P.S. зачем-то ведь придумали установку программ.
1
 Аватар для timsc1
15 / 15 / 2
Регистрация: 27.11.2011
Сообщений: 714
28.06.2019, 22:40
Использование шрифта из ресурсов без установки в системе (код Sklifosofsky)


VB.NET
1
2
3
4
5
Dim fc As New System.Drawing.Text.PrivateFontCollection()
 
        fc.AddMemoryFont(System.Runtime.InteropServices.GCHandle.Alloc(My.Resources.ARIALUNI, Runtime.InteropServices.GCHandleType.Pinned).AddrOfPinnedObject, My.Resources.ARIALUNI.Length)
 
        Dim f As Font = New Font(fc.Families(0), 20)
2
129 / 108 / 24
Регистрация: 11.07.2017
Сообщений: 274
29.06.2019, 13:21  [ТС]
timsc1, не помогает. У меня какой то другой глюк. Шрифт из ресурсов попадает в fc.Families(0). Но ни на этапе загрузки, ни потом контролы его не принимают. Рисование этим шрифтом идет на ура.
0
 Аватар для Sklifosofsky
1086 / 916 / 213
Регистрация: 29.09.2015
Сообщений: 1,019
29.06.2019, 22:34
Проверьте на любом контроле событие FontChanget проходит или нет с этим шрифтом

В общем ковырнул исходники некоторых контролов. Так там без особых проверок используется рисование при помощи GDI с указанным шрифтом. Раз вы говорите что отдельно рисование нормально происходит, то и контролами должно происходить тоже самое. Единственное хочу убедиться, что контролу в итоге присваивается указанный вами шрифт
1
129 / 108 / 24
Регистрация: 11.07.2017
Сообщений: 274
06.07.2019, 23:12  [ТС]
Sklifosofsky, 2 раза при загрузке приложения происходит событие FontChanged.
Вот что выдает txtName.Font.ToString():

[Font: Name=Microsoft Sans Serif, Size=14, Units=3, GdiCharSet=204, GdiVerticalFont=False]
[Font: Name=GOST type A, Size=14, Units=3, GdiCharSet=1, GdiVerticalFont=False]

Но по факту шрифт не меняется. Так и остается Microsoft Sans Serif.

Добавлено через 5 минут
И еще, если шрифт в свойствах изменить на любой, например на Mistral, то также 2 раза происходит событие FontChanged

[Font: Name=Mistral, Size=14,25, Units=3, GdiCharSet=204, GdiVerticalFont=False]
[Font: Name=GOST type A, Size=14, Units=3, GdiCharSet=1, GdiVerticalFont=False]

По факту выходит Microsoft Sans Serif.
0
Модератор
Эксперт .NET
 Аватар для Yury Komar
4358 / 3428 / 512
Регистрация: 27.01.2014
Сообщений: 6,258
07.07.2019, 08:59
rvs_dk, так в событии Form.Shown тоже не меняет?
0
129 / 108 / 24
Регистрация: 11.07.2017
Сообщений: 274
07.07.2019, 11:11  [ТС]
Yury Komar, пробовал, ничего не меняется.
0
 Аватар для Sklifosofsky
1086 / 916 / 213
Регистрация: 29.09.2015
Сообщений: 1,019
09.07.2019, 00:19
rvs_dk, копаем дальше. lblKF_A4 это Label? Какой флаг имеет свойство UseCompatibleTextRendering?
И можно мне скинуть это чудо шрифт?

Добавлено через 11 минут
Отбой, шрифт нашел. Выставьте флаг UseCompatibleTextRendering = True

Для всего приложения можно установить этот параметр по умолчанию.
Свойства проекта->Приложение->
Кнопка - Просмотр событий приложения

Вставить код

VB.NET
1
2
3
4
5
6
7
8
9
Namespace My
    Partial Friend Class MyApplication
        Protected Overloads Shared ReadOnly Property UseCompatibleTextRendering() As Boolean
            Get
                Return True
            End Get
        End Property
    End Class
End Namespace
2
Модератор
Эксперт .NET
 Аватар для Yury Komar
4358 / 3428 / 512
Регистрация: 27.01.2014
Сообщений: 6,258
09.07.2019, 13:34
Sklifosofsky, Что за чудо шрифт такой? Что не рисуется, как все осальные?)
0
2282 / 1598 / 400
Регистрация: 26.06.2017
Сообщений: 4,732
Записей в блоге: 1
09.07.2019, 15:45
Меня насторожила вот эта строка:
VB.NET
1
buffer = My.Resources.gost 'Шрифт GOST Type A .tft
а если конкретнее вот это .tft
Посмотрите внимательнее, какие файлы у Вас в ресурсах. Дело в том, что .tft совсем не одно и тоже, что .ttf.
Я сталкивался с такими шрифтами, но не при программировании. Если не полностью установить файлы шрифта, он нормально не отображается.
1
129 / 108 / 24
Регистрация: 11.07.2017
Сообщений: 274
09.07.2019, 21:59  [ТС]
Я пока в отпусках, постараюсь завтра вечером все проверить. Спасибо всем за помощь.
0
 Аватар для Sklifosofsky
1086 / 916 / 213
Регистрация: 29.09.2015
Сообщений: 1,019
10.07.2019, 00:21
Yury Komar, да там дело не совсем в шрифте. Формы c коробки .net для рендеринга текста по умолчанию юзают обычный GDI при UseCompatibleTextRendering = False (класс TextRenderer), при True - GDI+. Так вот в исходниках для первого варианта понаписано много инструкций: поверка кеша загруженных шрифтов, добавление шрифта в кеш если нет. Вот при добавлении где-то происходит косяк, что происходит сброс на дефолтный шрифт.
Особо времени проверить не было на каком моменте это происходит, но когда проверял отдельные методы связанные с нативными функциями которые прописанные там (где я надеялся встретить ошибку) - то все прекрасно работало. Предполагаю, где-то есть древняя ошибка разработчиков части этого кода.
Во втором варианте доп. инструкций ВООБЩЕ нет. Ничего не кешируется и не перепроверяется, все работает напрямую с классом Graphics. Вот вам и .net

Добавлено через 4 минуты
Забыл добавить, что все прекрасно работает в первом варианте, когда шрифт уже установлен в системе.
2
129 / 108 / 24
Регистрация: 11.07.2017
Сообщений: 274
10.07.2019, 21:46  [ТС]
1) Шрифт .ttf, это я в комментариях накосячил.
2) Вставил код от Sklifosofsky, в свойствах появился данный пункт. Поставил True - все заработало. Но только на label'ах.
3) У меня еще есть textBox'ы - можно ли их заставить так же рисовать данный шрифт?
0
 Аватар для Sklifosofsky
1086 / 916 / 213
Регистрация: 29.09.2015
Сообщений: 1,019
12.07.2019, 11:30
Провел еще исследований проблема прояснилась в неожиданном месте. В вкратце глюк происходит при использовании метода добавления .AddMemoryFont, но все прекрасно работает при добавлении в виде файла .AddFontFile. С чем это связано объяснить не могу, т.к. дальше нативной функции действия проследить не могу.
Позже выложу вариант кода, где выгрузка из ресурсов происходит в Temp папку системы и далее использование. При завершении работы приложения временные файлы будут удаляться.
1
129 / 108 / 24
Регистрация: 11.07.2017
Сообщений: 274
12.07.2019, 14:23  [ТС]
Да, все именно так. Тоже хотел спросить про вариант сохранения из ресурсов в файл.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
12.07.2019, 14:23
Помогаю со студенческими работами здесь

Как в консоли автоматически выбрать шрифт Lucida Console, а не точечный шрифт?
Например №36 (размер шрифта 22х36).

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

Шрифт собственной страницы отличается от шрифта сайта, не смотря на то,что шрифт указан одинаково в обеих страницах
Сверстал страницу по образцу данного сайта https://www.biglion.ru/deals/pivnoy-restoran-set9-50/. Я даже указывал ссылки на шрифт, которые...

Шрифт. как интегрировать нестандартный шрифт в БД?
Скажите пожалуйста, можно ли как-то интегрировать нестандартный шрифт в базу данных?

8x8 стандартныый растровый шрифт что это? Это значит шрифт Lucida 8 pt?
Пишу программку но не могу разобраться с этим понятием


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru