IDE.Wizard.WizardForm.pas 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212
  1. unit IDE.Wizard.WizardForm;
  2. {
  3. Inno Setup
  4. Copyright (C) 1997-2025 Jordan Russell
  5. Portions by Martijn Laan
  6. For conditions of distribution and use, see LICENSE.TXT.
  7. Compiler IDE Script Wizard form
  8. }
  9. interface
  10. uses
  11. Windows, Forms, Classes, Graphics, StdCtrls, ExtCtrls, Controls, Dialogs, pngimage,
  12. UIStateForm, NewStaticText, DropListBox, NewCheckListBox, NewNotebook,
  13. IDE.Wizard.WizardFormFilesHelper, IDE.Wizard.WizardFormRegistryHelper, BitmapButton,
  14. Vcl.BaseImageCollection, Vcl.ImageCollection, BitmapImage;
  15. type
  16. TWizardPage = (wpWelcome, wpAppInfo, wpAppDir, wpAppFiles, wpAppAssoc, wpAppIcons,
  17. wpAppDocs, wpPrivilegesRequired, wpAppRegistry, wpLanguages, wpCompiler,
  18. wpWizardStyle, wpISPP, wpFinished);
  19. TWizardFormResult = (wrNone, wrEmpty, wrComplete);
  20. TWizardForm = class(TUIStateForm)
  21. CancelButton: TButton;
  22. NextButton: TButton;
  23. BackButton: TButton;
  24. OuterNotebook: TNewNotebook;
  25. InnerNotebook: TNewNotebook;
  26. WelcomePage: TNewNotebookPage;
  27. MainPage: TNewNotebookPage;
  28. AppInfoPage: TNewNotebookPage;
  29. AppDirPage: TNewNotebookPage;
  30. AppFilesPage: TNewNotebookPage;
  31. AppIconsPage: TNewNotebookPage;
  32. AppDocsPage: TNewNotebookPage;
  33. PrivilegesRequiredPage: TNewNotebookPage;
  34. AppRegistryPage: TNewNotebookPage;
  35. LanguagesPage: TNewNotebookPage;
  36. CompilerPage: TNewNotebookPage;
  37. ISPPPage: TNewNotebookPage;
  38. FinishedPage: TNewNotebookPage;
  39. Bevel: TBevel;
  40. WelcomeImage: TBitmapImage;
  41. WelcomeLabel1: TNewStaticText;
  42. PnlMain: TPanel;
  43. Bevel1: TBevel;
  44. PageNameLabel: TNewStaticText;
  45. PageDescriptionLabel: TNewStaticText;
  46. InnerImage: TBitmapImage;
  47. FinishedLabel: TNewStaticText;
  48. FinishedImage: TBitmapImage;
  49. WelcomeLabel2: TNewStaticText;
  50. EmptyCheck: TCheckBox;
  51. WelcomeLabel3: TNewStaticText;
  52. AppNameLabel: TNewStaticText;
  53. AppNameEdit: TEdit;
  54. AppVersionLabel: TNewStaticText;
  55. AppVersionEdit: TEdit;
  56. AppDirNameLabel: TNewStaticText;
  57. AppRootDirComboBox: TComboBox;
  58. AppRootDirEdit: TEdit;
  59. AppDirNameEdit: TEdit;
  60. NotDisableDirPageCheck: TCheckBox;
  61. AppRootDirLabel: TNewStaticText;
  62. AppPublisherLabel: TNewStaticText;
  63. AppPublisherEdit: TEdit;
  64. OtherLabel: TNewStaticText;
  65. NotCreateAppDirCheck: TCheckBox;
  66. AppFilesLabel: TNewStaticText;
  67. AppFilesListBox: TDropListBox;
  68. AppFilesAddButton: TButton;
  69. AppFilesEditButton: TButton;
  70. AppFilesRemoveButton: TButton;
  71. AppURLLabel: TNewStaticText;
  72. AppURLEdit: TEdit;
  73. AppExeLabel: TNewStaticText;
  74. AppExeEdit: TEdit;
  75. AppExeRunCheck: TCheckBox;
  76. AppExeButton: TButton;
  77. AppGroupNameLabel: TNewStaticText;
  78. AppGroupNameEdit: TEdit;
  79. NotDisableProgramGroupPageCheck: TCheckBox;
  80. AllowNoIconsCheck: TCheckBox;
  81. AppExeIconsLabel: TNewStaticText;
  82. DesktopIconCheck: TCheckBox;
  83. CreateUninstallIconCheck: TCheckBox;
  84. CreateURLIconCheck: TCheckBox;
  85. AppLicenseFileLabel: TNewStaticText;
  86. AppLicenseFileEdit: TEdit;
  87. AppLicenseFileButton: TButton;
  88. AppInfoBeforeFileLabel: TNewStaticText;
  89. AppInfoBeforeFileEdit: TEdit;
  90. AppInfoBeforeFileButton: TButton;
  91. AppInfoAfterFileLabel: TNewStaticText;
  92. AppInfoAfterFileEdit: TEdit;
  93. AppInfoAfterFileButton: TButton;
  94. RequiredLabel1: TNewStaticText;
  95. RequiredLabel2: TNewStaticText;
  96. AppFilesAddDirButton: TButton;
  97. ISPPCheck: TCheckBox;
  98. ISPPLabel: TLabel;
  99. OutputDirLabel: TNewStaticText;
  100. OutputDirEdit: TEdit;
  101. OutputBaseFileNameLabel: TNewStaticText;
  102. OutputBaseFileNameEdit: TEdit;
  103. SetupIconFileLabel: TNewStaticText;
  104. SetupIconFileEdit: TEdit;
  105. PasswordLabel: TNewStaticText;
  106. PasswordEdit: TEdit;
  107. SetupIconFileButton: TButton;
  108. EncryptionCheck: TCheckBox;
  109. OutputDirButton: TButton;
  110. LanguagesLabel: TNewStaticText;
  111. LanguagesList: TNewCheckListBox;
  112. AllLanguagesButton: TButton;
  113. NoLanguagesButton: TButton;
  114. NoAppExeCheck: TCheckBox;
  115. UseAutoProgramsCheck: TCheckBox;
  116. PrivilegesRequiredLabel: TNewStaticText;
  117. PrivilegesRequiredAdminRadioButton: TRadioButton;
  118. PrivilegesRequiredLowestRadioButton: TRadioButton;
  119. PrivilegesRequiredOverridesAllowedCommandLineCheckbox: TCheckBox;
  120. PrivilegesRequiredOverridesAllowedDialogCheckbox: TCheckBox;
  121. AppAssocPage: TNewNotebookPage;
  122. AppAssocNameEdit: TEdit;
  123. AppAssocNameLabel: TNewStaticText;
  124. CreateAssocCheck: TCheckBox;
  125. AppAssocExtLabel: TNewStaticText;
  126. AppAssocExtEdit: TEdit;
  127. AppRegistryFileLabel: TNewStaticText;
  128. AppRegistryFileEdit: TEdit;
  129. AppRegistryFileButton: TButton;
  130. AppRegistrySettingsLabel: TNewStaticText;
  131. AppRegistryUninsDeleteKeyCheck: TCheckBox;
  132. AppRegistryUninsDeleteKeyIfEmptyCheck: TCheckBox;
  133. AppRegistryUninsDeleteValueCheck: TCheckBox;
  134. AppRegistryMinVerCheck: TCheckBox;
  135. AppRegistryMinVerEdit: TEdit;
  136. AppRegistryMinVerDocBitBtn: TBitmapButton;
  137. WelcomeImageDark: TBitmapImage;
  138. InnerImageDark: TBitmapImage;
  139. AppFilesAddDownloadButton: TButton;
  140. WizardStylePage: TNewNotebookPage;
  141. WizardStyleLabel: TNewStaticText;
  142. WizardStyleMainComboBox: TComboBox;
  143. WizardStyleDarkComboBox: TComboBox;
  144. WizardStyleSubStyleComboBox: TComboBox;
  145. WizardStyleImageCollection: TImageCollection;
  146. WizardStyleImage: TBitmapButton;
  147. WizardStyleImage2: TBitmapImage;
  148. WizardStyleImageTimer: TTimer;
  149. procedure FormCreate(Sender: TObject);
  150. procedure FormShow(Sender: TObject);
  151. procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  152. procedure FormDestroy(Sender: TObject);
  153. procedure NextButtonClick(Sender: TObject);
  154. procedure BackButtonClick(Sender: TObject);
  155. procedure FileButtonClick(Sender: TObject);
  156. procedure AppRootDirComboBoxChange(Sender: TObject);
  157. procedure NotCreateAppDirCheckClick(Sender: TObject);
  158. procedure AppExeButtonClick(Sender: TObject);
  159. procedure NotDisableProgramGroupPageCheckClick(Sender: TObject);
  160. procedure PasswordEditChange(Sender: TObject);
  161. procedure OutputDirButtonClick(Sender: TObject);
  162. procedure AllLanguagesButtonClick(Sender: TObject);
  163. procedure NoLanguagesButtonClick(Sender: TObject);
  164. procedure NoAppExeCheckClick(Sender: TObject);
  165. procedure UseAutoProgramsCheckClick(Sender: TObject);
  166. procedure PrivilegesRequiredOverridesAllowedDialogCheckboxClick(Sender: TObject);
  167. procedure CreateAssocCheckClick(Sender: TObject);
  168. procedure WizardStyleComboBoxChange(Sender: TObject);
  169. procedure WizardStyleImageTimerTimer(Sender: TObject);
  170. procedure WizardStyleImageClick(Sender: TObject);
  171. private
  172. FCurPage: TWizardPage;
  173. FWizardName: String;
  174. FFilesHelper: TWizardFormFilesHelper;
  175. FRegistryHelper: TWizardFormRegistryHelper;
  176. FLanguages: TStringList;
  177. FResult: TWizardFormResult;
  178. FResultScript: String;
  179. function FixLabel(const S: String): String;
  180. procedure SetWizardName(const WizardName: String);
  181. procedure CurPageChanged;
  182. function SkipCurPage: Boolean;
  183. procedure UpdateAppExeControls;
  184. procedure UpdateAppAssocControls;
  185. procedure UpdateAppIconsControls;
  186. procedure UpdateWizardStyleImages;
  187. procedure WizardStyleImagePreviewKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  188. procedure WizardStyleImagePreviewImageClick(Sender: TObject);
  189. function GetWizardStyle: String;
  190. procedure GenerateScript;
  191. public
  192. property WizardName: String write SetWizardName;
  193. property Result: TWizardFormResult read FResult;
  194. property ResultScript: String read FResultScript;
  195. end;
  196. implementation
  197. {$R *.DFM}
  198. uses
  199. SysUtils, ShlObj, ActiveX, UITypes,
  200. PathFunc, BrowseFunc,
  201. Shared.CommonFunc.Vcl, Shared.CommonFunc, Shared.FileClass, Shared.LicenseFunc,
  202. IDE.HelperFunc, IDE.Messages, IDE.Wizard.WizardFileForm;
  203. type
  204. TConstant = record
  205. Constant, Description: String;
  206. end;
  207. const
  208. NotebookPages: array[TWizardPage, 0..1] of Integer =
  209. ((0, -1), (1, 0), (1, 1), (1, 2),
  210. (1, 3), (1, 4), (1, 5), (1, 6),
  211. (1, 7), (1, 8), (1, 9), (1, 10), (1, 11), (2, -1));
  212. PageCaptions: array[TWizardPage] of String =
  213. (SWizardWelcome, SWizardAppInfo, SWizardAppDir, SWizardAppFiles, SWizardAppAssoc,
  214. SWizardAppIcons, SWizardAppDocs, SWizardPrivilegesRequired, SWizardAppRegistry,
  215. SWizardLanguages, SWizardCompiler, SWizardWizardStyle, SWizardISPP, SWizardFinished);
  216. PageDescriptions: array[TWizardPage] of String =
  217. ('', SWizardAppInfo2, SWizardAppDir2, SWizardAppFiles2, SWizardAppAssoc2,
  218. SWizardAppIcons2, SWizardAppDocs2, SWizardPrivilegesRequired2, SWizardAppRegistry2,
  219. SWizardLanguages2, SWizardCompiler2, SWizardWizardStyle2, SWizardISPP2, '');
  220. RequiredLabelVisibles: array[TWizardPage] of Boolean =
  221. (False, True, True, True, True, True, False, True, False, True, False, False, False, False);
  222. AppRootDirs: array[0..0] of TConstant =
  223. (
  224. ( Constant: '{autopf}'; Description: 'Program Files folder')
  225. );
  226. LanguagesDefaultIsl = 'Default.isl';
  227. LanguagesDefaultIslDescription = 'English';
  228. EnabledColors: array[Boolean] of TColor = (clBtnFace, clWindow);
  229. function EscapeAmpersands(const S: String): String;
  230. begin
  231. Result := S;
  232. StringChangeEx(Result, '&', '&&', True);
  233. end;
  234. function TWizardForm.FixLabel(const S: String): String;
  235. begin
  236. Result := S;
  237. {don't localize these}
  238. StringChange(Result, '[name]', FWizardName);
  239. end;
  240. procedure TWizardForm.SetWizardName(const WizardName: String);
  241. begin
  242. FWizardName := WizardName;
  243. end;
  244. { --- }
  245. procedure TWizardForm.FormCreate(Sender: TObject);
  246. procedure AddLanguages(const Extension: String);
  247. var
  248. SearchRec: TSearchRec;
  249. begin
  250. if FindFirst(PathExtractPath(NewParamStr(0)) + 'Languages\*.' + Extension, faAnyFile, SearchRec) = 0 then begin
  251. repeat
  252. FLanguages.Add(SearchRec.Name);
  253. until FindNext(SearchRec) <> 0;
  254. FindClose(SearchRec);
  255. end;
  256. end;
  257. procedure MakeBold(const Ctl: TNewStaticText);
  258. begin
  259. Ctl.Font.Style := [fsBold];
  260. end;
  261. function SpaceLanguageName(const LanguageName: String): String;
  262. var
  263. I: Integer;
  264. begin
  265. Result := '';
  266. for I := 1 to Length(LanguageName) do begin
  267. if (I <> 1) and CharInSet(LanguageName[I], ['A'..'Z']) then
  268. Result := Result + ' ';
  269. Result := Result + LanguageName[I];
  270. end;
  271. end;
  272. var
  273. I: Integer;
  274. begin
  275. FResult := wrNone;
  276. FWizardName := SWizardDefaultName;
  277. FFilesHelper := TWizardFormFilesHelper.Create(Self,
  278. NotCreateAppDirCheck, AppFilesListBox, AppFilesAddButton, AppFilesAddDirButton,
  279. AppFilesAddDownloadButton, AppFilesEditButton, AppFilesRemoveButton);
  280. FRegistryHelper := TWizardFormRegistryHelper.Create(Self, AppRegistryFileEdit,
  281. AppRegistryFileButton, AppRegistryUninsDeleteKeyCheck,
  282. AppRegistryUninsDeleteKeyIfEmptyCheck, AppRegistryUninsDeleteValueCheck,
  283. AppRegistryMinVerCheck, AppRegistryMinVerEdit, AppRegistryMinVerDocBitBtn);
  284. FLanguages := TStringList.Create;
  285. FLanguages.Sorted := True;
  286. AddLanguages('isl');
  287. FLanguages.Sorted := False;
  288. FLanguages.Insert(0, LanguagesDefaultIsl);
  289. InitFormFont(Self);
  290. if not InitFormTheme(Self) then
  291. OuterNotebook.Color := InitFormThemeGetBkColor(True);
  292. if FontExists('Segoe UI') then begin
  293. WelcomeLabel1.Font.Name := 'Segoe UI';
  294. WelcomeLabel1.Font.Size := 14;
  295. end;
  296. MakeBold(PageNameLabel);
  297. MakeBold(RequiredLabel1);
  298. MakeBold(AppNameLabel);
  299. MakeBold(AppVersionLabel);
  300. MakeBold(AppRootDirLabel);
  301. MakeBold(AppDirNameLabel);
  302. MakeBold(AppExeLabel);
  303. MakeBold(AppAssocNameLabel);
  304. MakeBold(AppAssocExtLabel);
  305. MakeBold(AppGroupNameLabel);
  306. MakeBold(PrivilegesRequiredLabel);
  307. MakeBold(LanguagesLabel);
  308. if InitFormThemeIsDark then begin
  309. WelcomeImage.Bitmap := WelcomeImageDark.Bitmap;
  310. InnerImage.Bitmap := InnerImageDark.Bitmap;
  311. end;
  312. FinishedImage.Bitmap := WelcomeImage.Bitmap;
  313. RequiredLabel2.Left := RequiredLabel1.Left + RequiredLabel1.Width;
  314. { See Setup.WizardForm }
  315. if IsCustomStyleActive then
  316. BackButton.Left := BackButton.Left - 2;
  317. { AppInfo }
  318. AppNameEdit.Text := 'My Program';
  319. AppVersionEdit.Text := '1.5';
  320. AppPublisherEdit.Text := 'My Company, Inc.';
  321. AppURLEdit.Text := 'https://www.example.com/';
  322. { AppDir }
  323. for I := Low(AppRootDirs) to High(AppRootDirs) do
  324. AppRootDirComboBox.Items.Add(AppRootDirs[I].Description);
  325. AppRootDirComboBox.Items.Add('(Custom)');
  326. AppRootDirComboBox.ItemIndex := 0;
  327. AppRootDirEdit.Enabled := False;
  328. AppRootDirEdit.Color := clBtnFace;
  329. NotDisableDirPageCheck.Checked := True;
  330. { AppFiles }
  331. AppExeEdit.Text := PathExtractPath(NewParamStr(0)) + 'Examples\MyProg-x64.exe';
  332. AppExeRunCheck.Checked := True;
  333. { AppAssoc }
  334. CreateAssocCheck.Checked := True;
  335. AppAssocExtEdit.Text := '.myp';
  336. { AppIcons }
  337. UseAutoProgramsCheck.Checked := True;
  338. NotDisableProgramGroupPageCheck.Checked := True;
  339. DesktopIconCheck.Checked := True;
  340. { PrivilegesRequired }
  341. PrivilegesRequiredAdminRadioButton.Checked := True;
  342. { Languages }
  343. for I := 0 to FLanguages.Count-1 do begin
  344. if FLanguages[I] <> LanguagesDefaultIsl then
  345. LanguagesList.AddCheckBox(SpaceLanguageName(PathChangeExt(FLanguages[I], '')), '', 0, False, True, False, True, TObject(I))
  346. else
  347. LanguagesList.AddCheckBox(LanguagesDefaultIslDescription, '', 0, True, True, False, True, TObject(I));
  348. end;
  349. { Compiler }
  350. OutputBaseFileNameEdit.Text := 'mysetup';
  351. EncryptionCheck.Checked := True;
  352. EncryptionCheck.Enabled := False;
  353. { ISPP }
  354. ISPPLabel.Caption := FixLabel(SWizardISPPLabel);
  355. ISPPCheck.Caption := SWizardISPPCheck;
  356. ISPPCheck.Checked := ISPPInstalled;
  357. FCurPage := Low(TWizardPage);
  358. CurPageChanged;
  359. end;
  360. procedure TWizardForm.FormShow(Sender: TObject);
  361. begin
  362. Caption := FWizardName;
  363. WelcomeLabel1.Caption := FixLabel(WelcomeLabel1.Caption);
  364. FinishedLabel.Caption := FixLabel(FinishedLabel.Caption);
  365. end;
  366. procedure TWizardForm.FormCloseQuery(Sender: TObject;
  367. var CanClose: Boolean);
  368. begin
  369. if ModalResult = mrCancel then
  370. CanClose := MsgBox(FixLabel(SWizardCancelMessage), FWizardName, mbConfirmation, MB_YESNO) = idYes;
  371. end;
  372. procedure TWizardForm.FormDestroy(Sender: TObject);
  373. begin
  374. FLanguages.Free;
  375. FRegistryHelper.Free;
  376. FFilesHelper.Free;
  377. end;
  378. { --- }
  379. procedure TWizardForm.CurPageChanged;
  380. { Call this whenever the current page is changed }
  381. begin
  382. OuterNotebook.ActivePage := OuterNotebook.Pages[NotebookPages[FCurPage, 0]];
  383. if NotebookPages[FCurPage, 1] <> -1 then
  384. InnerNotebook.ActivePage := InnerNotebook.Pages[NotebookPages[FCurPage, 1]];
  385. { Set button visibility and captions }
  386. BackButton.Visible := not (FCurPage = wpWelcome);
  387. if FCurPage = wpFinished then
  388. NextButton.Caption := SWizardFinishButton
  389. else
  390. NextButton.Caption := SWizardNextButton;
  391. RequiredLabel1.Visible := RequiredLabelVisibles[FCurPage];
  392. RequiredLabel2.Visible := RequiredLabel1.Visible;
  393. { Set the Caption to match the current page's title }
  394. PageNameLabel.Caption := PageCaptions[FCurPage];
  395. PageDescriptionLabel.Caption := PageDescriptions[FCurPage];
  396. { Adjust focus }
  397. case FCurPage of
  398. wpAppInfo: ActiveControl := AppNameEdit;
  399. wpAppDir:
  400. begin
  401. if AppRootDirComboBox.Enabled then
  402. ActiveControl := AppRootDirComboBox
  403. else
  404. ActiveControl := NotCreateAppDirCheck;
  405. end;
  406. wpAppFiles:
  407. begin
  408. if AppExeEdit.Enabled then
  409. ActiveControl := AppExeEdit
  410. else
  411. ActiveControl := AppFilesListBox;
  412. end;
  413. wpAppAssoc: ActiveControl := CreateAssocCheck;
  414. wpAppIcons:
  415. begin
  416. if UseAutoProgramsCheck.Enabled then
  417. ActiveControl := UseAutoProgramsCheck
  418. else
  419. ActiveControl := AppGroupNameEdit;
  420. end;
  421. wpAppDocs: ActiveControl := AppLicenseFileEdit;
  422. wpPrivilegesRequired:
  423. begin
  424. if PrivilegesRequiredAdminRadioButton.Checked then
  425. ActiveControl := PrivilegesRequiredAdminRadioButton
  426. else
  427. ActiveControl := PrivilegesRequiredLowestRadioButton;
  428. end;
  429. wpAppRegistry: ActiveControl := AppRegistryFileEdit;
  430. wpLanguages: ActiveControl := LanguagesList;
  431. wpCompiler: ActiveControl := OutputDirEdit;
  432. wpWizardStyle:
  433. begin
  434. ActiveControl := WizardStyleMainComboBox;
  435. UpdateWizardStyleImages;
  436. end;
  437. wpISPP: ActiveControl := ISPPCheck;
  438. end;
  439. end;
  440. function TWizardForm.SkipCurPage: Boolean;
  441. begin
  442. if ((FCurPage = wpAppAssoc) and not CreateAssocCheck.Enabled) or
  443. ((FCurPage = wpAppIcons) and NotCreateAppDirCheck.Checked) or
  444. ((FCurPage = wpLanguages) and not (FLanguages.Count > 1)) or
  445. ((FCurPage = wpISPP) and not ISPPInstalled) or
  446. (not (FCurPage in [wpWelcome, wpFinished]) and EmptyCheck.Checked) then
  447. Result := True
  448. else
  449. Result := False;
  450. end;
  451. procedure TWizardForm.NextButtonClick(Sender: TObject);
  452. function CheckAppInfoPage: Boolean;
  453. begin
  454. Result := False;
  455. if AppNameEdit.Text = '' then begin
  456. MsgBox(SWizardAppNameError, '', mbError, MB_OK);
  457. ActiveControl := AppNameEdit;
  458. end else if AppVersionEdit.Text = '' then begin
  459. MsgBox(SWizardAppVersionError, '', mbError, MB_OK);
  460. ActiveControl := AppVersionEdit;
  461. end else
  462. Result := True;
  463. end;
  464. function CheckAppDirPage: Boolean;
  465. begin
  466. Result := False;
  467. if not NotCreateAppDirCheck.Checked and
  468. (AppRootDirComboBox.ItemIndex = AppRootDirComboBox.Items.Count-1) and
  469. (AppRootDirEdit.Text = '') then begin
  470. MsgBox(SWizardAppRootDirError, '', mbError, MB_OK);
  471. ActiveControl := AppRootDirEdit;
  472. end else if not NotCreateAppDirCheck.Checked and (AppDirNameEdit.Text = '') then begin
  473. MsgBox(SWizardAppDirNameError, '', mbError, MB_OK);
  474. ActiveControl := AppDirNameEdit;
  475. end else
  476. Result := True;
  477. end;
  478. function CheckAppFilesPage: Boolean;
  479. begin
  480. Result := False;
  481. if AppExeEdit.Enabled and (AppExeEdit.Text = '') then begin
  482. MsgBox(SWizardAppExeError, '', mbError, MB_OK);
  483. ActiveControl := AppExeEdit;
  484. end else
  485. Result := True;
  486. end;
  487. function CheckAppIconsPage: Boolean;
  488. begin
  489. Result := False;
  490. if AppGroupNameEdit.Text = '' then begin
  491. MsgBox(SWizardAppGroupNameError, '', mbError, MB_OK);
  492. ActiveControl := AppGroupNameEdit;
  493. end else
  494. Result := True;
  495. end;
  496. function CheckLanguagesPage: Boolean;
  497. var
  498. I: Integer;
  499. begin
  500. Result := False;
  501. for I := 0 to LanguagesList.Items.Count-1 do begin
  502. if LanguagesList.Checked[I] then begin
  503. Result := True;
  504. Exit;
  505. end;
  506. end;
  507. MsgBox(SWizardLanguagesSelError, '', mbError, MB_OK);
  508. ActiveControl := LanguagesList;
  509. end;
  510. begin
  511. case FCurPage of
  512. wpAppInfo: if not CheckAppInfoPage then Exit;
  513. wpAppDir: if not CheckAppDirPage then Exit;
  514. wpAppFiles: if not CheckAppFilesPage then Exit;
  515. wpAppIcons: if not CheckAppIconsPage then Exit;
  516. wpLanguages: if not CheckLanguagesPage then Exit;
  517. end;
  518. repeat
  519. if FCurPage = wpAppAssoc then begin
  520. if (AppAssocExtEdit.Text <> '') and (AppAssocExtEdit.Text[1] <> '.') then
  521. AppAssocExtEdit.Text := '.' + AppAssocExtEdit.Text;
  522. end else if FCurPage = wpPrivilegesRequired then begin
  523. if not PrivilegesRequiredOverridesAllowedCommandLineCheckbox.Checked then begin
  524. if PrivilegesRequiredAdminRadioButton.Checked then
  525. FRegistryHelper.PrivilegesRequired := prAdmin
  526. else
  527. FRegistryHelper.PrivilegesRequired := prLowest
  528. end else
  529. FRegistryHelper.PrivilegesRequired := prDynamic;
  530. end else if FCurPage = wpFinished then begin
  531. GenerateScript;
  532. ModalResult := mrOk;
  533. Exit;
  534. end;
  535. Inc(FCurPage);
  536. { Even if we're skipping a page, we should still update it }
  537. case FCurPage of
  538. wpAppDir: if AppDirNameEdit.Text = '' then AppDirNameEdit.Text := AppNameEdit.Text;
  539. wpAppAssoc: if AppAssocNameEdit.Text = '' then AppAssocNameEdit.Text := AppNameEdit.Text + ' File';
  540. wpAppIcons: if AppGroupNameEdit.Text = '' then AppGroupNameEdit.Text := AppNameEdit.Text;
  541. end;
  542. until not SkipCurPage;
  543. CurPageChanged;
  544. end;
  545. procedure TWizardForm.BackButtonClick(Sender: TObject);
  546. begin
  547. if FCurPage = Low(TWizardPage) then Exit;
  548. { Go to the previous page }
  549. Dec(FCurPage);
  550. while SkipCurPage do
  551. Dec(FCurPage);
  552. CurPageChanged;
  553. end;
  554. {---}
  555. procedure TWizardForm.UpdateAppExeControls;
  556. var
  557. Enabled: Boolean;
  558. begin
  559. Enabled := not NotCreateAppDirCheck.Checked;
  560. NoAppExeCheck.Enabled := Enabled;
  561. Enabled := Enabled and not NoAppExeCheck.Checked;
  562. AppExeLabel.Enabled := Enabled;
  563. AppExeEdit.Enabled := Enabled;
  564. AppExeEdit.Color := EnabledColors[Enabled];
  565. AppExeButton.Enabled := Enabled;
  566. AppExeRunCheck.Enabled := Enabled;
  567. AppExeIconsLabel.Enabled := Enabled;
  568. DesktopIconCheck.Enabled := Enabled;
  569. if Enabled then
  570. AppExeLabel.Font.Style := AppExeLabel.Font.Style + [fsBold]
  571. else
  572. AppExeLabel.Font.Style := AppExeLabel.Font.Style - [fsBold];
  573. end;
  574. procedure TWizardForm.UpdateAppAssocControls;
  575. var
  576. Enabled: Boolean;
  577. begin
  578. Enabled := not NoAppExeCheck.Checked;
  579. CreateAssocCheck.Enabled := Enabled;
  580. Enabled := Enabled and CreateAssocCheck.Checked;
  581. AppAssocNameLabel.Enabled := Enabled;
  582. AppAssocNameEdit.Enabled := Enabled;
  583. AppAssocExtLabel.Enabled := Enabled;
  584. AppAssocExtEdit.Enabled := Enabled;
  585. if Enabled then begin
  586. AppAssocNameLabel.Font.Style := AppAssocNameLabel.Font.Style + [fsBold];
  587. AppAssocExtLabel.Font.Style := AppAssocExtLabel.Font.Style + [fsBold];
  588. end else begin
  589. AppAssocNameLabel.Font.Style := AppAssocNameLabel.Font.Style - [fsBold];
  590. AppAssocExtLabel.Font.Style := AppAssocExtLabel.Font.Style - [fsBold];
  591. end;
  592. end;
  593. procedure TWizardForm.UpdateAppIconsControls;
  594. var
  595. Enabled: Boolean;
  596. begin
  597. UseAutoProgramsCheck.Enabled := NoAppExeCheck.Enabled and not NoAppExeCheck.Checked;
  598. Enabled := not (UseAutoProgramsCheck.Enabled and UseAutoProgramsCheck.Checked);
  599. AppGroupNameLabel.Enabled := Enabled;
  600. AppGroupNameEdit.Enabled := Enabled;
  601. AppGroupNameEdit.Color := EnabledColors[Enabled];
  602. NotDisableProgramGroupPageCheck.Enabled := Enabled;
  603. AllowNoIconsCheck.Enabled := Enabled and NotDisableProgramGroupPageCheck.Checked;
  604. CreateURLIconCheck.Enabled := Enabled and (AppURLEdit.Text <> '');
  605. CreateUninstallIconCheck.Enabled := Enabled;
  606. if Enabled then
  607. AppGroupNameLabel.Font.Style := AppGroupNameLabel.Font.Style + [fsBold]
  608. else
  609. AppGroupNameLabel.Font.Style := AppGroupNameLabel.Font.Style - [fsBold];
  610. end;
  611. procedure TWizardForm.UpdateWizardStyleImages;
  612. procedure UpdateWizardStyleImage(const WizardStylePngImage: TPngImage; ImageName: String);
  613. begin
  614. ImageName := ImageName.Replace('dark windows11', 'dark');
  615. const ImageIndex = WizardStyleImageCollection.GetIndexByName(ImageName);
  616. if ImageIndex = -1 then
  617. raise Exception.CreateFmt('Image name ''%s'' not found', [ImageName]);
  618. WizardStylePngImage.Assign(WizardStyleImageCollection.GetSourceImage(ImageIndex, 0, 0));
  619. end;
  620. begin
  621. var WizardStyle := GetWizardStyle;
  622. const Dynamic = WizardStyle.Contains('dynamic');
  623. if Dynamic then begin
  624. WizardStyle := WizardStyle.Replace('dynamic', 'dark');
  625. UpdateWizardStyleImage(WizardStyleImage2.PngImage, WizardStyle); { This image is always invisible }
  626. WizardStyle := WizardStyle.Replace(' dark', '');
  627. end;
  628. UpdateWizardStyleImage(WizardStyleImage.PngImage, WizardStyle);
  629. { To keep things simple this timer is always running but here we do reset it so the new images
  630. will never be swapped too quickly }
  631. WizardStyleImageTimer.Enabled := False;
  632. WizardStyleImageTimer.Enabled := True;
  633. end;
  634. {---}
  635. procedure TWizardForm.AppRootDirComboBoxChange(Sender: TObject);
  636. begin
  637. if AppRootDirComboBox.ItemIndex = AppRootDirComboBox.Items.Count-1 then begin
  638. AppRootDirEdit.Enabled := True;
  639. AppRootDirEdit.Color := clWindow;
  640. ActiveControl := AppRootDirEdit;
  641. end else begin
  642. AppRootDirEdit.Enabled := False;
  643. AppRootDirEdit.Color := clBtnFace;
  644. end;
  645. end;
  646. procedure TWizardForm.NotCreateAppDirCheckClick(Sender: TObject);
  647. var
  648. Enabled: Boolean;
  649. begin
  650. Enabled := not NotCreateAppDirCheck.Checked;
  651. { AppDir }
  652. AppRootDirLabel.Enabled := Enabled;
  653. AppRootDirComboBox.Enabled := Enabled;
  654. AppRootDirComboBox.Color := EnabledColors[Enabled];
  655. AppRootDirEdit.Enabled := Enabled and (AppRootDirComboBox.ItemIndex = AppRootDirComboBox.Items.Count-1);
  656. AppRootDirEdit.Color := EnabledColors[AppRootDirEdit.Enabled];
  657. AppDirNameLabel.Enabled := Enabled;
  658. AppDirNameEdit.Enabled := Enabled;
  659. AppDirNameEdit.Color := EnabledColors[Enabled];
  660. NotDisableDirPageCheck.Enabled := Enabled;
  661. if Enabled then begin
  662. AppRootDirLabel.Font.Style := AppRootDirLabel.Font.Style + [fsBold];
  663. AppDirNameLabel.Font.Style := AppRootDirLabel.Font.Style + [fsBold];
  664. end else begin
  665. AppRootDirLabel.Font.Style := AppRootDirLabel.Font.Style - [fsBold];
  666. AppDirNameLabel.Font.Style := AppRootDirLabel.Font.Style - [fsBold];
  667. end;
  668. { AppFiles }
  669. UpdateAppExeControls;
  670. end;
  671. procedure TWizardForm.AppExeButtonClick(Sender: TObject);
  672. var
  673. FileName: String;
  674. begin
  675. FileName := AppExeEdit.Text;
  676. if NewGetOpenFileName('', FileName, PathExtractPath(FileName), SWizardAppExeFilter, SWizardAppExeDefaultExt, Handle) then
  677. AppExeEdit.Text := FileName;
  678. end;
  679. procedure TWizardForm.NoAppExeCheckClick(Sender: TObject);
  680. begin
  681. UpdateAppExeControls;
  682. UpdateAppAssocControls;
  683. UpdateAppIconsControls;
  684. end;
  685. procedure TWizardForm.CreateAssocCheckClick(Sender: TObject);
  686. begin
  687. UpdateAppAssocControls;
  688. end;
  689. procedure TWizardForm.UseAutoProgramsCheckClick(Sender: TObject);
  690. begin
  691. UpdateAppIconsControls;
  692. end;
  693. procedure TWizardForm.NotDisableProgramGroupPageCheckClick(
  694. Sender: TObject);
  695. begin
  696. UpdateAppIconsControls;
  697. end;
  698. procedure TWizardForm.FileButtonClick(Sender: TObject);
  699. var
  700. Edit: TEdit;
  701. Filter, DefaultExt, FileName: String;
  702. begin
  703. if Sender = AppLicenseFileButton then
  704. Edit := AppLicenseFileEdit
  705. else if Sender = AppInfoBeforeFileButton then
  706. Edit := AppInfoBeforeFileEdit
  707. else if Sender = AppInfoAfterFileButton then
  708. Edit := AppInfoAfterFileEdit
  709. else
  710. Edit := SetupIconFileEdit;
  711. if Sender <> SetupIconFileButton then begin
  712. Filter := SWizardAppDocsFilter;
  713. DefaultExt := SWizardAppDocsDefaultExt;
  714. end else begin
  715. Filter := SWizardCompilerSetupIconFileFilter;
  716. DefaultExt := SWizardCompilerSetupIconFileDefaultExt;
  717. end;
  718. FileName := Edit.Text;
  719. if NewGetOpenFileName('', FileName, PathExtractPath(FileName), Filter, DefaultExt, Handle) then
  720. Edit.Text := FileName;
  721. end;
  722. procedure TWizardForm.OutputDirButtonClick(Sender: TObject);
  723. var
  724. Path: String;
  725. begin
  726. Path := OutputDirEdit.Text;
  727. if PathDrivePartLength(Path) = 0 then
  728. Path := ''; { don't pass in a relative path to BrowseForFolder }
  729. if BrowseForFolder(SWizardCompilerOutputDir, Path, Handle, True) then
  730. OutputDirEdit.Text := Path;
  731. end;
  732. procedure TWizardForm.PasswordEditChange(Sender: TObject);
  733. begin
  734. EncryptionCheck.Enabled := PasswordEdit.Text <> '';
  735. end;
  736. procedure TWizardForm.AllLanguagesButtonClick(Sender: TObject);
  737. var
  738. I: Integer;
  739. begin
  740. for I := 0 to LanguagesList.Items.Count-1 do
  741. LanguagesList.Checked[I] := True;
  742. end;
  743. procedure TWizardForm.NoLanguagesButtonClick(Sender: TObject);
  744. var
  745. I: Integer;
  746. begin
  747. for I := 0 to LanguagesList.Items.Count-1 do
  748. LanguagesList.Checked[I] := False;
  749. end;
  750. procedure TWizardForm.PrivilegesRequiredOverridesAllowedDialogCheckboxClick(
  751. Sender: TObject);
  752. begin
  753. PrivilegesRequiredOverridesAllowedCommandLineCheckbox.Enabled := not PrivilegesRequiredOverridesAllowedDialogCheckbox.Checked;
  754. if PrivilegesRequiredOverridesAllowedDialogCheckbox.Checked then
  755. PrivilegesRequiredOverridesAllowedCommandLineCheckbox.Checked := True;
  756. end;
  757. procedure TWizardForm.WizardStyleComboBoxChange(Sender: TObject);
  758. begin
  759. if (WizardStyleDarkComboBox.Text <> 'light') and ((WizardStyleSubStyleComboBox.Text = 'slate') or (WizardStyleSubStyleComboBox.Text = 'zircon')) then
  760. WizardStyleDarkComboBox.ItemIndex := WizardStyleDarkComboBox.Items.IndexOf('light');
  761. UpdateWizardStyleImages;
  762. end;
  763. procedure TWizardForm.WizardStyleImagePreviewKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  764. begin
  765. if Key = VK_ESCAPE then
  766. (Sender as TForm).ModalResult := mrCancel;
  767. end;
  768. procedure TWizardForm.WizardStyleImagePreviewImageClick(Sender: TObject);
  769. begin
  770. const F = GetParentForm(Sender as TControl);
  771. if F <> nil then
  772. F.ModalResult := mrOk;
  773. end;
  774. procedure TWizardForm.WizardStyleImageClick(Sender: TObject);
  775. begin
  776. const PreviewForm = TForm.CreateNew(nil);
  777. try
  778. PreviewForm.AutoSize := True;
  779. PreviewForm.BorderStyle := bsNone;
  780. PreviewForm.BorderIcons := [];
  781. PreviewForm.Color := clWindow;
  782. PreviewForm.KeyPreview := True;
  783. PreviewForm.OnKeyDown := WizardStyleImagePreviewKeyDown;
  784. PreviewForm.Position := poDesigned;
  785. const R = BoundsRect;
  786. PreviewForm.Left := R.Left + MulDiv(32, CurrentPPI, 96);
  787. PreviewForm.Top := R.Top + MulDiv(32, CurrentPPI, 96);
  788. const PreviewImage = TBitmapImage.Create(PreviewForm);
  789. PreviewImage.AutoSize := True;
  790. PreviewImage.BackColor := clNone;
  791. PreviewImage.Bitmap.Assign(WizardStyleImage.Bitmap);
  792. PreviewImage.Cursor := crHandPoint;
  793. PreviewImage.OnClick := WizardStyleImagePreviewImageClick;
  794. PreviewImage.Parent := PreviewForm;
  795. PreviewForm.ShowModal;
  796. finally
  797. PreviewForm.Free;
  798. end;
  799. end;
  800. procedure TWizardForm.WizardStyleImageTimerTimer(Sender: TObject);
  801. begin
  802. if (FCurPage = wpWizardStyle) and (WizardStyleDarkComboBox.Text = 'dynamic') then begin
  803. const SaveBitmap = TBitmap.Create;
  804. try
  805. SaveBitmap.Assign(WizardStyleImage.Bitmap);
  806. WizardStyleImage.Bitmap.Assign(WizardStyleImage2.Bitmap);
  807. WizardStyleImage2.Bitmap.Assign(SaveBitmap);
  808. finally
  809. SaveBitmap.Free;
  810. end;
  811. end;
  812. end;
  813. { --- }
  814. function TWizardForm.GetWizardStyle: String;
  815. begin
  816. Result := WizardStyleMainComboBox.Text;
  817. if WizardStyleDarkComboBox.ItemIndex <> 0 then
  818. Result := Result + ' ' + WizardStyleDarkComboBox.Text;
  819. if WizardStyleSubStyleComboBox.ItemIndex <> 0 then
  820. Result := Result + ' ' + WizardStyleSubStyleComboBox.Text;
  821. end;
  822. procedure TWizardForm.GenerateScript;
  823. var
  824. Script, ISPP, Setup, Languages, Tasks, Files, Registry, INI, Icons, Run, UninstallDelete: String;
  825. I: Integer;
  826. AppExeName, AppName, AppAmpEscapedName, AppAssocKey, LanguageName, LanguageMessagesFile: String;
  827. begin
  828. Script := '';
  829. AppExeName := PathExtractName(AppExeEdit.Text);
  830. AppName := AppNameEdit.Text;
  831. AppAmpEscapedName := EscapeAmpersands(AppName);
  832. if ISPPCheck.Checked then begin
  833. { Setup ISPP usage. Change the edits to reflect ISPP usage. A bit ugly but for now it works. }
  834. ISPP := '#define MyAppName "' + AppNameEdit.Text + '"' + SNewLine +
  835. '#define MyAppVersion "' + AppVersionEdit.Text + '"' + SNewLine;
  836. if AppDirNameEdit.Text = AppNameEdit.Text then
  837. AppDirNameEdit.Text := '{#MyAppName}';
  838. if AppGroupNameEdit.Text = AppNameEdit.Text then
  839. AppGroupNameEdit.Text := '{#MyAppName}';
  840. AppNameEdit.Text := '{#MyAppName}';
  841. AppAmpEscapedName := '{#StringChange(MyAppName, ''&'', ''&&'')}';
  842. AppVersionEdit.Text := '{#MyAppVersion}';
  843. if AppPublisherEdit.Text <> '' then begin
  844. ISPP := ISPP + '#define MyAppPublisher "' + AppPublisherEdit.Text + '"' + SNewLine;
  845. AppPublisherEdit.Text := '{#MyAppPublisher}';
  846. end;
  847. if AppURLEdit.Text <> '' then begin
  848. ISPP := ISPP + '#define MyAppURL "' + AppURLEdit.Text + '"' + SNewLine;
  849. AppURLEdit.Text := '{#MyAppURL}';
  850. end;
  851. { Special ones }
  852. if not NoAppExeCheck.Checked then begin
  853. ISPP := ISPP + '#define MyAppExeName "' + AppExeName + '"' + SNewLine;
  854. AppExeName := '{#MyAppExeName}';
  855. end;
  856. if CreateAssocCheck.Enabled and CreateAssocCheck.Checked then begin
  857. if Pos(AppName, AppAssocNameEdit.Text) = 1 then
  858. ISPP := ISPP + '#define MyAppAssocName MyAppName + "' + Copy(AppAssocNameEdit.Text, Length(AppName)+1, MaxInt) + '"' + SNewLine
  859. else
  860. ISPP := ISPP + '#define MyAppAssocName "' + AppAssocNameEdit.Text + '"' + SNewLine;
  861. AppAssocNameEdit.Text := '{#MyAppAssocName}';
  862. ISPP := ISPP + '#define MyAppAssocExt "' + AppAssocExtEdit.Text + '"' + SNewLine;
  863. AppAssocExtEdit.Text := '{#MyAppAssocExt}';
  864. ISPP := ISPP + '#define MyAppAssocKey StringChange(MyAppAssocName, " ", "") + MyAppAssocExt' + SNewLine;
  865. AppAssocKey := '{#MyAppAssocKey}';
  866. end;
  867. end else begin
  868. ISPP := '';
  869. AppAssocKey := StringReplace(AppAssocNameEdit.Text, ' ', '', [rfReplaceAll]) + AppAssocExtEdit.Text;
  870. end;
  871. Setup := '[Setup]' + SNewLine;
  872. Languages := '[Languages]' + SNewLine;
  873. Tasks := '[Tasks]' + SNewLine;
  874. Files := '[Files]' + SNewLine;
  875. Registry := '[Registry]' + SNewLine;
  876. INI := '[INI]' + SNewLine;
  877. Icons := '[Icons]' + SNewLine;
  878. Run := '[Run]' + SNewLine;
  879. UninstallDelete := '[UninstallDelete]' + SNewLine;
  880. if not EmptyCheck.Checked then begin
  881. Setup := Setup + (
  882. '; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.' + SNewLine +
  883. '; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)' + SNewLine);
  884. Setup := Setup + 'AppId={' + GenerateGuid + SNewLine;
  885. { AppInfo }
  886. Setup := Setup + 'AppName=' + AppNameEdit.Text + SNewLine;
  887. Setup := Setup + 'AppVersion=' + AppVersionEdit.Text + SNewLine;
  888. Setup := Setup + ';AppVerName=' + AppNameEdit.Text + ' ' + AppVersionEdit.Text + SNewLine;
  889. if AppPublisherEdit.Text <> '' then
  890. Setup := Setup + 'AppPublisher=' + AppPublisherEdit.Text + SNewLine;
  891. if AppURLEdit.Text <> '' then begin
  892. Setup := Setup + 'AppPublisherURL=' + AppURLEdit.Text + SNewLine;
  893. Setup := Setup + 'AppSupportURL=' + AppURLEdit.Text + SNewLine;
  894. Setup := Setup + 'AppUpdatesURL=' + AppURLEdit.Text + SNewLine;
  895. end;
  896. { AppDir }
  897. if not NotCreateAppDirCheck.Checked then begin
  898. if AppRootDirComboBox.ItemIndex = AppRootDirComboBox.Items.Count-1 then
  899. Setup := Setup + 'DefaultDirName=' + AddBackslash(AppRootDirEdit.Text) + AppDirNameEdit.Text + SNewLine
  900. else
  901. Setup := Setup + 'DefaultDirName=' + AddBackslash(AppRootDirs[AppRootDirComboBox.ItemIndex].Constant) + AppDirNameEdit.Text + SNewLine;
  902. if not NotDisableDirPageCheck.Checked then
  903. Setup := Setup + 'DisableDirPage=yes' + SNewLine;
  904. end else begin
  905. Setup := Setup + 'CreateAppDir=no' + SNewLine;
  906. end;
  907. { AppFiles }
  908. if not NotCreateAppDirCheck.Checked and not NoAppExeCheck.Checked then begin
  909. Files := Files + 'Source: "' + PathExtractPath(AppExeEdit.Text) + AppExeName + '"; DestDir: "{app}"; Flags: ignoreversion' + SNewLine;
  910. var AppExeIsReallyExe := SameText(PathExtractExt(AppExeEdit.Text), '.exe');
  911. if AppExeRunCheck.Checked then begin
  912. if AppExeIsReallyExe then
  913. Run := Run + 'Filename: "{app}\' + AppExeName + '"; Description: "{cm:LaunchProgram,' + AppAmpEscapedName + '}"; Flags: nowait postinstall skipifsilent' + SNewLine
  914. else
  915. Run := Run + 'Filename: "{app}\' + AppExeName + '"; Description: "{cm:LaunchProgram,' + AppAmpEscapedName + '}"; Flags: shellexec postinstall skipifsilent' + SNewLine;
  916. end;
  917. if AppExeIsReallyExe then
  918. Setup := Setup + 'UninstallDisplayIcon={app}\' + AppExeName + SNewLine;
  919. if Is64BitPEImage(AppExeEdit.Text) then begin
  920. Setup := Setup + '; "ArchitecturesAllowed=x64compatible" specifies that Setup cannot run' + SNewLine;
  921. Setup := Setup + '; on anything but x64 and Windows 11 on Arm.' + SNewLine;
  922. Setup := Setup + 'ArchitecturesAllowed=x64compatible' + SNewLine;
  923. Setup := Setup + '; "ArchitecturesInstallIn64BitMode=x64compatible" requests that the' + SNewLine;
  924. Setup := Setup + '; install be done in "64-bit mode" on x64 or Windows 11 on Arm,' + SNewLine;
  925. Setup := Setup + '; meaning it should use the native 64-bit Program Files directory and' + SNewLine;
  926. Setup := Setup + '; the 64-bit view of the registry.' + SNewLine;
  927. Setup := Setup + 'ArchitecturesInstallIn64BitMode=x64compatible' + SNewLine;
  928. end;
  929. end;
  930. var HasExtractArchive: Boolean;
  931. FFilesHelper.AddScript(Files, HasExtractArchive);
  932. if HasExtractArchive then begin
  933. Setup := Setup + 'ArchiveExtraction=full' + SNewLine;
  934. Setup := Setup + '; Use "ArchiveExtraction=enhanced" if all your archives are .7z files' + SNewLine;
  935. Setup := Setup + '; Use "ArchiveExtraction=enhanced/nopassword" if all your archives are not password-protected' + SNewLine;
  936. end;
  937. { AppAssocation }
  938. if CreateAssocCheck.Enabled and CreateAssocCheck.Checked then begin
  939. Setup := Setup + 'ChangesAssociations=yes' + SNewLine;
  940. Registry := Registry + 'Root: HKA; Subkey: "Software\Classes\' + AppAssocExtEdit.Text + '\OpenWithProgids"; ValueType: string; ValueName: "' + AppAssocKey + '"; ValueData: ""; Flags: uninsdeletevalue' + SNewLine;
  941. Registry := Registry + 'Root: HKA; Subkey: "Software\Classes\' + AppAssocKey + '"; ValueType: string; ValueName: ""; ValueData: "' + AppAssocNameEdit.Text + '"; Flags: uninsdeletekey' + SNewLine;
  942. Registry := Registry + 'Root: HKA; Subkey: "Software\Classes\' + AppAssocKey + '\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\' + AppExeName + ',0"' + SNewLine;
  943. Registry := Registry + 'Root: HKA; Subkey: "Software\Classes\' + AppAssocKey + '\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\' + AppExeName + '"" ""%1"""' + SNewLine;
  944. end;
  945. { AppGroup }
  946. if not NotCreateAppDirCheck.Checked then begin
  947. if UseAutoProgramsCheck.Enabled and UseAutoProgramsCheck.Checked then begin
  948. Setup := Setup + 'DisableProgramGroupPage=yes' + SNewLine;
  949. Icons := Icons + 'Name: "{autoprograms}\' + AppNameEdit.Text + '"; Filename: "{app}\' + AppExeName + '"' + SNewLine;
  950. end else begin
  951. Setup := Setup + 'DefaultGroupName=' + AppGroupNameEdit.Text + SNewLine;
  952. if not NoAppExeCheck.Checked then
  953. Icons := Icons + 'Name: "{group}\' + AppNameEdit.Text + '"; Filename: "{app}\' + AppExeName + '"' + SNewLine;
  954. if not NotDisableProgramGroupPageCheck.Checked then
  955. Setup := Setup + 'DisableProgramGroupPage=yes' + SNewLine;
  956. if AllowNoIconsCheck.Checked and NotDisableProgramGroupPageCheck.Checked then
  957. Setup := Setup + 'AllowNoIcons=yes' + SNewLine;
  958. if CreateURLIconCheck.Enabled and CreateURLIconCheck.Checked then
  959. Icons := Icons + 'Name: "{group}\{cm:ProgramOnTheWeb,' + AppNameEdit.Text + '}"; Filename: "' + AppURLEdit.Text + '"' + SNewLine;
  960. if CreateUninstallIconCheck.Checked then
  961. Icons := Icons + 'Name: "{group}\{cm:UninstallProgram,' + AppNameEdit.Text + '}"; Filename: "{uninstallexe}"' + SNewLine;
  962. end;
  963. if DesktopIconCheck.Enabled and DesktopIconCheck.Checked then begin
  964. Tasks := Tasks + 'Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked' + SNewLine;
  965. Icons := Icons + 'Name: "{autodesktop}\' + AppNameEdit.Text + '"; Filename: "{app}\' + AppExeName + '"; Tasks: desktopicon' + SNewLine;
  966. end;
  967. end;
  968. { AppDocs }
  969. if AppLicenseFileEdit.Text <> '' then
  970. Setup := Setup + 'LicenseFile=' + AppLicenseFileEdit.Text + SNewLine;
  971. if AppInfoBeforeFileEdit.Text <> '' then
  972. Setup := Setup + 'InfoBeforeFile=' + AppInfoBeforeFileEdit.Text + SNewLine;
  973. if AppInfoAfterFileEdit.Text <> '' then
  974. Setup := Setup + 'InfoAfterFile=' + AppInfoAfterFileEdit.Text + SNewLine;
  975. { PrivilegesRequired }
  976. if PrivilegesRequiredAdminRadioButton.Checked then
  977. Setup := Setup + '; Uncomment the following line to run in non administrative install mode (install for current user only).' + SNewLine + ';'
  978. else
  979. Setup := Setup + '; Remove the following line to run in administrative install mode (install for all users).' + SNewLine;
  980. Setup := Setup + 'PrivilegesRequired=lowest' + SNewLine; { Note how previous made sure this is outputted as comment if needed. }
  981. if PrivilegesRequiredOverridesAllowedDialogCheckbox.Checked then
  982. Setup := Setup + 'PrivilegesRequiredOverridesAllowed=dialog' + SNewLine
  983. else if PrivilegesRequiredOverridesAllowedCommandLineCheckbox.Checked then
  984. Setup := Setup + 'PrivilegesRequiredOverridesAllowed=commandline' + SNewLine;
  985. { AppRegistry }
  986. FRegistryHelper.AddScript(Registry, False);
  987. { Languages }
  988. if FLanguages.Count > 1 then begin
  989. var UsingISPPEmitLanguagesSection: Boolean;
  990. if ISPPCheck.Checked then begin
  991. UsingISPPEmitLanguagesSection := True;
  992. for I := 0 to LanguagesList.Items.Count-1 do begin
  993. if not LanguagesList.Checked[I] then begin
  994. UsingISPPEmitLanguagesSection := False;
  995. Break;
  996. end;
  997. end;
  998. end else
  999. UsingISPPEmitLanguagesSection := False;
  1000. if UsingISPPEmitLanguagesSection then
  1001. ISPP := ISPP + '#expr EmitLanguagesSection' + SNewLine
  1002. else begin
  1003. for I := 0 to LanguagesList.Items.Count-1 do begin
  1004. if LanguagesList.Checked[I] then begin
  1005. LanguageMessagesFile := FLanguages[Integer(LanguagesList.ItemObject[I])];
  1006. if LanguageMessagesFile <> LanguagesDefaultIsl then begin
  1007. LanguageName := LanguagesList.Items[I];
  1008. LanguageMessagesFile := 'Languages\' + LanguageMessagesFile;
  1009. end else
  1010. LanguageName := LanguagesDefaultIslDescription;
  1011. StringChange(LanguageName, ' ', '');
  1012. LanguageName := LowerCase(LanguageName);
  1013. Languages := Languages + 'Name: "' + LanguageName + '"; MessagesFile: "compiler:' + LanguageMessagesFile + '"' + SNewLine;
  1014. end;
  1015. end;
  1016. end;
  1017. end;
  1018. { Compiler }
  1019. if OutputDirEdit.Text <> '' then
  1020. Setup := Setup + 'OutputDir=' + OutputDirEdit.Text + SNewLine;
  1021. if OutputBaseFileNameEdit.Text <> '' then
  1022. Setup := Setup + 'OutputBaseFilename=' + OutputBaseFileNameEdit.Text + SNewLine;
  1023. if SetupIconFileEdit.Text <> '' then
  1024. Setup := Setup + 'SetupIconFile=' + SetupIconFileEdit.Text + SNewLine;
  1025. if PasswordEdit.Text <> '' then begin
  1026. Setup := Setup + 'Password=' + PasswordEdit.Text + SNewLine;
  1027. if EncryptionCheck.Checked then
  1028. Setup := Setup + 'Encryption=yes' + SNewLine;
  1029. end;
  1030. { Other }
  1031. Setup := Setup + 'SolidCompression=yes' + SNewLine;
  1032. Setup := Setup + 'WizardStyle=' + GetWizardStyle + SNewLine;
  1033. { Build script }
  1034. if ISPP <> '' then
  1035. Script := Script + ISPP + SNewLine;
  1036. Script := Script + Setup + SNewLine;
  1037. if Length(Languages) > Length('[Languages]')+2 then
  1038. Script := Script + Languages + SNewLine;
  1039. if Length(Tasks) > Length('[Tasks]')+2 then
  1040. Script := Script + Tasks + SNewLine;
  1041. if Length(Files) > Length('[Files]')+2 then
  1042. Script := Script + Files +
  1043. '; NOTE: Don''t use "Flags: ignoreversion" on any shared system files' +
  1044. SNewLine2;
  1045. if Length(Registry) > Length('[Registry]')+2 then
  1046. Script := Script + Registry + SNewLine;
  1047. if Length(INI) > Length('[INI]')+2 then
  1048. Script := Script + INI + SNewLine;
  1049. if Length(Icons) > Length('[Icons]')+2 then
  1050. Script := Script + Icons + SNewLine;
  1051. if Length(Run) > Length('[Run]')+2 then
  1052. Script := Script + Run + SNewLine;
  1053. if Length(UninstallDelete) > Length('[UninstallDelete]')+2 then
  1054. Script := Script + UninstallDelete + SNewLine;
  1055. FResult := wrComplete;
  1056. end else begin
  1057. Script := Script + Setup;
  1058. FResult := wrEmpty;
  1059. end;
  1060. FResultScript := FixLabel(SWizardScriptHeader) + SNewLine;
  1061. if (FResult = wrComplete) and not IsLicensed then
  1062. FResultScript := FResultScript + '; ' + GetLicenseeDescription + SNewLine;
  1063. FResultScript := FResultScript + SNewLine + Script;
  1064. end;
  1065. { --- }
  1066. end.