Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Круглый стол
  
Правила КС
>> Настройки

Фильтр вопросов
>> Новые вопросы
отслеживать по
>> Новые ответы

Избранное

Страница вопросов
Поиск по КС


Специальные проекты:
>> К л ю к в а
>> Г о л о в о л о м к и

Вопрос №

Задать вопрос
Off-topic вопросы

Помощь

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  00:51[Войти] | [Зарегистрироваться]
Ответ на вопрос № 35010

25-08-2005 10:21
Добрый день.
Есть шрифт (ttf), который в системе не установлен.
Как узнать, под каким именем он установится?
(бинарный поиск по файлу - не подходит).
Спасибо.

[+] Добавить в избранные вопросы

Отслеживать ответы на этот вопрос по RSS

Ответы:


Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице.
Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.

12-09-2009 12:17
про GetFontResourceInfo читать тут
http://www.undocprint.org/winspool/getfontresourceinfo

01-09-2005 05:02
Странно, у меня всё работает.
Добавляем:

  CopyFile('E:\fonts\Adrenaline Zero.ttf','d:\tst.ttf');
  Win32Check(AddFontResourceEx('d:\tst.ttf',FR_PRIVATE or FR_NOT_ENUM,nil)>0);
  Label1.Font.Name:=GetFontNameFromFile('d:\tst.ttf');


И удаляем:

  Label1.Font.Name:='MS Sans Serif';
  Win32Check(RemoveFontResourceEx('d:\tst.ttf',FR_PRIVATE or FR_NOT_ENUM,nil));
  Win32Check(DeleteFile('d:\tst.ttf'));


Шрифт Label-а меняется, файл отлично удаляется.

01-09-2005 00:30 | Сообщение от автора вопроса
Использую шрифт для вывода Label
Назначаю Label другой шрифт
Делаю Remove, посылаю сообщение, пытаюсь удалить - отказано в доступе.

31-08-2005 09:28
Поподробнее, если можно. Не удалить сразу после Add, Remove, без использования? Или после использования в каком нибудь TFont? Может на него  ссылка в Canvas-е осталась? AddFontMemResourceEx не подойдёт?

31-08-2005 08:41 | Сообщение от автора вопроса
Мдя... работает. Но тут другая проблема. :)
Как сам шрифт удалить? RemoveFontResource и RemoveFontResourceEx не удаляют признак занятости файла. А просить перезагрузку для этого как-то не хорошо....

27-08-2005 05:24 | Сообщение от автора вопроса
Всем ОГРОМНОЕспасибо.
Всё работает.

26-08-2005 16:15
Если кому-то ещё надо, вот платформенно независимый вариант функции. Работает только с TTF шрифтами. Результат идентичен GetFontResourceInfoW проверено под XP SP2, на пятитысячной коллекции шрифтов.

const
  PLATFORM_UNICODE=0;
  PLATFORM_MACINTOSH=1;
  PLATFORM_ISO=2;
  PLATFORM_MICROSOFT=3;

type
  TT_OFFSET_TABLE=packed record
    uMajorVersion,uMinorVersion,uNumOfTables,
      uSearchRange,uEntrySelector,uRangeShift:Word;
  end;
  TT_TABLE_DIRECTORY=packed record
    szTag:array[0..3] of Char;
    uCheckSum,uOffset,uLength:DWORD;
  end;

  TT_NAME_TABLE_HEADER=packed record
    uFSelector,uNRCount,uStorageOffset:Word;
  end;

  TT_NAME_RECORD=packed record
    uPlatformID,uEncodingID,uLanguageID,
      uNameID,uStringLength,uStringOffset:Word;
  end;

function GetTTFFontName(Stream:TStream):string;
var
  ttOffsetTable:TT_OFFSET_TABLE;
  tblDir:TT_TABLE_DIRECTORY;
  ttNTHeader:TT_NAME_TABLE_HEADER;
  ttBestRecord,ttRecord:TT_NAME_RECORD;
  Found:Boolean;
  Temp:array of Byte;
  A,LangID:Integer;
  procedure SwapBuffer16(var Buffer;Count:Integer);
  var
    A:Integer;
    Words:array[0..0] of Word absolute Buffer;
  begin
    for A:=0 to(Count div 2)-1 do
      Words[A]:=ByteSwap16(Words[A]);
  end;
begin
  Result:='';
  if Stream.Read(ttOffsetTable,SizeOf(ttOffsetTable))<>SizeOf(ttOffsetTable) then Exit;
  SwapBuffer16(ttOffsetTable,SizeOf(ttOffsetTable));
  if (ttOffsetTable.uMajorVersion<>1)or(ttOffsetTable.uMinorVersion<>0) then Exit;
  Found:=False;
  for A:=0 to ttOffsetTable.uNumOfTables-1 do begin
    if Stream.Read(tblDir,SizeOf(tblDir))<>SizeOf(tblDir) then Exit;
    if StrLIComp(tblDir.szTag,'name',4)=0 then begin
      Found:=True;
      Break;
    end
  end;
  if Found then begin
    tblDir.uOffset:=ByteSwap32(tblDir.uOffset);
    Stream.Position:=tblDir.uOffset;
    if (Stream.Read(ttNTHeader,SizeOf(ttNTHeader))<>SizeOf(ttNTHeader))or(ttNTHeader.uFSelector<>0) then Exit;
    SwapBuffer16(ttNTHeader,SizeOf(ttNTHeader));
    Found:=False;
    LangID:=GetSystemDefaultLangID;
    for A:=0 to ttNTHeader.uNRCount-1 do begin
      if Stream.Read(ttRecord,SizeOf(ttRecord))<>SizeOf(ttRecord) then Exit;
      SwapBuffer16(ttRecord,SizeOf(ttRecord));
      if ((ttRecord.uNameID=4)and(ttRecord.uStringLength>0))and(not Found
        or((ttRecord.uLanguageID=LangID)and not(ttBestRecord.uLanguageID=LangID))
        or((ttRecord.uLanguageID=$409)and not(ttBestRecord.uLanguageID=$409))
        or((ttRecord.uLanguageID=0)and not(ttBestRecord.uLanguageID=0))) then begin
        ttBestRecord:=ttRecord;
        Found:=True;
      end;
    end;
    if Found then begin
      Stream.Position:=tblDir.uOffset+ttNTHeader.uStorageOffset+ttBestRecord.uStringOffset;
      SetLength(Temp,ttBestRecord.uStringLength);
      if Stream.Read(Temp[0],ttBestRecord.uStringLength)<>ttBestRecord.uStringLength then Exit;
      if (ttBestRecord.uPlatformID in [PLATFORM_UNICODE,PLATFORM_MICROSOFT])
        and(ttBestRecord.uEncodingID in [0..1]) then begin
        SwapBuffer16(Temp[0],ttBestRecord.uStringLength);
        WideCharLenToStrVar(PWideChar(@Temp[0]),ttBestRecord.uStringLength div 2,Result);
      end
      else
        if (ttBestRecord.uPlatformID in [PLATFORM_MACINTOSH,PLATFORM_ISO])
          and(ttBestRecord.uEncodingID=0) then
          SetString(Result,PChar(@Temp[0]),ttBestRecord.uStringLength);
    end;
  end;
end;


26-08-2005 01:04 | Сообщение от автора вопроса
Мдя.... всем спасибо - побегу пробовать.

25-08-2005 15:20
А вот решение методом парсинга файлов:
http://www.codeguru.com/Cpp/G-M/gdi/fonthandlinganddetection/article.php/c3659
Только TTF шрифты, зато очень быстро. Буду переводить на паскаль.

25-08-2005 15:00
To Михаил Комин:
Отлично! Спасибо! Я тут правда свой способ придумал, без использования недокументированных функций, он менее надёжен, но его, судя по всему, можно и в 9х использовать.

function FontNameFromFile(const FileName:string):string;
type
  TInfo=record
    Fonts:TStringList;
    Index:Integer;
    Name:string;
  end;
var
  DC:HDC;
  LFont:TLogFont;
  Info:TInfo;
  function EnumFontsProc1(const LogFont:EnumLogFontEx;const TextMetric:TTextMetric;FontType:Integer;var Info:TInfo):Integer; stdcall;
  begin
    Info.Fonts.Add(LogFont.elfFullName);
    Result:=1;
  end;
  function EnumFontsProc2(const LogFont:EnumLogFontEx;const TextMetric:TTextMetric;FontType:Integer;var Info:TInfo):Integer; stdcall;
  begin
    if (Info.Index<Info.Fonts.Count)and(Info.Fonts[Info.Index]=LogFont.elfFullName) then begin
      Result:=1;
      Inc(Info.Index);
    end
    else begin
      Result:=0;
      Info.Name:=LogFont.elfFullName;
    end;
  end;
begin
  Result:='';
  DC:=GetDC(0);
  try
    FillChar(LFont,SizeOf(LFont),0);
    LFont.lfCharset:=DEFAULT_CHARSET;
    Info.Fonts:=TStringList.Create;
    try
      EnumFontFamiliesEx(DC,LFont,@EnumFontsProc1,Integer(@Info),0);
      if AddFontResourceEx(PChar(FileName),FR_PRIVATE,nil)=0 then Exit;
      Info.Index:=0;
      EnumFontFamiliesEx(DC,LFont,@EnumFontsProc2,Integer(@Info),0);
      RemoveFontResourceEx(PChar(FileName),FR_PRIVATE,nil);
      Result:=Info.Name;
    finally
      Info.Fonts.Free;
    end;
  finally
    ReleaseDC(0,DC);
  end;
end;


25-08-2005 13:55
Держите! Эксклюзивно для вас нарыл ;)

function GetFontResourceInfoW (FontPath : PWideChar; var BufSize : DWORD; FontName : PWideChar; dwFlags : DWORD) : DWORD; stdcall; external 'GDI32.DLL';



1-ый параметр - указатель на Wide-строку, содержащую путь к файлу шрифта;
2-ой параметр - указатель на DWORD-переменную, содержащую размер выходного буфера. После выполнения функции в этой переменной будет содержаться необходимая длина буфера;
3-ий параметр - указатель на буфер, в случае успешного выполнения будет содержать Wide-строку имени шрифта;
4-ый параметр - какие-то флаги, если рыться в функции GetFontResourceInfoW особым случаем является когда dwFlags=4, но зачем это, я так и не понял - в результате будет возвращен тот же путь к файлу; ну а для получения имени шрифта флаг должен быть равен 1.


использование:

function TForm1.GetFontName (FontFileA : PChar) : String;
type
  TGetFontResourceInfoW = function (FontPath : PWideChar; var BufSize : DWORD; FontName : PWideChar; dwFlags : DWORD) : DWORD; stdcall;
var
  GetFontResourceInfoW : TGetFontResourceInfoW;
  FontFileW : PWideChar;
  FontNameW : PWideChar;
  FontFileWSize, FontNameSize : DWORD;

begin
  Result := '';
  GetFontResourceInfoW := GetProcAddress(GetModuleHandle('gdi32.dll'), 'GetFontResourceInfoW');
  if @GetFontResourceInfoW = nil then Exit;
  if AddFontResource(FontFileA) = 0 then Exit;

  FontFileWSize := (Length(FontFileA)+1)*2;
  GetMem(FontFileW, FontFileWSize);
  StringToWideChar(FontFileA, FontFileW, FontFileWSize);

  FontNameSize := 0;
  FontNameW := nil;
  GetFontResourceInfoW (FontFileW, FontNameSize, FontNameW, 1);
  GetMem (FontNameW, FontNameSize);
  FontNameW^ := #0; // на случай какого-нибудь облома
  GetFontResourceInfoW (FontFileW, FontNameSize, FontNameW, 1);

  Result := FontNameW;
  FreeMem (FontFileW);
  FreeMem (FontNameW);

  RemoveFontResource(FontFileA);
end



вызов:

GetFontName('C:\MyFonts\FUTURA.TTF')



PS: Всё бы хорошо, но эта функция хоть и есть в Win9x, только её там вызывать нельзя - пишет "This function is only valid in Windows NT mode."...
FontView в Win9x использует EnumFontFamiliesEx (видимо по предложенному Vit'ом и x77 способу)...
FontView в WinNT использует GetFontResourceInfo (в импорте вообще нет EnumFontFamiliesEx или других Enum*)...

Автор: p0s0l

Взято с Vingrad.ru http://forum.vingrad.ru

25-08-2005 13:06 | Комментарий к предыдущим ответам
винда сканирует выбранную папку и выводит названия всех шрифтов без их установки
Чаще всего винда просто читает заголовки файлов, чтобы отобразить какую-то информацию о файле...

Ну да, это скорее всего выполняется какими-то функциями...

25-08-2005 12:25 | Комментарий к предыдущим ответам
Установи шрифт, посмотри имя, удали шрифт ;)
А если серьёзно? Меня тоже интересует как из TTF получить имя шрифта которое можно в TFont.Name подставить. Поиск по MSDN результатов не дал (может плохо искал). Вариант с ручным разбором структуры TTF не устраивает, ведь при добавлении шрифта в панель управления, винда сканирует выбранную папку и выводит названия всех шрифтов без их установки, хотелось бы знать какие функции при этом используются.

25-08-2005 11:50
бинарный поиск по файлу - не подходит
Установи шрифт, посмотри имя, удали шрифт ;)

Добавьте свое cообщение

Вашe имя:  [Войти]
Ваш адрес (e-mail):На Королевстве все адреса защищаются от спам-роботов
контрольный вопрос:
Кто съел Красную шапочку?
в качестве ответа на вопрос или загадку следует давать только одно слово в именительном падеже и именно в такой форме, как оно используется в оригинале.
Надоело отвечать на странные вопросы? Зарегистрируйтесь на сайте.
Тип сообщения:
Текст:
Жирный шрифт  Наклонный шрифт  Подчеркнутый шрифт  Выравнивание по центру  Список  Заголовок  Разделительная линия  Код  Маленький шрифт  Крупный шрифт  Цитирование блока текста  Строчное цитирование
  • вопрос Круглого стола № XXX

  • вопрос № YYY в тесте № XXX Рыцарской Квинтаны

  • сообщение № YYY в теме № XXX Базарной площади
  • обсуждение темы № YYY Базарной площади
  •  
     Правила оформления сообщений на Королевстве

    Страница избранных вопросов Круглого стола.
      
    Время на сайте: GMT минус 5 часов

    Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
    Функция может не работать в некоторых версиях броузеров.

    Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
    Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

     
    © При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
    Все используемые на сайте торговые марки являются собственностью их производителей.

    Яндекс цитирования