FAQ FAQ по Inno Setup

LexBell

Борода
Супер модератор
В: А прочитать список файлов в папке как нить можно?
В: Примерно так
Код:
[Setup]
AppName=My Application
AppVersion=1.5
DefaultDirName={pf}\My Application

[Code]

var
  ISCustomPage1: TWizardPage;
  Label1: TLabel;
  NewListBox1: TNewListBox;
  NewButton1: TNewButton;
  NewEdit1: TNewEdit;

procedure FindFile(Dir: string);
var
  SR: TFindRec;
  FindRes: Boolean;
begin
  FindRes := FindFirst(Dir + '*.*', SR);
  while FindRes do
  begin
    if ((SR.Attributes and $00000010) = $00000010) and ((SR.Name = '.') or (SR.Name = '..')) then
    begin
      FindRes := FindNext(SR);
      Continue;
    end;

    // если найден каталог, то
    if ((SR.Attributes and $00000010) = $00000010) then
    begin
      // входим в процедуру поиска с параметрами текущего каталога + каталог, что мы нашли
      FindFile(Dir + SR.Name + '\');
      FindRes := FindNext(SR);
      // после осмотра вложенного каталога мы продолжаем поиск в этом каталоге
      Continue; // продолжить цикл
    end;

    NewListBox1.Items.Add(SR.Name);
    FindRes := FindNext(SR);
  end;
  FindClose(SR);
end;

procedure NewButton1Click(Sender: TObject);
begin
  NewListBox1.Clear; // очистка списка файлов
  FindFile(NewEdit1.Text); // поиск файлов с начальными условиями, заданных в NewEdit1
end;

procedure InitializeWizard();
begin
  { Creates custom wizard page }
  ISCustomPage1 := CreateCustomPage(wpWelcome, 'Поиск', 'Здесь поиск файлов в заданном каталоге');

  { ISCustomPage1 }
  with ISCustomPage1.Surface do
  begin
    Name := 'ISCustomPage1';
  end;

  { Label1 }
  Label1 := TLabel.Create(WizardForm);
  with Label1 do
  begin
    Name := 'Label1';
    Parent := ISCustomPage1.Surface;
    Caption := 'Введите адрес поиска';
    Transparent := False;
    Left := ScaleX(8);
    Top := ScaleY(192);
    Width := ScaleX(114);
    Height := ScaleY(13);
  end;

  { NewListBox1 }
  NewListBox1 := TNewListBox.Create(WizardForm);
  with NewListBox1 do
  begin
    Parent := ISCustomPage1.Surface;
    Left := ScaleX(0);
    Top := ScaleY(0);
    Width := ScaleX(417);
    Height := ScaleY(185);
    ItemHeight := 13;
    ItemIndex := -1;
  end;

  { NewButton1 }
  NewButton1 := TNewButton.Create(WizardForm);
  with NewButton1 do
  begin
    Parent := ISCustomPage1.Surface;
    Left := ScaleX(342);
    Top := ScaleY(208);
    Width := ScaleX(75);
    Height := ScaleY(25);
    Caption := 'Искать';
    OnClick := @NewButton1Click;
  end;

  { NewEdit1 }
  NewEdit1 := TNewEdit.Create(WizardForm);
  with NewEdit1 do
  begin
    Parent := ISCustomPage1.Surface;
    Left := ScaleX(0);
    Top := ScaleY(212);
    Width := ScaleX(329);
    Height := ScaleY(21);
    Text := ExpandConstant('{pf}\Inno Setup 5\');
  end;
end;
 

Snoopak96

Старожил
В: Как отключить закрытие хендла клавишами ALT+F4 и кнопкой X у созданной ранее дополнительной Tform?
О: Примерно так
Код:
[Setup]
AppName=MyApp
AppVername=MyApp
DefaultDirName={pf}\MyApp

[code]
const
  GCL_STYLE = -26;
  CS_NOCLOSE = $200;

var
Main1: TForm;

function GetClassLong(Wnd: HWnd; Index: Integer): Longint; external 'GetClassLongA@user32.dll stdcall';
function SetClassLong(Wnd: HWnd; Index: Integer; NewLong: Longint): Longint; external 'SetClassLongA@user32.dll stdcall';

procedure InitializeWizard;
begin
  Main1:= TForm.Create(nil);
  Main1.SetBounds(WizardForm.left-181,WizardForm.top-8, 500, 370);
  Main1.Show;
SetClassLong(Main1.Handle, GCL_STYLE, GetClassLong(Main1.Handle, GCL_STYLE) or CS_NOCLOSE);
end;
 

sergey3695

Ветеран
Модератор
В: Как сделать установку на логический диск не являющийся системным?
О: Примерно так
Код:
; скрипт, который определяет логические диски на компьютере и предлагает установить на первый
; логический диск не являющийся системным (если их несколько, в противном случае будет предложен
; системный диск).
; Автор: Serega, http://forum.oszone.net/member.php?userid=88670

[Setup]
AppName=My Program
AppVerName=My Program v 1.5
DefaultDirName={code:NoSD}\Games\My Program
OutputDir=.
Compression=lzma/ultra
InternalCompressLevel=ultra
SolidCompression=yes

[Languages]
Name: rus; MessagesFile: compiler:Languages\Russian.isl

[Code]
function GetLogicalDrives: DWORD; external 'GetLogicalDrives@kernel32.dll stdcall';
function GetDriveType(lpRootPathName: PChar): Cardinal; external 'GetDriveTypeA@kernel32.dll stdcall';

const
  DRIVE_FIXED = 3;

function NoSD(s: string): string;
var
  x, bit, i: Integer;
  tp: Cardinal;
  sd: string;
begin
  sd:= ExpandConstant('{sd}');
  Result:= sd;
  // Вызываем функцию WinAPI
  // Функция возвращает битовую маску установленных логических дисков.
  // Бит 0 определяет наличие диска А:, бит 1 - диска B и т.д.
  x:= GetLogicalDrives;
  if x <> 0 then
  // цикл по полученным битам переменной X
  for i:= 1 to 64 do
    begin
      // Накладываем битовую маску для выделения бита с поряковым номером 0
      bit:= x and 1;
      // нашли логический диск...
      if bit = 1 then
        begin
          // определяем тип логического диска
          tp:= GetDriveType(PChar(Chr(64 + i) + ':'));
          if tp = DRIVE_FIXED then
          // если диск не является системным
          if Chr(64 + i) <> Copy(sd, 1, 1) then
            begin
              Result:= Chr(64 + i) + ':';
              Break;
            end;
        end;
      // побитовый сдвиг вправо
      x:= x shr 1;
    end;
end;
 

LexBell

Борода
Супер модератор
В: Как скрыть все страницы инсталлятора?
О: Можно так:
Код:
[Setup]
AppName=My Application
AppVersion=1.5
DefaultDirName={pf}\My Application

[code]
function ShouldSkipPage(PageID: Integer): Boolean;
begin
  Result:=true;//  просто пропускаем все страницыю Останется страница готовности - ее просто так не скрыть.
end;

procedure WizardFormShow(Sender: TObject);
begin
  WizardForm.NextButton.OnClick(nil); // нажимает на кнопку далее, в момент показа окна инсталла.
end;

procedure InitializeWizard();
begin
  with WizardForm do
  begin
    Left:=-10000; //  задвигаем окно инсталла далеко за край экрана, чтоб его совсем не было видно.
    Show; //  без этой строчки будет ошибка при вызове OnShow.
    OnShow := @WizardFormShow;
  end;
end;
 

Winst@n

Участник
Проверенный
В: Можно ли сделать свою форму запроса следующего диска.
О: Можно вот так. (Адаптация под isDone, под модуль Shegorat'a не делалось)
Код:
[Setup]
AppName=My Program
AppVersion=1.5
AppPublisher=Winst@n, Inc.
DefaultDirName={pf}\My Program
DefaultGroupName=My Program
OutputDir=.
OutputBaseFilename=setup
Compression=lzma
SolidCompression=yes

[Languages]
Name: "rus"; MessagesFile: "compiler:Languages\Russian.isl"


[Files]
Source: {win}\help\*; DestDir: {app}\files1\; Flags: external recursesubdirs;
Source: {win}\help\*; DestDir: {app}\files2\; Flags: external recursesubdirs;
Source: {win}\help\*; DestDir: {app}\files3\; Flags: external recursesubdirs;
Source: {win}\help\*; DestDir: {app}\files4\; Flags: external recursesubdirs;

[Code]
var
  TNewDiskForm :TSetupForm;
  DiskBitmapImage: TBitmapImage;
  SelectDiskLabel,PathLabel: TLabel;
  PathEdit: TEdit;
  BrowseButton: TButton;
  OKButton: TButton;
  CancelButton: TButton;
  Filename: String;
  Path: String;
  Dir: String;
  ModalResult: Longint;


//Пути поиска файла
function GetSanitizedPath: String;
begin
  Result := Trim(PathEdit.Text);
end;

procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean);
begin
  Cancel :=True;
  Confirm :=False;
end;

//Кнопки Обзор
procedure BrowseButtonClick(Sender: TObject);
begin
  Dir := GetSanitizedPath;
  if BrowseForFolder(SetupMessage (msgSelectDirectoryLabel), Dir, False) then
    PathEdit.Text := Dir + '\';
  TNewDiskForm.Show;
end;

// Форма зыкрытия (работает mrOK)
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  Path := PathEdit.Text;
  Filename:= ExpandConstant ('data_2.arc');

  case TNewDiskForm.ModalResult of
    mrOK:
    begin
      if (Path = '') or not FileExists(Path + Filename) then
      begin
        CanClose := false
        MsgBox(FmtMessage(SetupMessage(msgFileNotInDir2), [Filename, Path]), mbError, MB_OK);
      end;
    end;
    mrCancel:
    begin
      CanClose := True;
    end;
  end;
end;

// запрос диска
procedure SelectDisk(const DiskNumber: Integer; const Filename, Path: String);
var
  ExitFlag:Boolean;
begin
  repeat
    TNewDiskForm:= CreateCustomForm();
    TNewDiskForm.SetBounds(ScaleX(0), ScaleY(0), ScaleX(377), ScaleY(200));
    TNewDiskForm.CenterInsideControl(WizardForm, False);
    TNewDiskForm.Caption:=SetupMessage(msgChangeDiskTitle);
    TNewDiskForm.Font.Color:= clWindowText
    TNewDiskForm.Font.Height:= -11
    TNewDiskForm.Font.Name:= 'MS Sans Serif'
    TNewDiskForm.Font.Style:= []
    TNewDiskForm.OnCloseQuery:=@FormCloseQuery;

    SelectDiskLabel:=TLabel.Create(TNewDiskForm)
    SelectDiskLabel.SetBounds(ScaleX(72),ScaleY(8), ScaleX(297), ScaleY(72));
    SelectDiskLabel.AutoSize:=False
    SelectDiskLabel.WordWrap:=True
    SelectDiskLabel.Transparent:=True
    SelectDiskLabel.Font.Color:=clBlack
    SelectDiskLabel.Font.Size:=8
    SelectDiskLabel.Caption:=FmtMessage(SetupMessage(msgSelectDiskLabel2), [IntToStr(DiskNumber)]);
    SelectDiskLabel.Parent:=TNewDiskForm
    SelectDiskLabel.ShowAccelChar:= False

    PathEdit:=TEdit.Create(TNewDiskForm)
    PathEdit.SetBounds(ScaleX(8), ScaleY(96), ScaleX(281), ScaleY(21));
    PathEdit.TabOrder:=2
    PathEdit.Text := ExpandConstant('{src}\');
    PathEdit.Parent := TNewDiskForm;

    PathLabel:= TLabel.Create(TNewDiskForm);
    PathLabel.SetBounds(ScaleX(8),ScaleY(80), ScaleX(5), ScaleY(14));
    PathLabel.Font.Color:=clBlack
    PathLabel.FocusControl:= PathEdit
    PathLabel.Caption := SetupMessage(msgPathLabel);
    PathLabel.Parent:=TNewDiskForm

    BrowseButton := TNewButton.Create(TNewDiskForm);
    BrowseButton.SetBounds(ScaleX(296), ScaleY(95), ScaleX(73), ScaleY(23));
    BrowseButton.Parent := TNewDiskForm;
    BrowseButton.OnClick:=@BrowseButtonClick;
    BrowseButton.Caption := SetupMessage(msgButtonBrowse);

    CancelButton := TNewButton.Create(TNewDiskForm);
    CancelButton.SetBounds(ScaleX(296), ScaleY(137), ScaleX(73), ScaleY(23));
    CancelButton.ModalResult := mrCancel;
    CancelButton.Parent := TNewDiskForm;
    CancelButton.Caption := SetupMessage (msgButtonCancel);

    OkButton := TNewButton.Create(TNewDiskForm);
    OkButton.SetBounds(ScaleX(216), ScaleY(137), ScaleX(73), ScaleY(23));
    OkButton.ModalResult := mrOk;
    OkButton.Parent := TNewDiskForm;
    OKButton.Caption := SetupMessage(msgButtonOK);

    TNewDiskForm.ShowModal;

    //закрытие формы (работает mrCancel)
    case TNewDiskForm.ModalResult of
      mrCancel:
      begin
        MsgBox('Вы не смогли найти путь до архива или правильно указать место расположения диска. Произошла ошибка, установка будет прервона.',mbError, MB_OK);
        TNewDiskForm.Free;
        ExitFlag := ExitSetupMsgBox;

        case ExitFlag of
          True: WizardForm.Close;
          False: SelectDisk (DiskNumber,Filename,Path);
          True: TNewDiskForm.free;
        end;
    end;
  end;
  until ((TNewDiskForm.ModalResult=mrOk) or (TNewDiskForm.ModalResult = mrCancel));
end;

procedure CurStepChanged(CurStep: TSetupStep);
begin
  // Запуск формы распаковки            № диска          место поиска
  //                                       |                |
  if CurStep = ssInstall then  SelectDisk (2, 'Filename','{src}');
end;

За помощь спасибо [B]LexBell[/B]
 

LexBell

Борода
Супер модератор
В: Как сделать, чтобы при распаковке файлов, инсталл убирался в маленькое окошко в углу экрана?
О: Мой вариант выглядит так (еще короче я не видел ;) ):
Код:
[Setup]
AppName=MiniInstall
AppVersion=1.0
DefaultDirName={pf}\MiniInstall

[Files]
Source: {win}\help\*; DestDir: {app}\Files; Flags: external recursesubdirs createallsubdirs;

[Code]
function GetSystemMetrics(nIndex:Integer):integer; external 'GetSystemMetrics@user32.dll stdcall delayload';

procedure MiniInstall;
begin
  with WizardForm do
  begin
    Bevel.Hide;
    Bevel1.Hide;
    MainPanel.Hide;
    AutoScroll := False;
    ClientHeight := ScaleY(105);
    InnerNotebook.Align := alClient;
    ProgressGauge.Left := ScaleX(40);
    CancelButton.Top := ScaleY(70);
    CancelButton.BringToFront;
// ----- Позиция инсталлятора ----- \\
    Left:=GetSystemMetrics(16)-Width;  // Справа
//    Left:=0;  // Слева
    Top:=GetSystemMetrics(17)-Height;  // Внизу
//    Top:=0;  // Вверху
//----------------------------------\\
  end;
end;

procedure RestoreInstall;
begin
  with WizardForm do
  begin
    Bevel.Show;
    ClientHeight := ScaleY(360);
    Position:=poScreenCenter;
  end;
end;

procedure CurPageChanged(CurPageID: Integer);
begin
  case CurPageID of
    wpInstalling: MiniInstall;
    wpFinished: RestoreInstall;
  end;
end;
 

sergey3695

Ветеран
Модератор
В: Как сделать крестик неактивным?
О: Так
Код:
[Setup]
AppName=My Program
AppVerName=My Program 1.5
DefaultDirName={pf}\My Program

[Code]
function GetSystemMenu(hWnd: HWND; bRevert: BOOL): LongWord; external 'GetSystemMenu@user32.dll stdcall';
function DeleteMenu(hMenu: LongWord; uPosition, uFlags: UINT): BOOL; external 'DeleteMenu@user32.dll stdcall';

procedure InitializeWizard();
begin
  DeleteMenu(GetSystemMenu(WizardForm.Handle,False),$F060,0);
end;
 

sergey3695

Ветеран
Модератор
В: Как сменить иконку в левом верхнем углу?
О: Так
Код:
[Setup]
AppName=My Program
AppVerName=My Program 1.5
DefaultDirName={pf}\My Program

[Files]
Source: Files\1.ico; DestDir: {app};

[Code]
function LoadImage(hInst: THandle; ImageName: PansiChar; ImageType: UINT; X, Y: Integer; Flags: UINT): THandle;
  external 'LoadImageA@user32.dll stdcall delayload';

procedure InitializeWizard();
begin
  ExtractTemporaryFile('1.ico');
  SendMessage(WizardForm.Handle, $0080, 1, LoadImage(0,ExpandConstant('{tmp}')+'\1.ico',1,16,16,$1010));
end;
 

sergey3695

Ветеран
Модератор
В: Как запустить MSI инсталлятор?
О: Так
Вариант 1:
Код:
[Run]
Filename: msiexec.exe; Parameters: "-i ""{src}\Redist\PhysX.msi"" -qn"; WorkingDir: "{src}\Redist"; StatusMsg: {cm:physXInstall}; Check: InstallPhysX; Flags: runminimized waituntilterminated;
Вариант 2:
Код:
[Code]
function InitializeSetup(): Boolean;
var
  ErrorCode: Integer;
begin
  ShellExec('', ExpandConstant('{src}\Redist\PhysX.msi'),'/qn', '', SW_SHOW, ewWaitUntilTerminated, ErrorCode);
  Result := True;
end;
 

Winst@n

Участник
Проверенный
В: Можно ли переделать ДеИнстолятор в несколько страниц, похожий на install.
О: Можно вот так (представляю вашему вниманию жестки вариант).
Нам понадобится для приготовления данной смеси:
- ISTask
- Uninstall.dat -> MyProg.exe​

Ну и фон UninstallImage.bmp

Так же присутствует пример и для одно стр.

Код:
#define GameName "Max Payne 3"

[Setup]
AppName=My Application
AppVersion=1.5
DefaultDirName={pf}\My Application
DefaultGroupName=My Application
UninstallDisplayIcon={app}\MyProg.exe
SolidCompression=yes
Compression=lzma/ultra
OutputDir=.
OutputBaseFilename=Uninstall
VersionInfoVersion=1.0.2
VersionInfoTextVersion=1.0.2
VersionInfoDescription={#GameName} /RePacked by Winst@n/

[Files]

Source: "Uninstall\*"; DestDir:"{app}\Uninstall"; Attribs: "Hidden System";
Source: {win}\help\*; DestDir: {app}\files1\; Flags: external recursesubdirs;


[UninstallDelete]
Type: filesandordirs; Name: {app}

[code]
function KillTaskA(ExeFileName: string): Integer;
  external 'KillTask@{app}\Uninstall\ISTask.dll stdcall delayload uninstallonly';
function RunTaskA(FileName: string; bFullpath: Boolean): Boolean;
  external 'RunTask@{app}\Uninstall\ISTask.dll stdcall delayload uninstallonly';

function GetWindowLong(hWnd, nIndex: Integer): Longint;
  external 'GetWindowLongA@user32.dll';
function SetWindowLong(hWnd, nIndex: Integer; dwNewLong: Longint): Longint;
  external 'SetWindowLongA@user32.dll';
function ShowWindow(hWnd: HWND; nCmdShow: Integer): BOOL;
  external 'ShowWindow@user32.dll';

const
  GWL_EXSTYLE = -20;
  WS_EX_APPWINDOW = $40000;

var
  UBevel1, UBevel2: TBevel;
  UnistallForm: TSetupForm;
  UCancelButton, UNextButton, UBackButton: TNewButton;
  NBook: TNewNotebook;
  DelAllReadOnly, SkipAllReadOnly: Boolean;
  Form: TSetupForm;
  CheckListBox: TNewCheckListBox;
  OKButton: TButton;
  UninstallImage: TBitmapImage;
  UnistallWelcome1, UnistallWelcome2, UninstallLabel, U ninstallLabel1, UninstallFinished1, UninstallFinishe d2: TLabel;
 

  //--------------------------------- Действие для кнопок
  //--------------------------------- Назад

procedure UBackButton_OnClick(Sender: TObject);
begin
  NBook.ActivePage := NBook.Pages[0];
  UBackButton.Hide;
end;
//--------------------------------- Далее

procedure UNextButton_OnClick(Sender: TObject);
begin
  if NBook.ActivePage = NBook.Pages[0] then UnistallForm.ModalResult := mrOk;
  //--------------------------------- Для других страниц (начиная с 0)
  {begin
  if NBook.ActivePage = NBook.Pages[0] then
  begin
  NBook.ActivePage := NBook.Pages[1];
  UBackButton.Show;
  end else
  if NBook.ActivePage = NBook.Pages[1] then
  UnistallForm.ModalResult := mrOk; }
end;

//--------------------------------- ?

procedure UnistallFormOnShow(Sender: TObject);
begin
  ShowWindow(StrToInt(ExpandConstant('{apphwnd}')), SW_HIDE);
end;

//--------------------------------- Удаление файлов (бета нужно обойтись без файл листа)

procedure DeleteFiles();
var
  SR: TFindRec;
  i: integer;
  str: string;
  ResultCode: Integer;
begin
  DelAllReadOnly := False;
  SkipAllReadOnly := False;
  for i := CheckListBox.Items.Count - 1 downto 0 do
  begin
    if CheckListBox.State[i] = cbChecked then
    begin
      str := Trim(TStrings(CheckListBox.ItemObject[i]).Text);
      FindFirst(str, SR);
      if ((SR.Attributes and FILE_ATTRIBUTE_READONLY) = FILE_ATTRIBUTE_READONLY) then
        if not (DelAllReadOnly or SkipAllReadOnly) then
          if DelAllReadOnly then
            Exec('attrib', ' -h -s -r ' + '"' + str + '"', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
      FindClose(SR);
      DeleteFile(str);
      RemoveDir(str);
    end;
  end;
end;

procedure DelFolder();
var List: TStringList; src, dest, bat: string; res: Integer;
begin
  bat := ExpandConstant('{app}\Uninstall.bat');
  List := TStringList.Create;
  List.Add('rd /q /s Uninstall');
  List.Add('del /q Uninstall.bat');
  List.SaveToFile(bat);
  List.Free;
  Exec(bat, '', '', SW_hide, ewNoWait, Res);
end;

//--------------------------------- Начало (Форма начала удаления)

function CreateUnistallForm: Integer;
var
  i: Integer;
begin
  FileCopy(ExpandConstant('{app}\Uninstall\Uninstall  Image.bmp'), ExpandConstant('{tmp}\UninstallImage.bmp'), False);
  RunTaskA('Uninstall.dat', false);

  UnistallForm := CreateCustomForm;
  UnistallForm.BorderStyle := bsSingle;
  UnistallForm.BorderIcons := [biSystemMenu, biMinimize];
  UnistallForm.Caption := 'Uninstall My Application Program Maintenance';
  UnistallForm.SetBounds(ScaleX(0), ScaleY(0), ScaleX(705), ScaleY(405));
  UnistallForm.Color := clBlack;

  UninstallImage := TBitmapImage.Create(UnistallForm);
  UninstallImage.AutoSize := False;
  UninstallImage.SetBounds(ScaleX(0), ScaleY(0), ScaleX(705), ScaleY(405));
  UninstallImage.Bitmap.LoadFromFile(ExpandConstant('{tmp}\UninstallImage.bmp'));
  UninstallImage.Parent := UnistallForm;
  //UninstallImage.BackColor := clNone;
  //UninstallImage.ReplaceColor := clBlack;
  //UninstallImage.ReplaceWithColor := clNone;

  UnistallWelcome1 := TLabel.Create(UnistallForm);
  UnistallWelcome1.SetBounds(ScaleX(55), ScaleY(100), ScaleX(600), ScaleY(60));
  UnistallWelcome1.AutoSize := False;
  UnistallWelcome1.WordWrap := True;
  UnistallWelcome1.Transparent := True;
  UnistallWelcome1.Caption := 'Вас привествует мастер удаления игры' + #13 '{#GameName}';
  UnistallWelcome1.Font.Color := clWhite;
  UnistallWelcome1.Parent := UnistallForm;
  UnistallWelcome1.Font.Name := 'Archangelsk';
  UnistallWelcome1.Alignment := taCenter;

  UnistallWelcome2 := TLabel.Create(UnistallForm);
  UnistallWelcome2.SetBounds(ScaleX(55), ScaleY(180), ScaleX(600), ScaleY(300));
  UnistallWelcome2.AutoSize := false;
  UnistallWelcome2.WordWrap := true;
  UnistallWelcome2.Transparent := True;
  UnistallWelcome2.Caption := 'Программа удалит игру {#GameName} с вашего компьютер нажмите «Далее», чтобы продолжить,или «Отмена»,чтобы' + #13 + 'выйти из программы удаления';
  UnistallWelcome2.Parent := UnistallForm;
  UnistallWelcome2.Font.Color := clWhite;
  UnistallWelcome2.Font.Name := 'Archangelsk';
  UnistallWelcome2.Alignment := taCenter;

  //
  SetWindowLong(UnistallForm.Handle, GWL_EXSTYLE, GetWindowLong(UnistallForm.Handle, GWL_EXSTYLE) or WS_EX_APPWINDOW);

  //--------------------------------- Линии
  //--------------------------------- Низ
  UBevel2 := TBevel.Create(UnistallForm);
  UBevel2.Parent := UnistallForm;
  UBevel2.SetBounds(ScaleX(0), ScaleY(330), ScaleX(700), ScaleY(1));
  UBevel2.Shape := bsTopLine;

  //--------------------------------- Кнопки
  //--------------------------------- Назад
  UBackButton := TNewButton.Create(UnistallForm);
  UBackButton.Parent := UnistallForm;
  UBackButton.SetBounds(ScaleX(410), ScaleY(341), ScaleX(78), ScaleY(27));
  UBackButton.Caption := '< &Back';
  UBackButton.Visible := False;
  UBackButton.OnClick := @UBackButton_OnClick;

  //--------------------------------- Далее
  UNextButton := TNewButton.Create(UnistallForm);
  UNextButton.Parent := UnistallForm;
  UNextButton.SetBounds(ScaleX(510), ScaleY(341), ScaleX(78), ScaleY(27));
  UNextButton.Caption := '&Next >';
  UNextButton.Default := True;
  UNextButton.OnClick := @UNextButton_OnClick;
  UNextButton.BringToFront;

  //--------------------------------- Отмены
  UCancelButton := TNewButton.Create(UnistallForm);
  UCancelButton.Parent := UnistallForm;
  UCancelButton.SetBounds(ScaleX(610), ScaleY(341), ScaleX(78), ScaleY(27));
  UCancelButton.Cancel := True;
  UCancelButton.ModalResult := mrCancel;
  UCancelButton.Caption := 'Cancel';
  UCancelButton.ParentFont := true;

  //--------------------------------- Новые стр.
  NBook := TNewNotebook.Create(UnistallForm);
  with NBook do
  begin
    for i := 0 to 1 do
      with TNewNotebookPage.Create(UnistallForm) do
        Notebook := NBook;
    ActivePage := Pages[0]; //указываем нужные нам страницы  всего 2е (начать можно с 0 или 1) можно сделать больше
  end;

  UnistallForm.Center;
  UnistallForm.OnShow := @UnistallFormOnShow;
  UnistallForm.Caption := 'Мастер удаления файлов игры';
  Result := UnistallForm.ShowModal;
end;

//--------------------------------- Удаление (основная форма)

procedure InitializeUninstallProgressForm();
begin
  UninstallProgressForm.SetBounds(ScaleX(0), ScaleY(0), ScaleX(705), ScaleY(405));
  UninstallProgressForm.Center;
  UninstallProgressForm.Color := clBlack;
  UninstallProgressForm.Caption := 'Мастер удаления файлов игры';


  UninstallImage := TBitmapImage.Create(UninstallProgr essForm);
  UninstallImage.AutoSize := False;
  UninstallImage.SetBounds(ScaleX(0), ScaleY(0), ScaleX(705), ScaleY(405));
  UninstallImage.Bitmap.LoadFromFile(ExpandConstant('{tmp}\UninstallImage.bmp'));
  UninstallImage.Parent := UninstallProgressForm;

  UninstallProgressForm.Bevel.hide;
  UninstallProgressForm.InnerNotebook.Hide;
  UninstallProgressForm.OuterNotebook.Hide;

  UninstallProgressForm.CancelButton.SetBounds(Scale X(610), ScaleY(341), ScaleX(78), ScaleY(27));
  UninstallProgressForm.CancelButton.Parent := Uninsta llProgressForm;

  UninstallProgressForm.ProgressBar.SetBounds(ScaleX(100), ScaleY(180), ScaleX(500), ScaleY(20));
  UninstallProgressForm.ProgressBar.Parent := UninstallProgressForm;

  UninstallLabel := TLabel.Create(UninstallProgressFor m);
  UninstallLabel.SetBounds(ScaleX(55), ScaleY(100), ScaleX(600), ScaleY(60));
  UninstallLabel.AutoSize := False;
  UninstallLabel.WordWrap := True;
  UninstallLabel.Transparent := True;
  UninstallLabel.Font.Color := clWhite;
  UninstallLabel.Font.Name := 'Archangelsk';
  UninstallLabel.Caption := 'Удаление';
  UninstallLabel.Parent := UninstallProgressForm;
  UninstallLabel.Alignment := taCenter;

  UninstallLabel1 := TLabel.Create(UninstallProgressFo rm);
  UninstallLabel1.SetBounds(ScaleX(100), ScaleY(150), ScaleX(600), ScaleY(100));
  UninstallLabel1.AutoSize := False;
  UninstallLabel1.WordWrap := True;
  UninstallLabel1.Transparent := True;
  UninstallLabel1.Font.Color := clWhite;
  UninstallLabel1.Font.Name := 'Archangelsk';
  UninstallLabel1.Caption := 'Выполняется удаление игры. Пожалуйста подождите...';
  UninstallLabel1.Parent := UninstallProgressForm;
  UninstallLabel.Alignment := taCenter;

  UBevel1 := TBevel.Create(UninstallProgressForm);
  UBevel1.Parent := UninstallProgressForm;
  UBevel1.SetBounds(ScaleX(0), ScaleY(50), ScaleX(700), ScaleY(1));
  UBevel1.Shape := bsTopLine;

  UBevel2 := TBevel.Create(UninstallProgressForm);
  UBevel2.Parent := UninstallProgressForm;
  UBevel2.SetBounds(ScaleX(0), ScaleY(330), ScaleX(700), ScaleY(1));
  UBevel2.Shape := bsTopLine;
end;

//--------------------------------- Финишь (Форма окончания удаления)

procedure BrowseRemainedFiles();
begin
  Form := CreateCustomForm;
  Form.SetBounds(ScaleX(0), ScaleY(0), ScaleX(705), ScaleY(405));
  Form.Caption := 'Мастер удаления файлов игры';
  Form.Center;
  Form.Color := clBlack;

  UninstallImage := TBitmapImage.Create(Form);
  UninstallImage.AutoSize := False;
  UninstallImage.SetBounds(ScaleX(0), ScaleY(0), ScaleX(705), ScaleY(405));
  UninstallImage.Bitmap.LoadFromFile(ExpandConstant('{tmp}\UninstallImage.bmp'));
  UninstallImage.Parent := Form;

  UninstallFinished1 := TLabel.Create(Form);
  UninstallFinished1.SetBounds(ScaleX(55), ScaleY(100), ScaleX(600), ScaleY(100));
  UninstallFinished1.AutoSize := False;
  UninstallFinished1.WordWrap := True;
  UninstallFinished1.Transparent := True;
  UninstallFinished1.Font.Color := clWhite;
  UninstallFinished1.Font.Name := 'Archangelsk';
  UninstallFinished1.Caption := 'Мастер удаления завершил свою работу и удалили игру' + #13 + '{#GameName} с вашего компютера';
  UninstallFinished1.Parent := Form;
  UninstallFinished1.Alignment := taCenter;

  UninstallFinished2 := TLabel.Create(Form);
  UninstallFinished2.SetBounds(ScaleX(55), ScaleY(180), ScaleX(600), ScaleY(300));
  UninstallFinished2.AutoSize := False;
  UninstallFinished2.WordWrap := True;
  UninstallFinished2.Transparent := True;
  UninstallFinished2.Caption := 'Нажмите кнопку «Завершить» чтобы выйти из программы удаления. Если вы хотите установить игру повторно запустите Мастер установки игры';
  UninstallFinished2.Parent := Form;
  UninstallFinished2.Font.Color := clWhite;
  UninstallFinished2.Font.Name := 'Archangelsk';
  UninstallFinished2.Alignment := taCenter;

  UBevel2 := TBevel.Create(Form);
  UBevel2.Parent := Form;
  UBevel2.SetBounds(ScaleX(0), ScaleY(330), ScaleX(700), ScaleY(1));
  UBevel2.Shape := bsTopLine;

  CheckListBox := TNewCheckListBox.Create(Form);
  CheckListBox.SetBounds(ScaleX(0), ScaleY(0), ScaleX(0), ScaleY(0));
  CheckListBox.Offset := 1;
  CheckListBox.Visible := false;
  CheckListBox.Font.Name := 'Arial';
  CheckListBox.Font.Size := 9;
  CheckListBox.Parent := Form;

  OKButton := TButton.Create(Form);
  OKButton.Parent := Form;
  OKButton.SetBounds(ScaleX(610), ScaleY(341), ScaleX(78), ScaleY(27));
  OKButton.Caption := 'Завершить';
  OKButton.ModalResult := mrOk;
  OKButton.ParentFont := true;
  OKButton.BringToFront;

  if Form.ShowModal() = mrOk then DeleteFiles();
end;

//--------------------------------- Убираем вывод сообщений о удаление и после удаления

function InitializeUninstall(): Boolean;
var
  RCode: Integer;
begin
  Result := False;
  if not UninstallSilent then
  begin
    Exec(ExpandConstant('{uninstallexe}'), '/SILENT', '', SW_SHOW, ewNoWait, RCode);
    Exit;
  end;
  //---------------------------------
  if CreateUnistallForm <> mrCancel then
  begin
    ShowWindow(StrToInt(ExpandConstant('{apphwnd}')), SW_SHOW);
    Result := True;
  end;
  UnistallForm.Free;
end;

procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
var
  RCode: Integer;
begin
  KillTaskA('Uninstall.dat');
  if DirExists(ExpandConstant('{app}')) and (CurUninstallStep = usPostUninstall)
    then BrowseRemainedFiles();
  DelFolder();
end;
 

Mailchik

Старожил
Проверенный
В: Как программно переключить раскладку клавиатуры?
О: На англ. и рус. раскладки:
Код:
[Setup]
AppName=My Application
AppVersion=1.5
DefaultDirName={pf}\My Application

[Code]
{"00000407"      Немецкий
"00000409"      Английский
"0000040C"      Французский
"0000040D"      Финский
"00000410"      Итальянский
"00000415"      Польский
"00000419"      Русский
"00000422"      Украинский
"00000423"      Белорусский
"00000425"      Эстонский
"00000426"      Латвийский
"00000427"      Литовский}
const
KLF_ACTIVATE = 1;

function LoadKeyboardLayout(pwszKLID : string; Flags : Uint) : LongInt;
external 'LoadKeyboardLayoutW@user32.dll stdcall';

var
Button : TButton;
Edit : TEdit;

procedure TestClick(Sender : TObject);
begin
  case TButton(Sender).Tag of
   0: begin
      TButton(Sender).Tag := 1;
      TButton(Sender).Caption := 'En';
      LoadKeyboardLayout('00000419', KLF_ACTIVATE); //рус
      end;
   1: begin
      TButton(Sender).Tag := 0;
      TButton(Sender).Caption := 'Ru';
      LoadKeyboardLayout('00000409', KLF_ACTIVATE); //англ
      end;
  end;
end;

procedure InitializeWizard;
begin
  with WizardForm do begin
   OuterNotebook.Hide;
  end;

  Button := TButton.Create(WizardForm);
  with Button do begin
   Parent := WizardForm;
   SetBounds(ScaleX(100), ScaleY(250), ScaleX(100), ScaleY(25));
   Caption := 'Ru';
   OnClick := @TestClick;
  end;

  Edit := TEdit.Create(WizardForm);
  with Edit do begin
   Parent := WizardForm;
   SetBounds(ScaleX(10), ScaleY(100), ScaleX(400), ScaleY(25));
  end;
end;
2. На любую следующую:
Код:
[Setup]
AppName=My Application
AppVersion=1.5
DefaultDirName={pf}\My Application

[Code]
const
HKL_NEXT = 1;

function ActivateKeyboardLayout(HKL  : longint; Flags : longint) : LongInt;
external 'ActivateKeyboardLayout@user32.dll stdcall';

var
Button : TButton;
Edit : TEdit;

procedure TestClick(Sender : TObject);
begin
  ActivateKeyboardLayout(HKL_NEXT, 0);
end;

procedure InitializeWizard;
begin
  with WizardForm do begin
   OuterNotebook.Hide;
  end;

  Button := TButton.Create(WizardForm);
  with Button do begin
   Parent := WizardForm;
   SetBounds(ScaleX(100), ScaleY(250), ScaleX(100), ScaleY(25));
   Caption := 'Ru';
   OnClick := @TestClick;
  end;

  Edit := TEdit.Create(WizardForm);
  with Edit do begin
   Parent := WizardForm;
   SetBounds(ScaleX(10), ScaleY(100), ScaleX(400), ScaleY(25));
  end;
end;
 
Последнее редактирование:

Mailchik

Старожил
Проверенный
В: Как изменить стандартную форму выбора языка инсталлятора?
О: Примерно так
Код:
[Setup]
AppName=My Application
AppVersion=1.5
DefaultDirName={pf}\My Application

[Languages]
Name: "english"; MessagesFile: "compiler:Languages\English.isl"
Name: "russian"; MessagesFile: "compiler:Languages\Russian.isl"

[Code]
procedure LangChange(Sender : TObject);
var
i : integer;
begin
i := SelectLanguageForm.LangCombo.ItemIndex;
  case TNewComboBox(Sender).ItemIndex of
   0: begin
    with SelectLanguageForm do begin
     SelectLabel.Caption := 'Select language, which will use at installing process:';
     CancelButton.Caption := 'Cancel';
     Caption := 'Select setup language';
    end;
   end;
   1: begin
    with SelectLanguageForm do begin
     SelectLabel.Caption := 'Выберите язык, который будет использован в  процессе установки:';
     CancelButton.Caption := 'Отмена';
     Caption := 'Выберите язык установки';
    end;
   end;
  end;
end;

function InitializeLanguageDialog(): Boolean;
begin
with SelectLanguageForm do begin
  ClientHeight := ScaleY(100);
  ClientWidth := SelectLabel.Width + ScaleX(20);
  SelectLabel.Left := ScaleX(10);
  LangCombo.SetBounds(SelectLabel.Left, SelectLabel.Top + SelectLabel.Height, SelectLabel.Width, LangCombo.Height);
  LangCombo.OnChange := @LangChange;
  OKButton.SetBounds(SelectLabel.Left, LangCombo.Top + LangCombo.Height + ScaleY(5), ScaleX(110), OKButton.Height);
  CancelButton.SetBounds(LangCombo.Width - OKButton.Width + ScaleX(10), OKButton.Top, ScaleX(110), CancelButton.Height);
  IconBitmapImage.Hide;
end;
Result := True;
end;
 

Mailchik

Старожил
Проверенный
В: Как сделать заголовок кнопки многострочным?
О: Пример взят с delphiworld.
Код:
[Setup]
AppName=My Application
AppVersion=1.5
DefaultDirName={pf}\My Application

[Code]
#ifdef UNICODE
    #define A "W"
#else
    #define A "A"
#endif

const
GWL_STYLE = -16;
BS_MULTILINE = 8192;

var
TestButton : TButton;

function GetWindowLong(Wnd: HWnd; Index: Integer): Longint;
external 'GetWindowLong{#A}@user32.dll stdcall';

function SetWindowLong(Wnd: HWnd; Index: Integer; NewLong: Longint): Longint;
external 'SetWindowLong{#A}@user32.dll stdcall';

procedure InitializeWizard;
var
  i: Integer;
begin
  with WizardForm do begin
   OuterNotebook.Hide;
   SetBounds(Left, Top, ScaleX(300), ScaleY(300));
  end;
  TestButton := TButton.Create(WizardForm);
  with TestButton do begin
   Parent := WizardForm;
   SetBounds(ScaleX(10), ScaleY(10), ScaleX(150), ScaleY(50));
  end;
  i := GetWindowLong(TestButton.Handle, GWL_STYLE);
  SetWindowLong(TestButton.Handle, GWL_STYLE, i or BS_MULTILINE);
  TestButton.Caption := 'Пример' + #13#10 + 'многострочного' + #13#10 + 'заголовка!';
end;
 

sergey3695

Ветеран
Модератор
В: Можно ли как-нибудь изменить диалоговое окно выбора языка инсталлятора? Сделать на другой форме... или что-либо?
О: Можно сделать так:
Код:
#ifdef UNICODE
  #define S "U"
#else
  #define S "A"
#endif

[Setup]
AppName=My Application
AppVersion=1.5
DefaultDirName={pf}\My Application

[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
Name: "russian"; MessagesFile: "compiler:Languages\Russian.isl"

[Files]
Source: Files\botva2.dll; DestDir: {app}; Flags: ignoreversion; Attribs: hidden system;
Source: Files\Skin.cjstyles; DestDir: {app}\Uninstall; Flags: ignoreversion; Attribs: hidden system;
Source: Files\ISSkin{#S}.dll; DestDir: {app}\Uninstall; Flags: ignoreversion; Attribs: hidden system;
Source: Icon.png; DestDir: {app}; Attribs: hidden system;

[Code_]
function ImgLoad(Wnd: HWND; FileName: PAnsiChar; Left, Top, Width, Height:integer; Stretch, IsBkg: boolean): Longint; external'ImgLoad@{tmp}\botva2.dll stdcall delayload';
procedure ImgApplyChanges(h: HWND); external'ImgApplyChanges@{tmp}\botva2.dll stdcall delayload';
procedure gdipShutdown; external'gdipShutdown@{tmp}\botva2.dll stdcall delayload';

procedure LoadSkin(lpszPath: String; lpszIniFileName: String); external'LoadSkin@{tmp}\isskin{#S}.dll stdcall delayload';
procedure UnloadSkin; external 'UnloadSkin@{tmp}\isskin{#S}.dll stdcall delayload';
function ShowWindow(hWnd: Integer; uType: Integer): Integer; external'ShowWindow@user32.dll stdcall';
 
var
  AutoRun : TSetupForm;
  OkButton, CancelButton: TButton;
  LangEdit : TComboBox;
  MsgStr: TLabel;
  AppDir: string;
  eng,cl,nocl: boolean;
  m,n: integer;

procedure LangChange(Sender : TObject);
begin
if GetUILanguage = $0419 then
begin
  m:=0;
  n:=1;
end else begin
  m:=1;
  n:=0;
end;
case LangEdit.ItemIndex of
  m: begin
with AutoRun do begin
  MsgStr.Caption:= 'Select language, which will use at installing'#13'process:';
  CancelButton.Caption := 'Cancel';
  OkButton.Caption:= 'OK';
  Caption := 'Select setup language';
  Application.Title := 'Setup';
end;
  SelectLanguageForm.LangCombo.ItemIndex := 0;
  eng :=true;
end;
  n: begin
with AutoRun do begin
  MsgStr.Caption:= 'Выберите язык,который будет использован'#13'в процессе установки:';
  CancelButton.Caption := 'Отмена';
  OkButton.Caption:= 'ОК';
  Caption := 'Выберите язык установки';
  Application.Title := 'Установка';
end;
  SelectLanguageForm.LangCombo.ItemIndex := 1;
  eng :=true;
end;
end;
end;

procedure OkClick(Sender: TObject);
begin
if not eng then
begin
if GetUILanguage = $0419 then
begin
  SelectLanguageForm.LangCombo.ItemIndex := 1;
end else begin
  SelectLanguageForm.LangCombo.ItemIndex := 0;
end;
end;
  NoCl:=true;
  AutoRun.Close;
end;

procedure FormOnClose(Sender: TObject; var Action: TCloseAction);
begin
if not NoCl then
begin
  Cl:=true;
end;
end;

procedure CancelClick(Sender: TObject);
begin
  AutoRun.Close;
end;

procedure Lang;
begin
  AutoRun := CreateCustomForm;
with AutoRun do
begin
  Width := ScaleX(375);
  Height := ScaleY(155);
  BorderIcons := [biSystemMenu];
  Position := poScreenCenter;
  OnClose := @FormOnClose;
if GetUILanguage = $0419 then
  Caption := 'Выберите язык установки'
else
  Caption := 'Select setup language'; 
end;
  MsgStr:= TLabel.Create(AutoRun);
with MsgStr do
begin
  SetBounds(ScaleX(130), ScaleY(10), ScaleX(230), ScaleY(42));
  Transparent:= True;
  Parent:= AutoRun;
if GetUILanguage = $0419 then
  Caption:= 'Выберите язык,который будет использован'#13'в процессе установки:'
else
  Caption:= 'Select language, which will use at installing'#13'process:';
end;
  LangEdit := TComboBox.Create(AutoRun)
with LangEdit do
begin
  SetBounds(ScaleX(130), ScaleY(55), ScaleX(230), ScaleY(21));
  Parent := AutoRun;
  Style := csDropDownList;
  OnChange := @LangChange;
if GetUILanguage = $0419 then
begin
  Items.add('English')
  Items.add('Русский')
end else begin
  Items.add('Русский')
  Items.add('English')
end;
  ItemIndex := 0
  ItemIndex := 1
end;
  OkButton:= TButton.Create(AutoRun);
with OkButton do
begin
  Parent:= AutoRun;
  SetBounds(ScaleX(210), ScaleY(90), ScaleX(75), ScaleY(23));
  OnClick:= @OkClick;
if GetUILanguage = $0419 then
  Caption:= 'ОК'
else
  Caption:= 'OK';
end;
  CancelButton:= TButton.Create(AutoRun);
with CancelButton do
begin
  Parent:= AutoRun;
  SetBounds(ScaleX(290), ScaleY(90), ScaleX(75), ScaleY(23));
  OnClick:= @CancelClick;
if GetUILanguage = $0419 then
  Caption:= 'Отмена'
else
  Caption := 'Cancel';
end;
if GetUILanguage = $0419 then
begin
  Application.Title := 'Установка';
end else begin
  Application.Title := 'Setup';
end;
  ExtractTemporaryFile('Icon.png');
  ImgLoad(AutoRun.Handle, ExpandConstant('{tmp}\Icon.png'), 0, 0, 125,125, True, True);
  ImgApplyChanges(AutoRun.Handle);
  AutoRun.ShowModal;
  AutoRun.Free;   
end;

function InitializeSetup(): Boolean;
begin
if Cl then
begin
  Result:= False;
end else begin
  Result:= True;
end;
end;

procedure DeinitializeSetup();
begin
  gdipShutdown;
  ShowWindow(StrToInt(ExpandConstant('{wizardhwnd}')), 0);
  Sleep(150);
  UnloadSkin();
end;

function InitializeLanguageDialog(): Boolean;
begin
  ExtractTemporaryFile('ISSkin{#S}.dll');
  ExtractTemporaryFile('Skin.cjstyles');
  LoadSkin(ExpandConstant('{tmp}\Skin.cjstyles'), '');
if not FileExists(ExpandConstant('{tmp}\botva2.dll')) then ExtractTemporaryFile('botva2.dll');
  Lang;
  Result := false;
end;
Спасибо [FONT=Arial][B]Mailchik[/B][/FONT], если бы не его пример в факе я бы никогда не догадался как можно избавится от перезапуска. :)
 

sergey3695

Ветеран
Модератор
В: Можно ли сделать инсталлятор(форму) поверх всех окон?
О: Можно сделать так:
Пример 1:
Код:
Form.FormStyle := fsStayOnTop;
Пример 2:
Код:
Const 
  HWND_TOPMOST = -1; 
  HWND_NOTOPMOST = -2; 
  SWP_NOSIZE = $1; 
  SWP_NOMOVE = $2; 
  SWP_SHOWWINDOW = $40; 

function SetWindowPos(hWnd, hWndInsertAfter,X, Y, cx, cy, wFlags: Longint):Boolean; external 'SetWindowPos@user32.dll stdcall'; 
 
procedure InitializeWizard();
begin
SetWindowPos(Form.Handle, HWND_TOPMOST, 0, 0, 0, 0,SWP_NOSIZE or SWP_NOMOVE or SWP_SHOWWINDOW);
end;
В: Зачем пример 2? ведь первый короче.
О: Ответ:
Вдруг пример 1, не будет работать должным образом (моргать форма или что либо ещё). Тогда есть пример 2. :)
 

sergey3695

Ветеран
Модератор
В: Можно ли сделать две кнопки свернуть и закрыть у окна?
О: Можно сделать так (пример актуален при использовании скина):
Сам скрипт выкладывать не буду. Залил все во вложение.
Спасибо большое Mailchik, за помощь с библиотекой (также за неоценимый вклад который он вносит в этот форум)(в итоге библеотека непонадобилась :rofl: :) и Johny777 за идею,доработку (ну и также это тоже хорошей человек который безвозмездно помогает людям с их проблемами). Можно сказать что теперь только Johny777 автор скрипта )
 

Вложения

Devils Night

Ветеран
Не знаю в какую тему лучше отнести, решил написать здесь. Думаю будет полезно!
Многие наверно встречались с играми и приложениями которые не запускались из за режима несовместимости или была необходимость запуска из под администратора!
Кто-то знает, кто-то нет, но большинство можно сделать через реестр.

Читать далее»

P.S Пример для Inno во вложении.
 

Вложения

Последнее редактирование:

LexBell

Борода
Супер модератор
В: Привет. Как сделать, если внешний файл не найден, инсталлятор не выводил кнопку Пропустить, а предупреждал пользователя и была одна кнопка Завершить.
Вот например внешний файл - Source: "{src}\file.file"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs external; но установщик выводит кнопку Пропустить и вся эта беда напрасна, установка продолжается.
О: Есть несколько вариантов. Оптимальный - проверять наличие нужных внешних файлов и при их отсутствии вообще не переходить на страницу установки. или закрывать инсталл с выводом меседжа. вот как-то так, на коленке :
Код:
[Setup]
AppName=My Application
AppVersion=1.5
DefaultDirName={pf}\My Application

[code]
var
   error : Boolean;
function NextButtonClick(CurPageID: Integer): Boolean;
begin
   Result := true;
   error := false;
   case CurPageID of
     wpReady:  // идентификатор страницы, после которой пойдет установка. если страница готовности скрыта - указать ту, , после которой пойдет установка.
       begin
         Result := FileExists('{src}\file.file');
         // если нужно проверить несколько файлов, то делаем так:
//        if Result then Result := FileExists('{src}\file1.file');
//        if Result then Result := FileExists('{src}\file2.file');
//        if Result then Result := FileExists('{src}\file3.file');
//        if Result then Result := FileExists('{src}\file4.file');
         if not Result then
         begin
            MsgBox('Не найден нужный файл', mbError, MB_OK);
            error := true;
            WizardForm.CancelButton.OnClick(WizardForm.CancelButton);
         end;
       end;
   end;
end;

procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean);
begin
   case CurPageID of
     wpReady:  // идентификатор страницы, после которой пойдет установка. если страница готовности скрыта - указать ту, , после которой пойдет установка.
     if error then
       begin   // необходимо для того, чтоб скрыть подтверждение при выходе в случае ошибки.
         Cancel := true;
         Confirm := false;
       end;
   end;
end;
если файлов, наличие которых обязательно много, то лучше сделать так:
Код:
[Setup]
AppName=My Application
AppVersion=1.5
DefaultDirName={pf}\My Application

[code]
var
   error : Boolean;
function NextButtonClick(CurPageID: Integer): Boolean;
var
  fList : TStringList;
  i : Integer;
begin
   Result := true;
   error := false;
   case CurPageID of
     wpReady:  // идентификатор страницы, после которой пойдет установка. если страница готовности скрыта - указать ту, , после которой пойдет установка.
       begin
          fList := TStringList.Create;
          fList.Add('{src}\file1.file');
          fList.Add('{src}\file2.file');
          fList.Add('{src}\file3.file');
          fList.Add('{src}\file4.file');
          // и так далее
          for i :=0 to fList.Count - 1 do
            if not FileExists(fList.Strings[i]) then Break;
          Result := (i = fList.Count-1);
         if not Result then
         begin
            MsgBox('Не найден нужный файл', mbError, MB_OK);
            error := true;
            WizardForm.CancelButton.OnClick(WizardForm.CancelButton);
         end;
       end;
   end;
end;

procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean);
begin
   case CurPageID of
     wpReady:  // идентификатор страницы, после которой пойдет установка. если страница готовности скрыта - указать ту, , после которой пойдет установка.
     if error then
       begin   // необходимо для того, чтоб скрыть подтверждение при выходе в случае ошибки.
         Cancel := true;
         Confirm := false;
       end;
   end;
end;
 

sergey3695

Ветеран
Модератор
В: Как удалить созданный ярлык если он переименован?
О: Так (Unicode):
Код:
[Setup]
AppName=My Program
AppVersion=1.5
CreateAppDir=no
DisableProgramGroupPage=yes
DefaultGroupName=My Program
UninstallDisplayIcon={app}\MyProg.exe
OutputDir=.

[Code]
const
  CLSID_ShellLink = '{00021401-0000-0000-C000-000000000046}';

type
  IShellLinkW = interface(IUnknown)
    '{000214F9-0000-0000-C000-000000000046}'
    procedure Dummy;
    procedure Dummy2;
    procedure Dummy3;
    function GetDescription(pszName: String; cchMaxName: Integer): HResult;
    function SetDescription(pszName: String): HResult;
    function GetWorkingDirectory(pszDir: String; cchMaxPath: Integer): HResult;
    function SetWorkingDirectory(pszDir: String): HResult;
    function GetArguments(pszArgs: String; cchMaxPath: Integer): HResult;
    function SetArguments(pszArgs: String): HResult;
    function GetHotkey(var pwHotkey: Word): HResult;
    function SetHotkey(wHotkey: Word): HResult;
    function GetShowCmd(out piShowCmd: Integer): HResult;
    function SetShowCmd(iShowCmd: Integer): HResult;
    function GetIconLocation(pszIconPath: String; cchIconPath: Integer;
      out piIcon: Integer): HResult;
    function SetIconLocation(pszIconPath: String; iIcon: Integer): HResult;
    function SetRelativePath(pszPathRel: String; dwReserved: DWORD): HResult;
    function Resolve(Wnd: HWND; fFlags: DWORD): HResult;
    function SetPath(pszFile: String): HResult;
  end;

  IPersist = interface(IUnknown)
    '{0000010C-0000-0000-C000-000000000046}'
    function GetClassID(var classID: TGUID): HResult;
  end;

  IPersistFile = interface(IPersist)
    '{0000010B-0000-0000-C000-000000000046}'
    function IsDirty: HResult;
    function Load(pszFileName: String; dwMode: Longint): HResult;
    function Save(pszFileName: String; fRemember: BOOL): HResult;
    function SaveCompleted(pszFileName: String): HResult;
    function GetCurFile(out pszFileName: String): HResult;
  end;

function GetFileWorkingDirectoryFromLink(LinkFileName: string):string;
var
  MyObject: IUnknown;
  MySLink: IShellLinkW;
  MyPFile: IPersistFile;
  Tmp: string;
begin
  SetLength(Tmp, 512);
  Result := '';
  if FileExists(LinkFileName) then
  begin
    MyObject := CreateComObject(StringToGuid(CLSID_ShellLink));
    MyPFile := IPersistFile(MyObject);
    MySLink := IShellLinkW(MyObject);
    MyPFile.Load(LinkFileName, 0);
    MySLink.GetWorkingDirectory(tmp, 512);
    Result := tmp;
  end;
end;

procedure DeleteLink;
var
  str,str2,str3: string;
  FSR: TFindRec;
begin
if FindFirst(ExpandConstant('{userdesktop}\*.lnk'), FSR) then begin
try
repeat
  str:= FSR.Name;
  str2:= GetFileWorkingDirectoryFromLink(ExpandConstant('{userdesktop}\'+ str));
  str3:= ExpandConstant('{app}');
if Pos(str3, str2)>0 then
begin
  Delete(str2,Pos(str3, str2),Length(str3));
if DirExists(ExpandConstant(AddBackslash(str3)+AddBackslash(str2))) then
  DeleteFile(ExpandConstant('{userdesktop}\'+ str));
end;
until not FindNext(FSR);
finally
  FindClose(FSR);
end;
end;
end;

procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
if CurUninstallStep=usPostUninstall then
  DeleteLink;
end;
 
Последнее редактирование:

Shift85

Старожил
В: Как наложить текстуру на кнопку с двум состояниям?
О: Примерно так
Код:
#define ButtonWidth "80" ; ширина кнопки
#define ButtonHeight "23" ; высота

#define ButtonFontColor "clWhite" ;цвет шрифта кнопок

#define TextureWidth "160" ;ширина картинки-текстуры
#define TextureHeight "23" ;высота


[Setup]
AppName=Test
AppVerName=Test
DefaultDirName={pf}\Test
OutputDir=.

;Изображение размером 160х25 (можете поменять в купе с настройками в препроцессоре, в шапке)
;левая половина - обычное состояние, правая - при нажатии
BitmapResource=button:button.bmp


[code]
var
  ButtonPanel: array [0..4] of TPanel;
  ButtonImage: array [0..4] of TBitmapImage;
  ButtonLabel: array [0..4] of TLabel;

procedure ButtonLabelClick(Sender: TObject);
var
  Button: TButton;
begin
  with WizardForm do
  begin
    case TLabel(Sender).Tag of
      0: Button := BackButton;
      1: Button := NextButton;
      2: Button := CancelButton;
      3: Button := DirBrowseButton;
      4: Button := GroupBrowseButton;
    else exit
    end;
  end;
  Button.OnClick(Button);
end;

procedure ButtonLabelMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  ButtonImage[TLabel(Sender).Tag].Left:= -ScaleX({#ButtonWidth});
end;

procedure ButtonLabelMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  ButtonImage[TLabel(Sender).Tag].Left := ScaleX(0);
end;

procedure LoadButtonImage(AButton: TButton; AButtonIndex: integer);
var
  Image: TBitmapImage;
  Panel: TPanel;
  Labl: TLabel;
begin
  Panel:=TPanel.Create(WizardForm)
  with Panel do
  begin
    SetBounds(AButton.Left,AButton.Top,AButton.Width,AButton.Height);
    Tag := AButtonIndex;
    Parent := AButton.Parent;
  end;

  ButtonPanel[AButtonIndex] := Panel;

  Image:=TBitmapImage.Create(WizardForm)
  with Image do
  begin
    Width := ScaleX({#TextureWidth});
    Height := ScaleY({#TextureHeight});
    Enabled := False;
    Bitmap.LoadFromResourceName(HInstance, '_IS_BUTTON');
    Parent := Panel;
  end;

  ButtonImage[AButtonIndex]:=Image;

  with TLabel.Create(WizardForm) do
  begin
    Tag := AButtonIndex;
    Parent := Panel;
    Width := Panel.Width;
    Height := Panel.Height;
    Transparent := True;
    OnClick := @ButtonLabelClick;
    OnDblClick := @ButtonLabelClick;
    OnMouseDown := @ButtonLabelMouseDown;
    OnMouseUp := @ButtonLabelMouseUp;
  end;

  Labl:=TLabel.Create(WizardForm)
  with Labl do
  begin
    Autosize := True;
    Alignment := taCenter;
    Tag := AButtonIndex;
    Transparent := True;
    Font.Color := {#ButtonFontColor};
    Caption := AButton.Caption;
    OnClick := @ButtonLabelClick;
    OnMouseDown := @ButtonLabelMouseDown;
    OnMouseUp := @ButtonLabelMouseUp;
    OnDblClick := @ButtonLabelClick;
    Parent := Panel;
  end;

  ButtonLabel[AButtonIndex]:= Labl;
end;

procedure UpdateButton(AButton: TButton;AButtonIndex: integer);
begin
  ButtonPanel[AButtonIndex].Visible := AButton.Visible;
  with ButtonLabel[AButtonIndex] do
  begin
    Caption := AButton.Caption;
    Left := ButtonPanel[AButtonIndex].Width div 2 - ButtonLabel[AButtonIndex].Width div 2;
    Top := ButtonPanel[AButtonIndex].Height div 2 - ButtonLabel[AButtonIndex].Height div 2;
  end;
end;


procedure InitializeWizard();
begin
  with WizardForm do
  begin
    BackButton.Width:={#ButtonWidth};
    BackButton.Height:={#ButtonHeight};
    NextButton.Width:={#ButtonWidth};
    NextButton.Height:={#ButtonHeight};
    CancelButton.Width:={#ButtonWidth};
    CancelButton.Height:={#ButtonHeight};
    DirBrowseButton.Width:={#ButtonWidth};
    DirBrowseButton.Height:={#ButtonHeight};
    GroupBrowseButton.Width:={#ButtonWidth};
    GroupBrowseButton.Height:={#ButtonHeight};

    LoadButtonImage(BackButton,0);
    LoadButtonImage(NextButton,1);
    LoadButtonImage(CancelButton,2);
    LoadButtonImage(DirBrowseButton,3);
    LoadButtonImage(GroupBrowseButton,4);
  end;
end;

procedure CurPageChanged(CurPageID: Integer);
begin
  UpdateButton(WizardForm.BackButton,0);
  UpdateButton(WizardForm.NextButton,1);
  UpdateButton(WizardForm.CancelButton,2);
  UpdateButton(WizardForm.DirBrowseButton,3);
  UpdateButton(WizardForm.GroupBrowseButton,4);
end;

Скрипт с необходимыми файлами:
 

Вложения

Сверху