メソッドやコンパイラ ディレクティブ、またはビルド/コンパイルの実行時にクエリやデータベース接続などの特定のコンポーネントが active=false に設定されたり切断されたりすることを保証する方法はありますか? これらは他の何かによってオンになっていることが非常に多いようで、手遅れになるまで気付かない.
私の特定のインストールはDelphi 7です
メソッドやコンパイラ ディレクティブ、またはビルド/コンパイルの実行時にクエリやデータベース接続などの特定のコンポーネントが active=false に設定されたり切断されたりすることを保証する方法はありますか? これらは他の何かによってオンになっていることが非常に多いようで、手遅れになるまで気付かない.
私の特定のインストールはDelphi 7です
最良のオプションは、ストック接続コンポーネントをサブクラス化し、.Loaded
そのような独自のオーバーライドメソッドで行うことだと思います
if not csDesigning in Self.ComponentState then
if not Self.ActiveInDFM {new boolean published property} then
if Self.Active then Self.Active := false;
inherited;
Delphi Form Designer の愚かさを (ab) 使用することで、新しいコンポーネントを IDE パレットに実際にインストールしなくても使用できます。ストック コンポーネント クラスと同じ名前を付けてから、独自のメソッドをフォームの interface-uses の最後に配置します。リスト:したがって、設計時にはストックコンポーネントがあり、コンパイル時にはそれが透過的に独自のものに置き換えられます。
または、(別のコンポーネントの場合) のようにフォーム宣言のすぐ上にサブクラス化することもできます。
type
TPanel = class(ExtCtrls.TPanel)
private
...
TForm1 = class(TForm) ....
このアプローチは、IDE の制限を開発者に有利な方法で使用して、アスペクト指向プログラミングに類似していると見なされる可能性があると思います。
別のアプローチは、保存時またはビルド前に DFM の .Active プロパティを消去するスクリプトかもしれませんが、この方法は複雑です。
Active
設計時のプロパティもリセットされます。厳密な観点から、これは適切なことです。しかし、これはあまり便利ではないかもしれません。Form と DataModule で同様のコードを使用することもできます.Loaded method
(その場合、接続のメソッドの代わりにオーバーライドする必要があります)。
すべての Form の Loaded メソッドに同じコードをコピーして貼り付けることができます。
procedure TMyForm.Loaded; // override
var c: TComponent; i: integer;
begin
try
for i := 0 to Self.ComponentsCount - 1 do begin
c := Self.Components[i];
if c is TCustomConnection then
with TCustomConnection(c) do // Hate those redundant typecasts!
if Connected then Connected := false;
if c is TDataSet then
with TDataSet(c) do // Delphi could took a lesson from Component Pascal
if Active then Active := false;
if c is ... // transactions, stored procedures, custom libriaries...
end;
finally
inherited;
end;
end;
これはあまり狡猾な方法ではないように思われるため、最も信頼性が高くなります。それでも、コピー アンド ペーストの場合は大変です。後で新しいコンポーネントやライブラリを追加する場合は、すべてのフォームでコピー アンド ペーストされたコードを変更する必要があります。
このコードを一部の MyDBUtils ユニットでグローバル プロシージャに集中化することができますDisconnect(const owner: TComponent);
。
procedure TMyForm.Loaded; // override
var c: TComponent; i: integer;
begin
try
MyDBUtils.Disconnect(Self);
finally
inherited;
end;
end;
ただし、このアプローチには欠点もあります。
MyDBUtils
のデータベース関連のライブラリおよびコンポーネントと緊密に結合されます。さまざまなバイナリ モジュールで構成される大規模な継承プロジェクトの場合、歴史的にさまざまな db-access ライブラリに基づいており、移行の過程にあるため、すべてのアクセス ライブラリをすべてのバイナリ モジュールに取り込みます。
私のアプリケーションでは、Tag
設計時に接続のプロパティを 1 に設定しました。OnBeforeConnect
イベントで をチェックしTag
、1 に等しい場合は、接続を中止して 0 に設定します。