Inno-Setup-issrc/Projects/Src/Setup.SelectFolderForm.pas
2024-12-11 03:22:41 -06:00

169 lines
5.5 KiB
ObjectPascal

unit Setup.SelectFolderForm;
{
Inno Setup
Copyright (C) 1997-2024 Jordan Russell
Portions by Martijn Laan
For conditions of distribution and use, see LICENSE.TXT.
"Select Folder" form
}
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Setup.SetupForm, StdCtrls, FolderTreeView, NewStaticText, BidiCtrls;
type
TSelectFolderForm = class(TSetupForm)
BrowseLabel: TNewStaticText;
PathEdit: TEdit;
NewFolderButton: TNewButton;
OKButton: TNewButton;
CancelButton: TNewButton;
procedure PathEditChange(Sender: TObject);
procedure NewFolderButtonClick(Sender: TObject);
private
{ Private declarations }
FFolderTreeView: TCustomFolderTreeView;
FNewFolderName: String;
FStartMenu, FAppendDir: Boolean;
procedure FolderTreeViewChange(Sender: TObject);
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
constructor Create2(AOwner: TComponent; AStartMenu: Boolean);
end;
function ShowSelectFolderDialog(const StartMenu, AppendDir: Boolean;
var Path: String; const NewFolderName: String): Boolean;
implementation
uses
PathFunc, SetupLdrAndSetup.Messages, Shared.SetupMessageIDs, Setup.MainFunc,
Shared.SetupTypes, Setup.WizardForm, Shared.CommonFunc;
{$R *.DFM}
function ShowSelectFolderDialog(const StartMenu, AppendDir: Boolean;
var Path: String; const NewFolderName: String): Boolean;
var
Form: TSelectFolderForm;
begin
Form := TSelectFolderForm.Create2(nil, StartMenu);
try
Form.FAppendDir := AppendDir;
Form.FNewFolderName := NewFolderName;
Form.NewFolderButton.Visible := not AppendDir and (NewFolderName <> '');
if StartMenu then begin
with Form.FFolderTreeView as TStartMenuFolderTreeView do
SetPaths(GetShellFolder(False, sfPrograms),
GetShellFolder(True, sfPrograms),
GetShellFolder(False, sfStartup),
GetShellFolder(True, sfStartup));
TidyUpGroupName(Path);
end
else
TidyUpDirName(Path);
if AppendDir then begin
if PathExtractDir(Path) <> Path then
Form.FFolderTreeView.ChangeDirectory(PathExtractDir(Path), True);
end
else
Form.FFolderTreeView.ChangeDirectory(Path, True);
if StartMenu or (Form.FFolderTreeView.Directory <> '') then
Form.ActiveControl := Form.FFolderTreeView;
Form.PathEdit.Text := Path;
Result := (Form.ShowModal = mrOK);
if Result then
Path := Trim(Form.PathEdit.Text);
finally
Form.Free;
end;
end;
{ TSelectFolderForm }
constructor TSelectFolderForm.Create(AOwner: TComponent);
var
YDiff, W: Integer;
begin
inherited;
if not FStartMenu then begin
FFolderTreeView := TFolderTreeView.Create(Self);
TFolderTreeView(FFolderTreeView).OnChange := FolderTreeViewChange;
TFolderTreeView(FFolderTreeView).OnRename := WizardForm.DirTreeRename;
end
else begin
FFolderTreeView := TStartMenuFolderTreeView.Create(Self);
TStartMenuFolderTreeView(FFolderTreeView).OnChange := FolderTreeViewChange;
TStartMenuFolderTreeView(FFolderTreeView).OnRename := WizardForm.GroupTreeRename;
end;
FFolderTreeView.SetBounds(16, 64, 317, 229);
FFolderTreeView.Anchors := [akLeft, akTop, akRight, akBottom];
FFolderTreeView.Visible := False;
{ The form needs its handle allocated before the Parent assignment,
otherwise the control's width and height get reduced later. Looks like
a Delphi 11 bug; the problem is seen in IS 6.3 but not 6.2.2. }
HandleNeeded;
FFolderTreeView.Parent := Self;
PathEdit.BringToFront; { for MSAA }
BrowseLabel.BringToFront; { for MSAA }
FFolderTreeView.TabOrder := 2;
FFolderTreeView.Visible := True;
InitializeFont;
Caption := SetupMessages[msgBrowseDialogTitle];
BrowseLabel.Caption := SetupMessages[msgBrowseDialogLabel];
YDiff := WizardForm.AdjustLabelHeight(BrowseLabel);
PathEdit.Top := PathEdit.Top + YDiff;
TryEnableAutoCompleteFileSystem(PathEdit.Handle);
FFolderTreeView.Top := FFolderTreeView.Top + YDiff;
NewFolderButton.Caption := SetupMessages[msgButtonNewFolder];
NewFolderButton.Top := NewFolderButton.Top + YDiff;
NewFolderButton.Width := CalculateButtonWidth([SetupMessages[msgButtonNewFolder]]);
W := CalculateButtonWidth([SetupMessages[msgButtonOK], SetupMessages[msgButtonCancel]]);
CancelButton.Caption := SetupMessages[msgButtonCancel];
CancelButton.SetBounds(CancelButton.Left + CancelButton.Width - W,
CancelButton.Top + YDiff, W, CancelButton.Height);
OKButton.Caption := SetupMessages[msgButtonOK];
OKButton.SetBounds(CancelButton.Left - ScalePixelsX(6) - W,
OKButton.Top + YDiff, W, OKButton.Height);
ClientHeight := ClientHeight + YDiff;
FlipSizeAndCenterIfNeeded(True, WizardForm, False);
end;
constructor TSelectFolderForm.Create2(AOwner: TComponent; AStartMenu: Boolean);
begin
FStartMenu := AStartMenu;
Create(AOwner);
end;
procedure TSelectFolderForm.PathEditChange(Sender: TObject);
begin
OKButton.Enabled := (Trim(PathEdit.Text) <> '');
end;
procedure TSelectFolderForm.FolderTreeViewChange(Sender: TObject);
begin
if FAppendDir then
PathEdit.Text := AddBackslash(FFolderTreeView.Directory) + FNewFolderName
else
PathEdit.Text := FFolderTreeView.Directory;
NewFolderButton.Enabled := FStartMenu or (FFolderTreeView.Directory <> '');
end;
procedure TSelectFolderForm.NewFolderButtonClick(Sender: TObject);
begin
FFolderTreeView.CreateNewDirectory(FNewFolderName);
end;
end.