Form2をReleaseした後でないと、再度Createできないはずなのに
「コンポーネント名 Form2 はすでに使われています」でエラーになります。
(1) アプリケーションがActiveになる時に、TCommXのオープンを行っています。
(親となるシステムでもQRコードリーダーを使っている為)
(2) アプリケーションがDeActiveになる時に、TCommXのクローズを行っています。
(3) Form2はエラーが発生したプログラムと並行に実行可能なプログラムでも共有しています。
(4) TCommXのオープン、クローズを行わない場合はエラーが発生しない様です。
(5) エラーが発生する場合と発生しない場合があります。
上記以外のエラーの発生する条件がわかっていません。
また、エラーはプログラムの提供先でのみ発生しているのでエラーが発生しているタイミングもわかっていません。
エラーを回避する方法等、おわかりの方いらっしゃいましたら、ご教授お願いします。
以下がソース(サンプル)です。よろしくお願いします。
TFrom1 = class(TForm)
//省略
CommX1: TCommX;
//省略
private
//省略
function ComPortOpen: Boolean;
public
procedure ActivateProc(Sender: TObject);
procedure DeActivateProc(Sender: TObject);
end;
//==============================================================================
// Form1
//==============================================================================
procedure TForm1.FormShow(Sender: TObject);
begin
Application.onfiltered= ActivateProc; //アプリがアクティブになった場合の処理
Application.onfiltered= DeActivateProc; //アプリがアクティブでなくなった場合の処理
QRComFlg := True; //QRを利用するかどうかの設定を持つのであれば、このフラグで切替え
if not ComPortOpen then QRComFlg := False;
end;
//-----------------------------------------------------------
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
DeActivateProc(Self);
end;
//==============================================================================
// QR制御
//==============================================================================
procedure TForm1.ActivateProc(Sender: TObject);
begin
if QRComFlg then
begin
try
ComPortOpen;
except
QRComFlg := False;
end;
end;
end;
//----------------------------------------------------------
procedure TForm1.DeActivateProc(Sender: TObject);
begin
if QRComFlg then
begin
CommX1.PortClose;
end;
end;
//-----------------------------------------------------------
// QRポートオープン
//-----------------------------------------------------------
function TForm1.ComPortOpen: Boolean;
begin
CommX1.ClearReceiveBuf;
Result := True;
CommX1.PortClose;
try
CommX1.PortNo := //省略;
CommX1.BitRate := //省略;
Commx1.CharSize := //省略;
Commx1.ParityBit := //省略;
Commx1.StopBit := //省略;
Commx1.FlowCtrl := //省略;
CommX1.PortOpen;
except
Result := False;
end;
end;
//==============================================================================
// Form2の表示
//==============================================================================
function TForm1.Button1Click(Sender: TObject)
begin
//Button1クリック前のControlにSetFocus
Button1.Enabled := False;
Form2 := TForm2.Create(Application);
try
//省略
Form2.ShowModal;
//省略
finally
Form2.Release;
Button1.Enabled := True;
end;
end;
> Application.onfiltered= ActivateProc; //アプリがアクティブになった場合の処理
> Application.onfiltered= DeActivateProc; //アプリがアクティブでなくなった場合の処理
????同じイベントに代入してるし := でもないし?
Application に OnFiltered なんてないでしょ?
>(1) アプリケーションがActiveになる時に、TCommXのオープンを行っていま>す。
> (親となるシステムでもQRコードリーダーを使っている為)
アプリが起動すれば自動的にActiveになるわけで、そしてアクティブになるとTCommX をオープンしているわけで
>(4) TCommXのオープン、クローズを行わない場合はエラーが発生しない様で>す。
TCommX のオープン、クローズを行わないときはどんなとき?
>(5) エラーが発生する場合と発生しない場合があります。
> 上記以外のエラーの発生する条件がわかっていません。
> また、エラーはプログラムの提供先でのみ発生しているのでエラーが発>生しているタイミングもわかっていません。
サンプルにエラーの発生する箇所か書いてあるのか?
多数のResありがとうございます。
Application.onfiltered= ActivateProc; //アプリがアクティブになった場合の処理
Application.onfiltered= DeActivateProc; //アプリがアクティブでなくなった場合の処理
は
Application.OnActivate := ActivateProc; //アプリがアクティブになった場合の処理
Application.OnDeActivate := DeActivateProc; //アプリがアクティブでなくなった場合の処理
の誤りです。
どこで、記述がかわってしまったのか...
ウィンドウの切り替えで他アプリがアクティブになった時に、他アプリにQRコードリーダーを使わせない様にしています。
Releaseしたのに云々と表題にあるので、とりあえずその周辺のコードでおかしいところ
> Form2 := TForm2.Create(Application);
Form2というのはTForm2を宣言したunitにあるグローバル変数?
このグローバル変数はフォームの自動生成・管理のためにApplicationが使うものです。
(新規フォーム作成時にIDEが自動的に宣言を作りますが、自動生成にしないのなら消してしまってかまいません。というか消すべき)
これを使わずにローカル変数にしてみてください。
あと、Createの引数がApplicationというのも変。普通はSelf。
ちなみに「Form2はすでに使われています」というエラーは文字通り、
Nameプロパティの値が 'Form2' であるコンポーネントを二つ同時に
同一Owner内に作ろうとすると発生します。
質問の(3)で言っている共有というのが具体的に何をやっているのかわかりませんが、
Applicationをオーナーにしているので前に作ったFormへの参照が残っているのでは?
> Form2.Release;
Releaseを使うのはForm2のイベント内で自分自身を解放する場合。
この場合はForm1のイベント内なのでFreeで十分です。
私も同様の現象が発生しています。
私からも質問させて下さい。
OSの関数を使って、ApplicationをオーナーにしてCreateしたFormが解放されるまでWaitする方法はないのでしょうか?
かなパパさんと同じかどうかわかりませんが、当方では、
(1)プロジェクトファイルからForm2のCreateを削除し、自動生成にしない様にしています。
(2)Form2のユニットを他のプロジェクトでも使っています。もちろん、Form2を使った2つのApplicationは並行して実行可能にしています。
ツイート | ![]() |