2017-05-15 3 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 윈도우와 안드로이드에서 작동합니다. 두 플랫폼 모두에서 볼 수있는 것과 동일한 동작입니다. 화면이 멈추고 프로세스가 끝나면 '로딩 완료'로 업데이트됩니다. 내가 뭘 잘못하고있어?


참고 : 마지막으로 내가 동기화를 사용했다,하지만 난 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는 안드로이드 또는 Firemonkey 지원하지 않습니다

이 대신 같은 더 뭔가를보십시오. 때로는 사용중인 버전을 아는 것이 유용합니다. 그런 세부 사항에 대해 정확하게 말하십시오. 나는 당신의 마지막 질문에이 점을 많이 설명했습니다. 당신이 이것을 유의하는 것이 중요합니다. 질문에 대해서는이 코드가 실행되는 상황에 대한 명확한 그림이 필요합니다. 따라서 [mcve]를 제공해주십시오. –

+0

Delphi Xe2 이후로 Firemonkey와 Android가 지원됩니다. 이 코드는 xe7, xe5 및 xe2에서 작동합니다. 당신을 도와 줄 코드를 개선 할 것입니다. –

+0

XE는 XE2 이전 버전입니다. Windows 만 대상으로합니다. 우리는 [mcve]가 필요합니다. 하나를 제공하십시오. –

답변

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에서 허용되지 않습니다. –

관련 문제