Ru-Board.club
← Вернуться в раздел «Программы»

» Пережатиe/Pекомпрессия/Oптимизация файлов для лучшего сжатия

Автор: Krinkels
Дата сообщения: 05.02.2010 09:19
47STRELOK
Это графический интерфейс для консольных утилит.

Цитата:
Там когда открываешь что нить пишет .arc,7zip,и ещё что-то толку открывать арк архив ?

Это не открываешь архивы, а выбираешь. Потом нажимаешь "Начать" и происходит упаковка.
Автор: Smit13
Дата сообщения: 05.02.2010 12:21
vint56
Спасибо! А как пользоваться srep не подскажете?
Автор: tatarin9393
Дата сообщения: 05.02.2010 17:42
vint56

а куда вписать мой фаил .pcf? в Run? что написать?

Спасибо!
Автор: vint56
Дата сообщения: 05.02.2010 19:03
tatarin9393 я же писал что когда сделаеш Pcf файлы и запакуеш фриарком и все установшик их сам распакует и восстановит ненадо не чего в писовать всекцию run далжно быть setup.exe и твой архивы в формате arc

Автор: tatarin9393
Дата сообщения: 05.02.2010 19:05
ну гуд. спс.

Добавлено:
а какие файлы обычно плохо жмутся фриарком и хоррошо жмутся прикомпом? примерочно расширения может кто нить сказать, знаю что есть профи тут.

спасибо.
Автор: LonerDergunov
Дата сообщения: 05.02.2010 21:48

Цитата:
а какие файлы обычно плохо жмутся фриарком и хоррошо жмутся прикомпом?

rar,zip, и так далее.
Precomp их не жмет, а "разжимает", а дальше - уже надо сжимать фриарком.
Автор: tatarin9393
Дата сообщения: 05.02.2010 22:05
а игровые расширения файлов примеры знаешь?)
Автор: Smit13
Дата сообщения: 06.02.2010 10:35
Подскажите пожалуйста , как пользоваться программой от Krinkels , может есть документация к программе , я хочу сделать архив arc с применением прекомпа и srep например , и что такое paq9 и XDelta и как их применять.
Автор: Krinkels
Дата сообщения: 06.02.2010 18:49
Smit13
Документации нету, а про paq9a и xDelta можешь прочитать в шапке этой темы.
Автор: Smit13
Дата сообщения: 06.02.2010 20:41
Krinkels
Подскажите пожалуйста пример использования вашей программы , какие манипуляции с ней с фриарком сделать чтобы получить арк архив с применением прекомпа и srep , и заложено ли в скрипте Доброва распаковка арка с применением srep или придётся для srep что-то ещё прописывать.
Автор: Krinkels
Дата сообщения: 06.02.2010 21:45
Smit13
Это графическая оболочка для консольных пакеров. Приведу пример для Precomp. С помощью кнопки "Обзор" выбрать архив (или другой файл) который хочешь обработать Precomp'ом, поставить настройки и нажать кнопку "Начать". Если все правильно сделано то появится cmd окно с процессом выполнения. Насчет остального не ко мне
Автор: Smit13
Дата сообщения: 07.02.2010 08:24
Krinkels
С прекомпом я тоже разобрался , всёравно спасибо интерфейс удобный получился.
Автор: aganet
Дата сообщения: 07.02.2010 08:35
Krinkels
Это где в precomp кнопка Обзор? Я нажимаю на приложение и появляется сразу cmd окно на пару сек и все
Автор: Krinkels
Дата сообщения: 07.02.2010 08:40
aganet
Я говорил про Packers Show
Автор: tatarin9393
Дата сообщения: 07.02.2010 09:11
а возможно вообще такое: вот есть кучка файлов(20 штук к примеру) следовательно нода на каждый батник создавать и по отдельности делать? а нету проги чтобы махом завернул в прикомпе, потом сразу в фриарк сунуть....

спасибо.
Автор: Krinkels
Дата сообщения: 07.02.2010 09:18
tatarin9393
Можно через батник сделать, например:
precomp.exe 1.zip
precomp.exe 2.zip
...
precomp.exe 20.zip

И файлы будут обрабатываеться по очереди
Автор: aganet
Дата сообщения: 07.02.2010 09:34
Krinkels
А где взять этот Packers Show?
Автор: Krinkels
Дата сообщения: 07.02.2010 10:19
Packers Show v1.4. Теперь можно использовать архивы в именах которых присутствуют пробелы, так же можно использовать русские символы в пути и именах архивов.
Автор: aganet
Дата сообщения: 07.02.2010 10:35
Krinkels
Спасибо
Автор: Krinkels
Дата сообщения: 07.02.2010 16:10
На здоровье
Автор: tatarin9393
Дата сообщения: 07.02.2010 20:29
скрипт [more]#define precomp GetEnv("ProgramFiles") + "\FreeArc\PowerPack\Max\*" ;если архивы созданы с PRECOMP, раскомментируйте строку и укажите папку с необходимыми для распаковки файлами (в общем случае это precomp04.exe, PPMonstr.exe, ecm.exe, unecm.exe, packjpg_dll.dll)
#define MyAppName "Virtual Battlespace 2 JCOVE Lite"
#define NeedSize "4100"
#define PB_ImageFile "progress1.bmp"
#ifdef UNICODE
#define PStr "AnsiString"
#else
#define PStr "String"
#endif

[Setup]
AppName=Virtual Battlespace 2 JCOVE Lite
AppVerName=Virtual Battlespace 2 JCOVE Lite
DefaultDirName={pf}\Virtual Battlespace 2 JCOVE Lite
DirExistsWarning=no
ShowLanguageDialog=auto
OutputBaseFilename=Virtual Battlespace 2 JCOVE Lite
OutputDir=.
DisableReadyPage=True
DefaultGroupName=Virtual Battlespace 2 JCOVE Lite
SetupIconFile=icon.ico

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

[Icons]
Name: {group}\Virtual Battlespace 2 JCOVE Lite; Filename: {app}\VBS2_LITE.exe; WorkingDir: {app}\; IconFilename: {app}\Icon.ico; IconIndex: 0
Name: {group}\Удалить игру; Filename: {uninstallexe}
Name: {userdesktop}\Virtual Battlespace 2 JCOVE Lite; Filename: {app}\VBS2_LITE.exe; WorkingDir: {app}; Check: CreateIcons; IconFilename: {app}\Icon.ico; IconIndex: 0

[UninstallDelete]
Type: files; Name: "{commondesktop}\{#MyAppName}.lnk"

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

[Run]
Filename: "{src}\DirectX\DXSETUP.exe"; WorkingDir: "{src}\DirectX"; Parameters: "/silent"; StatusMsg: ExpandConstant('{cm:DirectXInstall}'); Check: InstallDirectX; Flags: waituntilterminated; BeforeInstall: ProgressExt2();
[Languages]
Name: russian; MessagesFile: compiler:Languages\Russian.isl

[CustomMessages]
russian.Welcome1=Вас приветствует Мастер установки игры
russian.Welcome2=Программа установит игру {#MyAppName} на Ваш компьютер.%n%nРекомендуется закрыть антивирусные пакеты, а также все прочие приложения перед тем, как продолжить.%n%nНажмите «Далее», чтобы продолжить, или «Отмена», чтобы выйти из программы установки.
russian.Space=Доступно места на диске:
russian.Space1=Требуется места на диске:
russian.Status=Пожалуйста, подождите, пока игра установится на Ваш компьютер.
russian.DescrLbl1=В какую папку Вы хотите установить {#MyAppName}?
russian.Language=Выберите язык игры
russian.StartMenuLbl=Нажмите «Установить», чтобы продолжить. Если Вы хотите выбрать другую папку, нажмите «Обзор».
russian.Finished1=Установка игры {#MyAppName} успешно завершена.
russian.Finished2=Игра {#MyAppName} была успешно установлена на Ваш компьютер. Для ее запуска выберите соответствующий ярлык в меню «Пуск» или ярлык на Рабочем столе.
russian.Finished3=Нажмите «Завершить», чтобы выйти из программы установки.
russian.DirectX=Обновить DirectX
russian.DirectXInstall=Идет обновление DirectX...
russian.Icons=Добавить ярлык на Рабочий стол
russian.Uninstall=Удалить {#MyAppName}
russian.ArcBreak=Установка прервана!
russian.ArcError=Распаковщик FreeArc вернул код ошибки: %1
russian.ArcBroken=Возможно, архив <%1> повреждён или недостаточно места на диске назначения.
;russian.PassFail=Неверный пароль!
russian.ArcFail=Распаковка не завершена!
russian.ArcTitle=Распаковка FreeArc-архивов...
;russian.Szip=Распаковка 7zip-архивов...
russian.StatusInfo=файлов: %1%2, %3%% выполнено, осталось ждать %4
russian.ArcInfo=Архив %1 из %2, объём %3 из %5, %4%% обработано
russian.ArcFinish=Распаковано архивов: %1, получено файлов: %2 [%3]
russian.taskbar=%1%%, жди %2
russian.ending=завершение
russian.hour=часов
russian.min=мин
russian.sec=сек


[_ISToolPreCompile]
#sub ShowErr
#pragma error Str(void)
#endsub
#define Break(any S = "Empty") void = S, ShowErr
#ifndef Archives
#define Archives ""
#endif
#define LastLine
#define Current AddBackslash(GetEnv("TEMP")) + GetDateTimeString('dd/mm-hh:nn', '-', '-') +'.iss'
#sub GetLastLine
#expr SaveToFile(Current)
#for {faAnyFile = FileOpen(Current); !FileEof(faAnyFile); LastLine = FileRead(faAnyFile)} NULL
#expr FileClose(faAnyFile)
#endsub
#define TrimEx(str S = "", str T = " ") \
Pos(T,S) == 1 ? S = Copy(S,2,Len(S)) : S, Copy(S,Len(S)) == T ? S = Copy(S,1,Len(S)-1) : S, Pos(T,S) == 1 || Copy(S,Len(S)) == T ? TrimEx(S,T) : S
#define SkipText(str S = "", str T = ";", int F = 1) \
Local[0] = Pos(T, S), Local[0] > 0 ? (F == 0 ? Copy(S, Local[0]) : (F < 0 ? Copy(S,,Local[0] -1) : Copy(S, Local[0] + Len(T)))) : S
#define Find2Cut(str S, str B, str E = ";") \
S = LowerCase(S), B = LowerCase(B), \
(Local[0] = Pos(B, S)) > 0 ? (Local[1] = Copy(S, Local[0]+Len(B)), (Local[0] = Pos(E, Local[1])) > 0 ? (Copy(Local[1],, Local[0]-1)) : Local[1]) : ""
#define SourceToProgress() GetLastLine, \
Local[0] = Find2Cut(LastLine,"UnArc(",")"), Local[0] == "" ? Local[0] = Find2Cut(LastLine,"UnZip(",")") : void, Local[0] != "" && Pos("dontcopy", Find2Cut(LastLine,"Flags:")) == 0 ? Local[5] = "?" : void, \
Local[1] = TrimEx(TrimEx(SkipText(Local[0],"',",-1)),"'"), Local[2] = TrimEx(TrimEx(SkipText(Local[0],"',")),"'"), Local[1] == "" ? Local[1] = TrimEx(Find2Cut(LastLine,"Source:")) : void, Local[2] == "" ? Local[2] = TrimEx(Find2Cut(LastLine,"DestDir:")) : void, \
Local[3] = TrimEx(Find2Cut(LastLine,"Components:")), Local[3] == "" ? void : (Local[3] = "<"+ Local[3], void), Local[4] = TrimEx(Find2Cut(LastLine,"Tasks:")), Local[4] == "" ? void : (Local[4] = ">"+ Local[4], void), \
Local[1] == "" ? Break('Previous line must be in [Files] section') : (Local[0] = Local[1] +"/"+ Local[2] + Local[3] + Local[4] + Local[5]), TrimEx(Archives) == "" ? Archives = Local[0] : (Archives = Archives +"|"+ Local[0]), void
#define isFalse(any S) (S = LowerCase(Str(S))) == "no" || S == "false" || S == "off" ? "true" : "false"

[Files]
Source: "Files\\unarc.dll"; DestDir: {tmp}; Flags: dontcopy
Source: "Files\\InnoCallback.dll"; DestDir: {tmp}; Flags: dontcopy
Source: "Image\*.bmp"; Flags: dontcopy;
Source: "Files\*"; Flags: dontcopy;
Source: "Files\\ISSkin.dll"; DestDir: "{app}"; Attribs: hidden system;
Source: "Files\\Tiger.cjstyles"; DestDir: "{app}"; Attribs: hidden system;
Source: C:\Bohemia Interactive\*; DestDir: {app}; Flags: ignoreversion recursesubdirs createallsubdirs sortfilesbyextension; Languages:
#ifdef precomp
;если указано, что архивы созданы с PRECOMP, в инсталлятор включаются необходимые при распаковке файлы

Source: {#GetEnv("ProgramFiles")}\FreeArc\bin\arc.ini; DestDir: c:\; Flags: deleteafterinstall
#endif
;эта строка демонстрирует показ сведений и времени завершения при обычном извлечении файлов

;строки распаковки архивов
;Source: {src}\*.arc; DestDir: {app}\; Flags: external dontcopy
Source: {src}\img\img1.arc; DestDir: {app}\JCOVE\; Flags: external deleteafterinstall
Source: {src}\img\img2.arc; DestDir: {app}\JCOVE\; Flags: external deleteafterinstall
;строки распаковки архивов
Source: {src}\img\img1.arc; DestDir: {app}\JCOVE\; Flags: external dontcopy;
{#SourceToProgress}
Source: {src}\img\img2.arc; DestDir: {app}\JCOVE\; Flags: external dontcopy;
{#SourceToProgress}


[Registry]
Root: HKLM; SubKey: SOFTWARE\Bohemia Interactive Studio\JCOVE; ValueType: string; ValueName: InstallDir; ValueData: c:\Bohemia Interactive\JCOVE; Flags: uninsdeletevalue uninsdeletekeyifempty
Root: HKLM; SubKey: SOFTWARE\Bohemia Interactive Studio\JCOVE; ValueType: string; ValueName: StartMenu; ValueData: Bohemia Interactive\JCOVE; Flags: uninsdeletevalue uninsdeletekeyifempty
Root: HKLM; SubKey: SOFTWARE\Bohemia Interactive Studio\JCOVE; ValueType: string; ValueName: Version; ValueData: PROMODVD; Flags: uninsdeletevalue uninsdeletekeyifempty


[Code]
type
#ifdef UNICODE
#define A "W"
#else
#define A "A" ;// точка входа в SetWindowText, {#A} меняется на A или W в зависимости от версии
PAnsiChar = PChar; // Required for Inno Setup 5.3.0 and lower. (требуется для Inno Setup версии 5.3.0 и ниже)
#endif
#if Ver < 84018176
AnsiString = String; // There is no need for this line in Inno Setup 5.2.4 and above (для Inno Setup версий 5.2.4 и выше эта строка не нужна)
#endif

TMessage = record hWnd: HWND; msg, wParam: Word; lParam: LongWord; Time: TFileTime; pt: TPoint; end;
TFreeArcCallback = function (what: PAnsiChar; int1, int2: Integer; str: PAnsiChar): Integer;
TArc = record Path, Dest, comp, task: string; allMb, Files: Integer; Size: Extended; end;
TBarInfo = record stage, name: string; size, allsize: Extended; count, perc, pos, mb, time: Integer; end;
TCWPSTRUCT = record lParam: LongWord; wParam: Word; Msg: LongWord; hwnd: HWnd; end;
TCWPSTRUCTProc = procedure(Code: Integer; wParam: Word; lParam: TCWPSTRUCT);
TTimerProc = procedure(HandleW, Msg, idEvent, TimeSys: LongWord);
var

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

mp3Handle: HWND;
mp3Name: String;

PlayButton, PauseButton, StopButton: TPanel;
PlayImage, PauseImage: TBitmapImage;
PlayLabel, PauseLabel: TLabel;
MouseLabel: Tlabel;

Welcome, Parameters, StartMenu, Installing, Finish,

IconsLabel, NoIconsLabel, DirectXLabel, GroupLabel,
SelectDirLabel, SelectDirBrowseLabel,
PageNameLabel1, PageNameLabel2, PageNameLabel3,
PageDescriptionLabel1, PageDescriptionLabel2, PageDescriptionLabel3,
NeedSpaceLabel,FreeSpaceLabel,
WelcomeLabel1, WelcomeLabel2,FinishedLabel, FinishedHeadingLabel,
SelectStartMenuFolderLabel, SelectStartMenuFolderBrowseLabel, ReadyLabel, NoIconsLabel: TLabel;
DirectX, Icons, NoIconsCheck, Group: TCheckBox;

StatusLabel, FileNameLabel, ExtractFile, StatusInfo: TLabel;
ProgressBar: TNewProgressBar;
CancelCode, n, ArcInd, UnPackError, StartInstall, LastTimerEvent, lastMb, baseMb: Integer;
FreeMB, TotalMB: Cardinal;
WndHookID, TimerID: LongWord;
Arcs, Records: array of TArc;
msgError: string;
Status: TBarInfo;
FreezeTimer: Boolean;
totalUncompressedSize, origsize: Integer; // total uncompressed size of archive data in mb
Texture2, Texture: TBitmapImage;
NeedSize:Integer;
BmpFile: TBitmapImage;

function DetectPage(CurPageID: Integer): TNewNotebookPage;
begin
case CurPageID of
wpWelcome: Result:= WizardForm.WelcomePage;
wpSelectDir: Result:= WizardForm.SelectDirPage;
wpSelectProgramGroup: Result:= WizardForm.SelectProgramGroupPage;
wpSelectTasks: Result:= WizardForm.SelectTasksPage;
wpInstalling: Result:= WizardForm.InstallingPage;
wpFinished: Result:= WizardForm.FinishedPage;
end;
end;

procedure CurStepChanged1(CurStep: TSetupStep);
begin
if CurStep = ssPostInstall then
if Icons.Checked then
CreateShellLink(ExpandConstant('{group}\{#MyAppName}.lnk'), '',
ExpandConstant('{app}\game.exe'), '', ExpandConstant('{app}'), '', 0, SW_SHOWNORMAL);
end;

const
PM_REMOVE = 1;
CP_ACP = 0; CP_UTF8 = 65001;
oneMB=1024*1024;
Period = 250; // частота обновления кнопки таскбара и строки статуса
BackColor = $fcfbfb; EndColor = $d8e9ec; // цвета подобраны для темы Луна
VK_ESCAPE = 27;
HC_ACTION = 0;
WH_CALLWNDPROC = 4;
WM_PAINT = $F;
CancelDuringInstall = {#isFalse(SetupSetting("AllowCancelDuringInstall"))};

ButtonWidth = 80;
ButtonHeight = 23;

bidBack = 0;
bidNext = 1;
bidCancel = 2;
bidDirBrowse = 3;
bidGroupBrowse = 4;

BASS_ACTIVE_PLAYING = 1;
BASS_ACTIVE_STALLED = 2;
BASS_ACTIVE_PAUSED = 3;
BASS_SAMPLE_LOOP = 4;

function WrapFreeArcCallback (callback: TFreeArcCallback; paramcount: integer):longword; external 'wrapcallback@files:innocallback.dll stdcall';
function FreeArcExtract (callback: longword; cmd1,cmd2,cmd3,cmd4,cmd5,cmd6,cmd7,cmd8,cmd9,cmd10: PAnsiChar): integer; external 'FreeArcExtract@files:unarc.dll cdecl';

Function OemToChar(lpszSrc, lpszDst: AnsiString): longint; external 'OemToCharA@user32.dll stdcall';
Function MultiByteToWideChar(CodePage: UINT; dwFlags: DWORD; lpMultiByteStr: PAnsiChar; cbMultiByte: integer; lpWideCharStr: PAnsiChar; cchWideChar: integer): longint; external 'MultiByteToWideChar@kernel32.dll stdcall';
Function WideCharToMultiByte(CodePage: UINT; dwFlags: DWORD; lpWideCharStr: PAnsiChar; cchWideChar: integer; lpMultiByteStr: PAnsiChar; cbMultiByte: integer; lpDefaultChar: integer; lpUsedDefaultChar: integer): longint; external 'WideCharToMultiByte@kernel32.dll stdcall';

function PeekMessage(var lpMsg: TMessage; hWnd: HWND; wMsgFilterMin, wMsgFilterMax, wRemoveMsg: UINT): BOOL; external 'PeekMessageA@user32.dll stdcall';
function TranslateMessage(const lpMsg: TMessage): BOOL; external 'TranslateMessage@user32.dll stdcall';
function DispatchMessage(const lpMsg: TMessage): Longint; external 'DispatchMessageA@user32.dll stdcall';

function GetTickCount: DWord; external 'GetTickCount@kernel32';
function GetWindowLong(hWnd, nIndex: Integer): Longint; external 'GetWindowLongA@user32 stdcall delayload';
function SetWindowText(hWnd: Longint; lpString: String): Longint; external 'SetWindowText{#A}@user32 stdcall delayload';
function GetKeyState(nVirtKey: Integer): ShortInt; external 'GetKeyState@user32 stdcall delayload';
function GetCurrentThreadID: LongWord; external 'GetCurrentThreadId@kernel32 stdcall delayload';
function MulDiv(Number, Numerator, Denominator: Integer): Integer; external 'MulDiv@kernel32 stdcall delayload';

function CallNextWNDPROC(idHook: LongWord; Code: Integer; wParam: Word; lParam: TCWPSTRUCT): LongWord; external 'CallNextHookEx@user32 stdcall delayload';
function SetWindowsHookEx(idHook: LongWord; callback: LongWord; hMod: LongWord; dwThreadID: HWND): LongWord; external 'SetWindowsHookExW@user32 stdcall delayload';
function UnhookWindowsHookEx(idHook: LongWord): LongWord; external 'UnhookWindowsHookEx@user32 stdcall delayload';
function WrapCWPSTRUCTProc(callback:TCWPSTRUCTProc; paramcount:integer): longword; external 'wrapcallback@files:innocallback.dll';
function WrapTimerProc(callback: TTimerProc; Paramcount: Integer): longword; external 'wrapcallback@files:innocallback.dll stdcall';
function SetTimer(hWnd, nIDEvent, uElapse, lpTimerFunc: LongWord): longword; external 'SetTimer@user32';
function KillTimer(hWnd, nIDEvent: LongWord): LongWord; external 'KillTimer@user32 stdcall delayload';


procedure LoadSkin(lpszPath: {#PStr}; lpszIniFileName: {#PStr});
external 'LoadSkin@files:isskin.dll stdcall delayload setuponly';

procedure LoadSkinUninst(lpszPath: {#PStr}; lpszIniFileName: {#PStr});
external 'LoadSkin@{tmp}\isskin.dll stdcall delayload uninstallonly';

procedure UnloadSkin();
external 'UnloadSkin@files:isskin.dll stdcall delayload setuponly';

procedure UnloadSkinUninst();
external 'UnloadSkin@{tmp}\isskin.dll stdcall delayload uninstallonly';

function ShowWindow(hWnd: Integer; uType: Integer): Integer;
external 'ShowWindow@user32.dll stdcall';


function InstallDirectX: Boolean;
begin
Result:= DirectX.Checked;
end;

function CreateIcons: Boolean;
begin
Result:=Icons.Checked;
end;

function GroupIcons: Boolean;
begin
Result:=Group.Checked;
end;

function BackButtonClick(CurPageID: Integer): Boolean;
begin
Result := True;
if CurPageID = wpSelectDir then
ButtonPanel[bidNext].Enabled := True;
end;

procedure DirectXLabelOnClick(Sender: TObject);
begin
if DirectX.Checked = False then
DirectX.Checked:= True else
DirectX.Checked:= False;
end;

procedure IconsOnClick(Sender: TObject);
begin
if Icons.Checked = False then
Icons.Checked:= True else
Icons.Checked:= False;
end;

procedure CheckStartMenuOnClick(Sender: TObject);
begin
if WizardForm.NoIconsCheck.Checked then
begin
WizardForm.GroupEdit.Enabled := not (WizardForm.GroupEdit.Enabled);
WizardForm.GroupBrowseButton.Enabled := False;
ButtonLabel[bidGroupBrowse].Enabled := False;
ButtonPanel[bidGroupBrowse].Enabled := False;
end else
begin
WizardForm.GroupEdit.Enabled := True;
WizardForm.GroupEdit.Enabled := WizardForm.GroupEdit.Enabled;
WizardForm.GroupBrowseButton.Enabled := True;
ButtonLabel[bidGroupBrowse].Enabled := True;
ButtonPanel[bidGroupBrowse].Enabled := True;
end;
end;

procedure CheckNoIconsCheck(Sender: TObject);
begin
if (WizardForm.NoIconsCheck.Checked = False) then
WizardForm.NoIconsCheck.Checked := True
else
WizardForm.NoIconsCheck.Checked := False;
end;


//************************************************ [Начало - Текстуры кнопок] ***************************************************//
procedure ButtonLabelClick(Sender: TObject);
var
Button: TButton;
begin
ButtonImage[TLabel(Sender).Tag].Left := 0;
case TLabel(Sender).Tag of
bidBack: Button := WizardForm.BackButton;
bidNext: Button := WizardForm.NextButton;
bidCancel: Button := WizardForm.CancelButton;
bidDirBrowse: Button := WizardForm.DirBrowseButton;
bidGroupBrowse: Button := WizardForm.GroupBrowseButton;
else
Exit
end
Button.OnClick(Button);
end;

procedure ButtonLabelMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
if ButtonLabel[TLabel(Sender).Tag].Enabled then
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 := 0;
end;

procedure LoadButtonImage(AButton: TButton; AButtonIndex: integer);
var
Image: TBitmapImage;
Panel: TPanel;
Labl: TLabel;

begin
Panel := TPanel.Create(WizardForm);
Panel.Left := AButton.Left;
Panel.Top := AButton.Top;
Panel.Width := AButton.Width;
Panel.Height := AButton.Height;
Panel.Tag := AButtonIndex;
Panel.Parent := AButton.Parent;
ButtonPanel[AButtonIndex] := Panel;

Image := TBitmapImage.Create(WizardForm);
Image.Width := ScaleX(160);
Image.Height := ScaleY(23);
Image.Enabled := False;
Image.Bitmap.LoadFromFile(ExpandConstant('{tmp}\button.bmp'));
Image.Stretch := True;
Image.Parent := Panel;
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);
Labl.Autosize := True;
Labl.Alignment := taCenter;
Labl.Tag := AButtonIndex;
Labl.Transparent := True;
Labl.Font.Color := clWhite;
Labl.Font.Style := [fsBold];
Labl.Caption := AButton.Caption;
Labl.OnClick := @ButtonLabelClick;
Labl.OnDblClick := @ButtonLabelClick;
Labl.OnMouseDown := @ButtonLabelMouseDown;
Labl.OnMouseUp := @ButtonLabelMouseUp;
Labl.Parent := Panel;
ButtonLabel[AButtonIndex] := Labl;
end;

procedure UpdateButton(AButton: TButton;AButtonIndex: integer);
begin
ButtonLabel[AButtonIndex].Caption := AButton.Caption;
ButtonPanel[AButtonIndex].Visible := AButton.Visible;
ButtonLabel[AButtonIndex].Enabled := Abutton.Enabled;
end;
//************************************************ [Конец - Текстуры кнопок] ***************************************************//

//************************************************ [Начало - Музыка] ***************************************************//
function BASS_Init(device: Integer; freq, flags: DWORD; win: hwnd; CLSID: Integer): Boolean;
external 'BASS_Init@files:BASS.dll stdcall delayload';

function BASS_StreamCreateFile(mem: BOOL; f: PChar; offset: DWORD; length: DWORD; flags: DWORD): DWORD;
external 'BASS_StreamCreateFile@files:BASS.dll stdcall delayload';

function BASS_Start(): Boolean;
external 'BASS_Start@files:BASS.dll stdcall delayload';

function BASS_ChannelPlay(handle: DWORD; restart: BOOL): Boolean;
external 'BASS_ChannelPlay@files:BASS.dll stdcall delayload';

function BASS_ChannelIsActive(handle: DWORD): Integer;
external 'BASS_ChannelIsActive@files:BASS.dll stdcall delayload';

function BASS_ChannelPause(handle: DWORD): Boolean;
external 'BASS_ChannelPause@files:BASS.dll stdcall delayload';

function BASS_Pause(): Boolean;
external 'BASS_Pause@files:BASS.dll stdcall delayload';

function BASS_Free(): Boolean;
external 'BASS_Free@files:BASS.dll stdcall delayload';

procedure PlayMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
PlayImage.Left := -100
end;

procedure PlayMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
PlayImage.Left := 4
end;

procedure PlayMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
if PlayImage.Left <> 100 then PlayImage.Left := -196
end;

procedure PauseMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
PauseImage.Left := -132
end;

procedure PauseMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
PauseImage.Left := -36
end;

procedure PauseMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
if PauseImage.Left <> -132 then PauseImage.Left := -228
end;

procedure MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
PlayImage.Left := -4
PauseImage.Left := 36
end;

procedure PlayButtonOnClick(Sender: TObject);
begin
case BASS_ChannelIsActive(mp3Handle) of
BASS_ACTIVE_PAUSED:
begin
BASS_ChannelPlay(mp3Handle, False);
PlayButton.Hide
PauseButton.Show
end;
end;
end;

procedure PauseButtonOnClick(Sender: TObject);
begin
BASS_ChannelPause(mp3Handle);
PauseButton.Hide
PlayButton.Show
end;
//************************************************ [Конец - Музыка] ***************************************************//


procedure AppProcessMessage;
var
Msg: TMessage;
begin
if not PeekMessage(Msg, {WizardForm.Handle} 0, 0, 0, PM_REMOVE) then Exit;
TranslateMessage(Msg); DispatchMessage(Msg);
end;

Function FreeArcCmd(callback: longword; cmd1,cmd2,cmd3,cmd4,cmd5,cmd6,cmd7,cmd8,cmd9,cmd10: PAnsiChar): integer;
Begin
CancelCode:= 0; AppProcessMessage;
try
Result:= FreeArcExtract(callback, cmd1,cmd2,cmd3,cmd4,cmd5,cmd6,cmd7,cmd8,cmd9,cmd10); // Pass the specified arguments to 'unarc.dll'
if CancelCode < 0 then Result:= CancelCode;
except
Result:= -63; // ArcFail
end;
End;

// Sets the TaskBar title
Procedure SetTaskBarTitle(Title: String); var h: Integer;
Begin
h:= GetWindowLong(MainForm.Handle, -8); if h <> 0 then SetWindowText(h, Title);
End;

// Перевод числа в строку с точностью 2 знака (%.2n) с округлением дробной части, если она есть
Function NumToStr(Float: Extended): String;
Begin
Result:= Format('%.2n', [Float]); StringChange(Result, ',', '.');
while ((Result[Length(Result)] = '0') or (Result[Length(Result)] = '.')) and (Pos('.', Result) > 0) do
SetLength(Result, Length(Result)-1);
End;

Function ByteOrTB(Bytes: Extended; noMB: Boolean): String; {Перевод числа в значение бт/Кб/Мб/Гб/Тб (до 2х знаков после запятой)}
Begin
if not noMB then Result:= NumToStr(Int(Bytes)) +' Mb' else
if Bytes < 1024 then if Bytes = 0 then Result:= '0' else Result:= NumToStr(Int(Bytes)) +' Bt' else
if Bytes/1024 < 1024 then Result:= NumToStr(round((Bytes/1024)*10)/10) +' Kb' else
If Bytes/oneMB < 1024 then Result:= NumToStr(round(Bytes/oneMB*100)/100) +' Mb' else
If Bytes/oneMB/1000 < 1024 then Result:= NumToStr(round(Bytes/oneMB/1024*1000)/1000) +' Gb' else
Result:= NumToStr(round(Bytes/oneMB/oneMB*1000)/1000) +' Tb';
End;

Function StringToArray(Text, Cut: String): array of String; var i, k: Integer; // поместить строки текста в элементы массив. шаблон перевода строк может быть любым. шаблон в начале/конце текста игнорируются
Begin
SetArrayLength(Result, 0); if Cut = '' then Cut:= #1310; //если шаблон пуст, считаем переводы строк
Repeat k:= Pos(Cut,Text);
if k = 1 then begin Delete(Text, 1, Length(Cut)); CONTINUE
end;
SetArrayLength(Result, GetArrayLength(Result) +1); i:= GetArrayLength(Result) -1;
if k = 0 then
Result[i]:=Text
else begin
Result[i]:= Copy(Text, 1, k -1); Delete(Text, 1, Length(Result[i]) + Length(Cut));
end;
Until Length(Text) * k = 0;
End;

Function CreateLabel(Parent: TWinControl; AutoSize, WordWrap, Transparent: Boolean; FontName: String; FontStyle: TFontStyles; FontColor: TColor; Left, Top, Width, Height: Integer; Prefs: TObject): TLabel;
Begin
Result:=TLabel.Create(Parent); Result.parent:= Parent;
if Prefs <> Nil then begin
Top:= TWinControl(Prefs).Top; Left:= TWinControl(Prefs).Left; Width:= TWinControl(Prefs).Width; Height:= TWinControl(Prefs).Height;
end;
if Top > 0 then result.Top:=Top; if Left > 0 then result.Left:= Left; if Width > 0 then result.Width:= Width; if Height > 0 then result.Height:= Height;
if FontName <> '' then result.Font.Name:= FontName; if FontColor > 0 then result.Font.Color:= FontColor; if FontStyle <> [] then result.Font.Style:= FontStyle;
result.AutoSize:= AutoSize; result.WordWrap:= WordWrap; result.Transparent:=Transparent; result.ShowHint:= true;
End;

// Converts milliseconds to human-readable time
// Конвертирует милисекунды в человеко-читаемое изображение времени
Function TicksToTime(Ticks: DWord; h,m,s: String; detail: Boolean): String;
Begin
if detail then {hh:mm:ss format}
Result:= PADZ(IntToStr(Ticks/3600000), 2) +':'+ PADZ(IntToStr((Ticks/1000 - Ticks/1000/3600*3600)/60), 2) +':'+ PADZ(IntToStr(Ticks/1000 - Ticks/1000/60*60), 2)
else if Ticks/3600 >= 1000 then {more than hour}
Result:= IntToStr(Ticks/3600000) +h+' '+ PADZ(IntToStr((Ticks/1000 - Ticks/1000/3600*3600)/60), 2) +m
else if Ticks/60 >= 1000 then {1..60 minutes}
Result:= IntToStr(Ticks/60000) +m+' '+ IntToStr(Ticks/1000 - Ticks/1000/60*60) +s
else Result:= Format('%.1n', [Abs(Ticks/1000)]) +s {less than one minute}
End;

Function ExpandENV(string: String): String; var n: UINT; Begin // ExpandConstant + развёртывание DOS-переменных типа %SystemRoot%
if Pos('{',string) * Pos('}',string) = 0 then Result:= String else Result:= ExpandConstant(String); n:= Pos('%',result); if n = 0 then Exit;
Delete(result, n,1); Result:= Copy(Result,1, n-1) + ExpandConstant('{%'+Copy(Result, n, Pos('%',result) -n) +'}') + Copy(Result, Pos('%',result) +1, Length(result))
End;

Function cm(Message: String): String; Begin Result:= ExpandConstant('{cm:'+ Message +'}') End;
Function LoWord(lw: LongWord): LongWord; Begin Result:= lw shr 16; End;

Function Size64(Hi, Lo: Integer): Extended;
Begin
Result:= Lo;
if Lo<0 then Result:= Result + $7FFFFFFF + $7FFFFFFF + 2;
for Hi:= Hi-1 Downto 0 do
Result:= Result + $7FFFFFFF + $7FFFFFFF + 2;
End;

Function RGB(r, g, b: Longint): Longint; Begin Result:= (r or (g shl 8) or (b shl 16)) End;
Function GetBValue(rgb: DWord): Byte; Begin Result:= Byte(rgb shr 16) End;
Function GetGValue(rgb: DWord): Byte; Begin Result:= Byte(rgb shr 8) End;
Function GetRValue(rgb: DWord): Byte; Begin Result:= Byte(rgb) End;

Procedure GradientFill(WorkBmp: TBitmapImage; BeginColor, FinishColor: Integer); var ColorBand: TRect; StartColor, i: Integer; Begin {если BeginColor < 0, то градиент горизонтальный}
WorkBmp.Bitmap.Width:= WorkBmp.Width; WorkBmp.Bitmap.Height:= WorkBmp.Height; StartColor:= trunc(Abs(BeginColor))
if BeginColor < 0 then n:= WorkBmp.Width else n:= WorkBmp.Height;
for i:=0 to n do begin if BeginColor < 0 then begin
ColorBand.Top:= 0; ColorBand.Bottom:= WorkBmp.Height;
ColorBand.Left:= MulDiv(i, WorkBmp.Width, n); ColorBand.Right:= MulDiv(i+1, WorkBmp.Width, n);
end else begin
ColorBand.Top:= MulDiv(i, WorkBmp.Height, n); ColorBand.Bottom:= MulDiv(i+1, WorkBmp.Height, n);
ColorBand.Left:= 0; ColorBand.Right:= WorkBmp.Width; end;
WorkBmp.Bitmap.Canvas.Brush.Color:= RGB(GetRValue(StartColor) + MulDiv(I, GetRValue(FinishColor) - GetRValue(StartColor), n-1), GetGValue(StartColor) + MulDiv(I, GetGValue(FinishColor) - GetGValue(StartColor), n-1), GetBValue(StartColor) + MulDiv(I, GetBValue(FinishColor) - GetBValue(StartColor), n-1));
WorkBmp.Bitmap.Canvas.FillRect(ColorBand); end;
End;

// Converts OEM encoded string into ANSI (Преобразует OEM строку в ANSI кодировку)
function OemToAnsiStr(strSource: AnsiString): AnsiString;
var
nRet : longint;
begin
SetLength(Result, Length(strSource));
nRet:= OemToChar(strSource, Result);
end;

// Converts ANSI encoded string into UTF-8 (Преобразует строку из ANSI в UTF-8 кодировку)
function AnsiToUtf8(strSource: string): string;
var
nRet, nRet2: integer; WideCharBuf, MultiByteBuf: AnsiString;
begin
SetLength(WideCharBuf, Length(strSource) * 2);
SetLength(MultiByteBuf, Length(strSource) * 2);
nRet:= MultiByteToWideChar(CP_ACP, 0, strSource, -1, WideCharBuf, Length(WideCharBuf));
nRet2:= WideCharToMultiByte(CP_UTF8, 0, WideCharBuf, -1, MultiByteBuf, Length(MultiByteBuf), 0, 0);
if nRet * nRet2 = 0 then Result:= strSource else Result:= MultiByteBuf;
end;

// ArcInd - текущий архив, счёт с 0
// baseMb - записано из пред. архива на диск
// lastMb - извлечено из тек. архива на диск
// Status.mb - позиция в текущем архиве
// Status.allsize - объём всех архивов
// Status.size - всего извлечено Мб на текущий момент
// totalUncompressedSize - точный объём данных в архивах
// общий прогресс нарастает по мере записи данных из архива на диск (точка 'write')
// прогресс архивов двигается в соответствии с позицией в текущем архиве (точка 'read')

Procedure UpdateStatus(Flags: Integer); // выполняется с периодичностью, заданной константой Period
var
Remaining: Integer; i, t, s: string;
Begin
if Flags and $1 > 0 then FreezeTimer:= Flags and $2 = 0; // bit 0 = 1 change start/stop, bit 1 = 0 stop, bit 1 = 1 start
if (Flags and $4 > 0) or (Status.size <> baseMb+lastMb) then LastTimerEvent:= 0; // bit 2 = 1 UpdateNow // обновить по флагу или записи из архива на диск
if FreezeTimer or (GetTickCount - LastTimerEvent <= Period) then Exit else LastTimerEvent:= GetTickCount;
Status.size := baseMb+lastMb; // извлечено на текущий момент
if totalUncompressedSize > 0 then with WizardForm.ProgressGauge do begin // основной прогресс движется по мере записи данных на диск
Position:= round(Max * Status.size/totalUncompressedSize)
end;
with WizardForm.ProgressGauge do begin // оставшееся время
#ifndef precomp
// к сожалению, этот код иногда сбоит на очень больших архивах, созданных с использованием внешних упаковщиков
if position > 0 then Remaining:= trunc((GetTickCount - StartInstall) * Abs((max - position)/position)) else
#endif
Remaining:= 0;
t:= cm('ending'); i:= t;
if Remaining > 0 then begin
t:= FmtMessage(cm('taskbar'), [IntToStr(Status.perc/10), TicksToTime(Remaining, 'h', 'm', 's', false)])
i:= TicksToTime(Remaining, cm('hour'), cm('min'), cm('sec'), false)
end;
end;
SetTaskBarTitle(t); // проценты и оставшееся время на кнопке инсталлятора
if Status.size > 0 then
s:= ' ['+ ByteOrTB(Status.size*oneMB, true) +']'; // если сделать подсчёт размера папки {app} через CalcDirSize, то при частом пересчёте папки большого объёма это может замедлить работу
StatusInfo.Caption:= FmtMessage(cm('StatusInfo'), [IntToStr(Status.count +ord(Status.count < 0)), s, Format('%.1n', [Abs(Status.perc/10)]), i]);
// второй прогрессбар движется по мере считывания текущего архива
if (Status.stage = cm('ArcTitle')) and (GetArrayLength(Arcs) > 0) then begin
ExtractFile.Caption:= FmtMessage(cm('ArcInfo'), [IntToStr(ArcInd+1), IntToStr(GetArrayLength(Arcs)), ByteOrTB(Arcs[ArcInd].Size, true), Format('%.0n', [Status.mb/(Arcs[ArcInd].Size/oneMB)*100]), ByteOrTB(Status.allsize, true)])
ProgressBar.Position:= round(ProgressBar.Max * Status.mb/trunc(Arcs[ArcInd].Size/oneMB))
end;
End;

Procedure MyTimerProc(h, msg, idevent, dwTime: Longword);
Begin
if WizardForm.CurPageID = wpInstalling then UpdateStatus(0);
End;

Procedure OnWndHook(Code: Integer; wParam: Word; lParam: TCWPSTRUCT);
Begin
if (Code = HC_ACTION) and (LoWord(lParam.msg) = WM_PAINT) then begin // подготовка данных для последующего отображения по таймеру
if (Status.name <> WizardForm.FileNameLabel.Caption) and (WizardForm.FileNameLabel.Caption <> '') then begin // имя файла, названия ярлыка и прочее
FileNameLabel.Caption:= WizardForm.FileNameLabel.Caption;
Status.name:= WizardForm.FileNameLabel.Caption; // начало извлечения или распаковки очередного файла
Case Status.stage of
SetupMessage(msgStatusExtractFiles): // этап извлечения файлов инсталлятором
Status.count:= Status.count +1; // кол-во файлов
End;
end;
if (Status.stage <> WizardForm.StatusLabel.Caption) and (WizardForm.StatusLabel.Caption <> '') then begin
StatusLabel.Caption:= WizardForm.StatusLabel.Caption;
Status.stage:= WizardForm.StatusLabel.Caption; // текущий этап установки
if Status.stage = SetupMessage(msgStatusRollback) then begin
WizardForm.StatusLabel.Hide; WizardForm.FileNameLabel.Hide; StatusInfo.Hide; ExtractFile.Hide; ProgressBar.Hide;
end;
end;
with WizardForm.ProgressGauge do begin
n:= (Max - Min)/1000
if n > 0 then Status.perc:= (Position-Min)/n; // 1000 процентов
end;
UpdateStatus(0);
end;
CallNextWNDPROC(WndHookID, Code, wParam, lParam) {освобождение события}
End;

// compsize: в Mb объём архива
// total_files: в int2 ? число файлов в архиве
// origsize: в Mb общий объём данных в архиве
// write: в Mb число записанных (распакованных из архива) на диск мегабайт
// read: в Mb число обработанных мегабайт, в int2 размер текущего архива
// filename: вызывается перед обработкой каждого файла

// The main callback function for unpacking FreeArc archives
function FreeArcCallback(what: PAnsiChar; Mb, int2: Integer; str: PAnsiChar): Integer; // вызывается не менее 100 раз в секунду, что заменяет вызов по таймеру
begin
case string(what) of
'origsize': origsize:= Mb; // данных в тек. архиве (при распаковке не вызывается)
'total_files': Null;
'filename': begin // Update FileName label
WizardForm.FileNameLabel.Caption:= OemToAnsiStr(str); // извлекаемый файл, их имена пишутся в журнал установки
FileNameLabel.Caption:= OemToAnsiStr(str); // извлекаемый файл, их имена пишутся в журнал установки
Status.count:= Status.count + 1; // кол-во файлов, этап распаковки
end;
'read': // позиция в текущем архиве
Status.mb:= Mb;
'write': // Assign to Mb *total* amount of data extracted to the moment from all archives
lastMb:= Mb; // извлечено из текущего архива
end;
if WizardForm.CurPageID = wpInstalling then UpdateStatus(0); // обновить страницу установки, не сбрасывая таймер
if (GetKeyState(VK_ESCAPE) < 0) and not CancelDuringInstall then
WizardForm.Close; // опрашиваем Cancel (если разрешена отмена установки)
AppProcessMessage;
Result:= CancelCode;
end;

Function ArcDecode(Line: string): array of TArc; // разбор строки Archives
var tmp, cut: array of String; n, i: integer;
Begin
SetArrayLength(result,0); if Line <> '' then tmp:= StringToArray(Line,'|') else Exit;
for n:= 0 to GetArrayLength(tmp) - 1 do begin
if tmp[n][Length(tmp[n])] = '?' then Continue; // эта запись обрабатывается в AfterInstall: UnArc(...)
SetArrayLength(result, GetArrayLength(result) +1); i:= GetArrayLength(result) -1;
cut:= StringToArray(tmp[n],'>') // задачи, логика or and not наверное не будет работать
if GetArrayLength(cut) > 1 then result[i].task:= cut[1];
cut:= StringToArray(cut[0],'<') // компоненты
if GetArrayLength(cut) > 1 then result[i].comp:= cut[1];
cut:= StringToArray(cut[0],'/') // папка распаковки
if GetArrayLength(cut) > 1 then result[i].Dest:= cut[1] else result[i].Dest:= '{app}'; // по-умолчанию
if (ExtractFileDrive(ExpandENV(cut[0])) = '') and (ExpandENV(cut[0]) = cut[0]) then // строка вида Rus\*.arc
result[i].Path:= '{src}\'+ cut[0] else result[i].Path:= cut[0]; // остаток от исходной строки
result[i].Dest:= ExpandENV(result[i].Dest); result[i].Path:= ExpandENV(result[i].Path);
end;
End;

// Scans the specified folders for archives and add them to list
function AddArcs(files, target: string): Integer; // добавление архивов в общий список и подсчёт объёма распакованных данных
var FSR: TFindRec; i: integer;
Begin
Result:= 0; if FindFirst(ExpandENV(files), FSR) then
try
repeat
// Skip everything but the folders
if FSR.Attributes and FILE_ATTRIBUTE_DIRECTORY > 0 then CONTINUE;
// Expand the folder list
i:= GetArrayLength(Arcs); SetArrayLength(Arcs, i +1);
Arcs[i].Dest:= target; // путь распаковки для найденных по маске архивов
Arcs[i].Path:= ExtractFilePath(ExpandENV(files)) + FSR.Name;
Arcs[i].Size:= Size64(FSR.SizeHigh, FSR.SizeLow);
Status.allsize:= Status.allsize + Arcs[i].Size; // зарезервировано для подсчёта прогресса распаковки 7-zip архивов (is7z.dll)
Arcs[i].allMb:= FreeArcCmd(WrapFreeArcCallback(@FreeArcCallback,4),'l','--',AnsiToUtf8(Arcs[i].Path),'','','','','','',''); // код ошибки
if Arcs[i].allMb >= 0 then begin
Arcs[i].allMb:= origsize; result:= result + Arcs[i].allMb; // размер распакованных данных успешно считан
end;
until not FindNext(FSR);
finally
FindClose(FSR);
end;
End;

function UnPackArchive(Source, Destination: string; allMb, Mode: Integer): Integer;
var
callback: longword;
Begin
// если отмена установки разрешена, кнопка Cancel станет доступна
WizardForm.CancelButton.Enabled:= not CancelDuringInstall;
callback:= WrapFreeArcCallback(@FreeArcCallback,4); //FreeArcCallback has 4 arguments
Result:= FreeArcCmd(callback,'x','-o+','-dp'+AnsiToUtf8(Destination),'--',AnsiToUtf8(Source),'','','','',''); // код ошибки
// Error occured
if Result = 0 then Exit;
msgError:= FmtMessage(cm('ArcError'), [IntToStr(Result)]);
WizardForm.StatusLabel.Caption:= msgError;
WizardForm.FileNameLabel.Caption:= ExtractFileName(Source);
GetSpaceOnDisk(ExtractFileDrive(Destination), True, FreeMB, TotalMB);
case Result of
-1: if FreeMB < allMb {Мб на диске} then msgError:= SetupMessage(msgDiskSpaceWarningTitle)
else msgError:= msgError + #13#10 + FmtMessage(cm('ArcBroken'), [ExtractFileName(Source)]);
-127: msgError:= cm('ArcBreak'); //Cancel button
-63: msgError:= cm('ArcFail');
end;
Log(msgError); // записываем ошибку в лог, а также показываем её текст на странице завершения
End;

// Extracts all found archives
function UnPack(Archives: string): Integer;
begin
// UpdateStatus(1); // остановить таймер
Records:= ArcDecode(Archives); SetArrayLength(Arcs,0); Status.allsize:= 0; {общий объём}
for n:= 0 to GetArrayLength(Records) -1 do // Get the size of all archives
if (not IsTaskSelected(Records[n].task) and (Records[n].task <>'')) and (not IsComponentSelected(Records[n].comp) and (Records[n].comp <>'')) then Continue // компоненты и задачи не выбраны
else totalUncompressedSize:= totalUncompressedSize + AddArcs(Records[n].Path, Records[n].Dest); // создаём список архивов
// Other initializations
WizardForm.StatusLabel.Caption:= cm('ArcTitle'); // начало этапa распаковки
ExtractFile.Show; ProgressBar.Show;
baseMb:= 0; lastMb:= 0; Status.mb:= 0; // обнулить полученные мегабайты, если ранее вёлся подсчёт объёма файлов инсталлятора
Status.count:= 0; // не учитывать файлы, извлечённые инсталлятором
UpdateStatus(7); // немедленно обновить строку статуса
for ArcInd:= 0 to GetArrayLength(Arcs) -1 do begin // архивы в текущей папке, константы раскрыты в ArcDecode
Result:= UnPackArchive(Arcs[ArcInd].Path, Arcs[ArcInd].Dest, Arcs[ArcInd].allMb, 0); // код ошибки
if Result <> 0 then Break; // прервать цикл распаковки
baseMb:= baseMb + lastMb; lastMb:= 0; Status.mb:= 0; // общий объём распакованных файлов
// отработанный архив автоматически удаляется, если находится в папке {app} или {tmp}
if (Pos(AnsiLowercase(ExpandConstant('{app}')), AnsiLowercase(Arcs[ArcInd].Path)) > 0) or (Pos(AnsiLowercase(ExpandConstant('{tmp}')), AnsiLowercase(Arcs[ArcInd].Path)) > 0) then
DeleteFile(Arcs[ArcInd].Path);
end;
if Result = 0 then WizardForm.StatusLabel.Caption:= FmtMessage(cm('ArcFinish'), [IntToStr(GetArrayLength(Arcs)), IntToStr(Status.count), ByteOrTB(Status.size*oneMB, true)]);
StatusInfo.Hide; ExtractFile.Hide; ProgressBar.Hide;
end;

procedure CurStepChanged2(CurStep: TSetupStep);
begin
if CurStep = ssInstall then begin
StartInstall:= GetTickCount {время начала извлечения файлов}
WndHookID:= SetWindowsHookEx(WH_CALLWNDPROC, WrapCWPSTRUCTProc(@OnWndHook, 3), 0, GetCurrentThreadID); {установка SendMessage хука}
TimerID:= SetTimer(0, 0, 500 {полсекунды}, WrapTimerProc(@MyTimerProc, 4)); {установка таймера}
if not {#isFalse(SetupSetting("Uninstallable"))} then Status.count:= -1; // не считать файл unins000.exe
end;
if CurStep = ssPostInstall then
begin
StartInstall:= GetTickCount {время начала распаковки}
UnPackError:= UnPack('{#Archives}')
if UnPackError <> 0 then begin // Error occured, uninstall it then
if not {#isFalse(SetupSetting("Uninstallable"))} then // деинсталляция разрешёна
Exec(ExpandConstant('{uninstallexe}'), '/SILENT','', sw_Hide, ewWaitUntilTerminated, n); // откат установки из-за ошибки unarc.dll
WizardForm.caption:= SetupMessage(msgErrorTitle) +' - '+ cm('ArcBreak')
SetTaskBarTitle(SetupMessage(msgErrorTitle))
end else
SetTaskBarTitle(SetupMessage(msgSetupAppTitle));
end;
end;

Procedure SetTexture(CurPageID: Integer); // на каждой странице своя картинка
Begin
WizardForm.Bevel1.Visible:= (WizardForm.CurPageID <> wpWelcome) and (WizardForm.CurPageID <> wpFinished);
WizardForm.Bevel1.Parent:= WizardForm.OuterNotebook.ActivePage
Texture.Parent:= WizardForm.InnerNotebook.ActivePage; Texture.SendToBack;
Texture.Visible:= CurPageID = wpInstalling; Texture2.Visible:= Texture.Visible;
End;

Procedure CurPageChanged1(CurPageID: Integer);
Begin
UpdateButton(WizardForm.BackButton,bidBack)
UpdateButton(WizardForm.NextButton,bidNext)
UpdateButton(WizardForm.CancelButton,bidCancel)

ButtonLabel[bidBack].Left := ButtonPanel[bidBack].Width div 2 - ButtonLabel[bidBack].Width div 2;
ButtonLabel[bidBack].Top := ButtonPanel[bidBack].Height div 2 - ButtonLabel[bidBack].Height div 2;
ButtonLabel[bidNext].Left := ButtonPanel[bidNext].Width div 2 - ButtonLabel[bidNext].Width div 2;
ButtonLabel[bidNext].Top := ButtonPanel[bidNext].Height div 2 - ButtonLabel[bidNext].Height div 2;
ButtonLabel[bidCancel].Left := ButtonPanel[bidCancel].Width div 2 - ButtonLabel[bidCancel].Width div 2;
ButtonLabel[bidCancel].Top := ButtonPanel[bidCancel].Height div 2 - ButtonLabel[bidCancel].Height div 2;
ButtonLabel[bidDirBrowse].Left := ButtonPanel[bidDirBrowse].Width div 2 - ButtonLabel[bidDirBrowse].Width div 2;
ButtonLabel[bidDirBrowse].Top := ButtonPanel[bidDirBrowse].Height div 2 - ButtonLabel[bidDirBrowse].Height div 2;
ButtonLabel[bidGroupBrowse].Left := ButtonPanel[bidGroupBrowse].Width div 2 - ButtonLabel[bidGroupBrowse].Width div 2;
ButtonLabel[bidGroupBrowse].Top := ButtonPanel[bidGroupBrowse].Height div 2 - ButtonLabel[bidGroupBrowse].Height div 2;

PageNameLabel1.Caption:= WizardForm.PageNameLabel.Caption;
PageDescriptionLabel1.Caption:= WizardForm.PageDescriptionLabel.Caption;
PageNameLabel2.Caption:= WizardForm.PageNameLabel.Caption;
PageDescriptionLabel2.Caption:= WizardForm.PageDescriptionLabel.Caption;
PageNameLabel3.Caption:= WizardForm.PageNameLabel.Caption;

if CurPageID=wpSelectProgramGroup then
begin
If WizardForm.FindComponent('NextButton') is TButton
then
TButton(WizardForm.FindComponent('NextButton')).Caption:='Установить';
SetTexture(CurPageID)

if (CurPageID = wpFinished) and (UnPackError <> 0) then
begin // Extraction was unsuccessful (распаковщик вернул ошибку)
// Show error message
WizardForm.FinishedLabel.Font.Color:= $0000C0; // red (красный)
WizardForm.FinishedLabel.Height:= WizardForm.FinishedLabel.Height * 2;
WizardForm.FinishedLabel.Caption:= SetupMessage(msgSetupAborted) + #13#10#13#10 + msgError;
end;
End;
End;

procedure WizardClose(Sender: TObject; var Action: TCloseAction);
Begin
Action:= caNone; // так надо
if Status.stage = cm('ArcTitle') then begin // распаковка на этапе ssPostInstall
UpdateStatus(1); // остановить таймер
if MsgBox(SetupMessage(msgExitSetupMessage), mbInformation, MB_YESNO) = IDYES then
CancelCode:= -127; // прервать распаковку
UpdateStatus(7); // обновить информацию
end else
MainForm.Close; // стандартное нажатие кнопки закрытия окна, отмены или Escape.
End;

procedure GetFreeSpaceCaption(Sender: TObject);
var
Path: String;
begin
Path := ExtractFileDrive(WizardForm.DirEdit.Text);
GetSpaceOnDisk(Path, True, FreeMB, TotalMB);
if FreeMB > 1024 then
FreeSpaceLabel.Caption := ExpandConstant('{cm:SPACE} ')+ NumToStr(round(FreeMB/1024*100)/100) + ' GB' else
FreeSpaceLabel.Caption := ExpandConstant('{cm:SPACE} ')+ NumToStr(FreeMB)+ ' MB';
end;

procedure GetNeedSpaceCaption;
begin
if NeedSize > 1024 then
NeedSpaceLabel.Caption := ExpandConstant('{cm:SPACE1} ')+ NumToStr(round(NeedSize/1024*100)/100) + ' GB' else
NeedSpaceLabel.Caption := ExpandConstant('{cm:SPACE1} ')+ NumToStr(NeedSize)+ ' MB';
end;

procedure ProgressExt();
begin
FilenameLabel.Caption:= ExpandConstant(ExtractFileDir(CurrentFilename)) + '\' + ExtractFilename(CurrentFilename);
end;

procedure ProgressExt2();
begin
FilenameLabel.Caption:= ExpandConstant('{cm:DirectXInstall}')
end;

Procedure InitializeWizard();
Var
CurPageID: Integer;
Begin
ExtractTemporaryFile('MusicButton.bmp')
ExtractTemporaryFile('1.bmp');
ExtractTemporaryFile('2.bmp');
ExtractTemporaryFile('3.bmp');
ExtractTemporaryFile('4.bmp');
ExtractTemporaryFile('5.bmp');

NeedSize:= {#NeedSize};

BmpFile:= TBitmapImage.Create(WizardForm);
BmpFile.Bitmap.LoadFromFile(ExpandConstant('{tmp}\1.bmp'));
BmpFile.Top:= ScaleY(0);
BmpFile.Left:= ScaleX(0);
BmpFile.Width:= ScaleX(790);
BmpFile.Height:= ScaleY(533);
BmpFile.Stretch:= true;
BmpFile.Parent:= WizardForm.WelcomePage;

BmpFile:= TBitmapImage.Create(WizardForm);
BmpFile.Bitmap.LoadFromFile(ExpandConstant('{tmp}\2.bmp'));
BmpFile.Top:= ScaleY(0);
BmpFile.Left:= ScaleX(0);
BmpFile.Width:= ScaleX(790);
BmpFile.Height:= ScaleY(533);
BmpFile.Stretch:= true;
BmpFile.Parent:= WizardForm.SelectDirPage;

BmpFile:= TBitmapImage.Create(WizardForm);
BmpFile.Bitmap.LoadFromFile(ExpandConstant('{tmp}\3.bmp'));
BmpFile.Top:= ScaleY(0);
BmpFile.Left:= ScaleX(0);
BmpFile.Width:= ScaleX(790);
BmpFile.Height:= ScaleY(533);
BmpFile.Stretch:= true;
BmpFile.Parent:= WizardForm.SelectProgramGroupPage;

BmpFile:= TBitmapImage.Create(WizardForm);
BmpFile.Bitmap.LoadFromFile(ExpandConstant('{tmp}\4.bmp'));
BmpFile.Top:= ScaleY(0);
BmpFile.Left:= ScaleX(0);
BmpFile.Width:= ScaleX(790);
BmpFile.Height:= ScaleY(533);
BmpFile.Stretch:= true;
BmpFile.Parent:= WizardForm.InstallingPage;

BmpFile:= TBitmapImage.Create(WizardForm);
BmpFile.Bitmap.LoadFromFile(ExpandConstant('{tmp}\5.bmp'));
BmpFile.Top:= ScaleY(0);
BmpFile.Left:= ScaleX(0);
BmpFile.Width:= ScaleX(790);
BmpFile.Height:= ScaleY(533);
BmpFile.Stretch:= true
BmpFile.Parent:= WizardForm.FinishedPage;

WizardForm.ClientWidth:=ScaleX(790);
WizardForm.ClientHeight:=ScaleY(533);
WizardForm.Font.Color:=$ffffff;
WizardForm.Center;

with WizardForm do
begin
PageNameLabel.Hide;
PageDescriptionLabel.Hide;
WelcomeLabel1.Hide;
WelcomeLabel2.Hide;
DiskSpaceLabel.Hide;
SelectDirBitmapImage.Hide;
SelectDirBrowseLabel.Hide;
SelectDirLabel.Hide;
FinishedHeadingLabel.Hide;
FinishedLabel.Hide;
MainPanel.Hide;
FilenameLabel.Hide;
StatusLabel.Hide;
SelectStartMenuFolderLabel.Hide;
SelectStartMenuFolderBrowseLabel.Hide;
ReadyLabel.Hide;
end;

with WizardForm do
begin
InnerNotebook.Left := ScaleX(0);
InnerNotebook.Top := ScaleY(0);
InnerNotebook.Width := ScaleX(790);
InnerNotebook.Height := ScaleY(533);
OuterNotebook.Left := ScaleX(0);
OuterNotebook.Top := ScaleY(0);
OuterNotebook.Width := ScaleX(790);
OuterNotebook.Height := ScaleY(533);
end;

////////////////////// WelcomePage //////////////////////

WelcomeLabel1:= TLabel.Create(WizardForm);
with WelcomeLabel1 do
begin
Left:= ScaleX(70);
Top:= ScaleY(180);
Width:= ScaleX(650);
Height:= ScaleY(65);
AutoSize:= false;
Alignment := taCenter;
Transparent:= true;
WordWrap:= true;
Font.Name:='Georgia';
Font.Size:= 16;
Font.Color:=ClWhite;
Font.Style := [fsBold];
Parent:= WizardForm.WelcomePage;
Caption:= ExpandConstant('{cm:Welcome1}')+#13+('{#MyAppName}');
end;

WelcomeLabel2:=TLabel.Create(WizardForm);
with WelcomeLabel2 do
begin
Top:= ScaleY(270);
Left:= ScaleX(70);
Width:= ScaleX(650);
Height:= ScaleY(200);
AutoSize:= false;
WordWrap:= true;
Font.Name:= 'Georgia';
Font.Size:= 11
Font.Style := [fsBold, fsItalic];
Font.Color:=ClWhite;
Transparent:= true;
Parent:= WizardForm.WelcomePage;
Caption:= ExpandConstant('{cm:Welcome2}');
end;

////////////////////// WelcomePage //////////////////////

////////////////////// SelectDirPage //////////////////////

PageNameLabel1:= TLabel.Create(WizardForm);
with PageNameLabel1 do
begin
Left:= ScaleX(65);
Top:= ScaleY(185);
Width:= ScaleX(300);
Height:= ScaleY(30);
AutoSize:= False;
Font.Name:= 'Georgia'
Font.Size:= 13;
Font.Style:= [fsBold];
Font.Color:= ClWhite;
Transparent := True;
Parent:= WizardForm.SelectDirPage;
end;

PageDescriptionLabel1:= TLabel.Create(WizardForm);
with PageDescriptionLabel1 do
begin
Left:=ScaleX(95);
Top:= ScaleY(215);
Width:= ScaleX(600);
Height:= ScaleY(50);
AutoSize:= False;
Font.Name:= 'Georgia'
Font.Size:= 10;
Font.Style:= [fsBold, fsItalic];
Font.Color:= ClWhite;
Wordwrap:= True;
Transparent := True;
Parent:= WizardForm.SelectDirPage;
end;

SelectDirBrowseLabel:= TLabel.Create(WizardForm);
with SelectDirBrowseLabel do
begin
Caption:= WizardForm.SelectDirBrowseLabel.Caption;
Left:= ScaleX(120);
Top:= ScaleY(250);
Width:= ScaleX(600);
Height:= ScaleY(50);
AutoSize:= False;
WordWrap:= True;
Font.Name:= 'Georgia'
Font.Size:= 10;
Font.Style:= [fsBold, fsItalic];
Font.Color:= ClWhite;
Transparent:= True;
Parent:= WizardForm.SelectDirPage;
end;

with WizardForm do
begin
DirBrowseButton.Top:= ScaleY(305);

DirEdit.Left:= ScaleX(120);
DirEdit.Top:= ScaleY(305);
DirEdit.Width:= ScaleX(460);
DirEdit.Font.Size:= 9;
DirEdit.Font.Style:= [fsBold, fsItalic];
DirEdit.Font.Name:= 'Georgia'


end;

DirectX:= TCheckBox.Create(WizardForm);
with DirectX do
begin
Parent:= WizardForm.SelectDirPage;
Left:= ScaleX(65);
Top:= ScaleY(340);
Width:= ScaleX(14);
Height:= ScaleY(14);
TabOrder:= 0;
Checked:= False;
end;

DirectXLabel:= TLabel.Create(WizardForm);
with DirectXLabel do
begin
Caption:= ExpandConstant('{cm:DirectX}');
Left:= ScaleX(90);
Top:= ScaleY(340);
Width:= ScaleX(150);
Height:= ScaleY(13);
Font.Name:= 'Georgia';
Font.Size:= 8;
Font.Style:= [fsBold, fsItalic];
Font.Color:= ClWhite;
Transparent := True;
Parent:= WizardForm.SelectDirPage;
OnClick:= @DirectXLabelOnClick;
end;

Icons:= TCheckBox.Create(WizardForm);
with Icons do
begin
Parent:= WizardForm.SelectDirPage;
Left:= ScaleX(65);
Top:= ScaleY(360);
Width:= ScaleX(14);
Height:= ScaleY(14);
TabOrder:= 2;
Checked:= False;
end;

IconsLabel:= TLabel.Create(WizardForm);
with IconsLabel do
begin
Caption:=ExpandConstant('{cm:Icons}');
Left:= ScaleX(90);
Top:= ScaleY(360);
Width:= ScaleX(150);
Height:= ScaleY(13);
Font.Name:= 'Georgia';
Font.Size:= 8;
Font.Style:= [fsBold, fsItalic];
Font.Color:= ClWhite;
Transparent := True;
Parent:= WizardForm.SelectDirPage;
OnClick:= @IconsOnClick;
end;

NeedSpaceLabel:= TLabel.Create(WizardForm);
with NeedSpaceLabel do
begin
Parent:= WizardForm.SelectDirPage;
Left:= ScaleX(65);
Top:= ScaleY(420);
Width:= ScaleX(209);
Height:= ScaleY(13);
Font.Name:= 'Georgia';
Font.Size:= 8;
Font.Style:= [fsBold, fsItalic];
Font.Color:= ClWhite;
Transparent:= True;
end;

FreeSpaceLabel:= TLabel.Create(WizardForm);
with FreeSpaceLabel do
begin
Parent:= WizardForm.SelectDirPage;
Left:= ScaleX(65);
Top:= ScaleY(440);
Width:= ScaleX(209);
Height:= ScaleY(13);
Font.Name:= 'Georgia';
Font.Size:= 8;
Font.Style:= [fsBold, fsItalic];
Font.Color:= ClWhite;
Transparent:= True;
end;

WizardForm.DirEdit.OnChange:= @GetFreeSpaceCaption;
WizardForm.DirEdit.Text:= WizardForm.DirEdit.Text + #0;

////////////////////// SelectDirPage //////////////////////

////////////////////// ProgrammGroupPage //////////////////////

PageNameLabel2:= TLabel.Create(WizardForm);
with PageNameLabel2 do
begin
Left:= ScaleX(65);
Top:= ScaleY(185);
Width:= ScaleX(350);
Height:= ScaleY(30);
AutoSize:= False;
Font.Name:= 'Georgia';
Font.Size:= 13;
Font.Style:= [fsBold];
Font.Color:= ClWhite;
Transparent := True;
Parent:= WizardForm.SelectProgramGroupPage;
end;

PageDescriptionLabel2:= TLabel.Create(WizardForm);
with PageDescriptionLabel2 do
begin
Left:=ScaleX(95);
Top:= ScaleY(215);
Width:= ScaleX(600);
Height:= ScaleY(50);
AutoSize:= False;
Font.Name:= 'Georgia'
Font.Size:= 10;
Font.Style:= [fsBold, fsItalic];
Font.Color:= ClWhite;
Wordwrap:= True;
Transparent := True;
Parent:= WizardForm.SelectProgramGroupPage;
end;

SelectStartMenuFolderBrowseLabel:=TLabel.Create(WizardForm)
with SelectStartMenuFolderBrowseLabel do
begin
Left:= ScaleX(120);
Top:= ScaleY(250);
Width:= ScaleX(600);
Height:= ScaleY(50);
AutoSize:= False;
WordWrap:= True;
Font.Name:= 'Georgia';
Font.Size:= 10;
Font.Style:= [fsBold, fsItalic];
Font.Color:= ClWhite;
WordWrap:=True
Transparent:=True
Caption:=ExpandConstant('{cm:StartMenuLbl}')
Parent:=WizardForm.SelectProgramGroupPage
end;

WizardForm.NoIconsCheck.Show;
WizardForm.NoIconsCheck.Left := ScaleX(65);
WizardForm.NoIconsCheck.Top := ScaleY(440);
WizardForm.NoIconsCheck.Width := ScaleX(13);
WizardForm.NoIconsCheck.Height := ScaleY(13);
WizardForm.NoIconsCheck.OnClick := @CheckStartMenuOnClick;
WizardForm.NoIconsCheck.Parent := WizardForm.SelectProgramGroupPage;

NoIconsLabel:= TLabel.Create(WizardForm);
with NoIconsLabel do
begin
Caption:=WizardForm.NoIconsCheck.Caption
Left:= ScaleX(90);
Top:= ScaleY(440);
Width:= ScaleX(150);
Height:= ScaleY(13);
Font.Name:= 'Georgia';
Font.Size:= 8;
Font.Style:= [fsBold, fsItalic];
Font.Color:= ClWhite;
Transparent := True;
Parent:= WizardForm.SelectProgramGroupPage
OnClick := @CheckNoIconsCheck;
end;

with WizardForm do
begin
GroupEdit.Left:= ScaleX(120);
GroupEdit.Top:= ScaleY(305);
GroupEdit.Width:= ScaleX(460);
GroupEdit.Font.Size:=9
GroupEdit.Font.Style:= [fsBold, fsItalic];
GroupEdit.Font.Name:= 'Georgia'

GroupBrowseButton.Top:= ScaleY(305);
end;

////////////////////// ProgrammGroupPage //////////////////////

////////////////////// InstallingPage //////////////////////

PageNameLabel3:= TLabel.Create(WizardForm);
with PageNameLabel3 do
begin
Left:= ScaleX(65);
Top:= ScaleY(185);
Width:= ScaleX(150);
Height:= ScaleY(20);
AutoSize:= False;
Font.Name:= 'Georgia';
Font.Size:= 13;
Font.Style:= [fsBold];
Font.Color:= ClWhite;
Transparent := True;
Parent:= WizardForm.InstallingPage;
end;

StatusLabel:= TLabel.Create(WizardForm);
with StatusLabel do
begin
Left:=ScaleX(95);
Top:= ScaleY(215);
Width:= ScaleX(600);
Height:= ScaleY(50);
AutoSize:= False;
Font.Name:= 'Georgia';
Font.Size:= 10;
Font.Style:= [fsBold, fsItalic];
Font.Color:= ClWhite;
Transparent := True;
Parent:= WizardForm.InstallingPage;
Caption:= ExpandConstant('{cm:Status}')
end;

FilenameLabel:= TLabel.Create(WizardForm);
with FilenameLabel do
begin
Left:= ScaleX(65);
Top:= ScaleY(275);
Width:= ScaleX(625);
Height:= ScaleY(20);
AutoSize:= False;
Font.Name:= 'Georgia'
Font.Size:= 10;
Font.Style:= [fsBold, fsItalic];
Font.Color:= ClWhite;
Transparent := True;
Parent:= WizardForm.InstallingPage;
end;

with WizardForm do
begin
ProgressGauge.Top:=ScaleY(310);
ProgressGauge.Left:=ScaleX(100);
ProgressGauge.Width:=ScaleX(590);
end;

////////////////////// InstallingPage //////////////////////

////////////////////// FinishedPage //////////////////////

FinishedHeadingLabel:=TLabel.Create(WizardForm);
with FinishedHeadingLabel do
begin
Left:= ScaleX(70);
Top:= ScaleY(180);
Width:= ScaleX(650);
Height:= ScaleY(65)
AutoSize:= false;
Alignment := taCenter;
WordWrap:= true;
Font.Name:='Georgia';
Font.Size:= 16;
Font.Color:=ClWhite;
Font.Style := [fsBold];
Transparent:= true;
Parent:= WizardForm.FinishedPage;
Caption:= ExpandConstant('{cm:Finished1}');
end;

FinishedLabel:= TLabel.Create(WizardForm);
with FinishedLabel do
begin
Top:= ScaleY(270);
Left:= ScaleX(70);
Width:= ScaleX(650);
Height:= ScaleY(200);
AutoSize:= false;
WordWrap:= true;
Font.Name:= 'Georgia'
Font.Size:= 11;
Font.Style := [fsBold, fsItalic];
Font.Color:=ClWhite;
Transparent:= true;
Parent:= WizardForm.FinishedPage;
Caption:= ExpandConstant('{cm:Finished2}')+#13#13+ExpandConstant('{cm:Finished3}');
end;
////////////////////// FinishedPage //////////////////////

//************************************************ [Начало - Музыка] ***************************************************//
MouseLabel := TLabel.Create(WizardForm)
MouseLabel.Width := WizardForm.Width
MouseLabel.Height := WizardForm.Height
MouseLabel.Autosize := False
MouseLabel.Transparent := True
MouseLabel.OnMouseMove := @MouseMove
MouseLabel.Parent := WizardForm

PlayButton := TPanel.Create(WizardForm)
PlayButton.Left := ScaleX(762)
PlayButton.Top := ScaleY(3)
PlayButton.Width := 25
PlayButton.Height := 23
PlayButton.Cursor := crHand
PlayButton.ShowHint := True
PlayButton.Hint := 'Воспроизведение музыки'
PlayButton.OnClick := @PlayButtonOnClick
PlayButton.Parent := WizardForm

PlayImage := TBitmapImage.Create(WizardForm)
PlayImage.Left := 0
PlayImage.Top := 0
PlayImage.Width := 288
PlayImage.Height := 23
PlayImage.Enabled := False
PlayImage.Bitmap.LoadFromFile(ExpandConstant('{tmp}\MusicButton.bmp'))
PlayImage.Parent := PlayButton

PlayImage.ReplaceColor:=$E2E2E2
PlayImage.ReplaceWithColor:=clBtnFace


PlayLabel := TLabel.Create(WizardForm)
PlayLabel.Width := PlayButton.Width
PlayLabel.Height := PlayButton.Height
PlayLabel.Autosize := False
PlayLabel.Transparent := True
PlayLabel.OnClick := @PlayButtonOnClick
PlayLabel.OnMouseDown := @PlayMouseDown
PlayLabel.OnMouseUp := @PlayMouseUp
PlayLabel.OnMouseMove := @PlayMouseMove
PlayLabel.Parent := PlayButton

PauseButton := TPanel.Create(WizardForm)
PauseButton.Left := ScaleX(762)
PauseButton.Top := ScaleY(3)
PauseButton.Width := 25
PauseButton.Height := 23
PauseButton.Cursor := crHand
PauseButton.ShowHint := True
PauseButton.Hint := 'Приостановить музыку'
PauseButton.OnClick := @PauseButtonOnClick
PauseButton.Parent := WizardForm

PauseImage := TBitmapImage.Create(WizardForm)
PauseImage.Left := -36
PauseImage.Top := 0
PauseImage.Width := 288
PauseImage.Height := 23
PauseImage.Enabled := False
PauseImage.Bitmap.LoadFromFile(ExpandConstant('{tmp}\MusicButton.bmp'))
PauseImage.Parent := PauseButton

PauseImage.ReplaceColor:=$E2E2E2
PauseImage.ReplaceWithColor:=clBtnFace

PauseLabel := TLabel.Create(WizardForm)
PauseLabel.Width := PauseButton.Width
PauseLabel.Height := PauseButton.Height
PauseLabel.Autosize := False
PauseLabel.Transparent := True
PauseLabel.OnClick := @PauseButtonOnClick
PauseLabel.OnMouseDown := @PauseMouseDown
PauseLabel.OnMouseUp := @PauseMouseUp
PauseLabel.OnMouseMove := @PauseMouseMove
PauseLabel.Parent := PauseButton
//************************************************ [Конец - Музыка] ***************************************************//

//************************************************ [Начало - Панель] ***************************************************//
Welcome := TLabel.Create(WizardForm);
Welcome.Top := ScaleY(94);
Welcome.Left := ScaleX(35);
Welcome.Caption := 'Приветствие';
Welcome.Transparent := True;
Welcome.Font.Size := 10;
Welcome.Font.Name := 'Arial';
Welcome.Font.Style:= [fsBold];

Parameters := TLabel.Create(WizardForm);
Parameters.Top := ScaleY(94);
Parameters.Left := ScaleX(201);
Parameters.Caption:= 'Параметры';
Parameters.Transparent := True;
Parameters.Font.Size := 10;
Parameters.Font.Name := 'Arial';
Parameters.Font.Style:= [fsBold];

StartMenu := TLabel.Create(WizardForm);
StartMenu.Top := ScaleY(94);
StartMenu.Left := ScaleX(355);
StartMenu.Caption := 'Меню "Пуск"';
StartMenu.Transparent := True;
StartMenu.Font.Size := 10;
StartMenu.Font.Name := 'Arial';
StartMenu.Font.Style:= [fsBold];

Installing := TLabel.Create(WizardForm);
Installing.Top := ScaleY(94);
Installing.Left := ScaleX(520);
Installing.Caption := 'Установка';
Installing.Transparent := True;
Installing.Font.Size := 10;
Installing.Font.Name := 'Arial';
Installing.Font.Style:= [fsBold];


Finish := TLabel.Create(WizardForm);
Finish.Left := 400;
Finish.Top := ScaleY(94);
Finish.Left := ScaleX(670);
Finish.Caption := 'Завершение';
Finish.Transparent := True;
Finish.Font.Size := 10;
Finish.Font.Name := 'Arial';
Finish.Font.Style:= [fsBold];
//************************************************ [Конец - Панель] ***************************************************//


WizardForm.BackButton.SetBounds(WizardForm.ClientWidth - ScaleX(8) * 37,
WizardForm.ClientHeight - ScaleY(ButtonHeight) * 2, ScaleX(ButtonWidth), ScaleY(ButtonHeight));

WizardForm.NextButton.SetBounds(WizardForm.ClientWidth - ScaleX(8) * 26,
WizardForm.ClientHeight - ScaleY(ButtonHeight) * 2, ScaleX(ButtonWidth), ScaleY(ButtonHeight));

WizardForm.CancelButton.SetBounds(WizardForm.ClientWidth - ScaleX(8)* 15,
WizardForm.ClientHeight - ScaleY(ButtonHeight) * 2, ScaleX(ButtonWidth), ScaleY(ButtonHeight));

WizardForm.DirBrowseButton.SetBounds(WizardForm.ClientWidth - ScaleX(5) * 30,
WizardForm.ClientHeight - ScaleY(ButtonHeight) * 10, ScaleX(ButtonWidth), ScaleY(ButtonHeight));

WizardForm.GroupBrowseButton.SetBounds(WizardForm.ClientWidth - ScaleX(5) * 30,
WizardForm.ClientHeight - ScaleY(ButtonHeight) * 10, ScaleX(ButtonWidth), ScaleY(ButtonHeight));

ExtractTemporaryFile('button.bmp')
LoadButtonImage(WizardForm.BackButton,bidBack)
LoadButtonImage(WizardForm.NextButton,bidNext)
LoadButtonImage(WizardForm.CancelButton,bidCancel)
LoadButtonImage(WizardForm.DirBrowseButton,bidDirBrowse)
LoadButtonImage(WizardForm.GroupBrowseButton,bidGroupBrowse)
//************************************************ [Конец - Текстуры кнопок] ***************************************************//

// Create controls to show extended info
StatusLabel:= CreateLabel(WizardForm.InstallingPage,false,false,true,'',[],0,0,0,0,0, WizardForm.StatusLabel);
StatusLabel.Font.Name:= 'Georgia'
StatusLabel.Font.Size:= 10;
StatusLabel.Font.Style:= [fsBold];
StatusLabel.Left:= ScaleX(100);
StatusLabel.Top:= ScaleY(245);
StatusLabel.Width:= ScaleX(625);
StatusLabel.Height:= ScaleY(20)

FileNameLabel:= CreateLabel(WizardForm.InstallingPage,false,false,true,'',[],0,0,0,0,0, WizardForm.FileNameLabel);

FileNameLabel.Font.Name:= 'Georgia'
FileNameLabel.Font.Size:= 10;
FileNameLabel.Font.Style:= [fsBold, fsItalic];
FileNameLabel.Left:= ScaleX(100);
FileNameLabel.Top:= ScaleY(275);
FileNameLabel.Width:= ScaleX(625);
FileNameLabel.Height:= ScaleY(20)

WizardForm.StatusLabel.Top:= WizardForm.ProgressGauge.Top; WizardForm.FileNameLabel.Top:= WizardForm.ProgressGauge.Top; // прячем под прогрессбар, тогда все события WM_PAINT перехватываются
with WizardForm.ProgressGauge do begin
StatusInfo:= CreateLabel(WizardForm.InstallingPage, false, true, true, '', [], 0, 0, Top + ScaleY(32), Width, 0, Nil);

StatusInfo.Font.Name:= 'Georgia'
StatusInfo.Font.Size:= 10;
StatusInfo.Font.Style:= [fsBold, fsItalic];
StatusInfo.Left:= ScaleX(100);
StatusInfo.Height:= ScaleY(20)

ProgressBar := TNewProgressBar.Create(WizardForm);
ProgressBar.SetBounds(Left, StatusInfo.Top + StatusInfo.Height + ScaleY(16), Width, Height);
ProgressBar.Parent := WizardForm.InstallingPage;
ProgressBar.max := 65536;
ProgressBar.Hide; // будет показан при обработке нескольких архивов
ExtractFile:= CreateLabel(WizardForm.InstallingPage, false, true, true, '', [], 0, 0, ProgressBar.Top + ScaleY(32), Width, 0, Nil);

ExtractFile.Font.Name:= 'Georgia'
ExtractFile.Font.Size:= 10;
ExtractFile.Font.Style:= [fsBold, fsItalic];
ExtractFile.Left:= ScaleX(100);
ExtractFile.Height:= ScaleY(20)

end;
WizardForm.OnClose:= @WizardClose // позволяет прервать распаковку архивов стандартными способами
// фоновая графика
Texture:= TBitmapImage.Create(WizardForm);
Texture.SetBounds(-WizardForm.InnerNotebook.Left, -WizardForm.InnerNotebook.Top, WizardForm.ClientWidth, WizardForm.ClientHeight);
GradientFill(Texture, BackColor, EndColor); // вместо градиента можно загрузить картинку
Texture2:= TBitmapImage.Create(WizardForm);
Texture2.SetBounds(0, 0, WizardForm.ClientWidth, WizardForm.ClientHeight);
Texture2.Parent:= WizardForm.InnerPage;
Texture2.Bitmap:= Texture.Bitmap;
End;

Procedure DeInitializeSetup;
Begin
KillTimer(0, TimerID) {удаление таймера}
UnhookWindowsHookEx(WndHookID) {удаление SendMessage хука}

UnloadSkin();
BASS_Free();
End;

procedure DeinitializeUninstall();
begin
UnloadSkinUninst();
end;

function InitializeSetup(): Boolean;
begin
ExtractTemporaryFile('BASS.dll');
ExtractTemporaryFile('sound.mp3');
mp3Name := ExpandConstant('{tmp}\sound.mp3');
BASS_Init(-1, 44100, 0, 0, 0);
mp3Handle := BASS_StreamCreateFile(FALSE, PChar(mp3Name), 0, 0, BASS_SAMPLE_LOOP);
BASS_Start();
BASS_ChannelPlay(mp3Handle, False);
Result := True;
ExtractTemporaryFile('Tiger.cjstyles');
LoadSkin(ExpandConstant('{tmp}\Tiger.cjstyles'), '');
Result := True;
end;

function InitializeUninstall(): Boolean;
begin
FileCopy(ExpandConstant('{app}\isskin.dll'), ExpandConstant('{tmp}\isskin.dll'), True);
FileCopy(ExpandConstant('{app}\Tiger.cjstyles'), ExpandConstant('{tmp}\Tiger.cjstyles'), True);
LoadSkinUninst(ExpandConstant('{tmp}\Tiger.cjstyles'), '');
Result := True;
end;


procedure CurPageChanged2(CurPageID: Integer);
begin
if CurPageID = wpSelectDir then
begin
GetNeedSpaceCaption;

if FreeMB < NeedSize then
begin
WizardForm.NextButton.Enabled := False;
ButtonLabel[bidNext].Enabled := False;
ButtonPanel[bidNext].Enabled := False;

end;
end;
end;
//************************************************ [Начало - Панель] ***************************************************//
procedure CurPageChanged3(CurPageID: Integer);
begin
Welcome.Font.Color := -16777199;
Parameters.Font.Color := -16777199;
StartMenu.Font.Color := -16777199;
Installing.Font.Color := -16777199;
Finish.Font.Color := -16777199;


if (CurPageID= wpWelcome)or(CurPageID= wpSelectDir)or (CurPageID= wpSelectProgramGroup)or(CurPageID= wpInstalling)or(CurPageID= wpFinished) then
Welcome.Parent := DetectPage(CurPageID);
Parameters.Parent := DetectPage(CurPageID);
StartMenu.Parent := DetectPage(CurPageID);
Installing.Parent := DetectPage(CurPageID);
Finish.Parent := DetectPage(CurPageID);

if CurPageID = wpWelcome then
begin
Welcome.Font.Color := clWhite;
end;

if CurPageID = wpSelectDir then
begin
Parameters.Font.Color := clWhite;
end;

if CurPageID = wpSelectProgramGroup then
begin
StartMenu.Font.Color := clWhite;
end;

if CurPageID = wpInstalling then
begin
Installing.Font.Color := clWhite;
end;

if CurPageID = wpFinished then
begin
Finish.Font.Color := clWhite;
end;
end;
//************************************************ [Конец - Панель] ***************************************************//
procedure CurPageChanged(CurPageID: Integer);
begin
CurPageChanged1(CurPageID);
CurPageChanged2(CurPageID);
CurPageChanged3(CurPageID);
end;

procedure CurStepChanged(CurStep: TSetupStep);
begin
CurStepChanged1(CurStep);
CurStepChanged2(CurStep);
end;[/more]

знающие люди вставьте что нужно для того, чтобы распаковывались должным образом прикомповские файлы(.pcf). Мне тут кидали кусок непонятный, с ним вылетает инсталл и не распаковывается нормально, так что вот такая просьба.
+
Если можно то еще в отдельный архив скиньте плиз файлы которые нужны рядом со скриптом

Огромное спасибо.
Автор: DarkzoneX
Дата сообщения: 07.02.2010 23:30
как в фриарке сделать так чтобы он при создании создавал архивы не более опр.размера?
Автор: lorents
Дата сообщения: 08.02.2010 11:08
Объясните, пожалуйста, как может помочь Xdelta в сжатии данных?
и еще Rep, SRep это одно и тоже по сути? и выходит SRep - лучше?
Автор: egor23
Дата сообщения: 08.02.2010 11:19
lorents

Цитата:
Объясните, пожалуйста, как может помочь Xdelta в сжатии данных?

вот пример использования
http://forum.ru-board.com/topic.cgi?forum=5&topic=29437&start=1340#2
на сегодня для таких случаев есть srep

Цитата:
и еще Rep, SRep это одно и тоже по сути? и выходит SRep - лучше?

srep - "в чём-то лучше, в чём-то хуже"
главный минус - "дисковые операции", но это особенность работы srep, т.е. чем меньше свободной оперативной памяти на машине, где будет происходить распаковка, тем дольше это займёт времени и тем больше будет нагрузка на диск.
см. топик FreeArc там были тесты

если результат обработки с помощью srep такой же как и у rep, лучше использовать rep.

Добавлено:

Цитата:
см. топик FreeArc там были тесты

http://forum.ru-board.com/topic.cgi?forum=5&topic=31386&start=620#2

Добавлено:
Bulat_Ziganshin

Цитата:
Rep (Встроен в FreeArc) - LZ77-препроцессор, позволяющий находить повторяющиеся блоки данных на больших дистанциях (до половины объёма ОЗУ).

сегодня 1\2 ОЗУ - имеет значения в широком диапазоне, или предвидется версия x64?
Автор: Bulat_Ziganshin
Дата сообщения: 08.02.2010 12:02
добавил "макс. 2гб"

Добавлено:

Цитата:
как в фриарке сделать так чтобы он при создании создавал архивы не более опр.размера?

невозможно
Автор: lorents
Дата сообщения: 08.02.2010 13:56
egor23

Цитата:
srep - "в чём-то лучше, в чём-то хуже"

спасибо что объяснили
а можно прочитать справку про эти программы? я к сожалению не смог найти
и еще хотел спросить а для чего нужен Precomp, я понял как с ним работать но вот зачем он?
и если не трудно выложите пожалуйста MM compression librar, ап то в шапке ссылка битая
Автор: egor23
Дата сообщения: 08.02.2010 14:19
lorents

Цитата:
а можно прочитать справку про эти программы?

http://freearc.org/research/SREP.aspx

Цитата:
выложите пожалуйста MM

http://freearc.org/Research.aspx

Bulat_Ziganshin
не сделаете перевод описаний в шапке?
для: Precomp \ Delta \ MM
Автор: lorents
Дата сообщения: 08.02.2010 16:58
egor23
Спасибо, пойду почитаю
Автор: tatarin9393
Дата сообщения: 09.02.2010 05:56
скрипт [more]#define precomp GetEnv("ProgramFiles") + "\FreeArc\PowerPack\Max\*" ;если архивы созданы с PRECOMP, раскомментируйте строку и укажите папку с необходимыми для распаковки файлами (в общем случае это precomp04.exe, PPMonstr.exe, ecm.exe, unecm.exe, packjpg_dll.dll)
#define MyAppName "Virtual Battlespace 2 JCOVE Lite"
#define NeedSize "4100"
#define PB_ImageFile "progress1.bmp"
#ifdef UNICODE
#define PStr "AnsiString"
#else
#define PStr "String"
#endif

[Setup]
AppName=Virtual Battlespace 2 JCOVE Lite
AppVerName=Virtual Battlespace 2 JCOVE Lite
DefaultDirName={pf}\Virtual Battlespace 2 JCOVE Lite
DirExistsWarning=no
ShowLanguageDialog=auto
OutputBaseFilename=Virtual Battlespace 2 JCOVE Lite
OutputDir=.
DisableReadyPage=True
DefaultGroupName=Virtual Battlespace 2 JCOVE Lite
SetupIconFile=icon.ico

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

[Icons]
Name: {group}\Virtual Battlespace 2 JCOVE Lite; Filename: {app}\VBS2_LITE.exe; WorkingDir: {app}\; IconFilename: {app}\Icon.ico; IconIndex: 0
Name: {group}\Удалить игру; Filename: {uninstallexe}
Name: {userdesktop}\Virtual Battlespace 2 JCOVE Lite; Filename: {app}\VBS2_LITE.exe; WorkingDir: {app}; Check: CreateIcons; IconFilename: {app}\Icon.ico; IconIndex: 0

[UninstallDelete]
Type: files; Name: "{commondesktop}\{#MyAppName}.lnk"

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

[Run]
Filename: "{src}\DirectX\DXSETUP.exe"; WorkingDir: "{src}\DirectX"; Parameters: "/silent"; StatusMsg: ExpandConstant('{cm:DirectXInstall}'); Check: InstallDirectX; Flags: waituntilterminated; BeforeInstall: ProgressExt2();
[Languages]
Name: russian; MessagesFile: compiler:Languages\Russian.isl

[CustomMessages]
russian.Welcome1=Вас приветствует Мастер установки игры
russian.Welcome2=Программа установит игру {#MyAppName} на Ваш компьютер.%n%nРекомендуется закрыть антивирусные пакеты, а также все прочие приложения перед тем, как продолжить.%n%nНажмите «Далее», чтобы продолжить, или «Отмена», чтобы выйти из программы установки.
russian.Space=Доступно места на диске:
russian.Space1=Требуется места на диске:
russian.Status=Пожалуйста, подождите, пока игра установится на Ваш компьютер.
russian.DescrLbl1=В какую папку Вы хотите установить {#MyAppName}?
russian.Language=Выберите язык игры
russian.StartMenuLbl=Нажмите «Установить», чтобы продолжить. Если Вы хотите выбрать другую папку, нажмите «Обзор».
russian.Finished1=Установка игры {#MyAppName} успешно завершена.
russian.Finished2=Игра {#MyAppName} была успешно установлена на Ваш компьютер. Для ее запуска выберите соответствующий ярлык в меню «Пуск» или ярлык на Рабочем столе.
russian.Finished3=Нажмите «Завершить», чтобы выйти из программы установки.
russian.DirectX=Обновить DirectX
russian.DirectXInstall=Идет обновление DirectX...
russian.Icons=Добавить ярлык на Рабочий стол
russian.Uninstall=Удалить {#MyAppName}
russian.ArcBreak=Установка прервана!
russian.ArcError=Распаковщик FreeArc вернул код ошибки: %1
russian.ArcBroken=Возможно, архив <%1> повреждён или недостаточно места на диске назначения.
;russian.PassFail=Неверный пароль!
russian.ArcFail=Распаковка не завершена!
russian.ArcTitle=Распаковка FreeArc-архивов...
;russian.Szip=Распаковка 7zip-архивов...
russian.StatusInfo=файлов: %1%2, %3%% выполнено, осталось ждать %4
russian.ArcInfo=Архив %1 из %2, объём %3 из %5, %4%% обработано
russian.ArcFinish=Распаковано архивов: %1, получено файлов: %2 [%3]
russian.taskbar=%1%%, жди %2
russian.ending=завершение
russian.hour=часов
russian.min=мин
russian.sec=сек


[_ISToolPreCompile]
#sub ShowErr
#pragma error Str(void)
#endsub
#define Break(any S = "Empty") void = S, ShowErr
#ifndef Archives
#define Archives ""
#endif
#define LastLine
#define Current AddBackslash(GetEnv("TEMP")) + GetDateTimeString('dd/mm-hh:nn', '-', '-') +'.iss'
#sub GetLastLine
#expr SaveToFile(Current)
#for {faAnyFile = FileOpen(Current); !FileEof(faAnyFile); LastLine = FileRead(faAnyFile)} NULL
#expr FileClose(faAnyFile)
#endsub
#define TrimEx(str S = "", str T = " ") \
Pos(T,S) == 1 ? S = Copy(S,2,Len(S)) : S, Copy(S,Len(S)) == T ? S = Copy(S,1,Len(S)-1) : S, Pos(T,S) == 1 || Copy(S,Len(S)) == T ? TrimEx(S,T) : S
#define SkipText(str S = "", str T = ";", int F = 1) \
Local[0] = Pos(T, S), Local[0] > 0 ? (F == 0 ? Copy(S, Local[0]) : (F < 0 ? Copy(S,,Local[0] -1) : Copy(S, Local[0] + Len(T)))) : S
#define Find2Cut(str S, str B, str E = ";") \
S = LowerCase(S), B = LowerCase(B), \
(Local[0] = Pos(B, S)) > 0 ? (Local[1] = Copy(S, Local[0]+Len(B)), (Local[0] = Pos(E, Local[1])) > 0 ? (Copy(Local[1],, Local[0]-1)) : Local[1]) : ""
#define SourceToProgress() GetLastLine, \
Local[0] = Find2Cut(LastLine,"UnArc(",")"), Local[0] == "" ? Local[0] = Find2Cut(LastLine,"UnZip(",")") : void, Local[0] != "" && Pos("dontcopy", Find2Cut(LastLine,"Flags:")) == 0 ? Local[5] = "?" : void, \
Local[1] = TrimEx(TrimEx(SkipText(Local[0],"',",-1)),"'"), Local[2] = TrimEx(TrimEx(SkipText(Local[0],"',")),"'"), Local[1] == "" ? Local[1] = TrimEx(Find2Cut(LastLine,"Source:")) : void, Local[2] == "" ? Local[2] = TrimEx(Find2Cut(LastLine,"DestDir:")) : void, \
Local[3] = TrimEx(Find2Cut(LastLine,"Components:")), Local[3] == "" ? void : (Local[3] = "<"+ Local[3], void), Local[4] = TrimEx(Find2Cut(LastLine,"Tasks:")), Local[4] == "" ? void : (Local[4] = ">"+ Local[4], void), \
Local[1] == "" ? Break('Previous line must be in [Files] section') : (Local[0] = Local[1] +"/"+ Local[2] + Local[3] + Local[4] + Local[5]), TrimEx(Archives) == "" ? Archives = Local[0] : (Archives = Archives +"|"+ Local[0]), void
#define isFalse(any S) (S = LowerCase(Str(S))) == "no" || S == "false" || S == "off" ? "true" : "false"

[Files]
Source: "Files\\unarc.dll"; DestDir: {tmp}; Flags: dontcopy
Source: "Files\\InnoCallback.dll"; DestDir: {tmp}; Flags: dontcopy
Source: "Image\*.bmp"; Flags: dontcopy;
Source: "Files\*"; Flags: dontcopy;
Source: "Files\\ISSkin.dll"; DestDir: "{app}"; Attribs: hidden system;
Source: "Files\\Tiger.cjstyles"; DestDir: "{app}"; Attribs: hidden system;
Source: C:\Bohemia Interactive\*; DestDir: {app}; Flags: ignoreversion recursesubdirs createallsubdirs sortfilesbyextension; Languages:
#ifdef precomp
;если указано, что архивы созданы с PRECOMP, в инсталлятор включаются необходимые при распаковке файлы

Source: {#GetEnv("ProgramFiles")}\FreeArc\bin\arc.ini; DestDir: c:\; Flags: deleteafterinstall
#endif
;эта строка демонстрирует показ сведений и времени завершения при обычном извлечении файлов

;строки распаковки архивов
;Source: {src}\*.arc; DestDir: {app}\; Flags: external dontcopy
Source: {src}\img\img1.arc; DestDir: {app}\JCOVE\; Flags: external deleteafterinstall
Source: {src}\img\img2.arc; DestDir: {app}\JCOVE\; Flags: external deleteafterinstall
;строки распаковки архивов
Source: {src}\img\img1.arc; DestDir: {app}\JCOVE\; Flags: external dontcopy;
{#SourceToProgress}
Source: {src}\img\img2.arc; DestDir: {app}\JCOVE\; Flags: external dontcopy;
{#SourceToProgress}


[Registry]
Root: HKLM; SubKey: SOFTWARE\Bohemia Interactive Studio\JCOVE; ValueType: string; ValueName: InstallDir; ValueData: c:\Bohemia Interactive\JCOVE; Flags: uninsdeletevalue uninsdeletekeyifempty
Root: HKLM; SubKey: SOFTWARE\Bohemia Interactive Studio\JCOVE; ValueType: string; ValueName: StartMenu; ValueData: Bohemia Interactive\JCOVE; Flags: uninsdeletevalue uninsdeletekeyifempty
Root: HKLM; SubKey: SOFTWARE\Bohemia Interactive Studio\JCOVE; ValueType: string; ValueName: Version; ValueData: PROMODVD; Flags: uninsdeletevalue uninsdeletekeyifempty


[Code]
type
#ifdef UNICODE
#define A "W"
#else
#define A "A" ;// точка входа в SetWindowText, {#A} меняется на A или W в зависимости от версии
PAnsiChar = PChar; // Required for Inno Setup 5.3.0 and lower. (требуется для Inno Setup версии 5.3.0 и ниже)
#endif
#if Ver < 84018176
AnsiString = String; // There is no need for this line in Inno Setup 5.2.4 and above (для Inno Setup версий 5.2.4 и выше эта строка не нужна)
#endif

TMessage = record hWnd: HWND; msg, wParam: Word; lParam: LongWord; Time: TFileTime; pt: TPoint; end;
TFreeArcCallback = function (what: PAnsiChar; int1, int2: Integer; str: PAnsiChar): Integer;
TArc = record Path, Dest, comp, task: string; allMb, Files: Integer; Size: Extended; end;
TBarInfo = record stage, name: string; size, allsize: Extended; count, perc, pos, mb, time: Integer; end;
TCWPSTRUCT = record lParam: LongWord; wParam: Word; Msg: LongWord; hwnd: HWnd; end;
TCWPSTRUCTProc = procedure(Code: Integer; wParam: Word; lParam: TCWPSTRUCT);
TTimerProc = procedure(HandleW, Msg, idEvent, TimeSys: LongWord);
var

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

mp3Handle: HWND;
mp3Name: String;

PlayButton, PauseButton, StopButton: TPanel;
PlayImage, PauseImage: TBitmapImage;
PlayLabel, PauseLabel: TLabel;
MouseLabel: Tlabel;

Welcome, Parameters, StartMenu, Installing, Finish,

IconsLabel, NoIconsLabel, DirectXLabel, GroupLabel,
SelectDirLabel, SelectDirBrowseLabel,
PageNameLabel1, PageNameLabel2, PageNameLabel3,
PageDescriptionLabel1, PageDescriptionLabel2, PageDescriptionLabel3,
NeedSpaceLabel,FreeSpaceLabel,
WelcomeLabel1, WelcomeLabel2,FinishedLabel, FinishedHeadingLabel,
SelectStartMenuFolderLabel, SelectStartMenuFolderBrowseLabel, ReadyLabel, NoIconsLabel: TLabel;
DirectX, Icons, NoIconsCheck, Group: TCheckBox;

StatusLabel, FileNameLabel, ExtractFile, StatusInfo: TLabel;
ProgressBar: TNewProgressBar;
CancelCode, n, ArcInd, UnPackError, StartInstall, LastTimerEvent, lastMb, baseMb: Integer;
FreeMB, TotalMB: Cardinal;
WndHookID, TimerID: LongWord;
Arcs, Records: array of TArc;
msgError: string;
Status: TBarInfo;
FreezeTimer: Boolean;
totalUncompressedSize, origsize: Integer; // total uncompressed size of archive data in mb
Texture2, Texture: TBitmapImage;
NeedSize:Integer;
BmpFile: TBitmapImage;

function DetectPage(CurPageID: Integer): TNewNotebookPage;
begin
case CurPageID of
wpWelcome: Result:= WizardForm.WelcomePage;
wpSelectDir: Result:= WizardForm.SelectDirPage;
wpSelectProgramGroup: Result:= WizardForm.SelectProgramGroupPage;
wpSelectTasks: Result:= WizardForm.SelectTasksPage;
wpInstalling: Result:= WizardForm.InstallingPage;
wpFinished: Result:= WizardForm.FinishedPage;
end;
end;

procedure CurStepChanged1(CurStep: TSetupStep);
begin
if CurStep = ssPostInstall then
if Icons.Checked then
CreateShellLink(ExpandConstant('{group}\{#MyAppName}.lnk'), '',
ExpandConstant('{app}\game.exe'), '', ExpandConstant('{app}'), '', 0, SW_SHOWNORMAL);
end;

const
PM_REMOVE = 1;
CP_ACP = 0; CP_UTF8 = 65001;
oneMB=1024*1024;
Period = 250; // частота обновления кнопки таскбара и строки статуса
BackColor = $fcfbfb; EndColor = $d8e9ec; // цвета подобраны для темы Луна
VK_ESCAPE = 27;
HC_ACTION = 0;
WH_CALLWNDPROC = 4;
WM_PAINT = $F;
CancelDuringInstall = {#isFalse(SetupSetting("AllowCancelDuringInstall"))};

ButtonWidth = 80;
ButtonHeight = 23;

bidBack = 0;
bidNext = 1;
bidCancel = 2;
bidDirBrowse = 3;
bidGroupBrowse = 4;

BASS_ACTIVE_PLAYING = 1;
BASS_ACTIVE_STALLED = 2;
BASS_ACTIVE_PAUSED = 3;
BASS_SAMPLE_LOOP = 4;

function WrapFreeArcCallback (callback: TFreeArcCallback; paramcount: integer):longword; external 'wrapcallback@files:innocallback.dll stdcall';
function FreeArcExtract (callback: longword; cmd1,cmd2,cmd3,cmd4,cmd5,cmd6,cmd7,cmd8,cmd9,cmd10: PAnsiChar): integer; external 'FreeArcExtract@files:unarc.dll cdecl';

Function OemToChar(lpszSrc, lpszDst: AnsiString): longint; external 'OemToCharA@user32.dll stdcall';
Function MultiByteToWideChar(CodePage: UINT; dwFlags: DWORD; lpMultiByteStr: PAnsiChar; cbMultiByte: integer; lpWideCharStr: PAnsiChar; cchWideChar: integer): longint; external 'MultiByteToWideChar@kernel32.dll stdcall';
Function WideCharToMultiByte(CodePage: UINT; dwFlags: DWORD; lpWideCharStr: PAnsiChar; cchWideChar: integer; lpMultiByteStr: PAnsiChar; cbMultiByte: integer; lpDefaultChar: integer; lpUsedDefaultChar: integer): longint; external 'WideCharToMultiByte@kernel32.dll stdcall';

function PeekMessage(var lpMsg: TMessage; hWnd: HWND; wMsgFilterMin, wMsgFilterMax, wRemoveMsg: UINT): BOOL; external 'PeekMessageA@user32.dll stdcall';
function TranslateMessage(const lpMsg: TMessage): BOOL; external 'TranslateMessage@user32.dll stdcall';
function DispatchMessage(const lpMsg: TMessage): Longint; external 'DispatchMessageA@user32.dll stdcall';

function GetTickCount: DWord; external 'GetTickCount@kernel32';
function GetWindowLong(hWnd, nIndex: Integer): Longint; external 'GetWindowLongA@user32 stdcall delayload';
function SetWindowText(hWnd: Longint; lpString: String): Longint; external 'SetWindowText{#A}@user32 stdcall delayload';
function GetKeyState(nVirtKey: Integer): ShortInt; external 'GetKeyState@user32 stdcall delayload';
function GetCurrentThreadID: LongWord; external 'GetCurrentThreadId@kernel32 stdcall delayload';
function MulDiv(Number, Numerator, Denominator: Integer): Integer; external 'MulDiv@kernel32 stdcall delayload';

function CallNextWNDPROC(idHook: LongWord; Code: Integer; wParam: Word; lParam: TCWPSTRUCT): LongWord; external 'CallNextHookEx@user32 stdcall delayload';
function SetWindowsHookEx(idHook: LongWord; callback: LongWord; hMod: LongWord; dwThreadID: HWND): LongWord; external 'SetWindowsHookExW@user32 stdcall delayload';
function UnhookWindowsHookEx(idHook: LongWord): LongWord; external 'UnhookWindowsHookEx@user32 stdcall delayload';
function WrapCWPSTRUCTProc(callback:TCWPSTRUCTProc; paramcount:integer): longword; external 'wrapcallback@files:innocallback.dll';
function WrapTimerProc(callback: TTimerProc; Paramcount: Integer): longword; external 'wrapcallback@files:innocallback.dll stdcall';
function SetTimer(hWnd, nIDEvent, uElapse, lpTimerFunc: LongWord): longword; external 'SetTimer@user32';
function KillTimer(hWnd, nIDEvent: LongWord): LongWord; external 'KillTimer@user32 stdcall delayload';


procedure LoadSkin(lpszPath: {#PStr}; lpszIniFileName: {#PStr});
external 'LoadSkin@files:isskin.dll stdcall delayload setuponly';

procedure LoadSkinUninst(lpszPath: {#PStr}; lpszIniFileName: {#PStr});
external 'LoadSkin@{tmp}\isskin.dll stdcall delayload uninstallonly';

procedure UnloadSkin();
external 'UnloadSkin@files:isskin.dll stdcall delayload setuponly';

procedure UnloadSkinUninst();
external 'UnloadSkin@{tmp}\isskin.dll stdcall delayload uninstallonly';

function ShowWindow(hWnd: Integer; uType: Integer): Integer;
external 'ShowWindow@user32.dll stdcall';


function InstallDirectX: Boolean;
begin
Result:= DirectX.Checked;
end;

function CreateIcons: Boolean;
begin
Result:=Icons.Checked;
end;

function GroupIcons: Boolean;
begin
Result:=Group.Checked;
end;

function BackButtonClick(CurPageID: Integer): Boolean;
begin
Result := True;
if CurPageID = wpSelectDir then
ButtonPanel[bidNext].Enabled := True;
end;

procedure DirectXLabelOnClick(Sender: TObject);
begin
if DirectX.Checked = False then
DirectX.Checked:= True else
DirectX.Checked:= False;
end;

procedure IconsOnClick(Sender: TObject);
begin
if Icons.Checked = False then
Icons.Checked:= True else
Icons.Checked:= False;
end;

procedure CheckStartMenuOnClick(Sender: TObject);
begin
if WizardForm.NoIconsCheck.Checked then
begin
WizardForm.GroupEdit.Enabled := not (WizardForm.GroupEdit.Enabled);
WizardForm.GroupBrowseButton.Enabled := False;
ButtonLabel[bidGroupBrowse].Enabled := False;
ButtonPanel[bidGroupBrowse].Enabled := False;
end else
begin
WizardForm.GroupEdit.Enabled := True;
WizardForm.GroupEdit.Enabled := WizardForm.GroupEdit.Enabled;
WizardForm.GroupBrowseButton.Enabled := True;
ButtonLabel[bidGroupBrowse].Enabled := True;
ButtonPanel[bidGroupBrowse].Enabled := True;
end;
end;

procedure CheckNoIconsCheck(Sender: TObject);
begin
if (WizardForm.NoIconsCheck.Checked = False) then
WizardForm.NoIconsCheck.Checked := True
else
WizardForm.NoIconsCheck.Checked := False;
end;


//************************************************ [Начало - Текстуры кнопок] ***************************************************//
procedure ButtonLabelClick(Sender: TObject);
var
Button: TButton;
begin
ButtonImage[TLabel(Sender).Tag].Left := 0;
case TLabel(Sender).Tag of
bidBack: Button := WizardForm.BackButton;
bidNext: Button := WizardForm.NextButton;
bidCancel: Button := WizardForm.CancelButton;
bidDirBrowse: Button := WizardForm.DirBrowseButton;
bidGroupBrowse: Button := WizardForm.GroupBrowseButton;
else
Exit
end
Button.OnClick(Button);
end;

procedure ButtonLabelMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
if ButtonLabel[TLabel(Sender).Tag].Enabled then
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 := 0;
end;

procedure LoadButtonImage(AButton: TButton; AButtonIndex: integer);
var
Image: TBitmapImage;
Panel: TPanel;
Labl: TLabel;

begin
Panel := TPanel.Create(WizardForm);
Panel.Left := AButton.Left;
Panel.Top := AButton.Top;
Panel.Width := AButton.Width;
Panel.Height := AButton.Height;
Panel.Tag := AButtonIndex;
Panel.Parent := AButton.Parent;
ButtonPanel[AButtonIndex] := Panel;

Image := TBitmapImage.Create(WizardForm);
Image.Width := ScaleX(160);
Image.Height := ScaleY(23);
Image.Enabled := False;
Image.Bitmap.LoadFromFile(ExpandConstant('{tmp}\button.bmp'));
Image.Stretch := True;
Image.Parent := Panel;
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);
Labl.Autosize := True;
Labl.Alignment := taCenter;
Labl.Tag := AButtonIndex;
Labl.Transparent := True;
Labl.Font.Color := clWhite;
Labl.Font.Style := [fsBold];
Labl.Caption := AButton.Caption;
Labl.OnClick := @ButtonLabelClick;
Labl.OnDblClick := @ButtonLabelClick;
Labl.OnMouseDown := @ButtonLabelMouseDown;
Labl.OnMouseUp := @ButtonLabelMouseUp;
Labl.Parent := Panel;
ButtonLabel[AButtonIndex] := Labl;
end;

procedure UpdateButton(AButton: TButton;AButtonIndex: integer);
begin
ButtonLabel[AButtonIndex].Caption := AButton.Caption;
ButtonPanel[AButtonIndex].Visible := AButton.Visible;
ButtonLabel[AButtonIndex].Enabled := Abutton.Enabled;
end;
//************************************************ [Конец - Текстуры кнопок] ***************************************************//

//************************************************ [Начало - Музыка] ***************************************************//
function BASS_Init(device: Integer; freq, flags: DWORD; win: hwnd; CLSID: Integer): Boolean;
external 'BASS_Init@files:BASS.dll stdcall delayload';

function BASS_StreamCreateFile(mem: BOOL; f: PChar; offset: DWORD; length: DWORD; flags: DWORD): DWORD;
external 'BASS_StreamCreateFile@files:BASS.dll stdcall delayload';

function BASS_Start(): Boolean;
external 'BASS_Start@files:BASS.dll stdcall delayload';

function BASS_ChannelPlay(handle: DWORD; restart: BOOL): Boolean;
external 'BASS_ChannelPlay@files:BASS.dll stdcall delayload';

function BASS_ChannelIsActive(handle: DWORD): Integer;
external 'BASS_ChannelIsActive@files:BASS.dll stdcall delayload';

function BASS_ChannelPause(handle: DWORD): Boolean;
external 'BASS_ChannelPause@files:BASS.dll stdcall delayload';

function BASS_Pause(): Boolean;
external 'BASS_Pause@files:BASS.dll stdcall delayload';

function BASS_Free(): Boolean;
external 'BASS_Free@files:BASS.dll stdcall delayload';

procedure PlayMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
PlayImage.Left := -100
end;

procedure PlayMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
PlayImage.Left := 4
end;

procedure PlayMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
if PlayImage.Left <> 100 then PlayImage.Left := -196
end;

procedure PauseMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
PauseImage.Left := -132
end;

procedure PauseMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
PauseImage.Left := -36
end;

procedure PauseMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
if PauseImage.Left <> -132 then PauseImage.Left := -228
end;

procedure MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
PlayImage.Left := -4
PauseImage.Left := 36
end;

procedure PlayButtonOnClick(Sender: TObject);
begin
case BASS_ChannelIsActive(mp3Handle) of
BASS_ACTIVE_PAUSED:
begin
BASS_ChannelPlay(mp3Handle, False);
PlayButton.Hide
PauseButton.Show
end;
end;
end;

procedure PauseButtonOnClick(Sender: TObject);
begin
BASS_ChannelPause(mp3Handle);
PauseButton.Hide
PlayButton.Show
end;
//************************************************ [Конец - Музыка] ***************************************************//


procedure AppProcessMessage;
var
Msg: TMessage;
begin
if not PeekMessage(Msg, {WizardForm.Handle} 0, 0, 0, PM_REMOVE) then Exit;
TranslateMessage(Msg); DispatchMessage(Msg);
end;

Function FreeArcCmd(callback: longword; cmd1,cmd2,cmd3,cmd4,cmd5,cmd6,cmd7,cmd8,cmd9,cmd10: PAnsiChar): integer;
Begin
CancelCode:= 0; AppProcessMessage;
try
Result:= FreeArcExtract(callback, cmd1,cmd2,cmd3,cmd4,cmd5,cmd6,cmd7,cmd8,cmd9,cmd10); // Pass the specified arguments to 'unarc.dll'
if CancelCode < 0 then Result:= CancelCode;
except
Result:= -63; // ArcFail
end;
End;

// Sets the TaskBar title
Procedure SetTaskBarTitle(Title: String); var h: Integer;
Begin
h:= GetWindowLong(MainForm.Handle, -8); if h <> 0 then SetWindowText(h, Title);
End;

// Перевод числа в строку с точностью 2 знака (%.2n) с округлением дробной части, если она есть
Function NumToStr(Float: Extended): String;
Begin
Result:= Format('%.2n', [Float]); StringChange(Result, ',', '.');
while ((Result[Length(Result)] = '0') or (Result[Length(Result)] = '.')) and (Pos('.', Result) > 0) do
SetLength(Result, Length(Result)-1);
End;

Function ByteOrTB(Bytes: Extended; noMB: Boolean): String; {Перевод числа в значение бт/Кб/Мб/Гб/Тб (до 2х знаков после запятой)}
Begin
if not noMB then Result:= NumToStr(Int(Bytes)) +' Mb' else
if Bytes < 1024 then if Bytes = 0 then Result:= '0' else Result:= NumToStr(Int(Bytes)) +' Bt' else
if Bytes/1024 < 1024 then Result:= NumToStr(round((Bytes/1024)*10)/10) +' Kb' else
If Bytes/oneMB < 1024 then Result:= NumToStr(round(Bytes/oneMB*100)/100) +' Mb' else
If Bytes/oneMB/1000 < 1024 then Result:= NumToStr(round(Bytes/oneMB/1024*1000)/1000) +' Gb' else
Result:= NumToStr(round(Bytes/oneMB/oneMB*1000)/1000) +' Tb';
End;

Function StringToArray(Text, Cut: String): array of String; var i, k: Integer; // поместить строки текста в элементы массив. шаблон перевода строк может быть любым. шаблон в начале/конце текста игнорируются
Begin
SetArrayLength(Result, 0); if Cut = '' then Cut:= #1310; //если шаблон пуст, считаем переводы строк
Repeat k:= Pos(Cut,Text);
if k = 1 then begin Delete(Text, 1, Length(Cut)); CONTINUE
end;
SetArrayLength(Result, GetArrayLength(Result) +1); i:= GetArrayLength(Result) -1;
if k = 0 then
Result[i]:=Text
else begin
Result[i]:= Copy(Text, 1, k -1); Delete(Text, 1, Length(Result[i]) + Length(Cut));
end;
Until Length(Text) * k = 0;
End;

Function CreateLabel(Parent: TWinControl; AutoSize, WordWrap, Transparent: Boolean; FontName: String; FontStyle: TFontStyles; FontColor: TColor; Left, Top, Width, Height: Integer; Prefs: TObject): TLabel;
Begin
Result:=TLabel.Create(Parent); Result.parent:= Parent;
if Prefs <> Nil then begin
Top:= TWinControl(Prefs).Top; Left:= TWinControl(Prefs).Left; Width:= TWinControl(Prefs).Width; Height:= TWinControl(Prefs).Height;
end;
if Top > 0 then result.Top:=Top; if Left > 0 then result.Left:= Left; if Width > 0 then result.Width:= Width; if Height > 0 then result.Height:= Height;
if FontName <> '' then result.Font.Name:= FontName; if FontColor > 0 then result.Font.Color:= FontColor; if FontStyle <> [] then result.Font.Style:= FontStyle;
result.AutoSize:= AutoSize; result.WordWrap:= WordWrap; result.Transparent:=Transparent; result.ShowHint:= true;
End;

// Converts milliseconds to human-readable time
// Конвертирует милисекунды в человеко-читаемое изображение времени
Function TicksToTime(Ticks: DWord; h,m,s: String; detail: Boolean): String;
Begin
if detail then {hh:mm:ss format}
Result:= PADZ(IntToStr(Ticks/3600000), 2) +':'+ PADZ(IntToStr((Ticks/1000 - Ticks/1000/3600*3600)/60), 2) +':'+ PADZ(IntToStr(Ticks/1000 - Ticks/1000/60*60), 2)
else if Ticks/3600 >= 1000 then {more than hour}
Result:= IntToStr(Ticks/3600000) +h+' '+ PADZ(IntToStr((Ticks/1000 - Ticks/1000/3600*3600)/60), 2) +m
else if Ticks/60 >= 1000 then {1..60 minutes}
Result:= IntToStr(Ticks/60000) +m+' '+ IntToStr(Ticks/1000 - Ticks/1000/60*60) +s
else Result:= Format('%.1n', [Abs(Ticks/1000)]) +s {less than one minute}
End;

Function ExpandENV(string: String): String; var n: UINT; Begin // ExpandConstant + развёртывание DOS-переменных типа %SystemRoot%
if Pos('{',string) * Pos('}',string) = 0 then Result:= String else Result:= ExpandConstant(String); n:= Pos('%',result); if n = 0 then Exit;
Delete(result, n,1); Result:= Copy(Result,1, n-1) + ExpandConstant('{%'+Copy(Result, n, Pos('%',result) -n) +'}') + Copy(Result, Pos('%',result) +1, Length(result))
End;

Function cm(Message: String): String; Begin Result:= ExpandConstant('{cm:'+ Message +'}') End;
Function LoWord(lw: LongWord): LongWord; Begin Result:= lw shr 16; End;

Function Size64(Hi, Lo: Integer): Extended;
Begin
Result:= Lo;
if Lo<0 then Result:= Result + $7FFFFFFF + $7FFFFFFF + 2;
for Hi:= Hi-1 Downto 0 do
Result:= Result + $7FFFFFFF + $7FFFFFFF + 2;
End;

Function RGB(r, g, b: Longint): Longint; Begin Result:= (r or (g shl 8) or (b shl 16)) End;
Function GetBValue(rgb: DWord): Byte; Begin Result:= Byte(rgb shr 16) End;
Function GetGValue(rgb: DWord): Byte; Begin Result:= Byte(rgb shr 8) End;
Function GetRValue(rgb: DWord): Byte; Begin Result:= Byte(rgb) End;

Procedure GradientFill(WorkBmp: TBitmapImage; BeginColor, FinishColor: Integer); var ColorBand: TRect; StartColor, i: Integer; Begin {если BeginColor < 0, то градиент горизонтальный}
WorkBmp.Bitmap.Width:= WorkBmp.Width; WorkBmp.Bitmap.Height:= WorkBmp.Height; StartColor:= trunc(Abs(BeginColor))
if BeginColor < 0 then n:= WorkBmp.Width else n:= WorkBmp.Height;
for i:=0 to n do begin if BeginColor < 0 then begin
ColorBand.Top:= 0; ColorBand.Bottom:= WorkBmp.Height;
ColorBand.Left:= MulDiv(i, WorkBmp.Width, n); ColorBand.Right:= MulDiv(i+1, WorkBmp.Width, n);
end else begin
ColorBand.Top:= MulDiv(i, WorkBmp.Height, n); ColorBand.Bottom:= MulDiv(i+1, WorkBmp.Height, n);
ColorBand.Left:= 0; ColorBand.Right:= WorkBmp.Width; end;
WorkBmp.Bitmap.Canvas.Brush.Color:= RGB(GetRValue(StartColor) + MulDiv(I, GetRValue(FinishColor) - GetRValue(StartColor), n-1), GetGValue(StartColor) + MulDiv(I, GetGValue(FinishColor) - GetGValue(StartColor), n-1), GetBValue(StartColor) + MulDiv(I, GetBValue(FinishColor) - GetBValue(StartColor), n-1));
WorkBmp.Bitmap.Canvas.FillRect(ColorBand); end;
End;

// Converts OEM encoded string into ANSI (Преобразует OEM строку в ANSI кодировку)
function OemToAnsiStr(strSource: AnsiString): AnsiString;
var
nRet : longint;
begin
SetLength(Result, Length(strSource));
nRet:= OemToChar(strSource, Result);
end;

// Converts ANSI encoded string into UTF-8 (Преобразует строку из ANSI в UTF-8 кодировку)
function AnsiToUtf8(strSource: string): string;
var
nRet, nRet2: integer; WideCharBuf, MultiByteBuf: AnsiString;
begin
SetLength(WideCharBuf, Length(strSource) * 2);
SetLength(MultiByteBuf, Length(strSource) * 2);
nRet:= MultiByteToWideChar(CP_ACP, 0, strSource, -1, WideCharBuf, Length(WideCharBuf));
nRet2:= WideCharToMultiByte(CP_UTF8, 0, WideCharBuf, -1, MultiByteBuf, Length(MultiByteBuf), 0, 0);
if nRet * nRet2 = 0 then Result:= strSource else Result:= MultiByteBuf;
end;

// ArcInd - текущий архив, счёт с 0
// baseMb - записано из пред. архива на диск
// lastMb - извлечено из тек. архива на диск
// Status.mb - позиция в текущем архиве
// Status.allsize - объём всех архивов
// Status.size - всего извлечено Мб на текущий момент
// totalUncompressedSize - точный объём данных в архивах
// общий прогресс нарастает по мере записи данных из архива на диск (точка 'write')
// прогресс архивов двигается в соответствии с позицией в текущем архиве (точка 'read')

Procedure UpdateStatus(Flags: Integer); // выполняется с периодичностью, заданной константой Period
var
Remaining: Integer; i, t, s: string;
Begin
if Flags and $1 > 0 then FreezeTimer:= Flags and $2 = 0; // bit 0 = 1 change start/stop, bit 1 = 0 stop, bit 1 = 1 start
if (Flags and $4 > 0) or (Status.size <> baseMb+lastMb) then LastTimerEvent:= 0; // bit 2 = 1 UpdateNow // обновить по флагу или записи из архива на диск
if FreezeTimer or (GetTickCount - LastTimerEvent <= Period) then Exit else LastTimerEvent:= GetTickCount;
Status.size := baseMb+lastMb; // извлечено на текущий момент
if totalUncompressedSize > 0 then with WizardForm.ProgressGauge do begin // основной прогресс движется по мере записи данных на диск
Position:= round(Max * Status.size/totalUncompressedSize)
end;
with WizardForm.ProgressGauge do begin // оставшееся время
#ifndef precomp
// к сожалению, этот код иногда сбоит на очень больших архивах, созданных с использованием внешних упаковщиков
if position > 0 then Remaining:= trunc((GetTickCount - StartInstall) * Abs((max - position)/position)) else
#endif
Remaining:= 0;
t:= cm('ending'); i:= t;
if Remaining > 0 then begin
t:= FmtMessage(cm('taskbar'), [IntToStr(Status.perc/10), TicksToTime(Remaining, 'h', 'm', 's', false)])
i:= TicksToTime(Remaining, cm('hour'), cm('min'), cm('sec'), false)
end;
end;
SetTaskBarTitle(t); // проценты и оставшееся время на кнопке инсталлятора
if Status.size > 0 then
s:= ' ['+ ByteOrTB(Status.size*oneMB, true) +']'; // если сделать подсчёт размера папки {app} через CalcDirSize, то при частом пересчёте папки большого объёма это может замедлить работу
StatusInfo.Caption:= FmtMessage(cm('StatusInfo'), [IntToStr(Status.count +ord(Status.count < 0)), s, Format('%.1n', [Abs(Status.perc/10)]), i]);
// второй прогрессбар движется по мере считывания текущего архива
if (Status.stage = cm('ArcTitle')) and (GetArrayLength(Arcs) > 0) then begin
ExtractFile.Caption:= FmtMessage(cm('ArcInfo'), [IntToStr(ArcInd+1), IntToStr(GetArrayLength(Arcs)), ByteOrTB(Arcs[ArcInd].Size, true), Format('%.0n', [Status.mb/(Arcs[ArcInd].Size/oneMB)*100]), ByteOrTB(Status.allsize, true)])
ProgressBar.Position:= round(ProgressBar.Max * Status.mb/trunc(Arcs[ArcInd].Size/oneMB))
end;
End;

Procedure MyTimerProc(h, msg, idevent, dwTime: Longword);
Begin
if WizardForm.CurPageID = wpInstalling then UpdateStatus(0);
End;

Procedure OnWndHook(Code: Integer; wParam: Word; lParam: TCWPSTRUCT);
Begin
if (Code = HC_ACTION) and (LoWord(lParam.msg) = WM_PAINT) then begin // подготовка данных для последующего отображения по таймеру
if (Status.name <> WizardForm.FileNameLabel.Caption) and (WizardForm.FileNameLabel.Caption <> '') then begin // имя файла, названия ярлыка и прочее
FileNameLabel.Caption:= WizardForm.FileNameLabel.Caption;
Status.name:= WizardForm.FileNameLabel.Caption; // начало извлечения или распаковки очередного файла
Case Status.stage of
SetupMessage(msgStatusExtractFiles): // этап извлечения файлов инсталлятором
Status.count:= Status.count +1; // кол-во файлов
End;
end;
if (Status.stage <> WizardForm.StatusLabel.Caption) and (WizardForm.StatusLabel.Caption <> '') then begin
StatusLabel.Caption:= WizardForm.StatusLabel.Caption;
Status.stage:= WizardForm.StatusLabel.Caption; // текущий этап установки
if Status.stage = SetupMessage(msgStatusRollback) then begin
WizardForm.StatusLabel.Hide; WizardForm.FileNameLabel.Hide; StatusInfo.Hide; ExtractFile.Hide; ProgressBar.Hide;
end;
end;
with WizardForm.ProgressGauge do begin
n:= (Max - Min)/1000
if n > 0 then Status.perc:= (Position-Min)/n; // 1000 процентов
end;
UpdateStatus(0);
end;
CallNextWNDPROC(WndHookID, Code, wParam, lParam) {освобождение события}
End;

// compsize: в Mb объём архива
// total_files: в int2 ? число файлов в архиве
// origsize: в Mb общий объём данных в архиве
// write: в Mb число записанных (распакованных из архива) на диск мегабайт
// read: в Mb число обработанных мегабайт, в int2 размер текущего архива
// filename: вызывается перед обработкой каждого файла

// The main callback function for unpacking FreeArc archives
function FreeArcCallback(what: PAnsiChar; Mb, int2: Integer; str: PAnsiChar): Integer; // вызывается не менее 100 раз в секунду, что заменяет вызов по таймеру
begin
case string(what) of
'origsize': origsize:= Mb; // данных в тек. архиве (при распаковке не вызывается)
'total_files': Null;
'filename': begin // Update FileName label
WizardForm.FileNameLabel.Caption:= OemToAnsiStr(str); // извлекаемый файл, их имена пишутся в журнал установки
FileNameLabel.Caption:= OemToAnsiStr(str); // извлекаемый файл, их имена пишутся в журнал установки
Status.count:= Status.count + 1; // кол-во файлов, этап распаковки
end;
'read': // позиция в текущем архиве
Status.mb:= Mb;
'write': // Assign to Mb *total* amount of data extracted to the moment from all archives
lastMb:= Mb; // извлечено из текущего архива
end;
if WizardForm.CurPageID = wpInstalling then UpdateStatus(0); // обновить страницу установки, не сбрасывая таймер
if (GetKeyState(VK_ESCAPE) < 0) and not CancelDuringInstall then
WizardForm.Close; // опрашиваем Cancel (если разрешена отмена установки)
AppProcessMessage;
Result:= CancelCode;
end;

Function ArcDecode(Line: string): array of TArc; // разбор строки Archives
var tmp, cut: array of String; n, i: integer;
Begin
SetArrayLength(result,0); if Line <> '' then tmp:= StringToArray(Line,'|') else Exit;
for n:= 0 to GetArrayLength(tmp) - 1 do begin
if tmp[n][Length(tmp[n])] = '?' then Continue; // эта запись обрабатывается в AfterInstall: UnArc(...)
SetArrayLength(result, GetArrayLength(result) +1); i:= GetArrayLength(result) -1;
cut:= StringToArray(tmp[n],'>') // задачи, логика or and not наверное не будет работать
if GetArrayLength(cut) > 1 then result[i].task:= cut[1];
cut:= StringToArray(cut[0],'<') // компоненты
if GetArrayLength(cut) > 1 then result[i].comp:= cut[1];
cut:= StringToArray(cut[0],'/') // папка распаковки
if GetArrayLength(cut) > 1 then result[i].Dest:= cut[1] else result[i].Dest:= '{app}'; // по-умолчанию
if (ExtractFileDrive(ExpandENV(cut[0])) = '') and (ExpandENV(cut[0]) = cut[0]) then // строка вида Rus\*.arc
result[i].Path:= '{src}\'+ cut[0] else result[i].Path:= cut[0]; // остаток от исходной строки
result[i].Dest:= ExpandENV(result[i].Dest); result[i].Path:= ExpandENV(result[i].Path);
end;
End;

// Scans the specified folders for archives and add them to list
function AddArcs(files, target: string): Integer; // добавление архивов в общий список и подсчёт объёма распакованных данных
var FSR: TFindRec; i: integer;
Begin
Result:= 0; if FindFirst(ExpandENV(files), FSR) then
try
repeat
// Skip everything but the folders
if FSR.Attributes and FILE_ATTRIBUTE_DIRECTORY > 0 then CONTINUE;
// Expand the folder list
i:= GetArrayLength(Arcs); SetArrayLength(Arcs, i +1);
Arcs[i].Dest:= target; // путь распаковки для найденных по маске архивов
Arcs[i].Path:= ExtractFilePath(ExpandENV(files)) + FSR.Name;
Arcs[i].Size:= Size64(FSR.SizeHigh, FSR.SizeLow);
Status.allsize:= Status.allsize + Arcs[i].Size; // зарезервировано для подсчёта прогресса распаковки 7-zip архивов (is7z.dll)
Arcs[i].allMb:= FreeArcCmd(WrapFreeArcCallback(@FreeArcCallback,4),'l','--',AnsiToUtf8(Arcs[i].Path),'','','','','','',''); // код ошибки
if Arcs[i].allMb >= 0 then begin
Arcs[i].allMb:= origsize; result:= result + Arcs[i].allMb; // размер распакованных данных успешно считан
end;
until not FindNext(FSR);
finally
FindClose(FSR);
end;
End;

function UnPackArchive(Source, Destination: string; allMb, Mode: Integer): Integer;
var
callback: longword;
Begin
// если отмена установки разрешена, кнопка Cancel станет доступна
WizardForm.CancelButton.Enabled:= not CancelDuringInstall;
callback:= WrapFreeArcCallback(@FreeArcCallback,4); //FreeArcCallback has 4 arguments
Result:= FreeArcCmd(callback,'x','-o+','-dp'+AnsiToUtf8(Destination),'--',AnsiToUtf8(Source),'','','','',''); // код ошибки
// Error occured
if Result = 0 then Exit;
msgError:= FmtMessage(cm('ArcError'), [IntToStr(Result)]);
WizardForm.StatusLabel.Caption:= msgError;
WizardForm.FileNameLabel.Caption:= ExtractFileName(Source);
GetSpaceOnDisk(ExtractFileDrive(Destination), True, FreeMB, TotalMB);
case Result of
-1: if FreeMB < allMb {Мб на диске} then msgError:= SetupMessage(msgDiskSpaceWarningTitle)
else msgError:= msgError + #13#10 + FmtMessage(cm('ArcBroken'), [ExtractFileName(Source)]);
-127: msgError:= cm('ArcBreak'); //Cancel button
-63: msgError:= cm('ArcFail');
end;
Log(msgError); // записываем ошибку в лог, а также показываем её текст на странице завершения
End;

// Extracts all found archives
function UnPack(Archives: string): Integer;
begin
// UpdateStatus(1); // остановить таймер
Records:= ArcDecode(Archives); SetArrayLength(Arcs,0); Status.allsize:= 0; {общий объём}
for n:= 0 to GetArrayLength(Records) -1 do // Get the size of all archives
if (not IsTaskSelected(Records[n].task) and (Records[n].task <>'')) and (not IsComponentSelected(Records[n].comp) and (Records[n].comp <>'')) then Continue // компоненты и задачи не выбраны
else totalUncompressedSize:= totalUncompressedSize + AddArcs(Records[n].Path, Records[n].Dest); // создаём список архивов
// Other initializations
WizardForm.StatusLabel.Caption:= cm('ArcTitle'); // начало этапa распаковки
ExtractFile.Show; ProgressBar.Show;
baseMb:= 0; lastMb:= 0; Status.mb:= 0; // обнулить полученные мегабайты, если ранее вёлся подсчёт объёма файлов инсталлятора
Status.count:= 0; // не учитывать файлы, извлечённые инсталлятором
UpdateStatus(7); // немедленно обновить строку статуса
for ArcInd:= 0 to GetArrayLength(Arcs) -1 do begin // архивы в текущей папке, константы раскрыты в ArcDecode
Result:= UnPackArchive(Arcs[ArcInd].Path, Arcs[ArcInd].Dest, Arcs[ArcInd].allMb, 0); // код ошибки
if Result <> 0 then Break; // прервать цикл распаковки
baseMb:= baseMb + lastMb; lastMb:= 0; Status.mb:= 0; // общий объём распакованных файлов
// отработанный архив автоматически удаляется, если находится в папке {app} или {tmp}
if (Pos(AnsiLowercase(ExpandConstant('{app}')), AnsiLowercase(Arcs[ArcInd].Path)) > 0) or (Pos(AnsiLowercase(ExpandConstant('{tmp}')), AnsiLowercase(Arcs[ArcInd].Path)) > 0) then
DeleteFile(Arcs[ArcInd].Path);
end;
if Result = 0 then WizardForm.StatusLabel.Caption:= FmtMessage(cm('ArcFinish'), [IntToStr(GetArrayLength(Arcs)), IntToStr(Status.count), ByteOrTB(Status.size*oneMB, true)]);
StatusInfo.Hide; ExtractFile.Hide; ProgressBar.Hide;
end;

procedure CurStepChanged2(CurStep: TSetupStep);
begin
if CurStep = ssInstall then begin
StartInstall:= GetTickCount {время начала извлечения файлов}
WndHookID:= SetWindowsHookEx(WH_CALLWNDPROC, WrapCWPSTRUCTProc(@OnWndHook, 3), 0, GetCurrentThreadID); {установка SendMessage хука}
TimerID:= SetTimer(0, 0, 500 {полсекунды}, WrapTimerProc(@MyTimerProc, 4)); {установка таймера}
if not {#isFalse(SetupSetting("Uninstallable"))} then Status.count:= -1; // не считать файл unins000.exe
end;
if CurStep = ssPostInstall then
begin
StartInstall:= GetTickCount {время начала распаковки}
UnPackError:= UnPack('{#Archives}')
if UnPackError <> 0 then begin // Error occured, uninstall it then
if not {#isFalse(SetupSetting("Uninstallable"))} then // деинсталляция разрешёна
Exec(ExpandConstant('{uninstallexe}'), '/SILENT','', sw_Hide, ewWaitUntilTerminated, n); // откат установки из-за ошибки unarc.dll
WizardForm.caption:= SetupMessage(msgErrorTitle) +' - '+ cm('ArcBreak')
SetTaskBarTitle(SetupMessage(msgErrorTitle))
end else
SetTaskBarTitle(SetupMessage(msgSetupAppTitle));
end;
end;

Procedure SetTexture(CurPageID: Integer); // на каждой странице своя картинка
Begin
WizardForm.Bevel1.Visible:= (WizardForm.CurPageID <> wpWelcome) and (WizardForm.CurPageID <> wpFinished);
WizardForm.Bevel1.Parent:= WizardForm.OuterNotebook.ActivePage
Texture.Parent:= WizardForm.InnerNotebook.ActivePage; Texture.SendToBack;
Texture.Visible:= CurPageID = wpInstalling; Texture2.Visible:= Texture.Visible;
End;

Procedure CurPageChanged1(CurPageID: Integer);
Begin
UpdateButton(WizardForm.BackButton,bidBack)
UpdateButton(WizardForm.NextButton,bidNext)
UpdateButton(WizardForm.CancelButton,bidCancel)

ButtonLabel[bidBack].Left := ButtonPanel[bidBack].Width div 2 - ButtonLabel[bidBack].Width div 2;
ButtonLabel[bidBack].Top := ButtonPanel[bidBack].Height div 2 - ButtonLabel[bidBack].Height div 2;
ButtonLabel[bidNext].Left := ButtonPanel[bidNext].Width div 2 - ButtonLabel[bidNext].Width div 2;
ButtonLabel[bidNext].Top := ButtonPanel[bidNext].Height div 2 - ButtonLabel[bidNext].Height div 2;
ButtonLabel[bidCancel].Left := ButtonPanel[bidCancel].Width div 2 - ButtonLabel[bidCancel].Width div 2;
ButtonLabel[bidCancel].Top := ButtonPanel[bidCancel].Height div 2 - ButtonLabel[bidCancel].Height div 2;
ButtonLabel[bidDirBrowse].Left := ButtonPanel[bidDirBrowse].Width div 2 - ButtonLabel[bidDirBrowse].Width div 2;
ButtonLabel[bidDirBrowse].Top := ButtonPanel[bidDirBrowse].Height div 2 - ButtonLabel[bidDirBrowse].Height div 2;
ButtonLabel[bidGroupBrowse].Left := ButtonPanel[bidGroupBrowse].Width div 2 - ButtonLabel[bidGroupBrowse].Width div 2;
ButtonLabel[bidGroupBrowse].Top := ButtonPanel[bidGroupBrowse].Height div 2 - ButtonLabel[bidGroupBrowse].Height div 2;

PageNameLabel1.Caption:= WizardForm.PageNameLabel.Caption;
PageDescriptionLabel1.Caption:= WizardForm.PageDescriptionLabel.Caption;
PageNameLabel2.Caption:= WizardForm.PageNameLabel.Caption;
PageDescriptionLabel2.Caption:= WizardForm.PageDescriptionLabel.Caption;
PageNameLabel3.Caption:= WizardForm.PageNameLabel.Caption;

if CurPageID=wpSelectProgramGroup then
begin
If WizardForm.FindComponent('NextButton') is TButton
then
TButton(WizardForm.FindComponent('NextButton')).Caption:='Установить';
SetTexture(CurPageID)

if (CurPageID = wpFinished) and (UnPackError <> 0) then
begin // Extraction was unsuccessful (распаковщик вернул ошибку)
// Show error message
WizardForm.FinishedLabel.Font.Color:= $0000C0; // red (красный)
WizardForm.FinishedLabel.Height:= WizardForm.FinishedLabel.Height * 2;
WizardForm.FinishedLabel.Caption:= SetupMessage(msgSetupAborted) + #13#10#13#10 + msgError;
end;
End;
End;

procedure WizardClose(Sender: TObject; var Action: TCloseAction);
Begin
Action:= caNone; // так надо
if Status.stage = cm('ArcTitle') then begin // распаковка на этапе ssPostInstall
UpdateStatus(1); // остановить таймер
if MsgBox(SetupMessage(msgExitSetupMessage), mbInformation, MB_YESNO) = IDYES then
CancelCode:= -127; // прервать распаковку
UpdateStatus(7); // обновить информацию
end else
MainForm.Close; // стандартное нажатие кнопки закрытия окна, отмены или Escape.
End;

procedure GetFreeSpaceCaption(Sender: TObject);
var
Path: String;
begin
Path := ExtractFileDrive(WizardForm.DirEdit.Text);
GetSpaceOnDisk(Path, True, FreeMB, TotalMB);
if FreeMB > 1024 then
FreeSpaceLabel.Caption := ExpandConstant('{cm:SPACE} ')+ NumToStr(round(FreeMB/1024*100)/100) + ' GB' else
FreeSpaceLabel.Caption := ExpandConstant('{cm:SPACE} ')+ NumToStr(FreeMB)+ ' MB';
end;

procedure GetNeedSpaceCaption;
begin
if NeedSize > 1024 then
NeedSpaceLabel.Caption := ExpandConstant('{cm:SPACE1} ')+ NumToStr(round(NeedSize/1024*100)/100) + ' GB' else
NeedSpaceLabel.Caption := ExpandConstant('{cm:SPACE1} ')+ NumToStr(NeedSize)+ ' MB';
end;

procedure ProgressExt();
begin
FilenameLabel.Caption:= ExpandConstant(ExtractFileDir(CurrentFilename)) + '\' + ExtractFilename(CurrentFilename);
end;

procedure ProgressExt2();
begin
FilenameLabel.Caption:= ExpandConstant('{cm:DirectXInstall}')
end;

Procedure InitializeWizard();
Var
CurPageID: Integer;
Begin
ExtractTemporaryFile('MusicButton.bmp')
ExtractTemporaryFile('1.bmp');
ExtractTemporaryFile('2.bmp');
ExtractTemporaryFile('3.bmp');
ExtractTemporaryFile('4.bmp');
ExtractTemporaryFile('5.bmp');

NeedSize:= {#NeedSize};

BmpFile:= TBitmapImage.Create(WizardForm);
BmpFile.Bitmap.LoadFromFile(ExpandConstant('{tmp}\1.bmp'));
BmpFile.Top:= ScaleY(0);
BmpFile.Left:= ScaleX(0);
BmpFile.Width:= ScaleX(790);
BmpFile.Height:= ScaleY(533);
BmpFile.Stretch:= true;
BmpFile.Parent:= WizardForm.WelcomePage;

BmpFile:= TBitmapImage.Create(WizardForm);
BmpFile.Bitmap.LoadFromFile(ExpandConstant('{tmp}\2.bmp'));
BmpFile.Top:= ScaleY(0);
BmpFile.Left:= ScaleX(0);
BmpFile.Width:= ScaleX(790);
BmpFile.Height:= ScaleY(533);
BmpFile.Stretch:= true;
BmpFile.Parent:= WizardForm.SelectDirPage;

BmpFile:= TBitmapImage.Create(WizardForm);
BmpFile.Bitmap.LoadFromFile(ExpandConstant('{tmp}\3.bmp'));
BmpFile.Top:= ScaleY(0);
BmpFile.Left:= ScaleX(0);
BmpFile.Width:= ScaleX(790);
BmpFile.Height:= ScaleY(533);
BmpFile.Stretch:= true;
BmpFile.Parent:= WizardForm.SelectProgramGroupPage;

BmpFile:= TBitmapImage.Create(WizardForm);
BmpFile.Bitmap.LoadFromFile(ExpandConstant('{tmp}\4.bmp'));
BmpFile.Top:= ScaleY(0);
BmpFile.Left:= ScaleX(0);
BmpFile.Width:= ScaleX(790);
BmpFile.Height:= ScaleY(533);
BmpFile.Stretch:= true;
BmpFile.Parent:= WizardForm.InstallingPage;

BmpFile:= TBitmapImage.Create(WizardForm);
BmpFile.Bitmap.LoadFromFile(ExpandConstant('{tmp}\5.bmp'));
BmpFile.Top:= ScaleY(0);
BmpFile.Left:= ScaleX(0);
BmpFile.Width:= ScaleX(790);
BmpFile.Height:= ScaleY(533);
BmpFile.Stretch:= true
BmpFile.Parent:= WizardForm.FinishedPage;

WizardForm.ClientWidth:=ScaleX(790);
WizardForm.ClientHeight:=ScaleY(533);
WizardForm.Font.Color:=$ffffff;
WizardForm.Center;

with WizardForm do
begin
PageNameLabel.Hide;
PageDescriptionLabel.Hide;
WelcomeLabel1.Hide;
WelcomeLabel2.Hide;
DiskSpaceLabel.Hide;
SelectDirBitmapImage.Hide;
SelectDirBrowseLabel.Hide;
SelectDirLabel.Hide;
FinishedHeadingLabel.Hide;
FinishedLabel.Hide;
MainPanel.Hide;
FilenameLabel.Hide;
StatusLabel.Hide;
SelectStartMenuFolderLabel.Hide;
SelectStartMenuFolderBrowseLabel.Hide;
ReadyLabel.Hide;
end;

with WizardForm do
begin
InnerNotebook.Left := ScaleX(0);
InnerNotebook.Top := ScaleY(0);
InnerNotebook.Width := ScaleX(790);
InnerNotebook.Height := ScaleY(533);
OuterNotebook.Left := ScaleX(0);
OuterNotebook.Top := ScaleY(0);
OuterNotebook.Width := ScaleX(790);
OuterNotebook.Height := ScaleY(533);
end;

////////////////////// WelcomePage //////////////////////

WelcomeLabel1:= TLabel.Create(WizardForm);
with WelcomeLabel1 do
begin
Left:= ScaleX(70);
Top:= ScaleY(180);
Width:= ScaleX(650);
Height:= ScaleY(65);
AutoSize:= false;
Alignment := taCenter;
Transparent:= true;
WordWrap:= true;
Font.Name:='Georgia';
Font.Size:= 16;
Font.Color:=ClWhite;
Font.Style := [fsBold];
Parent:= WizardForm.WelcomePage;
Caption:= ExpandConstant('{cm:Welcome1}')+#13+('{#MyAppName}');
end;

WelcomeLabel2:=TLabel.Create(WizardForm);
with WelcomeLabel2 do
begin
Top:= ScaleY(270);
Left:= ScaleX(70);
Width:= ScaleX(650);
Height:= ScaleY(200);
AutoSize:= false;
WordWrap:= true;
Font.Name:= 'Georgia';
Font.Size:= 11
Font.Style := [fsBold, fsItalic];
Font.Color:=ClWhite;
Transparent:= true;
Parent:= WizardForm.WelcomePage;
Caption:= ExpandConstant('{cm:Welcome2}');
end;

////////////////////// WelcomePage //////////////////////

////////////////////// SelectDirPage //////////////////////

PageNameLabel1:= TLabel.Create(WizardForm);
with PageNameLabel1 do
begin
Left:= ScaleX(65);
Top:= ScaleY(185);
Width:= ScaleX(300);
Height:= ScaleY(30);
AutoSize:= False;
Font.Name:= 'Georgia'
Font.Size:= 13;
Font.Style:= [fsBold];
Font.Color:= ClWhite;
Transparent := True;
Parent:= WizardForm.SelectDirPage;
end;

PageDescriptionLabel1:= TLabel.Create(WizardForm);
with PageDescriptionLabel1 do
begin
Left:=ScaleX(95);
Top:= ScaleY(215);
Width:= ScaleX(600);
Height:= ScaleY(50);
AutoSize:= False;
Font.Name:= 'Georgia'
Font.Size:= 10;
Font.Style:= [fsBold, fsItalic];
Font.Color:= ClWhite;
Wordwrap:= True;
Transparent := True;
Parent:= WizardForm.SelectDirPage;
end;

SelectDirBrowseLabel:= TLabel.Create(WizardForm);
with SelectDirBrowseLabel do
begin
Caption:= WizardForm.SelectDirBrowseLabel.Caption;
Left:= ScaleX(120);
Top:= ScaleY(250);
Width:= ScaleX(600);
Height:= ScaleY(50);
AutoSize:= False;
WordWrap:= True;
Font.Name:= 'Georgia'
Font.Size:= 10;
Font.Style:= [fsBold, fsItalic];
Font.Color:= ClWhite;
Transparent:= True;
Parent:= WizardForm.SelectDirPage;
end;

with WizardForm do
begin
DirBrowseButton.Top:= ScaleY(305);

DirEdit.Left:= ScaleX(120);
DirEdit.Top:= ScaleY(305);
DirEdit.Width:= ScaleX(460);
DirEdit.Font.Size:= 9;
DirEdit.Font.Style:= [fsBold, fsItalic];
DirEdit.Font.Name:= 'Georgia'


end;

DirectX:= TCheckBox.Create(WizardForm);
with DirectX do
begin
Parent:= WizardForm.SelectDirPage;
Left:= ScaleX(65);
Top:= ScaleY(340);
Width:= ScaleX(14);
Height:= ScaleY(14);
TabOrder:= 0;
Checked:= False;
end;

DirectXLabel:= TLabel.Create(WizardForm);
with DirectXLabel do
begin
Caption:= ExpandConstant('{cm:DirectX}');
Left:= ScaleX(90);
Top:= ScaleY(340);
Width:= ScaleX(150);
Height:= ScaleY(13);
Font.Name:= 'Georgia';
Font.Size:= 8;
Font.Style:= [fsBold, fsItalic];
Font.Color:= ClWhite;
Transparent := True;
Parent:= WizardForm.SelectDirPage;
OnClick:= @DirectXLabelOnClick;
end;

Icons:= TCheckBox.Create(WizardForm);
with Icons do
begin
Parent:= WizardForm.SelectDirPage;
Left:= ScaleX(65);
Top:= ScaleY(360);
Width:= ScaleX(14);
Height:= ScaleY(14);
TabOrder:= 2;
Checked:= False;
end;

IconsLabel:= TLabel.Create(WizardForm);
with IconsLabel do
begin
Caption:=ExpandConstant('{cm:Icons}');
Left:= ScaleX(90);
Top:= ScaleY(360);
Width:= ScaleX(150);
Height:= ScaleY(13);
Font.Name:= 'Georgia';
Font.Size:= 8;
Font.Style:= [fsBold, fsItalic];
Font.Color:= ClWhite;
Transparent := True;
Parent:= WizardForm.SelectDirPage;
OnClick:= @IconsOnClick;
end;

NeedSpaceLabel:= TLabel.Create(WizardForm);
with NeedSpaceLabel do
begin
Parent:= WizardForm.SelectDirPage;
Left:= ScaleX(65);
Top:= ScaleY(420);
Width:= ScaleX(209);
Height:= ScaleY(13);
Font.Name:= 'Georgia';
Font.Size:= 8;
Font.Style:= [fsBold, fsItalic];
Font.Color:= ClWhite;
Transparent:= True;
end;

FreeSpaceLabel:= TLabel.Create(WizardForm);
with FreeSpaceLabel do
begin
Parent:= WizardForm.SelectDirPage;
Left:= ScaleX(65);
Top:= ScaleY(440);
Width:= ScaleX(209);
Height:= ScaleY(13);
Font.Name:= 'Georgia';
Font.Size:= 8;
Font.Style:= [fsBold, fsItalic];
Font.Color:= ClWhite;
Transparent:= True;
end;

WizardForm.DirEdit.OnChange:= @GetFreeSpaceCaption;
WizardForm.DirEdit.Text:= WizardForm.DirEdit.Text + #0;

////////////////////// SelectDirPage //////////////////////

////////////////////// ProgrammGroupPage //////////////////////

PageNameLabel2:= TLabel.Create(WizardForm);
with PageNameLabel2 do
begin
Left:= ScaleX(65);
Top:= ScaleY(185);
Width:= ScaleX(350);
Height:= ScaleY(30);
AutoSize:= False;
Font.Name:= 'Georgia';
Font.Size:= 13;
Font.Style:= [fsBold];
Font.Color:= ClWhite;
Transparent := True;
Parent:= WizardForm.SelectProgramGroupPage;
end;

PageDescriptionLabel2:= TLabel.Create(WizardForm);
with PageDescriptionLabel2 do
begin
Left:=ScaleX(95);
Top:= ScaleY(215);
Width:= ScaleX(600);
Height:= ScaleY(50);
AutoSize:= False;
Font.Name:= 'Georgia'
Font.Size:= 10;
Font.Style:= [fsBold, fsItalic];
Font.Color:= ClWhite;
Wordwrap:= True;
Transparent := True;
Parent:= WizardForm.SelectProgramGroupPage;
end;

SelectStartMenuFolderBrowseLabel:=TLabel.Create(WizardForm)
with SelectStartMenuFolderBrowseLabel do
begin
Left:= ScaleX(120);
Top:= ScaleY(250);
Width:= ScaleX(600);
Height:= ScaleY(50);
AutoSize:= False;
WordWrap:= True;
Font.Name:= 'Georgia';
Font.Size:= 10;
Font.Style:= [fsBold, fsItalic];
Font.Color:= ClWhite;
WordWrap:=True
Transparent:=True
Caption:=ExpandConstant('{cm:StartMenuLbl}')
Parent:=WizardForm.SelectProgramGroupPage
end;

WizardForm.NoIconsCheck.Show;
WizardForm.NoIconsCheck.Left := ScaleX(65);
WizardForm.NoIconsCheck.Top := ScaleY(440);
WizardForm.NoIconsCheck.Width := ScaleX(13);
WizardForm.NoIconsCheck.Height := ScaleY(13);
WizardForm.NoIconsCheck.OnClick := @CheckStartMenuOnClick;
WizardForm.NoIconsCheck.Parent := WizardForm.SelectProgramGroupPage;

NoIconsLabel:= TLabel.Create(WizardForm);
with NoIconsLabel do
begin
Caption:=WizardForm.NoIconsCheck.Caption
Left:= ScaleX(90);
Top:= ScaleY(440);
Width:= ScaleX(150);
Height:= ScaleY(13);
Font.Name:= 'Georgia';
Font.Size:= 8;
Font.Style:= [fsBold, fsItalic];
Font.Color:= ClWhite;
Transparent := True;
Parent:= WizardForm.SelectProgramGroupPage
OnClick := @CheckNoIconsCheck;
end;

with WizardForm do
begin
GroupEdit.Left:= ScaleX(120);
GroupEdit.Top:= ScaleY(305);
GroupEdit.Width:= ScaleX(460);
GroupEdit.Font.Size:=9
GroupEdit.Font.Style:= [fsBold, fsItalic];
GroupEdit.Font.Name:= 'Georgia'

GroupBrowseButton.Top:= ScaleY(305);
end;

////////////////////// ProgrammGroupPage //////////////////////

////////////////////// InstallingPage //////////////////////

PageNameLabel3:= TLabel.Create(WizardForm);
with PageNameLabel3 do
begin
Left:= ScaleX(65);
Top:= ScaleY(185);
Width:= ScaleX(150);
Height:= ScaleY(20);
AutoSize:= False;
Font.Name:= 'Georgia';
Font.Size:= 13;
Font.Style:= [fsBold];
Font.Color:= ClWhite;
Transparent := True;
Parent:= WizardForm.InstallingPage;
end;

StatusLabel:= TLabel.Create(WizardForm);
with StatusLabel do
begin
Left:=ScaleX(95);
Top:= ScaleY(215);
Width:= ScaleX(600);
Height:= ScaleY(50);
AutoSize:= False;
Font.Name:= 'Georgia';
Font.Size:= 10;
Font.Style:= [fsBold, fsItalic];
Font.Color:= ClWhite;
Transparent := True;
Parent:= WizardForm.InstallingPage;
Caption:= ExpandConstant('{cm:Status}')
end;

FilenameLabel:= TLabel.Create(WizardForm);
with FilenameLabel do
begin
Left:= ScaleX(65);
Top:= ScaleY(275);
Width:= ScaleX(625);
Height:= ScaleY(20);
AutoSize:= False;
Font.Name:= 'Georgia'
Font.Size:= 10;
Font.Style:= [fsBold, fsItalic];
Font.Color:= ClWhite;
Transparent := True;
Parent:= WizardForm.InstallingPage;
end;

with WizardForm do
begin
ProgressGauge.Top:=ScaleY(310);
ProgressGauge.Left:=ScaleX(100);
ProgressGauge.Width:=ScaleX(590);
end;

////////////////////// InstallingPage //////////////////////

////////////////////// FinishedPage //////////////////////

FinishedHeadingLabel:=TLabel.Create(WizardForm);
with FinishedHeadingLabel do
begin
Left:= ScaleX(70);
Top:= ScaleY(180);
Width:= ScaleX(650);
Height:= ScaleY(65)
AutoSize:= false;
Alignment := taCenter;
WordWrap:= true;
Font.Name:='Georgia';
Font.Size:= 16;
Font.Color:=ClWhite;
Font.Style := [fsBold];
Transparent:= true;
Parent:= WizardForm.FinishedPage;
Caption:= ExpandConstant('{cm:Finished1}');
end;

FinishedLabel:= TLabel.Create(WizardForm);
with FinishedLabel do
begin
Top:= ScaleY(270);
Left:= ScaleX(70);
Width:= ScaleX(650);
Height:= ScaleY(200);
AutoSize:= false;
WordWrap:= true;
Font.Name:= 'Georgia'
Font.Size:= 11;
Font.Style := [fsBold, fsItalic];
Font.Color:=ClWhite;
Transparent:= true;
Parent:= WizardForm.FinishedPage;
Caption:= ExpandConstant('{cm:Finished2}')+#13#13+ExpandConstant('{cm:Finished3}');
end;
////////////////////// FinishedPage //////////////////////

//************************************************ [Начало - Музыка] ***************************************************//
MouseLabel := TLabel.Create(WizardForm)
MouseLabel.Width := WizardForm.Width
MouseLabel.Height := WizardForm.Height
MouseLabel.Autosize := False
MouseLabel.Transparent := True
MouseLabel.OnMouseMove := @MouseMove
MouseLabel.Parent := WizardForm

PlayButton := TPanel.Create(WizardForm)
PlayButton.Left := ScaleX(762)
PlayButton.Top := ScaleY(3)
PlayButton.Width := 25
PlayButton.Height := 23
PlayButton.Cursor := crHand
PlayButton.ShowHint := True
PlayButton.Hint := 'Воспроизведение музыки'
PlayButton.OnClick := @PlayButtonOnClick
PlayButton.Parent := WizardForm

PlayImage := TBitmapImage.Create(WizardForm)
PlayImage.Left := 0
PlayImage.Top := 0
PlayImage.Width := 288
PlayImage.Height := 23
PlayImage.Enabled := False
PlayImage.Bitmap.LoadFromFile(ExpandConstant('{tmp}\MusicButton.bmp'))
PlayImage.Parent := PlayButton

PlayImage.ReplaceColor:=$E2E2E2
PlayImage.ReplaceWithColor:=clBtnFace


PlayLabel := TLabel.Create(WizardForm)
PlayLabel.Width := PlayButton.Width
PlayLabel.Height := PlayButton.Height
PlayLabel.Autosize := False
PlayLabel.Transparent := True
PlayLabel.OnClick := @PlayButtonOnClick
PlayLabel.OnMouseDown := @PlayMouseDown
PlayLabel.OnMouseUp := @PlayMouseUp
PlayLabel.OnMouseMove := @PlayMouseMove
PlayLabel.Parent := PlayButton

PauseButton := TPanel.Create(WizardForm)
PauseButton.Left := ScaleX(762)
PauseButton.Top := ScaleY(3)
PauseButton.Width := 25
PauseButton.Height := 23
PauseButton.Cursor := crHand
PauseButton.ShowHint := True
PauseButton.Hint := 'Приостановить музыку'
PauseButton.OnClick := @PauseButtonOnClick
PauseButton.Parent := WizardForm

PauseImage := TBitmapImage.Create(WizardForm)
PauseImage.Left := -36
PauseImage.Top := 0
PauseImage.Width := 288
PauseImage.Height := 23
PauseImage.Enabled := False
PauseImage.Bitmap.LoadFromFile(ExpandConstant('{tmp}\MusicButton.bmp'))
PauseImage.Parent := PauseButton

PauseImage.ReplaceColor:=$E2E2E2
PauseImage.ReplaceWithColor:=clBtnFace

PauseLabel := TLabel.Create(WizardForm)
PauseLabel.Width := PauseButton.Width
PauseLabel.Height := PauseButton.Height
PauseLabel.Autosize := False
PauseLabel.Transparent := True
PauseLabel.OnClick := @PauseButtonOnClick
PauseLabel.OnMouseDown := @PauseMouseDown
PauseLabel.OnMouseUp := @PauseMouseUp
PauseLabel.OnMouseMove := @PauseMouseMove
PauseLabel.Parent := PauseButton
//************************************************ [Конец - Музыка] ***************************************************//

//************************************************ [Начало - Панель] ***************************************************//
Welcome := TLabel.Create(WizardForm);
Welcome.Top := ScaleY(94);
Welcome.Left := ScaleX(35);
Welcome.Caption := 'Приветствие';
Welcome.Transparent := True;
Welcome.Font.Size := 10;
Welcome.Font.Name := 'Arial';
Welcome.Font.Style:= [fsBold];

Parameters := TLabel.Create(WizardForm);
Parameters.Top := ScaleY(94);
Parameters.Left := ScaleX(201);
Parameters.Caption:= 'Параметры';
Parameters.Transparent := True;
Parameters.Font.Size := 10;
Parameters.Font.Name := 'Arial';
Parameters.Font.Style:= [fsBold];

StartMenu := TLabel.Create(WizardForm);
StartMenu.Top := ScaleY(94);
StartMenu.Left := ScaleX(355);
StartMenu.Caption := 'Меню "Пуск"';
StartMenu.Transparent := True;
StartMenu.Font.Size := 10;
StartMenu.Font.Name := 'Arial';
StartMenu.Font.Style:= [fsBold];

Installing := TLabel.Create(WizardForm);
Installing.Top := ScaleY(94);
Installing.Left := ScaleX(520);
Installing.Caption := 'Установка';
Installing.Transparent := True;
Installing.Font.Size := 10;
Installing.Font.Name := 'Arial';
Installing.Font.Style:= [fsBold];


Finish := TLabel.Create(WizardForm);
Finish.Left := 400;
Finish.Top := ScaleY(94);
Finish.Left := ScaleX(670);
Finish.Caption := 'Завершение';
Finish.Transparent := True;
Finish.Font.Size := 10;
Finish.Font.Name := 'Arial';
Finish.Font.Style:= [fsBold];
//************************************************ [Конец - Панель] ***************************************************//


WizardForm.BackButton.SetBounds(WizardForm.ClientWidth - ScaleX(8) * 37,
WizardForm.ClientHeight - ScaleY(ButtonHeight) * 2, ScaleX(ButtonWidth), ScaleY(ButtonHeight));

WizardForm.NextButton.SetBounds(WizardForm.ClientWidth - ScaleX(8) * 26,
WizardForm.ClientHeight - ScaleY(ButtonHeight) * 2, ScaleX(ButtonWidth), ScaleY(ButtonHeight));

WizardForm.CancelButton.SetBounds(WizardForm.ClientWidth - ScaleX(8)* 15,
WizardForm.ClientHeight - ScaleY(ButtonHeight) * 2, ScaleX(ButtonWidth), ScaleY(ButtonHeight));

WizardForm.DirBrowseButton.SetBounds(WizardForm.ClientWidth - ScaleX(5) * 30,
WizardForm.ClientHeight - ScaleY(ButtonHeight) * 10, ScaleX(ButtonWidth), ScaleY(ButtonHeight));

WizardForm.GroupBrowseButton.SetBounds(WizardForm.ClientWidth - ScaleX(5) * 30,
WizardForm.ClientHeight - ScaleY(ButtonHeight) * 10, ScaleX(ButtonWidth), ScaleY(ButtonHeight));

ExtractTemporaryFile('button.bmp')
LoadButtonImage(WizardForm.BackButton,bidBack)
LoadButtonImage(WizardForm.NextButton,bidNext)
LoadButtonImage(WizardForm.CancelButton,bidCancel)
LoadButtonImage(WizardForm.DirBrowseButton,bidDirBrowse)
LoadButtonImage(WizardForm.GroupBrowseButton,bidGroupBrowse)
//************************************************ [Конец - Текстуры кнопок] ***************************************************//

// Create controls to show extended info
StatusLabel:= CreateLabel(WizardForm.InstallingPage,false,false,true,'',[],0,0,0,0,0, WizardForm.StatusLabel);
StatusLabel.Font.Name:= 'Georgia'
StatusLabel.Font.Size:= 10;
StatusLabel.Font.Style:= [fsBold];
StatusLabel.Left:= ScaleX(100);
StatusLabel.Top:= ScaleY(245);
StatusLabel.Width:= ScaleX(625);
StatusLabel.Height:= ScaleY(20)

FileNameLabel:= CreateLabel(WizardForm.InstallingPage,false,false,true,'',[],0,0,0,0,0, WizardForm.FileNameLabel);

FileNameLabel.Font.Name:= 'Georgia'
FileNameLabel.Font.Size:= 10;
FileNameLabel.Font.Style:= [fsBold, fsItalic];
FileNameLabel.Left:= ScaleX(100);
FileNameLabel.Top:= ScaleY(275);
FileNameLabel.Width:= ScaleX(625);
FileNameLabel.Height:= ScaleY(20)

WizardForm.StatusLabel.Top:= WizardForm.ProgressGauge.Top; WizardForm.FileNameLabel.Top:= WizardForm.ProgressGauge.Top; // прячем под прогрессбар, тогда все события WM_PAINT перехватываются
with WizardForm.ProgressGauge do begin
StatusInfo:= CreateLabel(WizardForm.InstallingPage, false, true, true, '', [], 0, 0, Top + ScaleY(32), Width, 0, Nil);

StatusInfo.Font.Name:= 'Georgia'
StatusInfo.Font.Size:= 10;
StatusInfo.Font.Style:= [fsBold, fsItalic];
StatusInfo.Left:= ScaleX(100);
StatusInfo.Height:= ScaleY(20)

ProgressBar := TNewProgressBar.Create(WizardForm);
ProgressBar.SetBounds(Left, StatusInfo.Top + StatusInfo.Height + ScaleY(16), Width, Height);
ProgressBar.Parent := WizardForm.InstallingPage;
ProgressBar.max := 65536;
ProgressBar.Hide; // будет показан при обработке нескольких архивов
ExtractFile:= CreateLabel(WizardForm.InstallingPage, false, true, true, '', [], 0, 0, ProgressBar.Top + ScaleY(32), Width, 0, Nil);

ExtractFile.Font.Name:= 'Georgia'
ExtractFile.Font.Size:= 10;
ExtractFile.Font.Style:= [fsBold, fsItalic];
ExtractFile.Left:= ScaleX(100);
ExtractFile.Height:= ScaleY(20)

end;
WizardForm.OnClose:= @WizardClose // позволяет прервать распаковку архивов стандартными способами
// фоновая графика
Texture:= TBitmapImage.Create(WizardForm);
Texture.SetBounds(-WizardForm.InnerNotebook.Left, -WizardForm.InnerNotebook.Top, WizardForm.ClientWidth, WizardForm.ClientHeight);
GradientFill(Texture, BackColor, EndColor); // вместо градиента можно загрузить картинку
Texture2:= TBitmapImage.Create(WizardForm);
Texture2.SetBounds(0, 0, WizardForm.ClientWidth, WizardForm.ClientHeight);
Texture2.Parent:= WizardForm.InnerPage;
Texture2.Bitmap:= Texture.Bitmap;
End;

Procedure DeInitializeSetup;
Begin
KillTimer(0, TimerID) {удаление таймера}
UnhookWindowsHookEx(WndHookID) {удаление SendMessage хука}

UnloadSkin();
BASS_Free();
End;

procedure DeinitializeUninstall();
begin
UnloadSkinUninst();
end;

function InitializeSetup(): Boolean;
begin
ExtractTemporaryFile('BASS.dll');
ExtractTemporaryFile('sound.mp3');
mp3Name := ExpandConstant('{tmp}\sound.mp3');
BASS_Init(-1, 44100, 0, 0, 0);
mp3Handle := BASS_StreamCreateFile(FALSE, PChar(mp3Name), 0, 0, BASS_SAMPLE_LOOP);
BASS_Start();
BASS_ChannelPlay(mp3Handle, False);
Result := True;
ExtractTemporaryFile('Tiger.cjstyles');
LoadSkin(ExpandConstant('{tmp}\Tiger.cjstyles'), '');
Result := True;
end;

function InitializeUninstall(): Boolean;
begin
FileCopy(ExpandConstant('{app}\isskin.dll'), ExpandConstant('{tmp}\isskin.dll'), True);
FileCopy(ExpandConstant('{app}\Tiger.cjstyles'), ExpandConstant('{tmp}\Tiger.cjstyles'), True);
LoadSkinUninst(ExpandConstant('{tmp}\Tiger.cjstyles'), '');
Result := True;
end;


procedure CurPageChanged2(CurPageID: Integer);
begin
if CurPageID = wpSelectDir then
begin
GetNeedSpaceCaption;

if FreeMB < NeedSize then
begin
WizardForm.NextButton.Enabled := False;
ButtonLabel[bidNext].Enabled := False;
ButtonPanel[bidNext].Enabled := False;

end;
end;
end;
//************************************************ [Начало - Панель] ***************************************************//
procedure CurPageChanged3(CurPageID: Integer);
begin
Welcome.Font.Color := -16777199;
Parameters.Font.Color := -16777199;
StartMenu.Font.Color := -16777199;
Installing.Font.Color := -16777199;
Finish.Font.Color := -16777199;


if (CurPageID= wpWelcome)or(CurPageID= wpSelectDir)or (CurPageID= wpSelectProgramGroup)or(CurPageID= wpInstalling)or(CurPageID= wpFinished) then
Welcome.Parent := DetectPage(CurPageID);
Parameters.Parent := DetectPage(CurPageID);
StartMenu.Parent := DetectPage(CurPageID);
Installing.Parent := DetectPage(CurPageID);
Finish.Parent := DetectPage(CurPageID);

if CurPageID = wpWelcome then
begin
Welcome.Font.Color := clWhite;
end;

if CurPageID = wpSelectDir then
begin
Parameters.Font.Color := clWhite;
end;

if CurPageID = wpSelectProgramGroup then
begin
StartMenu.Font.Color := clWhite;
end;

if CurPageID = wpInstalling then
begin
Installing.Font.Color := clWhite;
end;

if CurPageID = wpFinished then
begin
Finish.Font.Color := clWhite;
end;
end;
//************************************************ [Конец - Панель] ***************************************************//
procedure CurPageChanged(CurPageID: Integer);
begin
CurPageChanged1(CurPageID);
CurPageChanged2(CurPageID);
CurPageChanged3(CurPageID);
end;

procedure CurStepChanged(CurStep: TSetupStep);
begin
CurStepChanged1(CurStep);
CurStepChanged2(CurStep);
end;[/more]

знающие люди вставьте что нужно для того, чтобы распаковывались должным образом прикомповские файлы(.pcf). Мне тут кидали кусок непонятный, с ним вылетает инсталл и не распаковывается нормально, так что вот такая просьба.
+
Если можно то еще в отдельный архив скиньте плиз файлы которые нужны рядом со скриптом

Огромное спасибо.
Автор: vint56
Дата сообщения: 10.02.2010 06:52
tatarin9393 вот должно быть где файлы тогда будет все работать
[Files]
Source: unarc.dll; DestDir: {tmp}; Flags: dontcopy
Source: InnoCallback.dll; DestDir: {tmp}; Flags: dontcopy
;эти файлы необходимы для работы isprecomp
Source: isprecomp.dll; DestDir: {tmp}; Flags: dontcopy
Source: packjpg_dll.dll; DestDir: {sys}; Flags: deleteafterinstall
Source: precomp.dll; DestDir: {sys}; Flags: deleteafterinstall
Source: zlib1.dll; DestDir: {sys}; Flags: deleteafterinstall
Source: bass.dll; DestDir: {tmp}; Flags: dontcopy noencryption
Source: sound.mp3; DestDir: {tmp}; Flags: dontcopy noencryption nocompression
Source: ISSkin.dll; DestDir: {app}; Flags: ignoreversion;
Source: Tiger.cjstyles; DestDir: {app}; Flags: ignoreversion;
Source: Image\*.bmp; Flags: dontcopy;
;строки распаковки архивов
Source: {src}\*.arc; DestDir: {app}\; Flags: external dontcopy
{#SourceToProgress}

Страницы: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100

Предыдущая тема: Надстройки IE8


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.