2017-05-15 23 views
-2

Delphiアプリケーションの初期化で多くのフォームを作成するのにキューを使用していますが、正しく動作しません。コードFiremonkeyのキューが進行状況バーを更新しない

TThread.Queue(TThread.CurrentThread, 
     procedure() 
     begin 
       Application.CreateForm(TForm1, form1); 
       Application.CreateForm(TForm2, form2); 
       Application.CreateForm(TForm3, form3); 
       ..... 
       Application.CreateForm(TForm9, form9); 
       Application.CreateForm(TDatamodule1, datamodule1); 
     end); 

のフラグメントベロー

私は、ProgressBarとラベルで作成の進行状況を表示するように願っています。たとえば、次のように 各TFORMは最終的に作成し、私はTProgressBar.Value=TProgressBar.Value + 10を設定し、次のフォームのためのlabel.textを更新するために: 'ロードForm2を...'

apllicationは、WindowsとAndroidで動作します。私は両方のプラットフォームで同じ動作を見て、画面がフリーズし、プロセスの終了時に「ロード完了」を更新します。私は間違っているの?


注:前回、私は同期を使用していたが、私はのTThreadコンテキスト上のフォームを作成することができませんでした、その後、同期は良いアイデアではありませんでしたグローバルなVARをForm1と更新ラベルを、アクセスする必要がありました。

完全なコード、

TfrmSplash.create(Sender:TObject); 
begin 
TThread.Queue(TThread.CurrentThread, 
     procedure() 
     begin 
       Application.CreateForm(TForm1, form1); 
       TProgressBar.Value=TProgressBar.Value + 10 
       Label1.text:='Loading form2'; 
       Application.CreateForm(TForm2, form2); 
       TProgressBar.Value=TProgressBar.Value + 10 
       Label1.text:='Loading form3'; 
       Application.CreateForm(TForm3, form3); 
       TProgressBar.Value=TProgressBar.Value + 10 
       Label1.text:='Loading form4'; 
       ..... 
       Application.CreateForm(TForm9, form9); 
       TProgressBar.Value=TProgressBar.Value + 10 
       Label1.text:='Loading data'; 
       Application.CreateForm(TDatamodule1, datamodule1); 
       TProgressBar.Value:=100 
       Label1.text:='100% complete'; 
       Sleep(200); 
       frmSplash.hide; 
       Form1.show; 
     end); 
end; 
+0

XEは、AndroidやFireMonkeyのをサポートしていません。使用しているバージョンを知ることが有用なことがあります。そのような詳細については正確にしてください。私はあなたの最後の質問でこれの多くを説明しました。これに留意することが重要です。質問については、このコードが実行されるコンテキストを明確に把握する必要があります。したがって、[mcve]を提供してください。 –

+0

あなたは間違っています、FiremonkeyとAndroidはDelphi Xe2以降サポートされています。コードはxe7、xe5、xe2で動作します。私はコードを改善して助けてくれます。 –

+0

XEはXE2より前のバージョンです。それはWindowsのみを対象としています。私たちには[mcve]が必要です。 1つを入力してください。 –

答えて

1

あなたのコードには二つの問題があります。

  1. あなたはTThread.Queue()に単一の呼び出し内のあなたのUIのアップデートのすべてを実行しているすべての新しいUIのメッセージを処理せずには、更新の間にメインメッセージループは、キューに入れられたプロシージャが終了するまでブロックされます。そのため、最終更新メッセージのみが表示され、中間メッセージは表示されません。メインUIスレッドのコンテキストで呼び出されたときにTThread.Queue()は(RSP-15427 Add an option to let TThread.Queue() run asynchronously when called by the main UI threadのために投票してください)同期であることを

  2. ノート。したがって、TfrmSplashオブジェクトをメインスレッドで作成し、ワーカースレッドではないと仮定すると、TfrmSplashオブジェクトが完全に作成されるまで、すべてのUI更新は表示されません。

オブジェクトを作成している間に、メッセージキューに新しいメッセージ(少なくともメッセージをペイント)を処理させる必要があります。各オブジェクトの作成の間にApplication.ProcessMessages()(推奨しません)またはスプラッシュフォームのUpdate()(推奨)のいずれかを呼び出すことができます。

ではなく、より多くのこのような何かを試してみてください:

procedure TfrmSplash.Create(Sender: TObject); 
begin 
    TThread.CreateAnonymousThread(
    procedure 
    begin 
     TThread.Queue(nil, CreateObjects); 
    end 
).Start; 
end; 

procedure TfrmSplash.SetProgress(Progress: Integer; const Text: string); 
begin 
    TProgressBar.Value := Progress; 
    Label1.Text := Text; 
    //Application.ProcessMessages; 
    Update; 
end; 

procedure TfrmSplash.CreateObjects; 
begin 
    SetProgress(0, 'Loading form1'); 
    Application.CreateForm(TForm1, form1); 

    SetProgress(10, 'Loading form2'); 
    Application.CreateForm(TForm2, form2); 

    SetProgress(20, 'Loading form3'); 
    Application.CreateForm(TForm3, form3); 

    SetProgress(30, 'Loading form4'); 
    ... 

    SetProgress(80, 'Loading form9'); 
    Application.CreateForm(TForm9, form9); 

    SetProgress(90, 'Loading data'); 
    Application.CreateForm(TDatamodule1, datamodule1); 

    SetProgress(100, '100% complete'); 

    Hide; 
    Form1.Show; 
end; 
+0

ありがとう。それは私が必要なすべてです。 実際、ProcessMessagesはFiremonkeyでは使用できません。 –

関連する問題