プログラムを分割するには?

解決


めるめる  2006-06-05 23:33:58  No: 22029

毎度お世話になります。

実行モジュールのサイズダウンを兼ねて、プログラムを分割?したいと考えています。
例えば・・・、
Form1 に PageControl1 を貼り付け、さらに TabSheet1, TabSheet2, TabShht3 があります。
TabSheet1 には DBGrid1 を配置し、BDE 経由で Paradox に接続しています。
TabSheet2, TabSheet3 それぞれに、TabSheet1 のDBGrid1 の値を参照して処理します。

ここからが問題なのですが、上記は全て一つのプロジェクト?に所属していて当然一つの .exe ファイルが作成されます。担当者によっては TabSheet1 だけや TabSheet2 だけ、または全てを使用します。
そこで、使用しない機能を全てを .exe で実行するのではなく、メインの .exe ファイルを実行しながら(この場合は TabSheet1 だけの機能)必要に応じて、.dll 化した TabSheet2, TabSheet3 の機能を呼び出し、メモリにロードして実行する、ということを実現したいと考えています。

起動時間が長くなってきたため、こうすれば起動時間の短縮にもなり、また将来的には、担当者毎に、必要な .dll をインストールするなどを実現したいと考えています。

何かヒントになるようなモノが御座いましたら、アドバイスをよろしくお願いしたします。

※共通関数などを .dll 化して都度呼び出すのは実現しているのですが、フォームを .dll 化して呼び出して使用する方法がわからないのです。
WindowsXP + D7Pro です。


単純に  2006-06-06 00:36:18  No: 22030

ヘルプに「ダイアログの DLL 化」があったように思いますが、
それを呼び出す時に、Show で呼べばいいのでは?


めるめる  2006-06-06 01:04:38  No: 22031

お世話になります。

ヘルプで「DLL としてのフォームの再利用」という項目を発見したのですが、「複数のアプリケーションで使うフォームを作成する場合は,フォームをダイナミックリンクライブラリ(DLL)として作成できます。」とあるだけで実際の例がありません。リンクをたどると「パッケージとDLL の作成」に行き着いてしまいました。パッケージまでは手が出そうにありません。探し方が悪いようです。検索のキーワードを教えて頂ければ幸いです。

以上、よろしくお願いいたします。


う〜む  2006-06-06 01:55:43  No: 22032

うろ覚えで書くと・・。フォームの DLL 化とダイアログボックスのコンポーネント化がごっちゃになってました。
フォームを動的に作り出すコードをDLL化・・ぐらいしか思いつきません。


うーん  2006-06-06 11:04:26  No: 22033

DLL 化しても、労多くして功少なし、な感じですね。その用途だと。
面倒・複雑になるだけで、exe を軽量化してもあまり有意義とは思えないです。


起動オプション  2006-06-06 13:07:52  No: 22034

ひとつのままなら、全部のデータを読み込むのではなく、起動オプションって手で切り抜けるとか・・・。


めるめる  2006-06-06 18:15:34  No: 22035

いろいろ、ご意見アドバイスありがとうございました。
現在、TabSheet が1〜19、.exe ファイルのサイズが 6.8MB です。画面の数はさらに増えそうです。
全部の機能を一つの.exe で実現すると何かと便利だったのですが、やはり無理があるようです。
さしあたって DLL化 は見送り、ひとつひとつの画面ごとに .exe ファイルを作成し、おのおのをメニュープログラムから起動するようにし、必要であれば中間ファイルでデータを受け渡す方法で分割してみます。
ひとまず、「解決」にしておきますが、もし何か参考になるモノがございましたら、引き続きよろしくお願いいたします。


deldel  2006-06-08 00:58:51  No: 22036

むか〜し、アプリをパネルなどに貼り付けたくて、色々実験したことがあります。
以下がそのときのコードですが、一応貼り付きます。
これがいいのかどうかは分かりません^^;

貼り付けられるアプリのフォームのNameは、FrmTestで、
BorderStyle は bsNone にしてます。

var
  h: THandle;
  R: TRect;
  iwW, iwH: Word;
begin
  ShellExecute(Handle, nil, PChar('C:\test.exe'), nil, nil, SW_SHOW);
  sleep(100);
  h := FindWindow(PChar('TFrmTest'), nil);
  Application.ProcessMessages;

  GetWindowRect(h, R);
  iwW := R.Right - R.Left;
  iwH := R.Bottom - R.Top;
  MoveWindow(h, Screen.Width, Screen.Height, iwW, iwH, True);
  SetWindowLong(h, GWL_STYLE, WS_CHILD);
  Windows.SetParent(h, TabSheet1.Handle);
  ShowWindow(h, SW_SHOWMAXIMIZED);
  MoveWindow(h, 0, 0, iwW, iwH, True);
end;


Fusa  2006-06-08 09:55:49  No: 22037

6年も前に書いたので、全くソースに自信なしですが
多分動くんじゃないかしら?

ただ、ろくなことがなかったので
それ以来、DLLFormは作りませんでした。

動的リンクするDLLにFormをいれると
動的リンクが遅かった気がする。

お望みの方法とは違うような気もしますが
一応、はっときます

書いておいてなんですが、
めるめるさんのやり方のほうが綺麗と思いますよ。
中間ファイルでのデータ受け渡しを発展させて
WM_DATAとか、ソケット通信を使う方法とかも考えられます。
複数人開発とかの時は私ならそうします。

DLLForm
////////////////////////////////////////////////////////////
//DLLプロジェクトソース
library DLLProject;

uses
  SysUtils,
  Classes,
  DLLUnit in 'DLLUnit.pas' {Form1};

Exports
  TestProc;

{$R *.RES}

begin

end.

////////////////////////////////////////////////////////////
//DLLユニットソース
unit DLLUnit;

interface

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

type
  TForm1 = class(TForm)
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

procedure TestProc; stdcall; export;

implementation

{$R *.DFM}

procedure TestProc; stdcall;
//ここにexport指令は必要なし。
//なしというかexport指令があると、ハングアップしてバグの原因も分からないので
//非常に注意すべし。
var
  DllForm: TForm1;
begin
  DllForm := TForm1.Create(Application);
  try
    DllForm.ShowModal;
  finally
    DllForm.Free;
  end;
end;

end.

DLLコールアプリケーション
////////////////////////////////////////////////////////////
//アプリプロジェクト
program AppliProject;

uses
  Forms,
  AppliUnit in 'AppliUnit.pas' {Form2};

{$R *.RES}

begin
  Application.Initialize;
  Application.CreateForm(TForm2, Form2);
  Application.Run;
end.
//特に何も変化無し

////////////////////////////////////////////////////////////
//アプリユニット
unit AppliUnit;

interface

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

type
  TForm2 = class(TForm)
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form2: TForm2;

implementation

{$R *.DFM}

procedure TestProc; stdcall; external 'DLLProject.dll';
//interface部での宣言でもよいと思う。

procedure TForm2.Button1Click(Sender: TObject);
begin
  TestProc;
end;

end.


めるめる  2006-06-08 18:29:07  No: 22038

deldelさん、Fusaさん、その他の皆さん、貴重な情報をどうもありがとうございました。
最終的には.exe にするかもしれませんが、ちょっと興味があるので技術検証も兼ねてトライしてみます。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加