2017-07-12 10 views
1

前のインストールを新しい場所にコピー(移行)している間、PrepareToInstallページに進行状況バーとラベルを表示しようとしています。私はMartin PrikrylのDirectoryCopyプロシージャのわずかに修正されたバージョンを使用していますが、これは期待どおりに動作します。ファイルとディレクトリが新しい場所にコピーされ、操作がファイルに記録されます。Inno Setup show directory copyの進行状況バーとラベルをPrepareToInstallページに表示

しかし、多くのファイルがある場合(これは2,500ファイルで合計約1.2GB)、GUIが更新されずフリーズしているように見える私のカスタムコントロールの(すなわち、進行状況バーと進捗ラベルなし)。 RefreshまたはUpdateのいずれかを呼び出して強制的に表示させることができましたが、進行状況バーにはアニメーションが表示されず、コピー操作が完了してもGUI全体が応答しないように見えます。 Inno Setupはsingle-threaded operations is maybe what is causing the GUI to freeze and not updateしかサポートしていないと思います。ファイルをコピーして同時にGUIを更新する方法はありますか?

[Code] 
var 
    PrepareToInstallLabel: TNewStaticText; 
    PrepareToInstallProgressBar: TNewProgressBar; 

//Slightly modified Public Domain code to copy a directory recursively and update PrepareToInstall label progress 
//Contributed by Martin Prikryl on Stack Overflow 
procedure DirCopy(strSourcePath, strDestPath: String); 
var 
    FindRec: TFindRec; 
    strSourceFilePath, strDestFilePath: String; 
begin 
    if FindFirst(strSourcePath + '\*', FindRec) then 
    begin 
     try 
     repeat 
      if (FindRec.Name <> '.') and (FindRec.Name <> '..') then 
      begin 
       strSourceFilePath := strSourcePath + '\' + FindRec.Name; 
       strDestFilePath := strDestPath + '\' + FindRec.Name; 
       if FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY = 0 then 
       begin 
        PrepareToInstallLabel.Caption := 'Copying ' + strSourceFilePath + '...'; 
        if FileCopy(strSourceFilePath, strDestFilePath, False) then 
        begin 
         Log(Format('Copied %s to %s', [strSourceFilePath, strDestFilePath])); 
        end 
        else 
        begin 
         SuppressibleMsgBox(Format('Failed to copy %s to %s', [strSourceFilePath, strDestFilePath]), 
         mbError, MB_OK, IDOK); 
        end; 
       end 
       else 
       begin 
        if CreateDir(strDestFilePath) then 
        begin 
         Log(Format('Created %s', [strDestFilePath])); 
         DirCopy(strSourceFilePath, strDestFilePath); 
        end 
        else 
        begin 
         SuppressibleMsgBox(Format('Failed to create %s', [strDestFilePath]), 
         mbError, MB_OK, IDOK); 
        end; 
       end; 
      end; 
     until 
      not FindNext(FindRec); 
     finally 
     FindClose(FindRec); 
     end; 
    end 
    else 
    begin 
     SuppressibleMsgBox(Format('Failed to list %s', [strSourcePath]), 
     mbError, MB_OK, IDOK); 
    end; 
end; 

//Show PrepareToInstall page GUI controls 
procedure ShowPrepareToInstallGuiControls(); 
begin 
    PrepareToInstallProgressBar.Visible := True; 
    PrepareToInstallLabel.Visible := True; 
end; 

//Update PrepareToInstall page GUI controls; note this procedure should not be needed 
procedure UpdatePrepareToInstallGuiControls(); 
begin 
//Both lines below seem to be needed to force the Cancel button to disable, 
//despite already disabling the button at the beginning of the PrepareToInstall event 
    WizardForm.CancelButton.Enabled := False; 
    WizardForm.CancelButton.Refresh; 
//Both lines below seem to be needed to force display of the progress bar and label, 
//despite already showing them in the PrepareToInstall event; without them no controls are shown on the page. 
    PrepareToInstallLabel.Update; 
    PrepareToInstallProgressBar.Update; 
end; 

//Hide PrepareToInstall page GUI controls 
procedure HidePrepareToInstallGuiControls(); 
begin 
    PrepareToInstallProgressBar.Visible := False; 
    PrepareToInstallLabel.Visible := False; 
end; 

function PrepareToInstall(var NeedsRestart: Boolean): String; 
begin 
    WizardForm.CancelButton.Enabled := False; 
//Migrate installation 
    if IsMigration then 
    begin 
     ShowPrepareToInstallGuiControls; 
     PrepareToInstallLabel.Caption := 'Migrating installation...'; 
     UpdatePrepareToInstallGuiControls; 
     Log('Installation migration started.'); 
     ForceDirectories(ExpandConstant('{app}\FolderToMigrate')); 
     DirCopy(strExistingInstallPath + '\Database', ExpandConstant('{app}\FolderToMigrate')); 
     Log('Installation migration finished.'); 
    end; 
    HidePrepareToInstallGuiControls; 
end; 

procedure InitializeWizard(); 
//Define the label for the Preparing to Install page 
    PrepareToInstallLabel := TNewStaticText.Create(WizardForm); 
    with PrepareToInstallLabel do 
    begin 
     Visible := False; 
     Parent := WizardForm.PreparingPage; 
     Left := WizardForm.StatusLabel.Left; 
     Top := WizardForm.StatusLabel.Top; 
    end; 
//Define Progress Bar for the Preparing to Install Page 
    PrepareToInstallProgressBar := TNewProgressBar.Create(WizardForm); 
    with PrepareToInstallProgressBar do 
    begin 
     Visible := False; 
     Parent := WizardForm.PreparingPage; 
     Left := WizardForm.ProgressGauge.Left; 
     Top := WizardForm.ProgressGauge.Top; 
     Width := WizardForm.ProgressGauge.Width; 
     Height := WizardForm.ProgressGauge.Height; 
     Min := 0; 
     Max := 100; 
     Style := npbstMarquee; 
    end; 
end; 

アップデート:私はPrepareToInstallLabel.Caption := 'Copying ' + strSourceFilePath + '...';WizardForm.Refresh;を追加し、これは、更新するためのラベルを強制するようだが、何のプログレスバーのアニメーションはまだありません。また、各ファイルのコピー後にWizardForm.Refreshを何千回も呼び出すと、特に効率的ではないようです。

答えて

関連する問題