Setup.ScriptDlg.pas 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192
  1. unit Setup.ScriptDlg;
  2. {
  3. Inno Setup
  4. Copyright (C) 1997-2012 Jordan Russell
  5. Portions by Martijn Laan
  6. For conditions of distribution and use, see LICENSE.TXT.
  7. Custom wizard pages
  8. }
  9. interface
  10. uses
  11. Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, StdCtrls, Contnrs, Generics.Collections,
  12. Setup.WizardForm, Setup.Install, Compression.SevenZipDecoder,
  13. NewCheckListBox, NewStaticText, NewProgressBar, PasswordEdit, RichEditViewer,
  14. BidiCtrls, TaskbarProgressFunc;
  15. type
  16. TInputQueryWizardPage = class(TWizardPage)
  17. private
  18. FEdits: TList;
  19. FPromptLabels: TList;
  20. FSubCaptionLabel: TNewStaticText;
  21. FY: Integer;
  22. function GetEdit(Index: Integer): TPasswordEdit;
  23. function GetPromptLabel(Index: Integer): TNewStaticText;
  24. function GetValue(Index: Integer): String;
  25. procedure SetValue(Index: Integer; const Value: String);
  26. public
  27. constructor Create(AOwner: TComponent); override;
  28. destructor Destroy; override;
  29. function Add(const APrompt: String; const APassword: Boolean): Integer;
  30. property Edits[Index: Integer]: TPasswordEdit read GetEdit;
  31. procedure Initialize(const SubCaption: String);
  32. property PromptLabels[Index: Integer]: TNewStaticText read GetPromptLabel;
  33. property Values[Index: Integer]: String read GetValue write SetValue;
  34. published
  35. property SubCaptionLabel: TNewStaticText read FSubCaptionLabel;
  36. end;
  37. TInputOptionWizardPage = class(TWizardPage)
  38. private
  39. FCheckListBox: TNewCheckListBox;
  40. FExclusive: Boolean;
  41. FSubCaptionLabel: TNewStaticText;
  42. function GetSelectedValueIndex: Integer;
  43. function GetValue(Index: Integer): Boolean;
  44. procedure SetSelectedValueIndex(Value: Integer);
  45. procedure SetValue(Index: Integer; Value: Boolean);
  46. public
  47. function Add(const ACaption: String): Integer;
  48. function AddEx(const ACaption: String; const ALevel: Byte; const AExclusive: Boolean): Integer;
  49. procedure Initialize(const SubCaption: String; const Exclusive, ListBox: Boolean);
  50. property SelectedValueIndex: Integer read GetSelectedValueIndex write SetSelectedValueIndex;
  51. property Values[Index: Integer]: Boolean read GetValue write SetValue;
  52. published
  53. property CheckListBox: TNewCheckListBox read FCheckListBox;
  54. property SubCaptionLabel: TNewStaticText read FSubCaptionLabel;
  55. end;
  56. TInputDirWizardPage = class(TWizardPage)
  57. private
  58. FAppendDir: Boolean;
  59. FButtons: TList;
  60. FEdits: TList;
  61. FNewFolderName: String;
  62. FPromptLabels: TList;
  63. FSubCaptionLabel: TNewStaticText;
  64. FY: Integer;
  65. procedure ButtonClick(Sender: TObject);
  66. function GetButton(Index: Integer): TNewButton;
  67. function GetEdit(Index: Integer): TEdit;
  68. function GetPromptLabel(Index: Integer): TNewStaticText;
  69. function GetValue(Index: Integer): String;
  70. procedure SetValue(Index: Integer; const Value: String);
  71. protected
  72. procedure NextButtonClick(var Continue: Boolean); override;
  73. public
  74. constructor Create(AOwner: TComponent); override;
  75. destructor Destroy; override;
  76. function Add(const APrompt: String): Integer;
  77. property Buttons[Index: Integer]: TNewButton read GetButton;
  78. property Edits[Index: Integer]: TEdit read GetEdit;
  79. procedure Initialize(const SubCaption: String; const AppendDir: Boolean;
  80. const NewFolderName: String);
  81. property PromptLabels[Index: Integer]: TNewStaticText read GetPromptLabel;
  82. property Values[Index: Integer]: String read GetValue write SetValue;
  83. published
  84. property NewFolderName: String read FNewFolderName write FNewFolderName;
  85. property SubCaptionLabel: TNewStaticText read FSubCaptionLabel;
  86. end;
  87. TInputFileWizardPage = class(TWizardPage)
  88. private
  89. FButtons: TList;
  90. FEdits: TList;
  91. FInputFileDefaultExtensions: TStringList;
  92. FInputFileFilters: TStringList;
  93. FPromptLabels: TList;
  94. FSubCaptionLabel: TNewStaticText;
  95. FY: Integer;
  96. procedure ButtonClick(Sender: TObject);
  97. function GetButton(Index: Integer): TNewButton;
  98. function GetEdit(Index: Integer): TEdit;
  99. function GetPromptLabel(Index: Integer): TNewStaticText;
  100. function GetValue(Index: Integer): String;
  101. procedure SetValue(Index: Integer; const Value: String);
  102. function GetIsSaveButton(Index: Integer): Boolean;
  103. procedure SetIsSaveButton(Index: Integer; const IsSaveButton: Boolean);
  104. public
  105. constructor Create(AOwner: TComponent); override;
  106. destructor Destroy; override;
  107. function Add(const APrompt, AFilter, ADefaultExtension: String): Integer;
  108. property Buttons[Index: Integer]: TNewButton read GetButton;
  109. property Edits[Index: Integer]: TEdit read GetEdit;
  110. procedure Initialize(const SubCaption: String);
  111. property PromptLabels[Index: Integer]: TNewStaticText read GetPromptLabel;
  112. property Values[Index: Integer]: String read GetValue write SetValue;
  113. property IsSaveButton[Index: Integer]: Boolean read GetIsSaveButton write SetIsSaveButton;
  114. published
  115. property SubCaptionLabel: TNewStaticText read FSubCaptionLabel;
  116. end;
  117. TOutputMsgWizardPage = class(TWizardPage)
  118. private
  119. FMsgLabel: TNewStaticText;
  120. public
  121. procedure Initialize(const Msg: String);
  122. published
  123. property MsgLabel: TNewStaticText read FMsgLabel;
  124. end;
  125. TOutputMsgMemoWizardPage = class(TWizardPage)
  126. private
  127. FRichEditViewer: TRichEditViewer;
  128. FSubCaptionLabel: TNewStaticText;
  129. public
  130. procedure Initialize(const SubCaption: String; const Msg: AnsiString);
  131. published
  132. property RichEditViewer: TRichEditViewer read FRichEditViewer;
  133. property SubCaptionLabel: TNewStaticText read FSubCaptionLabel;
  134. end;
  135. TOutputProgressWizardPage = class(TWizardPage)
  136. private
  137. FMsg1Label: TNewStaticText;
  138. FMsg2Label: TNewStaticText;
  139. FProgressBar: TNewProgressBar;
  140. FUseMarqueeStyle: Boolean;
  141. FSavePageID: Integer;
  142. procedure ProcessMsgs;
  143. public
  144. constructor Create(AOwner: TComponent); override;
  145. procedure Hide;
  146. procedure Initialize; virtual;
  147. procedure SetProgress(const Position, Max: Longint);
  148. procedure SetText(const Msg1, Msg2: String);
  149. procedure Show; virtual;
  150. published
  151. property Msg1Label: TNewStaticText read FMsg1Label;
  152. property Msg2Label: TNewStaticText read FMsg2Label;
  153. property ProgressBar: TNewProgressBar read FProgressBar;
  154. end;
  155. TOutputMarqueeProgressWizardPage = class(TOutputProgressWizardPage)
  156. public
  157. constructor Create(AOwner: TComponent); override;
  158. procedure Animate;
  159. procedure Initialize; override;
  160. procedure SetProgress(const Position, Max: Longint);
  161. end;
  162. TDownloadFile = class
  163. Url, BaseName, RequiredSHA256OfFile, UserName, Password: String;
  164. end;
  165. TDownloadFiles = TObjectList<TDownloadFile>;
  166. TDownloadWizardPage = class(TOutputProgressWizardPage)
  167. private
  168. FFiles: TDownloadFiles;
  169. FOnDownloadProgress: TOnDownloadProgress;
  170. FShowBaseNameInsteadOfUrl: Boolean;
  171. FAbortButton: TNewButton;
  172. FShowProgressControlsOnNextProgress, FAbortedByUser: Boolean;
  173. procedure AbortButtonClick(Sender: TObject);
  174. function InternalOnDownloadProgress(const Url, BaseName: string; const Progress, ProgressMax: Int64): Boolean;
  175. procedure ShowProgressControls(const AVisible: Boolean);
  176. public
  177. constructor Create(AOwner: TComponent); override;
  178. destructor Destroy; override;
  179. procedure Initialize; override;
  180. procedure Add(const Url, BaseName, RequiredSHA256OfFile: String);
  181. procedure AddEx(const Url, BaseName, RequiredSHA256OfFile, UserName, Password: String);
  182. procedure Clear;
  183. function Download: Int64;
  184. property OnDownloadProgress: TOnDownloadProgress write FOnDownloadProgress;
  185. procedure Show; override;
  186. published
  187. property AbortButton: TNewButton read FAbortButton;
  188. property AbortedByUser: Boolean read FAbortedByUser;
  189. property ShowBaseNameInsteadOfUrl: Boolean read FShowBaseNameInsteadOfUrl write FShowBaseNameInsteadOfUrl;
  190. end;
  191. TArchive = class
  192. FileName, DestDir: String;
  193. FullPaths: Boolean;
  194. end;
  195. TArchives = TObjectList<TArchive>;
  196. TExtractionWizardPage = class(TOutputProgressWizardPage)
  197. private
  198. FArchives: TArchives;
  199. FOnExtractionProgress: TOnExtractionProgress;
  200. FShowArchiveInsteadOfFile: Boolean;
  201. FAbortButton: TNewButton;
  202. FShowProgressControlsOnNextProgress, FAbortedByUser: Boolean;
  203. procedure AbortButtonClick(Sender: TObject);
  204. function InternalOnExtractionProgress(const ArchiveName, FileName: string; const Progress, ProgressMax: Int64): Boolean;
  205. procedure ShowProgressControls(const AVisible: Boolean);
  206. public
  207. constructor Create(AOwner: TComponent); override;
  208. destructor Destroy; override;
  209. procedure Initialize; override;
  210. procedure Add(const ArchiveFileName, DestDir: String; const FullPaths: Boolean);
  211. procedure Clear;
  212. procedure Extract;
  213. property OnExtractionProgress: TOnExtractionProgress write FOnExtractionProgress;
  214. procedure Show; override;
  215. published
  216. property AbortButton: TNewButton read FAbortButton;
  217. property AbortedByUser: Boolean read FAbortedByUser;
  218. property ShowArchiveInsteadOfFile: Boolean read FShowArchiveInsteadOfFile write FShowArchiveInsteadOfFile;
  219. end;
  220. implementation
  221. uses
  222. StrUtils,
  223. Shared.Struct, Setup.MainFunc, Setup.SelectFolderForm, SetupLdrAndSetup.Messages,
  224. Shared.SetupMessageIDs, PathFunc, Shared.CommonFunc.Vcl, Shared.CommonFunc,
  225. BrowseFunc, Setup.LoggingFunc, Setup.InstFunc;
  226. const
  227. DefaultLabelHeight = 14;
  228. DefaultBoxTop = 24; { relative to top of InnerNotebook }
  229. DefaultBoxBottom = DefaultBoxTop + 205;
  230. {------}
  231. procedure SetCtlParent(const AControl, AParent: TWinControl);
  232. { Like assigning to AControl.Parent, but puts the control at the *bottom* of
  233. the z-order instead of the top, for MSAA compatibility. }
  234. var
  235. OldVisible: Boolean;
  236. begin
  237. { Hide the control so the handle won't be created yet, so that unnecessary
  238. "OBJ_REORDER" MSAA events don't get sent }
  239. OldVisible := AControl.Visible;
  240. AControl.Visible := False;
  241. AControl.Parent := AParent;
  242. AControl.SendToBack;
  243. AControl.Visible := OldVisible;
  244. end;
  245. {--- InputQuery ---}
  246. constructor TInputQueryWizardPage.Create(AOwner: TComponent);
  247. begin
  248. inherited;
  249. FEdits := TList.Create;
  250. FPromptLabels := TList.Create;
  251. end;
  252. destructor TInputQueryWizardPage.Destroy;
  253. begin
  254. FPromptLabels.Free;
  255. FEdits.Free;
  256. inherited;
  257. end;
  258. procedure TInputQueryWizardPage.Initialize(const SubCaption: String);
  259. begin
  260. FSubCaptionLabel := TNewStaticText.Create(Self);
  261. with FSubCaptionLabel do begin
  262. AutoSize := False;
  263. Width := SurfaceWidth;
  264. Height := WizardForm.ScalePixelsY(DefaultLabelHeight);
  265. WordWrap := True;
  266. Caption := SubCaption;
  267. Parent := Surface;
  268. end;
  269. FY := WizardForm.AdjustLabelHeight(FSubCaptionLabel) + WizardForm.ScalePixelsY(DefaultBoxTop);
  270. end;
  271. function TInputQueryWizardPage.Add(const APrompt: String;
  272. const APassword: Boolean): Integer;
  273. var
  274. PromptLabel: TNewStaticText;
  275. Edit: TPasswordEdit;
  276. begin
  277. if APrompt <> '' then begin
  278. PromptLabel := TNewStaticText.Create(Self);
  279. with PromptLabel do begin
  280. AutoSize := False;
  281. Top := FY;
  282. Width := SurfaceWidth;
  283. Height := WizardForm.ScalePixelsY(DefaultLabelHeight);
  284. Anchors := [akLeft, akTop, akRight];
  285. WordWrap := True;
  286. Caption := APrompt;
  287. end;
  288. SetCtlParent(PromptLabel, Surface);
  289. Inc(FY, WizardForm.AdjustLabelHeight(PromptLabel) + WizardForm.ScalePixelsY(16));
  290. end else
  291. PromptLabel := nil;
  292. Edit := TPasswordEdit.Create(Self);
  293. with Edit do begin
  294. Password := APassword;
  295. Top := FY;
  296. Width := SurfaceWidth;
  297. Anchors := [akLeft, akTop, akRight];
  298. end;
  299. SetCtlParent(Edit, Surface);
  300. Inc(FY, WizardForm.ScalePixelsY(36));
  301. if PromptLabel <> nil then
  302. PromptLabel.FocusControl := Edit;
  303. FPromptLabels.Add(PromptLabel);
  304. Result := FEdits.Add(Edit);
  305. end;
  306. function TInputQueryWizardPage.GetEdit(Index: Integer): TPasswordEdit;
  307. begin
  308. Result := TPasswordEdit(FEdits[Index]);
  309. end;
  310. function TInputQueryWizardPage.GetPromptLabel(Index: Integer): TNewStaticText;
  311. begin
  312. Result := TNewStaticText(FPromptLabels[Index]);
  313. end;
  314. function TInputQueryWizardPage.GetValue(Index: Integer): String;
  315. begin
  316. Result := GetEdit(Index).Text;
  317. end;
  318. procedure TInputQueryWizardPage.SetValue(Index: Integer; const Value: String);
  319. begin
  320. GetEdit(Index).Text := Value;
  321. end;
  322. {--- InputOption ---}
  323. procedure TInputOptionWizardPage.Initialize(const SubCaption: String;
  324. const Exclusive, ListBox: Boolean);
  325. var
  326. CaptionYDiff: Integer;
  327. begin
  328. FSubCaptionLabel := TNewStaticText.Create(Self);
  329. with SubCaptionLabel do begin
  330. AutoSize := False;
  331. Width := SurfaceWidth;
  332. Height := WizardForm.ScalePixelsY(DefaultLabelHeight);
  333. Anchors := [akLeft, akTop, akRight];
  334. WordWrap := True;
  335. Caption := SubCaption;
  336. Parent := Surface;
  337. end;
  338. CaptionYDiff := WizardForm.AdjustLabelHeight(SubCaptionLabel);
  339. FCheckListBox := TNewCheckListBox.Create(Self);
  340. with FCheckListBox do begin
  341. Top := CaptionYDiff + WizardForm.ScalePixelsY(DefaultBoxTop);
  342. Width := SurfaceWidth;
  343. Height := WizardForm.ScalePixelsY(DefaultBoxBottom) - Top;
  344. Anchors := [akLeft, akTop, akRight, akBottom];
  345. Flat := ListBox and (shFlatComponentsList in SetupHeader.Options);
  346. end;
  347. SetCtlParent(FCheckListBox, Surface);
  348. FExclusive := Exclusive;
  349. if not ListBox then begin
  350. FCheckListBox.BorderStyle := bsNone;
  351. FCheckListBox.Color := SurfaceColor;
  352. FCheckListBox.MinItemHeight := WizardForm.ScalePixelsY(22);
  353. FCheckListBox.WantTabs := True;
  354. end;
  355. end;
  356. function TInputOptionWizardPage.Add(const ACaption: String): Integer;
  357. begin
  358. Result := AddEx(ACaption, 0, FExclusive);
  359. end;
  360. function TInputOptionWizardPage.AddEx(const ACaption: String;
  361. const ALevel: Byte; const AExclusive: Boolean): Integer;
  362. begin
  363. if AExclusive then
  364. Result := FCheckListBox.AddRadioButton(ACaption, '', ALevel, False, True, nil)
  365. else
  366. Result := FCheckListBox.AddCheckBox(ACaption, '', ALevel, False, True, True,
  367. True, nil);
  368. end;
  369. function TInputOptionWizardPage.GetSelectedValueIndex: Integer;
  370. var
  371. I: Integer;
  372. begin
  373. for I := 0 to FCheckListBox.Items.Count-1 do
  374. if (FCheckListBox.ItemLevel[I] = 0) and FCheckListBox.Checked[I] then begin
  375. Result := I;
  376. Exit;
  377. end;
  378. Result := -1;
  379. end;
  380. function TInputOptionWizardPage.GetValue(Index: Integer): Boolean;
  381. begin
  382. Result := FCheckListBox.Checked[Index];
  383. end;
  384. procedure TInputOptionWizardPage.SetSelectedValueIndex(Value: Integer);
  385. var
  386. I: Integer;
  387. begin
  388. for I := 0 to FCheckListBox.Items.Count-1 do
  389. if FCheckListBox.ItemLevel[I] = 0 then
  390. FCheckListBox.Checked[I] := (I = Value);
  391. end;
  392. procedure TInputOptionWizardPage.SetValue(Index: Integer; Value: Boolean);
  393. begin
  394. FCheckListBox.Checked[Index] := Value;
  395. end;
  396. {--- InputDir ---}
  397. constructor TInputDirWizardPage.Create(AOwner: TComponent);
  398. begin
  399. inherited;
  400. FButtons := TList.Create;
  401. FEdits := TList.Create;
  402. FPromptLabels := TList.Create;
  403. end;
  404. destructor TInputDirWizardPage.Destroy;
  405. begin
  406. FPromptLabels.Free;
  407. FEdits.Free;
  408. FButtons.Free;
  409. inherited;
  410. end;
  411. procedure TInputDirWizardPage.ButtonClick(Sender: TObject);
  412. var
  413. I: Integer;
  414. Edit: TEdit;
  415. S: String;
  416. begin
  417. I := FButtons.IndexOf(Sender);
  418. if I <> -1 then begin
  419. Edit := TEdit(FEdits[I]);
  420. S := Edit.Text;
  421. if ShowSelectFolderDialog(False, FAppendDir, S, FNewFolderName) then
  422. Edit.Text := S;
  423. end;
  424. end;
  425. procedure TInputDirWizardPage.NextButtonClick(var Continue: Boolean);
  426. var
  427. I: Integer;
  428. Edit: TEdit;
  429. begin
  430. for I := 0 to FEdits.Count-1 do begin
  431. Edit := FEdits[I];
  432. if not ValidateCustomDirEdit(Edit, True, True, True) then begin
  433. if WizardForm.Visible then
  434. Edit.SetFocus;
  435. Continue := False;
  436. Exit;
  437. end;
  438. end;
  439. inherited;
  440. end;
  441. procedure TInputDirWizardPage.Initialize(const SubCaption: String;
  442. const AppendDir: Boolean; const NewFolderName: String);
  443. begin
  444. FSubCaptionLabel := TNewStaticText.Create(Self);
  445. with FSubCaptionLabel do begin
  446. AutoSize := False;
  447. Width := SurfaceWidth;
  448. Height := WizardForm.ScalePixelsY(DefaultLabelHeight);
  449. Anchors := [akLeft, akTop, akRight];
  450. WordWrap := True;
  451. Caption := SubCaption;
  452. Parent := Surface;
  453. end;
  454. FY := WizardForm.AdjustLabelHeight(FSubCaptionLabel) + WizardForm.ScalePixelsY(DefaultBoxTop);
  455. FAppendDir := AppendDir;
  456. FNewFolderName := NewFolderName;
  457. end;
  458. function TInputDirWizardPage.Add(const APrompt: String): Integer;
  459. var
  460. ButtonWidth: Integer;
  461. PromptLabel: TNewStaticText;
  462. Edit: TEdit;
  463. Button: TNewButton;
  464. begin
  465. ButtonWidth := WizardForm.CalculateButtonWidth([SetupMessages[msgButtonWizardBrowse]]);
  466. if APrompt <> '' then begin
  467. PromptLabel := TNewStaticText.Create(Self);
  468. with PromptLabel do begin
  469. AutoSize := False;
  470. Top := FY;
  471. Width := SurfaceWidth;
  472. Height := WizardForm.ScalePixelsY(DefaultLabelHeight);
  473. Anchors := [akLeft, akTop, akRight];
  474. WordWrap := True;
  475. Caption := APrompt;
  476. end;
  477. SetCtlParent(PromptLabel, Surface);
  478. Inc(FY, WizardForm.AdjustLabelHeight(PromptLabel) + WizardForm.ScalePixelsY(16));
  479. end else
  480. PromptLabel := nil;
  481. Edit := TEdit.Create(Self);
  482. with Edit do begin
  483. Top := FY;
  484. Width := SurfaceWidth-ButtonWidth-WizardForm.ScalePixelsX(10);
  485. Anchors := [akLeft, akTop, akRight];
  486. end;
  487. SetCtlParent(Edit, Surface);
  488. TryEnableAutoCompleteFileSystem(Edit.Handle);
  489. if PromptLabel <> nil then
  490. PromptLabel.FocusControl := Edit;
  491. Button := TNewButton.Create(Self);
  492. with Button do begin
  493. Left := SurfaceWidth-ButtonWidth;
  494. Top := Edit.Top-1;
  495. Width := ButtonWidth;
  496. Height := WizardForm.NextButton.Height;
  497. Anchors := [akTop, akRight];
  498. if FEdits.Count = 0 then
  499. Caption := SetupMessages[msgButtonWizardBrowse]
  500. else
  501. { Can't use the same accel key for secondary buttons... }
  502. Caption := RemoveAccelChar(SetupMessages[msgButtonWizardBrowse]);
  503. OnClick := ButtonClick;
  504. end;
  505. SetCtlParent(Button, Surface);
  506. Inc(FY, WizardForm.ScalePixelsY(36));
  507. FButtons.Add(Button);
  508. FPromptLabels.Add(PromptLabel);
  509. Result := FEdits.Add(Edit);
  510. end;
  511. function TInputDirWizardPage.GetButton(Index: Integer): TNewButton;
  512. begin
  513. Result := TNewButton(FButtons[Index]);
  514. end;
  515. function TInputDirWizardPage.GetEdit(Index: Integer): TEdit;
  516. begin
  517. Result := TEdit(FEdits[Index]);
  518. end;
  519. function TInputDirWizardPage.GetPromptLabel(Index: Integer): TNewStaticText;
  520. begin
  521. Result := TNewStaticText(FPromptLabels[Index]);
  522. end;
  523. function TInputDirWizardPage.GetValue(Index: Integer): String;
  524. begin
  525. Result := GetEdit(Index).Text;
  526. end;
  527. procedure TInputDirWizardPage.SetValue(Index: Integer; const Value: String);
  528. begin
  529. GetEdit(Index).Text := RemoveBackslashUnlessRoot(PathExpand(Value));
  530. end;
  531. {--- InputFile ---}
  532. constructor TInputFileWizardPage.Create(AOwner: TComponent);
  533. begin
  534. inherited;
  535. FButtons := TList.Create;
  536. FEdits := TList.Create;
  537. FInputFileDefaultExtensions := TStringList.Create;
  538. FInputFileFilters := TStringList.Create;
  539. FPromptLabels := TList.Create;
  540. end;
  541. destructor TInputFileWizardPage.Destroy;
  542. begin
  543. FPromptLabels.Free;
  544. FInputFileFilters.Free;
  545. FInputFileDefaultExtensions.Free;
  546. FEdits.Free;
  547. FButtons.Free;
  548. inherited;
  549. end;
  550. procedure TInputFileWizardPage.ButtonClick(Sender: TObject);
  551. var
  552. I: Integer;
  553. Edit: TEdit;
  554. FileName: String;
  555. begin
  556. I := FButtons.IndexOf(Sender);
  557. if I <> -1 then begin
  558. Edit := TEdit(FEdits[I]);
  559. FileName := Edit.Text;
  560. if (not IsSaveButton[I] and NewGetOpenFileName(RemoveAccelChar(SetupMessages[msgButtonWizardBrowse]),
  561. FileName, PathExtractPath(FileName), FInputFileFilters[I],
  562. FInputFileDefaultExtensions[I], Surface.Handle)) or
  563. (IsSaveButton[I] and NewGetSaveFileName(RemoveAccelChar(SetupMessages[msgButtonWizardBrowse]),
  564. FileName, PathExtractPath(FileName), FInputFileFilters[I],
  565. FInputFileDefaultExtensions[I], Surface.Handle)) then
  566. Edit.Text := FileName;
  567. end;
  568. end;
  569. procedure TInputFileWizardPage.Initialize(const SubCaption: String);
  570. begin
  571. FSubCaptionLabel := TNewStaticText.Create(Self);
  572. with FSubCaptionLabel do begin
  573. AutoSize := False;
  574. Width := SurfaceWidth;
  575. Height := WizardForm.ScalePixelsY(DefaultLabelHeight);
  576. Anchors := [akLeft, akTop, akRight];
  577. WordWrap := True;
  578. Caption := SubCaption;
  579. Parent := Surface;
  580. end;
  581. FY := WizardForm.AdjustLabelHeight(FSubCaptionLabel) + WizardForm.ScalePixelsY(DefaultBoxTop);
  582. end;
  583. function TInputFileWizardPage.Add(const APrompt, AFilter,
  584. ADefaultExtension: String): Integer;
  585. var
  586. ButtonWidth: Integer;
  587. PromptLabel: TNewStaticText;
  588. Edit: TEdit;
  589. Button: TNewButton;
  590. begin
  591. ButtonWidth := WizardForm.CalculateButtonWidth([SetupMessages[msgButtonWizardBrowse]]);
  592. if APrompt <> '' then begin
  593. PromptLabel := TNewStaticText.Create(Self);
  594. with PromptLabel do begin
  595. AutoSize := False;
  596. Top := FY;
  597. Width := SurfaceWidth;
  598. Height := WizardForm.ScalePixelsY(DefaultLabelHeight);
  599. Anchors := [akLeft, akTop, akRight];
  600. WordWrap := True;
  601. Caption := APrompt;
  602. end;
  603. SetCtlParent(PromptLabel, Surface);
  604. Inc(FY, WizardForm.AdjustLabelHeight(PromptLabel) + WizardForm.ScalePixelsY(16));
  605. end else
  606. PromptLabel := nil;
  607. Edit := TEdit.Create(Self);
  608. with Edit do begin
  609. Top := FY;
  610. Width := SurfaceWidth-ButtonWidth-WizardForm.ScalePixelsX(10);
  611. Anchors := [akLeft, akTop, akRight];
  612. end;
  613. SetCtlParent(Edit, Surface);
  614. TryEnableAutoCompleteFileSystem(Edit.Handle);
  615. if PromptLabel <> nil then
  616. PromptLabel.FocusControl := Edit;
  617. Button := TNewButton.Create(Self);
  618. with Button do begin
  619. Left := SurfaceWidth-ButtonWidth;
  620. Top := Edit.Top-1;
  621. Width := ButtonWidth;
  622. Height := WizardForm.NextButton.Height;
  623. Anchors := [akTop, akRight];
  624. if FButtons.Count = 0 then
  625. Caption := SetupMessages[msgButtonWizardBrowse]
  626. else
  627. { Can't use the same accel key for secondary buttons... }
  628. Caption := RemoveAccelChar(SetupMessages[msgButtonWizardBrowse]);
  629. OnClick := ButtonClick;
  630. end;
  631. SetCtlParent(Button, Surface);
  632. Inc(FY, WizardForm.ScalePixelsY(36));
  633. FInputFileFilters.Add(AFilter);
  634. FInputFileDefaultExtensions.Add(ADefaultExtension);
  635. FButtons.Add(Button);
  636. FPromptLabels.Add(PromptLabel);
  637. Result := FEdits.Add(Edit);
  638. end;
  639. function TInputFileWizardPage.GetButton(Index: Integer): TNewButton;
  640. begin
  641. Result := TNewButton(FButtons[Index]);
  642. end;
  643. function TInputFileWizardPage.GetEdit(Index: Integer): TEdit;
  644. begin
  645. Result := TEdit(FEdits[Index]);
  646. end;
  647. function TInputFileWizardPage.GetPromptLabel(Index: Integer): TNewStaticText;
  648. begin
  649. Result := TNewStaticText(FPromptLabels[Index]);
  650. end;
  651. function TInputFileWizardPage.GetValue(Index: Integer): String;
  652. begin
  653. Result := GetEdit(Index).Text;
  654. end;
  655. procedure TInputFileWizardPage.SetValue(Index: Integer; const Value: String);
  656. begin
  657. GetEdit(Index).Text := Value;
  658. end;
  659. function TInputFileWizardPage.GetIsSaveButton(Index: Integer): Boolean;
  660. begin
  661. Result := GetButton(Index).Tag = 1;
  662. end;
  663. procedure TInputFileWizardPage.SetIsSaveButton(Index: Integer; const IsSaveButton: Boolean);
  664. begin
  665. if IsSaveButton then
  666. GetButton(Index).Tag := 1
  667. else
  668. GetButton(Index).Tag := 0;
  669. end;
  670. {--- OutputMsg ---}
  671. procedure TOutputMsgWizardPage.Initialize(const Msg: String);
  672. begin
  673. FMsgLabel := TNewStaticText.Create(Self);
  674. with FMsgLabel do begin
  675. AutoSize := False;
  676. Width := SurfaceWidth;
  677. Height := WizardForm.ScalePixelsY(DefaultLabelHeight);
  678. WordWrap := True;
  679. Caption := Msg;
  680. Parent := Surface;
  681. end;
  682. WizardForm.AdjustLabelHeight(MsgLabel);
  683. end;
  684. {--- OutputMsgMemo ---}
  685. procedure TOutputMsgMemoWizardPage.Initialize(const SubCaption: String; const Msg: AnsiString);
  686. var
  687. Y: Integer;
  688. begin
  689. Y := 0;
  690. if SubCaption <> '' then begin
  691. FSubCaptionLabel := TNewStaticText.Create(Self);
  692. with FSubCaptionLabel do begin
  693. AutoSize := False;
  694. Width := SurfaceWidth;
  695. Height := WizardForm.ScalePixelsY(DefaultLabelHeight);
  696. Anchors := [akLeft, akTop, akRight];
  697. WordWrap := True;
  698. Caption := SubCaption;
  699. Parent := Surface;
  700. end;
  701. Inc(Y, WizardForm.ScalePixelsY(DefaultBoxTop) +
  702. WizardForm.AdjustLabelHeight(FSubCaptionLabel));
  703. end else
  704. FSubCaptionLabel := nil;
  705. FRichEditViewer := TRichEditViewer.Create(Self);
  706. with FRichEditViewer do begin
  707. Top := Y;
  708. Width := SurfaceWidth;
  709. Height := WizardForm.ScalePixelsY(DefaultBoxBottom) - Y;
  710. Anchors := [akLeft, akTop, akRight, akBottom];
  711. BevelKind := bkFlat;
  712. BorderStyle := bsNone;
  713. ReadOnly := True;
  714. ScrollBars := ssVertical;
  715. WantReturns := False;
  716. end;
  717. SetCtlParent(FRichEditViewer, Surface);
  718. with FRichEditViewer do begin
  719. UseRichEdit := True;
  720. RTFText := Msg;
  721. end;
  722. end;
  723. {--- OutputProgress ---}
  724. constructor TOutputProgressWizardPage.Create(AOwner: TComponent);
  725. begin
  726. inherited;
  727. Style := Style + [psAlwaysSkip, psNoButtons];
  728. end;
  729. procedure TOutputProgressWizardPage.Initialize;
  730. begin
  731. FMsg1Label := TNewStaticText.Create(Self);
  732. with FMsg1Label do begin
  733. AutoSize := False;
  734. ShowAccelChar := False;
  735. Width := SurfaceWidth;
  736. Anchors := [akLeft, akTop, akRight];
  737. Height := WizardForm.StatusLabel.Height;
  738. WordWrap := WizardForm.StatusLabel.WordWrap;
  739. Parent := Surface;
  740. end;
  741. FMsg2Label := TNewStaticText.Create(Self);
  742. with FMsg2Label do begin
  743. AutoSize := False;
  744. ForceLTRReading := True;
  745. ShowAccelChar := False;
  746. Top := WizardForm.ScalePixelsY(16);
  747. Width := SurfaceWidth;
  748. Height := WizardForm.FileNameLabel.Height;
  749. Anchors := [akLeft, akTop, akRight];
  750. end;
  751. SetCtlParent(FMsg2Label, Surface);
  752. FProgressBar := TNewProgressBar.Create(Self);
  753. with FProgressBar do begin
  754. Top := WizardForm.ScalePixelsY(42);
  755. Width := SurfaceWidth;
  756. Height := WizardForm.ScalePixelsY(21);
  757. Anchors := [akLeft, akTop, akRight];
  758. Visible := False;
  759. end;
  760. SetCtlParent(FProgressBar, Surface);
  761. end;
  762. procedure TOutputProgressWizardPage.Hide;
  763. begin
  764. if (WizardForm.CurPageID = ID) and (FSavePageID <> 0) then begin
  765. SetMessageBoxCallbackFunc(nil, 0);
  766. SetAppTaskbarProgressState(tpsNoProgress);
  767. WizardForm.SetCurPage(FSavePageID);
  768. FSavePageID := 0;
  769. end;
  770. end;
  771. procedure TOutputProgressWizardPage.ProcessMsgs;
  772. { Process messages to repaint and keep Windows from thinking the process is
  773. hung. This is safe; due to the psNoButtons style the user shouldn't be able
  774. to cancel or do anything else during this time. }
  775. begin
  776. if WizardForm.CurPageID = ID then
  777. Application.ProcessMessages;
  778. end;
  779. procedure TOutputProgressWizardPage.SetProgress(const Position, Max: Longint);
  780. begin
  781. if Max > 0 then begin
  782. FProgressBar.Style := npbstNormal;
  783. FProgressBar.Max := Max;
  784. FProgressBar.Position := Position;
  785. FProgressBar.Visible := True;
  786. SetAppTaskbarProgressState(tpsNormal);
  787. SetAppTaskbarProgressValue(Position, Max);
  788. end else begin
  789. if FUseMarqueeStyle then
  790. FProgressBar.Style := npbstMarquee
  791. else
  792. FProgressBar.Visible := False;
  793. SetAppTaskbarProgressState(tpsNoProgress);
  794. end;
  795. ProcessMsgs;
  796. end;
  797. procedure TOutputProgressWizardPage.SetText(const Msg1, Msg2: String);
  798. begin
  799. FMsg1Label.Caption := Msg1;
  800. FMsg2Label.Caption := MinimizePathName(Msg2, FMsg2Label.Font,
  801. FMsg2Label.Width);
  802. ProcessMsgs;
  803. end;
  804. procedure OutputProgressWizardPageMessageBoxCallback(const Flags: LongInt; const After: Boolean;
  805. const Param: LongInt);
  806. const
  807. States: array [TNewProgressBarState] of TTaskbarProgressState =
  808. (tpsNormal, tpsError, tpsPaused);
  809. var
  810. OutputProgressWizardPage: TOutputProgressWizardPage;
  811. NewState: TNewProgressBarState;
  812. begin
  813. OutputProgressWizardPage := TOutputProgressWizardPage(Param);
  814. if After then
  815. NewState := npbsNormal
  816. else if (Flags and MB_ICONSTOP) <> 0 then
  817. NewState := npbsError
  818. else
  819. NewState := npbsPaused;
  820. with OutputProgressWizardPage.ProgressBar do begin
  821. State := NewState;
  822. Invalidate;
  823. end;
  824. SetAppTaskbarProgressState(States[NewState]);
  825. end;
  826. procedure TOutputProgressWizardPage.Show;
  827. begin
  828. if WizardForm.CurPageID <> ID then begin
  829. FSavePageID := WizardForm.CurPageID;
  830. WizardForm.SetCurPage(ID);
  831. SetMessageBoxCallbackFunc(OutputProgressWizardPageMessageBoxCallback, LongInt(Self));
  832. ProcessMsgs;
  833. end;
  834. end;
  835. constructor TOutputMarqueeProgressWizardPage.Create(AOwner: TComponent);
  836. begin
  837. inherited;
  838. FUseMarqueeStyle := True;
  839. end;
  840. procedure TOutputMarqueeProgressWizardPage.Animate;
  841. begin
  842. ProcessMsgs;
  843. end;
  844. procedure TOutputMarqueeProgressWizardPage.Initialize;
  845. begin
  846. inherited;
  847. FProgressBar.Visible := True;
  848. inherited SetProgress(0, 0);
  849. end;
  850. procedure TOutputMarqueeProgressWizardPage.SetProgress(const Position, Max: Longint);
  851. begin
  852. InternalError('Cannot call TOutputMarqueeProgressWizardPage.SetProgress');
  853. end;
  854. {--- Download ---}
  855. procedure TDownloadWizardPage.AbortButtonClick(Sender: TObject);
  856. begin
  857. FAbortedByUser := LoggedMsgBox(SetupMessages[msgStopDownload], '', mbConfirmation, MB_YESNO, True, ID_YES) = IDYES;
  858. end;
  859. function TDownloadWizardPage.InternalOnDownloadProgress(const Url, BaseName: string; const Progress, ProgressMax: Int64): Boolean;
  860. var
  861. Progress32, ProgressMax32: LongInt;
  862. begin
  863. if FAbortedByUser then begin
  864. Log('Need to abort download.');
  865. Result := False;
  866. end else begin
  867. if ProgressMax > 0 then
  868. Log(Format(' %d of %d bytes done.', [Progress, ProgressMax]))
  869. else
  870. Log(Format(' %d bytes done.', [Progress]));
  871. FMsg2Label.Caption := IfThen(FShowBaseNameInsteadOfUrl, BaseName, Url);
  872. if ProgressMax > MaxLongInt then begin
  873. Progress32 := Round((Progress / ProgressMax) * MaxLongInt);
  874. ProgressMax32 := MaxLongInt;
  875. end else begin
  876. Progress32 := Progress;
  877. ProgressMax32 := ProgressMax;
  878. end;
  879. SetProgress(Progress32, ProgressMax32); { This will process messages which we need for the abort button to work }
  880. if FShowProgressControlsOnNextProgress then begin
  881. ShowProgressControls(True);
  882. FShowProgressControlsOnNextProgress := False;
  883. ProcessMsgs;
  884. end;
  885. if Assigned(FOnDownloadProgress) then
  886. Result := FOnDownloadProgress(Url, BaseName, Progress, ProgressMax)
  887. else
  888. Result := True;
  889. end;
  890. end;
  891. constructor TDownloadWizardPage.Create(AOwner: TComponent);
  892. begin
  893. inherited;
  894. FUseMarqueeStyle := True;
  895. FFiles := TDownloadFiles.Create;
  896. end;
  897. destructor TDownloadWizardPage.Destroy;
  898. begin
  899. FFiles.Free;
  900. inherited;
  901. end;
  902. procedure TDownloadWizardPage.Initialize;
  903. begin
  904. inherited;
  905. FMsg1Label.Caption := SetupMessages[msgDownloadingLabel];
  906. FAbortButton := TNewButton.Create(Self);
  907. with FAbortButton do begin
  908. Caption := SetupMessages[msgButtonStopDownload];
  909. Top := FProgressBar.Top + FProgressBar.Height + WizardForm.ScalePixelsY(8);
  910. Width := WizardForm.CalculateButtonWidth([Caption]);
  911. Anchors := [akLeft, akTop];
  912. Height := WizardForm.CancelButton.Height;
  913. OnClick := AbortButtonClick;
  914. end;
  915. SetCtlParent(FAbortButton, Surface);
  916. end;
  917. procedure TDownloadWizardPage.Show;
  918. begin
  919. if WizardForm.CurPageID <> ID then begin
  920. ShowProgressControls(False);
  921. FShowProgressControlsOnNextProgress := True;
  922. end;
  923. inherited;
  924. end;
  925. procedure TDownloadWizardPage.ShowProgressControls(const AVisible: Boolean);
  926. begin
  927. FMsg2Label.Visible := AVisible;
  928. FProgressBar.Visible := AVisible;
  929. FAbortButton.Visible := AVisible;
  930. end;
  931. procedure TDownloadWizardPage.Add(const Url, BaseName, RequiredSHA256OfFile: String);
  932. begin
  933. AddEx(Url, BaseName, RequiredSHA256OfFile, '', '');
  934. end;
  935. procedure TDownloadWizardPage.AddEx(const Url, BaseName, RequiredSHA256OfFile, UserName, Password: String);
  936. begin
  937. var F := TDownloadFile.Create;
  938. F.Url := Url;
  939. F.BaseName := BaseName;
  940. F.RequiredSHA256OfFile := RequiredSHA256OfFile;
  941. F.UserName := UserName;
  942. F.Password := Password;
  943. FFiles.Add(F);
  944. end;
  945. procedure TDownloadWizardPage.Clear;
  946. begin
  947. FFiles.Clear;
  948. end;
  949. function TDownloadWizardPage.Download: Int64;
  950. begin
  951. FAbortedByUser := False;
  952. Result := 0;
  953. for var F in FFiles do begin
  954. { Don't need to set DownloadTemporaryFileOrExtract7ZipArchiveProcessMessages before downloading since we already process messages ourselves. }
  955. SetDownloadCredentials(F.UserName, F.Password);
  956. Result := Result + DownloadTemporaryFile(F.Url, F.BaseName, F.RequiredSHA256OfFile, InternalOnDownloadProgress);
  957. end;
  958. SetDownloadCredentials('', '');
  959. end;
  960. {--- Extraction ---}
  961. procedure TExtractionWizardPage.AbortButtonClick(Sender: TObject);
  962. begin
  963. FAbortedByUser := LoggedMsgBox(SetupMessages[msgStopExtraction], '', mbConfirmation, MB_YESNO, True, ID_YES) = IDYES;
  964. end;
  965. function TExtractionWizardPage.InternalOnExtractionProgress(const ArchiveName, FileName: string; const Progress, ProgressMax: Int64): Boolean;
  966. var
  967. Progress32, ProgressMax32: LongInt;
  968. begin
  969. if FAbortedByUser then begin
  970. Log('Need to abort extraction.');
  971. Result := False;
  972. end else begin
  973. { Unlike TDownloadWizardPage we don't log progress here. This is because 7zMain.c already logs output dirs and names. }
  974. FMsg2Label.Caption := IfThen(FShowArchiveInsteadOfFile, ArchiveName, FileName);
  975. if ProgressMax > MaxLongInt then begin
  976. Progress32 := Round((Progress / ProgressMax) * MaxLongInt);
  977. ProgressMax32 := MaxLongInt;
  978. end else begin
  979. Progress32 := Progress;
  980. ProgressMax32 := ProgressMax;
  981. end;
  982. SetProgress(Progress32, ProgressMax32); { This will process messages which we need for the abort button to work }
  983. if FShowProgressControlsOnNextProgress then begin
  984. ShowProgressControls(True);
  985. FShowProgressControlsOnNextProgress := False;
  986. ProcessMsgs;
  987. end;
  988. if Assigned(FOnExtractionProgress) then
  989. Result := FOnExtractionProgress(ArchiveName, FileName, Progress, ProgressMax)
  990. else
  991. Result := True;
  992. end;
  993. end;
  994. constructor TExtractionWizardPage.Create(AOwner: TComponent);
  995. begin
  996. inherited;
  997. FUseMarqueeStyle := True;
  998. FArchives := TArchives.Create;
  999. end;
  1000. destructor TExtractionWizardPage.Destroy;
  1001. begin
  1002. FArchives.Free;
  1003. inherited;
  1004. end;
  1005. procedure TExtractionWizardPage.Initialize;
  1006. begin
  1007. inherited;
  1008. FMsg1Label.Caption := SetupMessages[msgExtractionLabel];
  1009. FAbortButton := TNewButton.Create(Self);
  1010. with FAbortButton do begin
  1011. Caption := SetupMessages[msgButtonStopExtraction];
  1012. Top := FProgressBar.Top + FProgressBar.Height + WizardForm.ScalePixelsY(8);
  1013. Width := WizardForm.CalculateButtonWidth([Caption]);
  1014. Anchors := [akLeft, akTop];
  1015. Height := WizardForm.CancelButton.Height;
  1016. OnClick := AbortButtonClick;
  1017. end;
  1018. SetCtlParent(FAbortButton, Surface);
  1019. end;
  1020. procedure TExtractionWizardPage.Show;
  1021. begin
  1022. if WizardForm.CurPageID <> ID then begin
  1023. ShowProgressControls(False);
  1024. FShowProgressControlsOnNextProgress := True;
  1025. end;
  1026. inherited;
  1027. end;
  1028. procedure TExtractionWizardPage.ShowProgressControls(const AVisible: Boolean);
  1029. begin
  1030. FMsg2Label.Visible := AVisible;
  1031. FProgressBar.Visible := AVisible;
  1032. FAbortButton.Visible := AVisible;
  1033. end;
  1034. procedure TExtractionWizardPage.Add(const ArchiveFileName, DestDir: String; const FullPaths: Boolean);
  1035. begin
  1036. var A := TArchive.Create;
  1037. A.FileName := ArchiveFileName;
  1038. A.DestDir := DestDir;
  1039. A.FullPaths := FullPaths;
  1040. FArchives.Add(A);
  1041. end;
  1042. procedure TExtractionWizardPage.Clear;
  1043. begin
  1044. FArchives.Clear;
  1045. end;
  1046. procedure TExtractionWizardPage.Extract;
  1047. begin
  1048. FAbortedByUser := False;
  1049. for var A in FArchives do begin
  1050. { Don't need to set DownloadTemporaryFileOrExtract7ZipArchiveProcessMessages before extraction since we already process messages ourselves. }
  1051. Extract7ZipArchive(A.FileName, A.DestDir, A.FullPaths, InternalOnExtractionProgress);
  1052. end;
  1053. end;
  1054. end.