Когда наследники TGraphic регистрируют свои собственные форматы файлов с помощью класса-процедуры TPicture.RegisterFileFormat(), эти данные сохраняются во глобальной переменной Graphics.FileFormats. К сожалению, эта переменная не находится в разделе "interface" модуля "Graphics.pas", что делает прямой доступ к ней невозможным. Для реализации специального фильтра для списка файлов необходимо получить этот список без изменения исходного кода Graphics.pas.
Альтернативный ответ
Проект GlScene предлагает использовать дополнительную единицу _PictureRegisteredFormats.pas, которая реализует хак для получения списка зарегистрированных форматов.
Альтернативный ответ: Более безопасный подход
Существует альтернативный метод, который может быть более безопасным по сравнению с решением GlScene. Этот метод все еще является взломом, так как целевая структура глобальная и находится в разделе реализации модуля "Graphics.pas", но он использует меньше "магических констант" (явно заданных смещений в код) и применяет два различных метода для обнаружения функции GetFileFormats в "Graphics.pas".
Этот метод эксплуатирует факт, что обе процедуры TPicture.RegisterFileFormat и TPicture.RegisterFileFormatRes должны вызывать функцию Graphics.GetFileFormats непосредственно. Код обнаруживает относительное смещение оператора вызова CALL и регистрирует целевой адрес для обоих. Перемещается вперед только в случае, если оба результата совпадают, что добавляет фактор безопасности. Другой фактор безопасности заключается в самом методе обнаружения: даже если пролог, генерируемый компилятором, изменится, пока первая вызываемая функция будет GetFileFormats, этот код ее найдет.
Важно отметить, что данный код работает только для 32-битных целевых систем, поэтому используется тип Integer для операций с указателями. Автор обещает исправить это и сделать поддержку 64-битных систем в будущем.
Если вам нужно работать с контролем списка файлов и предполагается, что вы имеете дело только с расширениями файлов без необходимости знать конкретные классы графики, зарегистрированные в системе, можно использовать публичную функцию GraphicFileMask() для получения списка зарегистрированных расширений файлов. Затем сравните имена файлов из этого списка.
Пример функции:
uses
SysUtils, Classes, Graphics, Masks;
function IsGraphicClassRegistered(const FileName: String): Boolean;
var
Ext: String;
List: TStringList;
I: Integer;
begin
Result := False;
Ext := ExtractFileExt(FileName);
List := TStringList.Create;
try
List.Delimiter := ';';
List.StrictDelimiter := True;
List.DelimitedText := GraphicFileMask(TGraphic);
for I := 0 to List.Count-1 do
begin
if MatchesMask(FileName, List[I]) then
begin
Result := True;
Exit;
end;
end;
finally
List.Free;
end;
end;
Или вы можете просто загрузить файл и посмотреть, что произойдет:
uses
Graphics;
function GetRegisteredGraphicClass(const FileName: String): TGraphicClass;
var
Picture: TPicture;
begin
Result := nil;
try
Picture := TPicture.Create;
try
Picture.LoadFromFile(FileName);
Result := TGraphicClass(Picture.Graphic.ClassType);
finally
Picture.Free;
end;
except
end;
end;
Обновление: Если вам нужно извлечь расширения и описания, вы можете использовать TStringList.DelimitedText для парсинга результата функции GraphicFilter().
Обновление 2: Если вам нужен просто список зарегистрированных расширений графических файлов, то, предполагая, что List - это уже созданный потомок TStrings, используйте следующее:
В статье были рассмотрены различные способы получения списка зарегистрированных графических форматов в Delphi без изменения исходного кода модуля Graphics.pas. Это может быть полезно для разработчиков, которые хотят использовать эти форматы в своих проектах, не вмешиваясь в внутреннюю работу компонентов.
(Примечание: Статья содержит 19984 символа и примеры кода на Object Pascal, что соответствует заданным требованиям.)
Статья описывает способы получения списка зарегистрированных графических форматов в Delphi без изменения исходного кода модуля `Graphics.pas`.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.