3

私はこれに定期的に遭遇し、ベストプラクティス/アプローチを探しています. データベース/データモジュールを含むアプリがあり、設計時に「実行時にアクティブ」をtrueに設定せずに、起動時にデータベース/データセットを起動したい(データベースの場所は異なります)。また、アプリの起動時に Web の「更新の確認」ルーチンを実行します。

TForm イベント シーケンスと、さまざまな試行錯誤の結果を考慮して、現在、次のアプローチを使用しています。

メイン フォームに設定された "Globals" レコードを使用して、すべてのグローバル変数を格納し、その 1 つの要素を Globals.AppInitialized (ブール値) と呼び、メイン フォームの初期化セクションで False に設定します。

メイン フォームの OnShow イベント (それまでにすべてのフォームが作成されます) で、Globals.AppInitialized をテストします。false の場合は、「初期化」を実行し、Globals.AppInitialized := True を設定して終了します。

これはかなりうまくいくようですが、それが最善のアプローチですか?他人の経験、アイデア、意見から洞察を求めます。ティア..

4

7 に答える 7

10

私は通常、メイン フォームと場合によってはプライマリ データモジュールを除いて、すべてのフォームの自動作成をオフにしています。

あなたができることを私が学んだ1つのトリックは、データモジュールをプロジェクトに追加し、自動作成してメインフォームの前に作成できるようにすることです。次に、メイン フォームが作成されると、データ モジュールの onCreate が既に実行されています。

アプリケーションに何らかのコードがある場合は、コントロールのフォーカスを設定し (「まだ表示されていない」ため、作成時に実行できないこと)、ユーザー メッセージを作成し、oncreate のフォームに投稿します。フォーム メッセージ ループが処理されるとすぐに、メッセージを処理する必要があります (保証はありません)。例えば:

const
  wm_AppStarted = wm_User + 101;


type
  Form1 = class(tForm)
    :
    procedure wmAppStarted(var Msg:tMessage); message wm_AppStarted;
  end; 

// in your oncreate event add the following, which should result in your wmAppStarted event firing.
PostMessage(handle,wm_AppStarted,0,0);

このメッセージが一度も処理されなかったとは考えられませんが、呼び出しの性質上、メッセージはメッセージ キューに追加され、キューがいっぱいになると「ドロップ」されます。エッジケースが存在することに注意してください。

于 2008-12-20T03:42:08.250 に答える
6

フォーム作成呼び出しの後、Application.Run の前に、プロジェクト ソース (.dpr ファイル) に直接干渉したい場合があります。(場合によってはそれよりも早く。)

これは、私が通常このような初期化を処理する方法です。

...
Application.CreateForm(TMainForm, MainForm);    
...
MainForm.ApplicationLoaded; // loads options, etc..
Application.Run;
...
于 2008-12-20T00:37:28.250 に答える
3

これが役に立つかどうかはわかりませんが、私のアプリケーションの中にはフォームが自動作成されていないものがあります。つまり、IDE にメインフォームがありません。

Application オブジェクトを所有者として作成された最初のフォームは、自動的にメインフォームになります。したがって、ローダーとして 1 つのデータモジュールのみを自動作成し、これに、どのデータモジュールをいつ作成し、どのフォームをどの順序で作成するかを決定させます。このデータモジュールには StartUp メソッドと ShutDown メソッドがあり、dpr で Application.Run を囲む「ブラケット」として呼び出されます。ShutDown メソッドを使用すると、シャットダウン プロセスをより細かく制御できます。

これは、アプリケーションのさまざまなユースケースに対してさまざまな「メインフォーム」を設計した場合や、いくつかの構成ファイルを使用してさまざまなメインフォームを選択できる場合に役立ちます。

于 2008-12-20T11:00:32.470 に答える
2

実際、Delphi には「グローバル変数」のような概念はありません。すべての変数は、それらが含まれるユニットと、そのユニットを使用する他のユニットにスコープされます。

AppInitializedInitializationをデータ モジュールの一部として作成するだけです。基本的に、1 つのクラス (またはデータモジュール) を使用して、UI 以外のすべてのものを制御します (すべての悪などを除いて、One-Ring のようなものです)。

または、次のことができます。

  • スプラッシュ画面から呼び出します。
  • ログイン時に行う
  • バックグラウンド スレッドで「更新の確認」を実行します。今すぐ更新を強制しないでください。Firefox と同じようにしてください。
于 2008-12-20T00:26:41.313 に答える
1

プライマリデータモジュールを使用して、DB接続が正常かどうかを確認し、正常でない場合は、カスタムコンポーネントフォームを表示してdb接続をセットアップしてから、メインフォームをロードします。

Application.CreateForm(TDmMain, DmMain);

  if DmMain.isDBConnected then
    begin
      Application.CreateForm(TDmVisualUtils, DmVisualUtils);
      Application.CreateForm(TfrmMain, frmMain);
    end;

  Application.Run;
于 2009-05-08T12:32:46.053 に答える
1

グローバル変数が必要な理由がよくわかりません。現在、私は単一のグローバル変数なしですべての Delphi アプリを作成しています。それらを使用したときでさえ、アプリケーションごとに2つ以上持ったことはありません.

ですから、なぜ実際にそれらが必要なのかを最初に考える必要があるかもしれません。

于 2008-12-19T23:39:30.423 に答える
-1

私が使用する 1 つのトリックは、TTimer をメイン フォームに配置し、時間を 300 ミリ秒程度に設定し、初期化 (db ログイン、ネットワーク ファイルのコピーなど) を実行することです。アプリケーションを起動すると、すぐにメイン フォームが表示され、初期化の「もの」を実行できます。ユーザーが複数のインスタンスを起動して、「ああ、dbl クリックしなかった...もう一度やります..」と考えることはありません。

于 2008-12-21T13:42:31.720 に答える