Форум программистов, компьютерный форум, киберфорум
Delphi: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.77/13: Рейтинг темы: голосов - 13, средняя оценка - 4.77
Нарушитель
10225 / 5655 / 1257
Регистрация: 12.03.2015
Сообщений: 26,180
RAD XE3+

Имя шрифта, подгруженного из ресурса

15.05.2020, 03:45. Показов 4253. Ответов 22

Студворк — интернет-сервис помощи студентам
Возможно ли узнать имя шрифта, подгруженного из ресурса (приватно). Функции для работы с перечислимыми шрифтами в этом случае не работают, хотя сами шрифты прекрасно отображаются.

Название: 001189.png
Просмотров: 274

Размер: 11.0 Кб

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const
  UF_RESOURCE_TYPENAME = 'RT_FONT'; // тип ресурса шрифтов (из RC-файла)
 
// загрузка приватного шрифта из ресурса. Прекрасно работает!
function LoadResourceFont(const ResourceName: string): HFont;
var
  FontsCount : integer;
begin
   var stream:= TResourceStream.Create(hInstance, ResourceName, UF_RESOURCE_TYPENAME);
   try
     result:= AddFontMemResourceEx(stream.Memory, stream.Size, nil, @FontsCount);
   finally
     stream.Free();
   end;
end;
Кто шарит?

модуль:
Кликните здесь для просмотра всего текста
Delphi
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
unit uFonts;
 
{$R fonts\fonts.res}
 
interface
 
{$REGION 'Info'}
(* Модуль работы со шрифтами.
   Инфа взята отсюда:
     https://delphisources.ru/forum/showthread.php?t=25264
     https://********************/showthread.php?t=180046
     http://users.atw.hu/delphicikk/listaz.php?id=2128&oldal=38
     http://www.undocprint.org/winspool/getfontresourceinfo
     https://forum.lazarus.freepascal.org/index.php?topic=39124.0 *)
{$ENDREGION}
 
{$REGION 'uses'}
uses
  //============================== Модули проекта ==============================
  //==================== Модули проекта с формами и фреймами ===================
  //=============================== Левые модули ===============================
  //=================== Системные модули, добавленные вручную ==================
  Windows, Messages, Classes, SysUtils, Graphics;
{$ENDREGION}
 
// установка всех шрифтов из секции ресурсов FONT
function InitUserFontResources(const SkipInstalled: Boolean = false): int32;
function GetUserFontData(const hf: HFONT; stream: TCustomMemoryStream): boolean;
 
// глобальные переменные
var
  UserFontNames: TStringList;
 
implementation
 
const
  UF_RESOURCE_TYPENAME = 'RT_FONT'; // тип ресурса шрифтов (из RC-файла)
 
// загрузка приватного шрифта из ресурса. Прекрасно работает!
function LoadResourceFont(const ResourceName: string): HFont;
var
  FontsCount : integer;
begin
   var stream:= TResourceStream.Create(hInstance, ResourceName, UF_RESOURCE_TYPENAME);
   try
     result:= AddFontMemResourceEx(stream.Memory, stream.Size, nil, @FontsCount);
   finally
     stream.Free();
   end;
end;
 
// коллбэк для перечисления EnumResourceNames()
function EnumResNameCallback(hModule: NativeUInt; lpszType: LPCTSTR; lpszName: LPTSTR; lParam: LONG_PTR): boolean; stdcall;
var
  list: TStringList absolute lParam;
begin
  var res_name:= string(lpszName);
  assert(res_name <> '');
 
  var hf:= LoadResourceFont(res_name);
  list.AddObject(Format('%s [0x%.8X]', [res_name, hf]), pointer(hf));
  result:= true;
end;
 
// установка всех шрифтов из секции ресурсов FONT
function InitUserFontResources(const SkipInstalled: Boolean): int32;
begin
  // чтение имён ресурсов-шрифтов
  if not EnumResourceNames(0, UF_RESOURCE_TYPENAME, @EnumResNameCallback, LONG_PTR(UserFontNames))
    then exit(-1);
 
  result:= UserFontNames.Count; // возвращает кол-во добавленных шрифтов
  SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
end;
 
// образ файла шрифта по HFont (не работает со шрифтами, установленными из памяти)
function GetUserFontData(const hf: HFONT; stream: TCustomMemoryStream): boolean;
begin
  var dc:= CreateCompatibleDC(0);
 
  if dc = 0
    then exit(false);
 
  try
    SelectObject(dc, hf);
    var size: int32:= GetFontData(dc, 0, 0, nil, 0); // размер данных
    if size <= 0
      then exit(false);
 
    stream.Size:= size;
    result:= GetFontData(dc, 0, 0, stream.Memory, size) = size;
  finally
    DeleteDC(dc);
  end;
end;
 
initialization
  UserFontNames:= TStringList.Create();
 
finalization
  FreeAndNil(UserFontNames);
 
end.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
15.05.2020, 03:45
Ответы с готовыми решениями:

Артефакты прозрачности при отображении TBitmap(подгруженного из png-ресурса) в строчках TPopupMenu.
Всем привет.:) Не очень получается использовать png для изображений в пунктах всплывающего меню. На некоторых появляются артефакты в...

Использование шрифта из ресурса
Можно ли добавить шрифт в ресурс, а после использовать его? Что бы вместо public static Font text_data = new...

Имя ресурса с именем из цикла
Доброго времени суток. Сразу к сути - в ресурсы проекта загружены изображения (pic_0, pic_1, pic_2 ... pic_100). Имеется форма с...

22
4187 / 1835 / 220
Регистрация: 06.10.2010
Сообщений: 4,123
15.05.2020, 09:11
GetTextFace тоже не работает? Может просто давать ресурсам соответствующее имя?
0
Нарушитель
10225 / 5655 / 1257
Регистрация: 12.03.2015
Сообщений: 26,180
15.05.2020, 15:02  [ТС]
Цитата Сообщение от murderer Посмотреть сообщение
GetTextFace тоже не работает?
нет. Не работают все функции, связанные со шрифтами через дескрипторы HFont.
Цитата Сообщение от murderer Посмотреть сообщение
Может просто давать ресурсам соответствующее имя?
В именах шрифтов встречаются недопустимые для имён ресурсов символы.
0
 Аватар для GoodWeather
886 / 588 / 179
Регистрация: 28.02.2017
Сообщений: 2,359
Записей в блоге: 1
15.05.2020, 19:34
Хранить в ресурсах текстовый файл с соответствием res_name его UI-имени..?

Не по теме:

А чито ето за ширифт? :О

0
Нарушитель
10225 / 5655 / 1257
Регистрация: 12.03.2015
Сообщений: 26,180
15.05.2020, 20:53  [ТС]
Цитата Сообщение от GoodWeather Посмотреть сообщение
Хранить в ресурсах текстовый файл с соответствием res_name его UI-имени..?
Ну зачем же так по-дилетантски? Я хочу сделать универсальную вещ. Костыльное решение любой дурак сделает, а я хочу добавить такой функционал во все свои программы. Чтобы приюзал модуль - и всё само сделалось. Я же самая ленивая жопа в рунете!

0
Нарушитель
10225 / 5655 / 1257
Регистрация: 12.03.2015
Сообщений: 26,180
16.05.2020, 02:31  [ТС]
Короче, написал я автосоздаваемый класс, который при старте приложения просматривает все ресурсы RT_FONT, вытаскивает из них подлинные имена шрифтов и приватно устанавливает их (до выхода из приложения), пропуская те шрифты, которые глобально установлены в системе.

Для тестирования я просто спионерил несколько рандомных шрифтов из интернетов и слепил из них RES-файл.



Врядли кому-то будет это интересно, но я оставлю это тут, на всякий случай - демо с исходником внутри.
Вложения
Тип файла: 7z UserFonts-rc.7z (5.11 Мб, 23 просмотров)
1
Нарушитель
10225 / 5655 / 1257
Регистрация: 12.03.2015
Сообщений: 26,180
16.05.2020, 02:45  [ТС]
Тестирование на виртуалках:





Прогоните под вайном, а то мне лениво его устанавливать.
0
16.05.2020, 16:02

Не по теме:

Почему эт дилетантский? Стандартный общепринятый подход. Вам что, никогда не прилетало от юзеров тикетов вида?:
"Почему написано `VinqueRg-Regular`?? Какой ещё Винкуй?? Шо за РэГэ?? Какой нафик Регулар?? Хотим чтоб было нормально написано!! Меняйте на `Античный`!!"

0
Нарушитель
10225 / 5655 / 1257
Регистрация: 12.03.2015
Сообщений: 26,180
16.05.2020, 16:11  [ТС]
Цитата Сообщение от GoodWeather Посмотреть сообщение
Почему эт дилетантский?
По кочану.
И по капусте.
Цитата Сообщение от GoodWeather Посмотреть сообщение
Вам что, никогда не прилетало от юзеров тикетов вида?
Никогда.
0
16.05.2020, 17:37

Не по теме:

Ну шо сказать, везёт. А нам по нескольку раз в неделю прилетает такое. Приходится делать.
Была бы такая штука со шрифтами - прям точно бы прикопались. Вот и как бы вы изменяли тогда в вашем варианте?

0
Нарушитель
10225 / 5655 / 1257
Регистрация: 12.03.2015
Сообщений: 26,180
16.05.2020, 18:19  [ТС]
Цитата Сообщение от GoodWeather Посмотреть сообщение
Ну шо сказать, везёт. А нам по нескольку раз в неделю прилетает такое. Приходится делать.
Я пишу серьёзные программы управления и контроля внешним оборудованием. Оборудование военное. Мои потребители предъявляют претензии только тогда, когда программа работает неправильно. За изыски типа шрифтов, тем оформления, звуков, горячих клавиш, настроек и их сохранение/загрузку и прочие свистоперделки, делающие работу с программой комфортнее, они просто говорят "спасибо". Тут, имхо, важен правильный подход: прикручивать очередную функцию к программе я начинаю с добавления опции "включить/отключить вундервафлю".
Цитата Сообщение от GoodWeather Посмотреть сообщение
Была бы такая штука со шрифтами - прям точно бы прикопались. Вот и как бы вы изменяли тогда в вашем варианте?
Послал бы нах... К чему тут прикапываться? Я не понимаю. Мне нужны были имена шрифтов для того, чтобы подгружать только те, которые не установлены в системе. Чо не так-то? На основные функции программы возможность подгружать свои шрифты никак не влияет.
0
16.05.2020, 19:45

Не по теме:

Как я уже сказал - везёт. Мне уже добавить нечего. Не знаете такого головняка как у нас. Порядком сбивает с основной разработки.

0
Нарушитель
10225 / 5655 / 1257
Регистрация: 12.03.2015
Сообщений: 26,180
16.05.2020, 20:01  [ТС]
Цитата Сообщение от GoodWeather Посмотреть сообщение
Не знаете такого головняка как у нас. Порядком сбивает с основной разработки.


У нас свои головняки есть, которые это "везение" компенсируют. Не переживай.
0
0 / 0 / 0
Регистрация: 27.10.2014
Сообщений: 5
12.06.2022, 20:30
Привет, тема бородатая, но все же, было бы интересно глянуть на исходники - в архиве в упор не увидел
0
Нарушитель
10225 / 5655 / 1257
Регистрация: 12.03.2015
Сообщений: 26,180
12.06.2022, 20:37  [ТС]
Цитата Сообщение от Vayrus Посмотреть сообщение
было бы интересно глянуть на исходники - в архиве в упор не увидел
Все бинарники, которые я здесь выкладываю без исходников, содержат их внутри себя. Извлекаются они по Shift+F11.
--------
Если не влом, пожалуйста, после просмотра исходника, черкани пару строк - что ты обо всём этом думаешь.
0
0 / 0 / 0
Регистрация: 27.10.2014
Сообщений: 5
12.06.2022, 20:46
Как чувствовал спинным мозгом, что надо загнать в PE Explorer или еще куда, чтобы глянуть оверлеи и ресурсы, но было влом)
0
Нарушитель
10225 / 5655 / 1257
Регистрация: 12.03.2015
Сообщений: 26,180
12.06.2022, 20:58  [ТС]
Цитата Сообщение от Vayrus Посмотреть сообщение
Как чувствовал спинным мозгом, что надо загнать в PE Explorer или еще куда, чтобы глянуть оверлеи и ресурсы, но было влом)
Значит, ты такая же ленивая жопа, как и я.
0
 Аватар для krapotkin
6847 / 4674 / 1463
Регистрация: 14.04.2014
Сообщений: 20,653
Записей в блоге: 21
14.06.2022, 11:23
настоящая ленивая жопа как я не ищет хоткей в постах, а ищет их прямо на форме программы!
0
0 / 0 / 0
Регистрация: 03.11.2025
Сообщений: 3
07.11.2025, 14:02
Если ещё актуально, чтение имени и типа шрифта из памяти.
Пришлось изучать формат TTF, кое что нашел на этом форуме, что то на других, в сети инфы мало.

Delphi
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
type TFontInfo = record
  Pitch: Boolean;
  Name: String;
end;
 
function GetFontInfoFromMemory(m_addr: Pointer; m_size: DWORD): TFontInfo;
var
  _name: array[0..31] of Char;
  _pich: Byte;
begin
  ZeroMemory(@_name, 32);
 
  asm
      jmp @start
 
  @str:
      db 'name'
      db 'post'
 
  @start:
      push esi
      push edi
      mov edx,m_size
      mov eax,m_addr
  @next_0:
      lea edi,@str
      mov esi,eax
      mov ecx,$04
      cld
      rep cmpsb
      jz @find_name
      inc eax
      dec edx
      jnz @next_0
      jmp @exit
  @find_name:
      xor eax,eax
      mov ah,[esi+$04]      // 4 байта смещения к таблице 'name'
      mov al,[esi+$05]
      rol eax,16
      mov ah,[esi+$06]
      mov al,[esi+$07]
      add eax,m_addr        // EAX = адрес таблицы 'name'
 
      xor ecx,ecx
      mov edi,eax
      mov ch,[edi+$04]
      mov cl,[edi+$05]
      add edi,ecx           // EDI = начало 'текстов'
 
      mov esi,eax
      xor ecx,ecx
      mov ch,[esi+$02]
      mov cl,[esi+$03]      // ECX = кол-во таблиц
      add esi,$06           // ESI = начало таблиц по 12 байт
 
  @next_1:
      cmp BYTE[esi+$01],$01 // ищем ID = 01-01
      jz @find_1
  @next_2:
      add esi,$0C           // переход на следующую таблицу
      dec ecx
      jnz @next_1
      jmp @exit
  @find_1:
      cmp BYTE[esi+$07],$01
      jnz @next_2
 
      xor ecx,ecx
      xor edx,edx
      mov cl,[esi+$09]      // длина имени
      mov dh,[esi+$0A]      // 2 байта смещение к имени
      mov dl,[esi+$0B]
      add edi,edx
      lea esi,_name         // получатель массив, длина уже в ECX
      xchg esi,edi
      cld
      rep movsb             // копируем
 
      mov edx,m_size
      mov eax,m_addr
  @next_3:
      lea edi,@str+$04
      mov esi,eax
      mov ecx,$04
      cld
      rep cmpsb
      jz @find_post
      inc eax
      dec edx
      jnz @next_3
      jmp @exit
  @find_post:
      xor eax,eax
      mov ah,[esi+$04]      // берем 4 байта смещения к таблице 'post'
      mov al,[esi+$05]
      rol eax,16
      mov ah,[esi+$06]
      mov al,[esi+$07]
      add eax,m_addr        // EAX = адрес таблицы 'post'
      add eax,$0F           // пропустить 4+4+2+2 и 3 старших байта isFixedPitch
      mov al,[eax]
      and al,$03
      mov _pich,al
 
  @exit:
      pop edi
      pop esi
    end;
 
  SetLength(Result.Name,32);
  Result.Name := Copy(_name,0,32);
  Result.Pitch := (_pich = 0);
end;
 
function LoadFontFromResource(const ResourceName: string; ResourceType: PChar): TFontInfo;
var
  ResStream: TResourceStream;
  FontsCount: DWORD;
begin
  ResStream := TResourceStream.Create(hInstance, ResourceName, ResourceType);
  try
    if (AddFontMemResourceEx(ResStream.Memory, ResStream.Size, nil, @FontsCount) <> 0) then
      Result := GetFontInfoFromMemory(ResStream.Memory,ResStream.Size);
  finally
    ResStream.Free;
  end;
end;
Использование:

Delphi
1
2
3
4
var fi: TFontInfo;
 
fi := LoadFontFromResource('FONT_1','RT_FONT');
Label1.Font.Name := fi.Name;
0
Нарушитель
10225 / 5655 / 1257
Регистрация: 12.03.2015
Сообщений: 26,180
07.11.2025, 14:11  [ТС]
Цитата Сообщение от Oleg777333 Посмотреть сообщение
Если ещё актуально, чтение имени и типа шрифта из памяти.
Давно проехали, я даже на Lazarus всё это безобразие портировал.
Цитата Сообщение от Oleg777333 Посмотреть сообщение
Пришлось изучать формат TTF, кое что нашел на этом форуме, что то на других, в сети инфы мало.
ИМХО, твоя колбаса на ассемблере не взлетит под x64.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
07.11.2025, 14:11
Помогаю со студенческими работами здесь

Как вытащить сетевое имя ресурса?
Здравствуйте! Если кто знает, скажите, п-та, как узнать, является какой-либо ресурс моего компьютера (папака, файл и т.п.) общим и,...

Изменить имя ресурса во время выполнения программы
Доброго времени суток. допустим есть вот такая вещь : rsc = R.drawable.name1; Bitmap bMap=...

Ошибка. Имя ресурса не может использоваться несколько раз
при компиляции программы в VS на языке vb.net в процессе сборки появляется ошибка: Имя ресурса (НАЗВАНИЕ РЕСУРСА) не может использоваться...

Получить имя ресурса на котором был произведен клик
Допустим есть картинка с названием 1.jpg. Я кbдаю ее в drawable и получается ее адрес R.drawable.1 Как сделать, когда я размещу ее на...

Узнать имя шрифта
Вечер добрый, помогите решить задачу. Есть папка с неустановленными шрифтами, как узнать имя шрифта(не название файла)?


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru