Search code examples
inno-setuppascalscript

Select image file on custom layout page and and copy the file to installation folder


My goal is for the user to use this installer, insert your name, select your language and set custom parameters. That is done. But what I need is that the user selects an image to put it as avatar in the application, that is why the user to select an image and then copy the file to the application folder.

Something like this:

enter image description here

This is my code, if anyone can help would greatly appreciate it:

[Code]
{ RedesignWizardFormBegin } // Don't remove this line!
// Don't modify this section. It is generated automatically.
procedure RedesignWizardForm;
begin
  with WizardForm.WizardSmallBitmapImage do
  begin
    Left := ScaleX(350);
    Width := ScaleX(150);
    Height := ScaleY(57);
  end;

  with WizardForm.PageDescriptionLabel do
  begin
    Width := ScaleX(309);
  end;

  with WizardForm.PageNameLabel do
  begin
    Width := ScaleX(293);
  end;

{ ReservationBegin }
  // This part is for you. Add your specialized code here.

{ ReservationEnd }
end;
// Don't modify this section. It is generated automatically.
{ RedesignWizardFormEnd } // Don't remove this line!

var
  NameEdit: TNewEdit;
  ParametresEdit: TNewEdit;
  LanguageCombo: TNewComboBox;
  LanguageNames: TStringList;

function ConvertLanguageName(const Value: string): string;
var
  I: Integer;
  WideCharCode: Word;
begin
  Result := '';
  I := 1;
  while I <= Length(Value) do
  begin
    if Value[I] = '<' then
    begin
      WideCharCode := StrToInt('$' + Copy(Value, I + 1, 4));
      I := I + 6;
    end
    else
    begin
      WideCharCode := Ord(Value[I]);
      I := I + 1;
    end;
    SetLength(Result, Length(Result) + 1);
    Result[Length(Result)] := Chr(WideCharCode);
  end;
end;

function GetLanguageName(const Value: string): string;
begin
  Result := LanguageNames[LanguageCombo.ItemIndex];
end;

function GetPlayerName(const Value: string): string;
begin
  Result := NameEdit.Text;
end;

function GetParametres(const Value: string): string;
begin
  Result := ParametresEdit.Text;
end;

procedure InitializeWizard;
var
  PlayerSettingsPage: TWizardPage;
  NameLabel: TLabel;
  LanguageLabel: TLabel;
  ParaLabel: TLabel;
  Info1Label: TLabel;
  Info2Label: TLabel;
  Info3Label: TLabel;
  Info4Label: TLabel;
  Info5Label: TLabel;
  Info6Label: TLabel;

  begin
  RedesignWizardForm;
  PlayerSettingsPage := CreateCustomPage(wpSelectComponents, 'Ingrese Datos', 'Informacón del juego');

  NameLabel := TLabel.Create(WizardForm);
  NameLabel.Parent := PlayerSettingsPage.Surface;
  NameLabel.Left := 0;
  NameLabel.Top := 0;
  NameLabel.Font.Style := [fsBold];
  NameLabel.Caption := 'Nombre';
  NameEdit := TNewEdit.Create(WizardForm);
  NameEdit.Parent := PlayerSettingsPage.Surface;
  NameEdit.Left := 0;
  NameEdit.Top := NameLabel.Top + NameLabel.Height + 4;
  NameEdit.Width := 180;

  ParaLabel := TLabel.Create(WizardForm);
  ParaLabel.Parent := PlayerSettingsPage.Surface;
  ParaLabel.Left := 0;
  ParaLabel.Top := 100;
  ParaLabel.Font.Style := [fsBold];
  ParaLabel.Caption := 'Parametros de Left 4 Dead 2';
  ParametresEdit := TNewEdit.Create(WizardForm);
  ParametresEdit.Parent := PlayerSettingsPage.Surface;
  ParametresEdit.Left := 0;
  ParametresEdit.Top := ParaLabel.Top + ParaLabel.Height + 4;
  ParametresEdit.Width := 180;

  Info1Label := TLabel.Create(WizardForm);
  Info1Label.Parent := PlayerSettingsPage.Surface;
  Info1Label.Left := 190;
  Info1Label.Top := 15;
  Info1Label.Font.Style := [fsBold];
  Info1Label.Caption := 'Introduzca su Nombre que se mostrara';

  Info2Label := TLabel.Create(WizardForm);
  Info2Label.Parent := PlayerSettingsPage.Surface;
  Info2Label.Left := 190;
  Info2Label.Top := 30;
  Info2Label.Font.Style := [fsBold];  
  Info2Label.Caption := 'en el juego';

  Info3Label := TLabel.Create(WizardForm);
  Info3Label.Parent := PlayerSettingsPage.Surface;
  Info3Label.Left := 190;
  Info3Label.Top := 65;
  Info3Label.Font.Style := [fsBold]; 
  Info3Label.Caption := 'Selecciona tu Idioma';


  Info4Label := TLabel.Create(WizardForm);
  Info4Label.Parent := PlayerSettingsPage.Surface;
  Info4Label.Left := 190;
  Info4Label.Top := 120;
  Info4Label.Font.Style := [fsBold];  
  Info4Label.Caption := '-console: Muestra la consola';

  Info5Label := TLabel.Create(WizardForm);
  Info5Label.Parent := PlayerSettingsPage.Surface;
  Info5Label.Left := 190;
  Info5Label.Top := 135;
  Info5Label.Font.Style := [fsBold]; 
  Info5Label.Caption := '-novid: Salta el intro del juego';

  Info6Label := TLabel.Create(WizardForm);
  Info6Label.Parent := PlayerSettingsPage.Surface;
  Info6Label.Left := 190;
  Info6Label.Top := 150;
  Info6Label.Font.Style := [fsBold];  
  Info6Label.Caption := '-sw: Fuerza al juego en modo ventana';

  LanguageNames := TStringList.Create;
  #sub AddLanguageInternalNames
    #define GetLanguageInternalName(str S) \
      Local[0] = Copy(S, Pos("Name:", S) + Len("Name:")), \
      Local[1] = Copy(Local[0], Pos("""", Local[0]) + 1), \
      Copy(Local[1], 1, Pos("""", Local[1]) - 1)
    #emit '  LanguageNames.Add(''' + GetLanguageInternalName(LanguageList[LanguageIndex]) + ''');'
  #endsub
  #for {LanguageIndex = 0; LanguageIndex < LanguageCount; LanguageIndex++} AddLanguageInternalNames

  LanguageLabel := TLabel.Create(WizardForm);
  LanguageLabel.Parent := PlayerSettingsPage.Surface;
  LanguageLabel.Left := 0;
  LanguageLabel.Top := NameEdit.Top + NameEdit.Height + 8;
  LanguageLabel.Font.Style := [fsBold];
  LanguageLabel.Caption := 'Lenguaje';
  LanguageCombo := TNewComboBox.Create(WizardForm);
  LanguageCombo.Parent := PlayerSettingsPage.Surface;
  LanguageCombo.Left := 0;
  LanguageCombo.Top := LanguageLabel.Top + LanguageLabel.Height + 4;
  LanguageCombo.Width := NameEdit.Width;
  LanguageCombo.Style := csDropDownList;
  #sub AddLanguageDisplayNames
    #define GetLanguageDisplayName(str S) \
      ReadIni(S, "LangOptions", "LanguageName")
    #define GetLanguageFile(str S) \
      Local[0] = Copy(S, Pos("MessagesFile:", S) + Len("MessagesFile:")), \
      Local[1] = Copy(Local[0], Pos("""", Local[0]) + 1), \
      StringChange(Copy(Local[1], 1, Pos("""", Local[1]) - 1), "compiler:", CompilerPath)
    #expr LanguageName = GetLanguageDisplayName(GetLanguageFile(LanguageList[LanguageIndex]))
    #emit '  LanguageCombo.Items.Add(ConvertLanguageName(''' + LanguageName + '''));'
  #endsub
  #for {LanguageIndex = 0; LanguageIndex < LanguageCount; LanguageIndex++} AddLanguageDisplayNames
  LanguageCombo.ItemIndex := LanguageNames.IndexOf(ActiveLanguage);
end;

procedure DeinitializeSetup;
begin
  LanguageNames.Free;
end;

My code currently produce this page:

enter image description here


Solution

  • The easiest if to make use of the TInputFileWizardPage created using the CreateInputFilePage function. There's nothing preventing you from adding your custom controls to the "input file" page. You just have to alter the layout of the automatically added "file input" controls.

    You will also need to change type of the PlayerSettingsPage variable and make it global, so that you can access the values entered by the user outside of the InitializeWizard function.

    // global variables
    var
      PlayerSettingsPage: TInputFileWizardPage;
      AvatarIndex: Integer;
    
    procedure InitializeWizard;
    var
      Delta: Integer;
      ... // your other variables but not the PlayerSettingsPage
    begin
      PlayerSettingsPage :=
        CreateInputFilePage(
          wpSelectComponents, 'Ingrese Datos', 'Informacon del juego', '');
    
      // Your existing code
    
      AvatarIndex :=
        PlayerSettingsPage.Add(
          'Avatar:', 'Image files|*.png;*.jpg;*.jpeg;*.gif|All files|*.*', '.jpg');
      Delta :=
        ParametresEdit.Top + ParametresEdit.Height + ScaleY(32) -
        PlayerSettingsPage.PromptLabels[AvatarIndex].Top;
    
      PlayerSettingsPage.PromptLabels[AvatarIndex].Top :=
        PlayerSettingsPage.PromptLabels[AvatarIndex].Top + Delta;
      PlayerSettingsPage.Edits[AvatarIndex].Top :=
        PlayerSettingsPage.Edits[AvatarIndex].Top + Delta;
      PlayerSettingsPage.Buttons[AvatarIndex].Top :=
        PlayerSettingsPage.Buttons[AvatarIndex].Top + Delta;
    end;
    

    enter image description here

    Then install the selected avatar in the CurStepChanged(ssPostInstall):

    procedure CurStepChanged(CurStep: TSetupStep);
    var
      AvatarSource: string;
      AvatarDest: string;
    begin
      if CurStep = ssPostInstall then
      begin
        AvatarSource := PlayerSettingsPage.Edits[AvatarIndex].Text;
        AvatarDest := ExpandConstant('{app}\' + ExtractFileName(AvatarSource));
        Log(Format('Installing avatar from "%s" to "%s"', [AvatarSource, AvatarDest]));
        if FileCopy(AvatarSource, AvatarDest, False) then
        begin
          Log('Avatar installer');
        end
          else
        begin
          Log('Error installing avatar');
        end;
      end;
    end;