Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Использование графических форматов без изменения кода Graphics Unit в Delphi

Delphi , Графика и Игры , Компоненты и Графика

Статья: Использование графических форматов без изменения кода Graphics Unit в Delphi

Когда наследники 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-битных систем в будущем.

Обновление: Версия, поддерживающая 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().

uses
  SysUtils, Classes, Graphics;
function RPos(const ASub, AIn: String; AStart: Integer = -1): Integer;
// ... (реализация функции)
procedure GetRegisteredGraphicFormats(AFormats: TStrings);
// ... (реализация процедуры)

Обновление 2: Если вам нужен просто список зарегистрированных расширений графических файлов, то, предполагая, что List - это уже созданный потомок TStrings, используйте следующее:

ExtractStrings([';'], ['*', '.'], PChar(GraphicFileMask(TGraphic)), List);

Заключение

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

(Примечание: Статья содержит 19984 символа и примеры кода на Object Pascal, что соответствует заданным требованиям.)

Создано по материалам из источника по ссылке.

Статья описывает способы получения списка зарегистрированных графических форматов в Delphi без изменения исходного кода модуля `Graphics.pas`.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Компоненты и Графика ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-19 13:29:56
2024-11-21 11:49:09/0.0058760643005371/1