自己実行形式ファイルの処理例

(***
*** 実行ファイルの後ろに追加したデータを実行時に読込んで処理する例
***
*** この例では追加したテキストファイルを読込んで表示させるという、
*** テキストファイルを実行ファイル化した処理を取り上げる
*** この例ではTFormを使用せずに、自力でWindowとEditコントロールを
*** 作成しているが、TFormを用いたDelphi標準のプログラムスタイルでも
*** 同様の事が可能。その場合には、TFormのCreateイベント内でGetSrcを
*** コールすればOK。
***
*** 注意点:
*** 誤作動を防ぐため、最初はSelfSizeに充分大きな値をセットしておく。
*** 実行ファイルを一旦作成したら、プロジェクトメニューの情報でファイ
*** ルの大きさを確認し、その値をセットしたうえで再度コンパイルして仕
*** 上げる。
***
***)

program textexe;

{$R *.RES}       //アイコンリソース
uses
  Windows, Messages, SysUtils;

const
  AppName= 'TextExe';
  SelfSize = 38912; //自分自身の実行ファイルサイズ

var
  cRect: TRect;
  hMain, hMemo: HWND;
  TxtLine: string;    //テキストファイル読込み用

function GetSrc: Boolean;
var
  Buff: PChar;
  SelfName: string;
  F, SrcSize: integer;
begin
  Result := False;
  SelfName := ParamStr(0);
  F := FileOpen(PChar(SelfName), fmOpenRead or fmShareDenyNone);
  if F <= 0 then
    Exit;
  // 実行ファイルサイズから元のファイルサイズを差し引く
  SrcSize := FileSeek(F, 0, 2) - SelfSize;
  if SrcSize <= 0 then
  Exit;
  // 自分自身の後ろにくっついている部分を読込む
  FileSeek(F, SelfSize, 0);
  Buff := AllocMem(SrcSize + 1);
  try
    // ソースを読込む
    FileRead(F, Buff^, SrcSize);
    FileClose(F);
    TxtLine := Buff;
    Result := True;
  finally
    FreeMem(Buff);
  end;
end;

// Widdowプロシージャ
function WindowProc(hWnd:HWND; msg,wParam:Word; lParam:Longint):
Longint; stdcall;
begin
  case msg of
    wm_Size:     //リサイズ
      MoveWindow(hMemo, 0, 0, LoWord(lParam), HiWord(lParam), True);
    wm_Destroy:  //終了
      PostQuitMessage(0);
  end;
  Result := DefWindowProc(hWnd, msg, wParam, lParam);
end;

function WinMain(hThisInst,hPrevInst:THandle; lpArgs:pChar; cmdShow:Integer):
 Integer; stdcall;
var
  wc: TWndClass;
  msg: TMsg;
begin
  Result := 0;
  // くっついたデータを読込む。失敗した場合(データがない)には終了する。
  if not GetSrc then
    Exit;
  // Windowクラスを作成
  wc.style        := CS_HREDRAW or CS_VREDRAW;//ウィンドウクラス登録
  wc.lpfnWndProc  := @WindowProc;
  wc.cbClsExtra   := 0;
  wc.cbWndExtra   := 0;
  wc.hInstance    := hThisInst;
  wc.hIcon        := LoadIcon(hInstance,'MAINICON');
  wc.hCursor      := LoadCursor(0,idc_Arrow);
  wc.hbrBackground:= Color_Window+1;
  wc.lpszClassName:= AppName;
  Windows.RegisterClass(wc);

  hMain:=Windows.CreateWindowEX(     //メインウィンドウの作成
      WS_EX_ACCEPTFILES,
      AppName,
      'TextExecuter',
      ws_OverlappedWindow,
      cw_UseDefault,
      cw_UseDefault,
      cw_UseDefault,
      cw_UseDefault,
      0,
      0,
      hInstance,
      nil
  );

  GetClientRect(hMain, cRect);       //Editコントロールの作成

  hMemo:=CreateWindow(
      'Edit',
      '',
      ws_Child or ws_Visible or es_MultiLine or es_AutoHScroll or
      es_AutoVScroll or es_WantReturn or ws_HScroll or ws_VScroll or ws_Border,
      0,
      0,
      cRect.right- cRect.left,
      cRect.bottom- cRect.top,
      hMain,
      0,
      hInstance,
      nil
  );

  ShowWindow(hMain,cmdShow);    //ウィンドウ表示
  UpdateWindow(hMain);
  SetFocus(hMemo);

  // 自分自身の後ろにデータがくっついていたら、読込んでEDITに表示
  SendMessage(hMemo, WM_SETTEXT, 0, Integer(PChar(TxtLine)));

  // メインループ
  while GetMessage(Msg, 0, 0, 0) do begin
    TranslateMessage(Msg);
    DispatchMessage(Msg);
  end;

  Halt(Msg.wParam);
  Result:=0;
end;

// エントリーポイント
begin
  WinMain(hInstance, 0, nil, cmdShow);
end.


サンプル(ソースと実行ファイル)のダウンロード(24,594byte)

サンプルに含まれる実行形式ファイルの試し方


戻る