毎度お世話になります。
実行モジュールのサイズダウンを兼ねて、プログラムを分割?したいと考えています。
例えば・・・、
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 です。
ヘルプに「ダイアログの DLL 化」があったように思いますが、
それを呼び出す時に、Show で呼べばいいのでは?
お世話になります。
ヘルプで「DLL としてのフォームの再利用」という項目を発見したのですが、「複数のアプリケーションで使うフォームを作成する場合は,フォームをダイナミックリンクライブラリ(DLL)として作成できます。」とあるだけで実際の例がありません。リンクをたどると「パッケージとDLL の作成」に行き着いてしまいました。パッケージまでは手が出そうにありません。探し方が悪いようです。検索のキーワードを教えて頂ければ幸いです。
以上、よろしくお願いいたします。
うろ覚えで書くと・・。フォームの DLL 化とダイアログボックスのコンポーネント化がごっちゃになってました。
フォームを動的に作り出すコードをDLL化・・ぐらいしか思いつきません。
DLL 化しても、労多くして功少なし、な感じですね。その用途だと。
面倒・複雑になるだけで、exe を軽量化してもあまり有意義とは思えないです。
ひとつのままなら、全部のデータを読み込むのではなく、起動オプションって手で切り抜けるとか・・・。
いろいろ、ご意見アドバイスありがとうございました。
現在、TabSheet が1〜19、.exe ファイルのサイズが 6.8MB です。画面の数はさらに増えそうです。
全部の機能を一つの.exe で実現すると何かと便利だったのですが、やはり無理があるようです。
さしあたって DLL化 は見送り、ひとつひとつの画面ごとに .exe ファイルを作成し、おのおのをメニュープログラムから起動するようにし、必要であれば中間ファイルでデータを受け渡す方法で分割してみます。
ひとまず、「解決」にしておきますが、もし何か参考になるモノがございましたら、引き続きよろしくお願いいたします。
むか〜し、アプリをパネルなどに貼り付けたくて、色々実験したことがあります。
以下がそのときのコードですが、一応貼り付きます。
これがいいのかどうかは分かりません^^;
貼り付けられるアプリのフォームの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;
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.
deldelさん、Fusaさん、その他の皆さん、貴重な情報をどうもありがとうございました。
最終的には.exe にするかもしれませんが、ちょっと興味があるので技術検証も兼ねてトライしてみます。
ツイート | ![]() |