メインフォーム非表示でApplication.Run後に処理する方法を教えて下さい
begin
Application.Initialize;
Application.CreateForm(TFormMain, FormMain);
Application.Run;
end;
Delphi7 Enterprise
追記です。
今まではメインフォーム表示していたので、メインフォームのVisibleをfalseに
してApplication.Run後にメインフォームのVisibleが自動的にTureになるのを利用してEOnShowイベントで処理をしていました。
begin
Application.Initialize;
Application.CreateForm(TFormMain, FormMain);
Application.ShowMainForm := False; // 追記
Application.Run;
end;
訂正です。
EOnShowイベントで処理をしていました 訂正前
OnShowイベントで処理をしていました 訂正後
どのような現象が発生しているか,詳しくはわかりませんが,
例えば,Application.Runを削除して,かわりに実行したいコ
ードを記述します.
(場合によってはRunが必要な場合もあります.それはあくまでも
アプリケーションの動作仕様とかコーディングにもよります)
[例] FormMainのAAAというメソッドを実行する場合
begin
Application.Initialize;
Application.CreateForm(TFormMain, FormMain);
Application.ShowMainForm := False; // 追記
FormMain.AAA;
end;
おっと失礼.Run後でしたね.
一般に,アプリケーションのRunはメッセージループが終了するまで,
次のコードに移動しません.これは通常フォームを閉じることに相当
します.
したがって,確実にRunの次にコードが移動するようなアプリケーション
であれば,単にRunの次に実行したいコードを書きます.
そうでないと場合は,前のレスの様にRunのコードは削除します.
でないと,Formの非表示の場合は,フォームの終了が検出できませんから,
永久にRunの次に実行が移動しません.
実際にどんな問題があったのかが分かればまたレスします.
【既存】
1.画面を表示
2.Application.Run
3.OnShowイベント内でメイン処理
4.アプリの自動終了しない
【実現したいこと】
1.コマンドライン引数が無→画面表示
コマンドライン引数が有→画面非表示
2.Application.Run
3.メイン処理(画面非表示の場合OnShowイベントが発生しない為、代わりのイベントや処理など)←ここがわかりません
4.コマンドライン引数が無→アプリの自動終了しない
コマンドライン引数が有→アプリの自動終了する
↓で一応、動いたのですが既存と処理の順番が異なります。
既存の処理と同じ順番で実現できる方法がないかと思い質問しました。
begin
Application.Initialize;
Application.CreateForm(TFormMain, FormMain);
if ParamCount <> 0 then // コマンドライン引数判定
begin
Application.ShowMainForm := False; // メインフォーム非表示
FormMain.MainSyori; // メイン処理 自動終了する為に最後にFormMain.Close
end;
Application.Run;
end;
Application.Run; はメッセージループですから、これを削除したら Windows の
GUI アプリケーションは実際上動作しません。
メインフォームを表示するかどうかと、Application.Run; のあとに実行したい
コードがあるかどうかは全く無関係です。
誤解があるようです。
> Application.Run後にメインフォームのVisibleが自動的にTureになるのを利用して
これは間違いです。Application.Run を実行中に表示されます。Application.Run から抜けてきたときは、もうすでに FormMain のインスタンス
はありません。ですから、FormMain のメソッドはその後に実行できません。
OnShow での MainSyori をやめて
begin
Application.Initialize;
Application.CreateForm(TFormMain, FormMain);
FormMain.MainSyori; // メイン処理 (FormMain.Close を含まない)
if ParamCount <> 0 then // コマンドライン引数判定
begin
FormMain.Close;
end;
Application.Run;
end;
のようにするとパラメータがあるなしにかかわらず同じタイミングで FormMain.MainSyori
が実行されます。
>1.コマンドライン引数が無→画面表示.フォームCloseで終了
> コマンドライン引数が有→画面非表示してあるメソッドを実行して終了
を実現するコードです.
フォームが非表示の時は,MainSyoriの内容にもよりますが,通常(?)
MainSyori が終了すればアプリは終了します.
MainSyoriの最後にMainForm.Closeは必要ありません.何故なら表示して
いなのですから.りおりおさんのレスと合わせて解読して下さい.
begin
Application.Initialize;
Application.CreateForm(TFormMain, FormMain);
if ParamCount=0 then begin
Application.Run;
end else begin
Application.ShowMainForm := False;
FormMain.MainSyori;
end;
end.
MainSyoriは例えば...
procedure TFormMain.MainSyori;
begin
ShowMessage('コマンドラインに引数がありません');
end;
逆ですよね.
procedure TFormMain.MainSyori;
begin
ShowMessage('コマンドラインに引数は指定できません');
end;
>りおりおさんの
>OnShow での MainSyori をやめて (以下 略)
なるほど,フォームの表示,非表示にかかわらず,同じメソッドを
実行するには,りおりおさんのコードですね.
Application.Runの意味を自分が理解できていません。根本原因です。すみません。
処理の内容にもよると思うですが、処理のタイミングが
・Application.Runの実行中
・Application.Runの実行中以外
での違いはありますか?
できればメイン処理を既存と同じ
Application.Run実行中に行いたいです。
多分Application.Runを勘違いされているのだと思いますが
>・Application.Runの実行中
>・Application.Runの実行中以外
>での違いはありますか?
イベント処理が必要ないのであればどちらも違いはないと思われます。
補足
Application.Runの中は
・・・
repeat
try
HandleMessage;
except
HandleException(Self);
end;
until Terminated;
・・・
というように単にメッセージループを回っているだけです。
よってメッセージ処理の必要がなければApplication.Runも必要ありません。
>よってメッセージ処理の必要がなければApplication.Runも必要ありません。
そうですけど、実際は暗黙に作られる Apllication のウィンドウや FromMain のウィンドウを
破棄するためには WM_QUIT や WM_CLOSE のメッセージ処理が必要です。
質問者の方が詳しく説明していないので想像で書いたのですが
コマンドライン引数ありの時は画面表示がないのでVCLもいらないのかなと勝手に想像しました。(フォームもCreateする必要がないという意味です)
>メッセージ処理の必要がなければ
というのはそういう意味です。
あ〜っと
メインフォームが必要なくてもプログレスウィンドウを表示する場合もあるか。
前言撤回します。
Eさん忘れてください。
こんな感じでしょうか?
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
if ParamCount <> 0 then begin // コマンドライン引数判定
Application.ShowMainForm := False; // メインフォーム非表示
end;
Application.Run;
end.
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
Timer1 の Enabled は False にしておく。
Interval は 10 程度。
procedure TForm1.FormCreate(Sender: TObject);
begin
Timer1.Enabled := True;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Timer1.Enabled := False; //このタイマールーチンは1度しか動作しない
ShowMessage('メイン処理実行中');
//コマンドライン引数が無→アプリの自動終了しない
if ParamCount = 0 then begin
//コマンドライン引数が有→アプリの自動終了する
end else begin
Close;
end;
end;
ツイート | ![]() |