作り方の基本

  • DLLSample.dpr(DLLのソースファイル)
    library DLLSample; // library はDLLであることを示す。
    
    uses
      SysUtils,
      Classes; // Unit作成時と同様に、必要ならばユニットを追加して構わない。
    
    {$R *.res}
    
    // ここから、DLL側が行う処理をUnit作成時と同様に記述。
    // 返し値を持たない処理は procedure
    // 返し値を持つ処理は function
    // 固定値は受け渡せないので、DLL側で管理する固定値は function で返す。
    
    function Version: ShortString; stdcall;
    // 最後に stdcall を追加すると、Delphi以外の言語でも返し値が使えるようになる。
    // ただしDelphi以外の言語で返し値を使いたい場合は、返し値の型にも注意すること。
    // 例えば String はDelphi独自の型なので、PChar か ShortString を使うようにする。
    begin
      Result := DateToStr( FileDateToDateTime(FileAge('DLLSample.dll')) );
      // この場合、返し値は'DLLSample.dll'と言うファイルのタイムスタンプ。
    end;
    
    exports
      Version; // 外部ファイルから呼び出せる処理を記述。
          // ここに記述されない処理は、DLL内部専用処理になる。
    begin
    end.
    
  • Unit_Sample.pas(DLLを呼び出す Unit のソースファイル)
    unit Unit_Sample;
    :
    :
    {$R *.dfm}
    
    // ここから、DLLを呼び出すための記述。
    
    function ver: ShortString; stdcall;
    // 処理名や引数名は異なっても構わないが、
    // 引数や返し値の型と「stdcall」の有無は、DLL側と同じにすること。
      external 'DLLsample.dll' name 'Version';
    // external で呼び出すDLLを指定する。
    // name は、DLL内部での処理名が、ここに記述した処理名と異なることを示す。
    // DLL内部での処理名と、ここに記述した処理名が同じなら不要。
    // また、DLL内部の処理名は常に大文字と小文字が区別されるので、
    // 大文字・小文字は常に正確に記述すること。
    
    // ここまで、DLLを呼び出すための記述。
    
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      self.Caption := ver;
    end;
    
    end.
    

フォーム付きDLLの作り方

  • DLLSample.dpr(DLLのソースファイル)
    library DLLSample;
    
    uses
      Windows,  // 呼び出し元の特定に使用。
      Forms,    // フォームの操作に使用。
      Controls, // 返し値 TModalResult の操作に使用。
      Unit_DLLForm in 'Unit_DLLForm.pas' {DLLForm}; // フォームのソースファイル。
    
    {$R *.res}
    
    function ShowDLLForm(hOwner: HWND): TModalResult; stdcall;
    begin
      Application.Handle := hOwner; // 呼び出し元の情報をDLL側が受け取る。
      DllForm := TDllForm.Create(Application); // DLL側でフォームを作成する。
      // フォームに配置された各オブジェクトも、自動で作成される。
      Result := DllForm.ShowModal; // 返し値を設定。
      DllForm.Free; // DLL側で作成したフォームを破棄。
      Application.Handle := 0; // 呼び出し元の情報を破棄。
    end;
    
    procedure ShowDLLForm2; 
    begin
      DllForm := TDllForm.Create(Application); // DLL側でフォームを作成する。
      DllForm.Show; // 作成したフォームを表示。
    end;
    
    exports
      ShowDLLForm,
      ShowDLLForm2;
    
    begin
    end.
    
  • Unit_DLLForm(DLLに組み込みたいフォームのソースファイル)
     通常のアプリケーションと同様に作成。
     このプログラムの場合、Button1を配置し、Button1.ModalResult := mrOK に設定する。
  • Unit_Sample.pas(DLLを呼び出す Unit のソースファイル)
     フォームにButton1とButton2を配置する。
    unit Unit_Sample;
    :
    :
    implementation
    
    {$R *.dfm}
    
    // ここから、DLLを呼び出すための記述。
    
    function ShowDLLForm(hOwner: HWND): TModalResult; stdcall;
      external 'DLLSample.dll';
    
    procedure ShowDLLForm2;
      external 'DLLSample.dll';
    
    // ここまで、DLLを呼び出すための記述。
    
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      ShowDLLForm(Application.Handle);
      // DLL側でフォームを作成した後、
      // 通常のフォームのShowModalメソッドと同じ動作をして
      // 作成したフォームを破棄。
    end;
    
    procedure TForm1.Button2Click(Sender: TObject);
    begin
      ShowDLLForm2;
      // DLL側でフォームを作成した後、
      // 作成したフォームを表示。
    end;
    
    end.
    

実行ファイルからDLL内フォームを制御する

DLL内フォームの表示/非表示を、実行ファイルのToolButtonで制御するプログラムのソース。頑張れば他の制御にも応用できるかも。
基本的な仕組みは、

  1. 実行ファイルにToolButtonを配置。
  2. DLLフォームのソースファイルに、ToolButtonを使ったイベント処理を記述。
  3. DLLソースファイルに、ToolButtonのイベント設定(DLLフォームのソースにイベント処理の実行部があるので、その受け渡し)と、実行ファイル→DLL内フォームへのToolButton名を受け渡す処理を記述。
  • DLLSample.dpr(DLLのソースファイル)
    library DLLSample;
    
    uses
      Windows,  // 呼び出し元の特定に使用。
      Forms,    // フォームの操作に使用。
      ComCtrls, // ToolButtonの特定に使用。
      Unit_DLLForm in 'Unit_DLLForm.pas' {DLLForm}; // DLLフォームのソースファイル。
    
    {$R *.res}
    
    procedure CreateDLLForm(hOwner: HWND); stdcall; // DLLフォームを作成する。
    begin
      Application.Handle := hOwner; // DLLフォームの親アプリケーションを特定。
      DllForm := TDllForm.Create(Application); // DLLフォームを作成。
    end;
    
    procedure FreeDLLForm; stdcall; // DLLフォームを破棄する。
    begin
      DLLForm.Free; // DLLフォームを破棄。
      Application.Handle := 0; // DLLフォームの親アプリケーションを解放。
    end;
    
    procedure SetToolBtn1(Sender: TToolButton);
    begin // 親アプリのToolButtonとDLLフォームを連携させる。
      DLLForm.ToolBtn1 := Sender; // 親アプリのToolButton名をDLLフォーム側に保存。
      with Sender do // 親アプリ側のToolButton設定を変更する。
      begin
        Style := tbsCheck; // ToolButtonをトグルスイッチ型に設定。
        // ↑動作確認用。ToolButtonのプロパティを直接設定して構わない。
        OnClick := DLLForm.ToolBtn1Click;
        // ToolButtonをクリックしたときの処理をDLLフォームで用意したものに変更。
      end;
    end;
    
    exports // 親アプリから呼び出せる処理を設定。
      CreateDLLForm,
      FreeDLLForm,
      SetToolBtn1;
    
    begin
    end.
    
  • Unit_DLLForm(DLLに組み込みたいフォームのソースファイル)
    unit Unit_DLLForm;
    :
    :
    type
     TDLLForm = class(TForm)
    :
    :
     public
       ToolBtn1: TToolButton; // 親アプリのToolButtonを保存するための変数。
       procedure ToolBtn1Click(Sender: TObject);
       // 親アプリのToolButtonをクリックしたときの処理の定義。
    :
    :
    implementation
    
    {$R *.dfm}
    
    procedure TDLLForm.ToolBtn1Click(Sender: TObject);
    begin // 親アプリのToolButtonがクリックされたとき、
      DLLForm.Visible := TToolButton(Sender).Down;
    end; // DLLフォームの表示/非表示は ToolButton.Downプロパティに合わせる。
    
    procedure TDLLForm.FormClose(Sender: TObject; var Action: TCloseAction);
    begin // DLLフォームが閉じられるとき、
      ToolBtn1.Down := False;
    end; // 親アプリのToolButtonのトグルをオフ側にする。
    :
    :
    
  • Unit_Sample.pas(DLLを呼び出す Unit のソースファイル)
     フォームにToolBar1を配置し、ToolBar1上にToolButton1を作成する。
    unit Unit_Sample;
    :
    :
    implementation
    
    {$R *.dfm}
    
    // ここから、DLLを呼び出すための記述。
    
    procedure CreateDLLForm(hOwner: HWND); stdcall;
      external 'DLLSample.dll'; //
    
    procedure FreeDLLForm; stdcall;
      external 'DLLSample.dll';
    
    procedure SetToolBtn1(Sender: TToolButton);
      external 'DLLSample.dll';
    
    // ここまで、DLLを呼び出すための記述。
    
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      CreateDLLForm(Application.Handle); // DLLフォームを初期化。
      SetToolBtn1(ToolButton1); // ToolButton設定を初期化。
    end;
    
    procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      FreeDLLForm; // DLLフォームを破棄。
    end;
    :
    :
    
最終更新:2009年07月24日 00:52