본문 바로가기

카테고리 없음

[일반/컴포넌트] 실행파일에서 잃어버린 DFM 파일 뽑아내기

// 델파이로 프로그램 작성하다 dfm 파일 삭제하여 다시 만든 경헙이 있다면
// 한번 사용해 보세요

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    Button2: TButton;
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

type
  TDFMorTXT = (ConvertToForm, ConvertToText);

var
  Form1: TForm1;

implementation

{$R *.dfm}

function ConvertFormOrText(FileToConvertFrom: string;
                           ConversionType: TDFMorTXT): boolean;
var
  InputStream, OutputStream: TFileStream;
  FileToConvertTo: string;
begin
  Result := True;
  FileToConvertTo := FileToConvertFrom;

  {파일의 확장자를 변환하는 방법에 따라 바꾼다}
  case ConversionType of
    ConvertToForm: {TXT -> DFM}
      begin
        FileToConvertFrom := SysUtils.ChangeFileExt(FileToConvertFrom, '.TXT');
        FileToConvertTo   := SysUtils.ChangeFileExt(FileToConvertFrom, '.DFM');
      end;
    ConvertToText: {DFM -> TXT}
      begin
        FileToConvertFrom := SysUtils.ChangeFileExt(FileToConvertFrom, '.DFM');
        FileToConvertTo   := SysUtils.ChangeFileExt(FileToConvertFrom, '.TXT');
      end;
  end;

  try
    try
      {file stream 을 만든다}
      InputStream  := TFileStream.Create(FileToConvertFrom, fmOpenRead); {읽기용}
      OutputStream := TFileStream.Create(FileToConvertTo, fmCreate); {쓰기용}

      {변환}
      case ConversionType of
        ConvertToForm: ObjectTextToResource(InputStream, OutputStream);
        ConvertToText: ObjectResourceToText(InputStream, OutputStream);
      end;
    except
      on EStreamError do
        Result := False;
    end;
  finally
    InputStream.Free;
    OutputStream.Free;
  end;
end;

function ExtractDFM(ApplicationName, FormClassName: string): string;
var
  AppHandle: THandle;
  ResStream: TResourceStream;
  ResultStream: TStringStream;
begin
  Result := '';
  AppHandle := LoadLibraryEx(PChar(ApplicationName), 0, LOAD_LIBRARY_AS_DATAFILE);
  if AppHandle = 0 then
    raise Exception.Create('Could not load application');
  ResStream := nil;
  ResultStream := nil;
  try
    ResStream := TResourceStream.Create(AppHandle, FormClassName, RT_RCDATA);
    ResultStream := TStringStream.Create('');
    ObjectBinaryToText(ResStream, ResultStream);
    Result := ResultStream.DataString;
  finally
    ResultStream.Free;
    ResStream.Free;
    FreeLibrary(AppHandle);
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  // 실행파일에서 TForm1 을 TXT 형태로 뽑아내기
  Memo1.Text := ExtractDFM('Project1.exe', 'TForm1');
  Memo1.Lines.SaveToFile('ExtractedForm.txt');

  // TXT -> DFM 변환
  ConvertFormOrText('ExtractedForm.txt', ConvertToForm);
end;

end.