2012-01-19 14 views
7

私はメインフォームと他のフォームを持つプロジェクトを持っています。 アプリが読み込まれると、いくつかのタスクを実行し、結果をモーダルフォームでメインフォームの上部に表示する必要があります。 問題は、タスク/作成を行う関数を呼び出すと、メインフォームonshowイベントでモーダルフォームを表示すると、モーダルフォームが表示されますが、モーダルフォームが閉じられるまでメインフォームは表示されません。私は何が起こると思いますか。これに対処するために、メインフォームにタイマーを追加し、メインフォームのonshowイベントでタイマーを起動します。タイマーは、タスクを実行する関数を呼び出します/モーダルフォームを作成して表示します。これでモーダルフォームの前にメインフォームが表示されます。Delphi onshowメインフォーム/モーダルフォーム

しかし、私はこれが最善の解決策であるとは見えず、誰かがより良いものを提供できるかどうか疑問に思っていました。私は、Delphi 7

コリンを使用しています

+1

PostMessageを使用してください。 http://stackoverflow.com/questions/7094873/visibility-of-form-in-delphi – SimaWB

+0

この質問は主題リストに「ぼやけた」と表示されるのはなぜですか? – kobik

+0

@kobik:AFAIKの質問には、あなたが無視したタグがある場合、および一定の制限を超えた否定的な投票得点がある場合に淡色表示されます。 BTWは、SOの作品がメタサイトでよりよく尋ねられる方法について質問します(メインナビゲーションのリンクを参照)。 –

答えて

9

1つの一般的に使用さオプションは、自分自身のフォームのOnShowでメッセージを投稿することです。このように:

const 
    WM_SHOWMYOTHERFORM = WM_USER + 0; 

type 
    TMyMainForm = class(TForm) 
    procedure FormShow(Sender: TObject); 
    protected 
    procedure WMShowMyOtherForm(var Message: TMessage); message WM_SHOWMYOTHERFORM; 
    end; 

... 


procedure TMyMainForm.FormShow(Sender: TObject); 
begin 
    PostMessage(Handle, WM_SHOWMYOTHERFORM, 0, 0); 
end; 

procedure TMyMainForm.WMShowMyOtherForm(var Message: TMessage); 
begin 
    inherited; 
    with TMyOtherForm.Create(nil) do begin 
    try 
     ShowModal; 
    finally 
     Free; 
    end; 
    end; 
end; 
+2

これはソリューションの正しいアイデアですが、その実装はあまり良くありません。 :)カスタムメッセージを使用し、WndProc全体を置き換えるのではなく、その特定のメッセージのハンドラを実装します。カスタムメッセージをフォームの型宣言の前に宣言し、 'procedure UMShowMyOtherForm(var Message:TMessage);を追加してください。メッセージUM_SHOWMYOTHERFORM; '。それで、 'WndProc'の通常の流れを妨げるのはあなたのカスタムメッセージだけです。 –

+0

@Kenそれは本当です。私は実行時に割り当てられるメッセージIDを処理するのに慣れています –

+0

これは私がこれを処理する前の方法です。あなたがそれらを持っている場合、いくつかの技術的な詳細がいいだろう。 –

2

なぜあなたがそうのようなMainForm OnActivateイベントを使用していけませんか?

procedure TMyMainForm.FormActivate(Sender: TObject); 
begin 
    //Only execute this event once ... 
    OnActivate := nil; 

    //and then using the code David Heffernan offered ... 
    with TMyOtherForm.Create(nil) do begin 
    try 
     ShowModal; 
    finally 
     Free; 
    end; 
end; 

イベントをnilに設定すると、起動時にこのコードが1回だけ実行されます。

0

Windows API関数ShowWindowの呼び出しが行われる直前に、OnShowイベントが発生します。 ShowWindowへのこの呼び出しが実際に画面に表示されます。

ShowWindowの呼び出しの直後に実行する必要があるのが理想です。このすべてを駆動するVCLコードは、CM_SHOWINGCHANGEDのメッセージハンドラTCustomFormの内部にあることが判明しました。そのメッセージハンドラはOnShowイベントを発生させ、ShowWindowを呼び出します。したがって、優れた解決策は、CM_SHOWINGCHANGEDのハンドラが実行された直後にモーダルフォームを表示することです。このように:

type 
    TMyMainForm = class(TForm) 
    private 
    FMyOtherFormHasBeenShown: Boolean; 
    protected 
    procedure CMShowingChanged(var Message: TMessage); message CM_SHOWINGCHANGED; 
    end; 

..... 

procedure TMyMainForm.CMShowingChanged(var Message: TMessage); 
begin 
    inherited; 
    if Showing and not FMyOtherFormHasBeenShown then begin 
    FMyOtherFormHasBeenShown := True; 
    with TMyOtherForm.Create(nil) do begin 
     try 
     ShowModal; 
     finally 
     Free; 
     end; 
    end; 
    end; 
end; 
関連する問題