type
TTimerProc = procedure (h: Longword; msg: Longword; idevent: Longword; dwTime: Longword);
TBtnEventProc = procedure (h:HWND);
TALabel = array of TLabel;
const
BtnClickEventID = 1;
BtnMouseEnterEventID = 2;
WFDiskTimerID = 1;
var
hCancelBtn, hNextBtn, hBackBtn, hDirBrowseBtn, hGroupBrowseBtn: HWND;
ButtonFont: TFont;
OldDisk: string;
TotalSpaceLabel, NeedSpaceLabel, FreeSpaceLabel: TLabel;
FreeMB, TotalMB: Cardinal;
ADisk: TALabel;
function WrapBtnCallback(Callback: TBtnEventProc; ParamCount: Integer): Longword; external 'wrapcallback@{tmp}\innocallback.dll stdcall delayload';
function BtnCreate(hParent:HWND; Left,Top,Width,Height:integer; FileName:PAnsiChar; ShadowWidth:integer; IsCheckBtn:boolean):HWND; external 'BtnCreate@{tmp}\botva2.dll stdcall delayload';
procedure BtnRefresh(h:HWND); external 'BtnRefresh@{tmp}\botva2.dll stdcall delayload';
function BtnGetChecked(h:HWND):boolean; external 'BtnGetChecked@{tmp}\botva2.dll stdcall delayload';
procedure BtnSetChecked(h:HWND; Value:boolean); external 'BtnSetChecked@{tmp}\botva2.dll stdcall delayload';
procedure BtnSetText(h:HWND; Text:PAnsiChar); external 'BtnSetText@{tmp}\botva2.dll stdcall delayload';
procedure BtnSetVisibility(h:HWND; Value:boolean); external 'BtnSetVisibility@{tmp}\botva2.dll stdcall delayload';
function BtnGetEnabled(h:HWND):boolean; external 'BtnGetEnabled@{tmp}\botva2.dll stdcall delayload';
procedure BtnSetEnabled(h:HWND; Value:boolean); external 'BtnSetEnabled@{tmp}\botva2.dll stdcall delayload';
procedure BtnSetFont(h:HWND; Font:Cardinal); external 'BtnSetFont@{tmp}\botva2.dll stdcall delayload';
procedure BtnSetFontColor(h:HWND; NormalFontColor, FocusedFontColor, PressedFontColor, DisabledFontColor: Cardinal); external 'BtnSetFontColor@{tmp}\botva2.dll stdcall delayload';
procedure BtnSetEvent(h:HWND; EventID:integer; Event:Longword); external 'BtnSetEvent@{tmp}\botva2.dll stdcall delayload';
procedure BtnSetCursor(h:HWND; hCur:Cardinal); external 'BtnSetCursor@{tmp}\botva2.dll stdcall delayload';
function GetSysCursorHandle(id:integer):Cardinal; external 'GetSysCursorHandle@{tmp}\botva2.dll stdcall delayload';
procedure gdipShutdown; external 'gdipShutdown@{tmp}\botva2.dll stdcall delayload';
function sndPlaySound(lpszSoundName: AnsiString; uFlags: cardinal):integer; external 'sndPlaySoundA@winmm.dll stdcall';
function SetTimer(hWnd, nIDEvent, uElapse, lpTimerFunc: LongWord): LongWord; external 'SetTimer@user32.dll stdcall';
function KillTimer(hWnd, nIDEvent: LongWord): LongWord; external 'KillTimer@user32.dll stdcall';
function WrapTimerProc(callback:TTimerProc; paramcount:integer):LongWord; external 'wrapcallback@{tmp}\innocallback.dll stdcall delayload';
procedure SetStateNewButtons;
begin
with WizardForm.BackButton do begin
BtnSetText(hBackBtn,PAnsiChar(Caption));
BtnSetVisibility(hBackBtn,Visible);
BtnSetEnabled(hBackBtn,Enabled);
end;
with WizardForm.NextButton do begin
BtnSetText(hNextBtn,PAnsiChar(Caption));
BtnSetVisibility(hNextBtn,Visible);
BtnSetEnabled(hNextBtn,Enabled);
end;
with WizardForm.CancelButton do begin
BtnSetText(hCancelBtn,PAnsiChar(Caption));
BtnSetVisibility(hCancelBtn,Visible);
BtnSetEnabled(hCancelBtn,Enabled);
end;
BtnSetText(hDirBrowseBtn,PAnsiChar(WizardForm.DirBrowseButton.Caption));
end;
procedure WizardFormBtnClick(hBtn:HWND);
var
Btn:TButton;
begin
sndPlaySound(ExpandConstant('{tmp}\Click.wav'),$0001);
case hBtn of
hCancelBtn: Btn:=WizardForm.CancelButton;
hNextBtn: Btn:=WizardForm.NextButton;
hBackBtn: Btn:=WizardForm.BackButton;
hDirBrowseBtn: Btn:=WizardForm.DirBrowseButton;
end;
Btn.OnClick(Btn);
SetStateNewButtons;
BtnRefresh(hBtn);
end;
procedure BtnEnter(hBtn:HWND);
begin
sndPlaySound(ExpandConstant('{tmp}\Enter.wav'),$0001);
end;
procedure ButtonsTextures;
begin
ButtonFont:=TFont.Create;
ButtonFont.Style:=[fsBold];
with WizardForm.BackButton do begin
hBackBtn:=BtnCreate(WizardForm.Handle,Left-20,Top-8,Width+16,Height+16,ExpandConstant('{tmp}\button.png'),18,False);
BtnSetEvent(hBackBtn,BtnMouseEnterEventID,WrapBtnCallback(@BtnEnter,1));
BtnSetEvent(hBackBtn,BtnClickEventID,WrapBtnCallback(@WizardFormBtnClick,1));
BtnSetFont(hBackBtn,ButtonFont.Handle);
BtnSetFontColor(hBackBtn,$DAE369,$DAE369,$DAE369,$B6B6B6);
BtnSetCursor(hBackBtn,GetSysCursorHandle(32649));
Width:=0;
Height:=0;
end;
with WizardForm.NextButton do begin
hNextBtn:=BtnCreate(WizardForm.Handle,Left-8,Top-8,Width+16,Height+16,ExpandConstant('{tmp}\button.png'),18,False);
BtnSetEvent(hNextBtn,BtnMouseEnterEventID,WrapBtnCallback(@BtnEnter,1));
BtnSetEvent(hNextBtn,BtnClickEventID,WrapBtnCallback(@WizardFormBtnClick,1));
BtnSetFont(hNextBtn,ButtonFont.Handle);
BtnSetFontColor(hNextBtn,$DAE369,$DAE369,$DAE369,$B6B6B6);
BtnSetCursor(hNextBtn,GetSysCursorHandle(32649));
Width:=0;
Height:=0;
end;
with WizardForm.CancelButton do begin
hCancelBtn:=BtnCreate(WizardForm.Handle,Left-8,Top-8,Width+16,Height+16,ExpandConstant('{tmp}\button.png'),18,False);
BtnSetEvent(hCancelBtn,BtnMouseEnterEventID,WrapBtnCallback(@BtnEnter,1));
BtnSetEvent(hCancelBtn,BtnClickEventID,WrapBtnCallback(@WizardFormBtnClick,1));
BtnSetFont(hCancelBtn,ButtonFont.Handle);
BtnSetFontColor(hCancelBtn,$DAE369,$DAE369,$DAE369,$B6B6B6);
BtnSetCursor(hCancelBtn,GetSysCursorHandle(32649));
Width:=0;
Height:=0;
end;
with WizardForm.DirBrowseButton do begin
hDirBrowseBtn:=BtnCreate(WizardForm.SelectDirPage.Handle,Left-11,Top-8,Width+16,Height+16,ExpandConstant('{tmp}\button.png'),18,False);
BtnSetEvent(hDirBrowseBtn,BtnMouseEnterEventID,WrapBtnCallback(@BtnEnter,1));
BtnSetEvent(hDirBrowseBtn,BtnClickEventID,WrapBtnCallback(@WizardFormBtnClick,1));
BtnSetFont(hDirBrowseBtn,ButtonFont.Handle);
BtnSetFontColor(hDirBrowseBtn,$DAE369,$DAE369,$DAE369,$B6B6B6);
BtnSetCursor(hDirBrowseBtn,GetSysCursorHandle(32649));
Width:=0;
Height:=0;
end;
end;
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 MbOrTB(Float: Extended): string;
begin
if Float<1024 then Result:=NumToStr(Float)+' MB'
else if (Float/1024)<1024 then Result:=NumToStr(Float/1024)+' GB'
else if (Float/(1024*1024))<1024 then Result:=NumToStr(Float/(1024*1024))+' TB'
end;
procedure DiskFlashing(h: Longword; msg: Longword; idevent: Longword; dwTime: Longword);
var
i:integer;
begin
for i:= 0 to GetArrayLength(ADisk)-1 do
if ADisk[i].Font.Color=$000000 then ADisk[i].Font.Color:=$0000FF else ADisk[i].Font.Color:=$000000;
end;
function GetElementIndex(a:TALabel; lbl:TLabel):integer;
var
i:integer;
f:boolean;
begin
Result:=-1;
f:=False;
for i:=0 to GetArrayLength(a)-1 do
if a[i]=lbl then begin
f:=True;
Break;
end;
if f then Result:=i;
end;
procedure AddLabelToArray(var a:TALabel; lbl:TLabel);
begin
if GetElementIndex(a,lbl)=-1 then begin
SetArrayLength(a,GetArrayLength(a)+1);
a[GetArrayLength(a)-1]:=lbl;
end;
end;
procedure DeleteLabelFromArray(var a:TALabel; lbl:integer);
var
Last,i:integer;
begin
if lbl<>-1 then begin
Last:=GetArrayLength(a)-1;
if lbl<Last then
for i:=lbl to Last-1 do a[i]:=a[i+1];
SetArrayLength(a,Last);
end;
end;
procedure GetFreeSpaceCaption(Sender: TObject);
var
CurrentDisk: String;
i:integer;
begin
CurrentDisk:=ExtractFileDrive(WizardForm.DirEdit.Text);
if not GetSpaceOnDisk(CurrentDisk,True,FreeMB,TotalMB) then begin
KillTimer(WizardForm.Handle,WFDiskTimerID);
SetArrayLength(ADisk,0);
TotalSpaceLabel.Visible:=False;
FreeSpaceLabel.Visible:=False;
BtnSetEnabled(hNextBtn,False);
WizardForm.NextButton.Enabled:=False;
OldDisk:=CurrentDisk;
Exit;
end;
TotalSpaceLabel.Visible:=True;
FreeSpaceLabel.Visible:=True;
if CurrentDisk<>OldDisk then begin
OldDisk:=CurrentDisk;
TotalSpaceLabel.Caption := ExpandConstant('{cm:TotalSpace} ') + MbOrTB(TotalMb);
FreeSpaceLabel.Caption := ExpandConstant('{cm:FreeSpace} ') + MbOrTB(FreeMb) + ' (' + IntToStr((FreeMb*100) div TotalMB) + ' %)';
if WizardForm.CurPageID = wpSelectDir then begin
if FreeMB>={#NeedSize} then begin
i:=GetElementIndex(ADisk,FreeSpaceLabel);
if i<>-1 then begin
DeleteLabelFromArray(ADisk,i);
FreeSpaceLabel.Font.Color:=$000000;
if GetArrayLength(ADisk)=0 then KillTimer(WizardForm.Handle,WFDiskTimerID);
end;
end else AddLabelToArray(ADisk,FreeSpaceLabel);
if TotalMb>={#NeedSize} then begin
i:=GetElementIndex(ADisk,TotalSpaceLabel);
if i<>-1 then begin
DeleteLabelFromArray(ADisk,i);
TotalSpaceLabel.Font.Color:=$000000;
if GetArrayLength(ADisk)=0 then KillTimer(WizardForm.Handle,WFDiskTimerID);
end;
end else AddLabelToArray(ADisk,TotalSpaceLabel);
if GetArrayLength(ADisk)>0 then SetTimer(WizardForm.Handle,WFDiskTimerID,1000,WrapTimerProc(@DiskFlashing,4));
BtnSetEnabled(hNextBtn,not (GetArrayLength(ADisk)>0));
WizardForm.NextButton.Enabled:=not (GetArrayLength(ADisk)>0);
end;
end;
end;
procedure RedesignWizardForm;
begin
WizardForm.DiskSpaceLabel.Hide;
ExtractTemporaryFile('botva2.dll');
ExtractTemporaryFile('InnoCallback.dll');
ExtractTemporaryFile('Click.wav');
ExtractTemporaryFile('Enter.wav');
ExtractTemporaryFile('Button.png');
TotalSpaceLabel := TLabel.Create(WizardForm);
with TotalSpaceLabel do begin
AutoSize:=False;
SetBounds(ScaleX(0), ScaleY(180), ScaleX(417), ScaleY(14));
Transparent:=True;
Parent := WizardForm.SelectDirPage;
end;
FreeSpaceLabel := TLabel.Create(WizardForm);
with FreeSpaceLabel do begin
AutoSize:=False;
SetBounds(ScaleX(0), ScaleY(198), ScaleX(417), ScaleY(14));
Transparent:=True;
Parent := WizardForm.SelectDirPage;
end;
NeedSpaceLabel := TLabel.Create(WizardForm);
with NeedSpaceLabel do begin
AutoSize:=False;
SetBounds(ScaleX(0), ScaleY(216), ScaleX(417), ScaleY(14));
Transparent:=True;
Caption := ExpandConstant('{cm:NeedSpace} ') + MbOrTB({#NeedSize});
Parent := WizardForm.SelectDirPage;
end;
WizardForm.DirEdit.OnChange:= @GetFreeSpaceCaption;
WizardForm.DirEdit.Text:= WizardForm.DirEdit.Text + #0;
end;
procedure InitializeWizard;
begin
RedesignWizardForm;
ButtonsTextures;
end;
procedure CurPageChanged(CurPageID: Integer);
begin
SetStateNewButtons;
if CurPageID=wpSelectDir then begin
OldDisk:='';
GetFreeSpaceCaption(nil);
end else if GetArrayLength(ADisk)>0 then KillTimer(WizardForm.Handle,WFDiskTimerID);
end;
procedure DeinitializeSetup;
begin
gdipShutdown;
end;[/SPOILER]