Componentes.Terceros.jvcl/official/3.32/install/JVCLInstall/Core.pas

377 lines
12 KiB
ObjectPascal

{-----------------------------------------------------------------------------
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/MPL-1.1.html
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
the specific language governing rights and limitations under the License.
The Original Code is: Core.pas, released on 2004-03-29.
The Initial Developer of the Original Code is Andreas Hausladen
(Andreas dott Hausladen att gmx dott de)
Portions created by Andreas Hausladen are Copyright (C) 2004 Andreas Hausladen.
All Rights Reserved.
Contributor(s): -
You may retrieve the latest version of this file at the Project JEDI's JVCL
home page, located at http://jvcl.sourceforge.net
Known Issues:
-----------------------------------------------------------------------------}
// $Id: Core.pas 10610 2006-05-19 13:35:08Z elahn $
unit Core;
{$I jvcl.inc}
interface
uses
SysUtils, Classes, Contnrs, Controls, StdCtrls, ExtCtrls, ImgList,
Windows, ShellAPI, CommCtrl;
type
THorzOrientation = (hoDefault, hoLeft, hoCenter, hoRight);
IInstallerPage = interface;
IInstaller = interface;
IPackageInstaller = interface;
{ IInstallerPage supports all methods that are necessary for a installer page.
There is no page builder for an IInstallerPage implementation. So you have
to implement pages that are derived from IInstallerPage. }
IInstallerPage = interface
['{B3B1AA03-CBA3-448B-B89C-99D7F79181D8}']
procedure Title(var Title, SubTitle: WideString);
{ Title returns the title and subtitle of the page. No Title and no
SubTitle means no header. }
function NextPage: IInstallerPage;
{ NextPage returns the next page that should be displayed. All options are
garanteed to be transitted before calling NextPage. The installer can
go back to another page by it's page cache. Return nil if this is
the very last page. }
function CanNext: Boolean;
{ CanNext must return False if the next page is available }
function CanPrev: Boolean;
{ CanPrev must return False if the installer should not allow going
back. }
procedure Init;
{ Init is called through PackageInstaller.RebuildPage and by the
constructor of TInstallerPage. }
procedure Action;
{ Action is called when the page is visible. This allows auto-action
pages. }
end;
{ IMultiChoosePage represents a page that contains only CheckBoxes. }
IMultiChoosePage = interface(IInstallerPage)
['{D331311B-19C2-4B66-942C-A47406C127A8}']
procedure CheckBoxes(CheckBoxes: TStrings; var HorzOrientation: THorzOrientation);
{ returns a list of check boxes. Format: "Caption|Hint" }
procedure SetCheckBox(Index: Integer; Value: Boolean);
{ called by the installer to set the check box state. Index is from the
CheckBoxes list. Return True if the page order has changed due to the
changes. }
function GetCheckBox(Index: Integer): Boolean;
{ called by the installer to obtain the check box state. Index is from the
CheckBoxes list. }
procedure SetupCheckBox(Index: Integer; Control: TCheckBox);
{ The installer calls SetupCheckBox for every check box. }
end;
ISingleChoosePage = interface(IInstallerPage)
['{976AE67C-0C9D-4EB3-9250-94FB283EB5E7}']
procedure Options(Options: TStrings; var HorzOrientation: THorzOrientation);
{ returns a list of radio buttons. Format: "Caption|Hint" }
procedure SetSelectedOption(Index: Integer);
{ called by the installer to set the active radio button. Return True if
the page order has changed due to the changes.}
function GetSelectedOption: Integer;
{ called by the installer to obtain the active radio button. }
procedure SetupRadioButton(Index: Integer; Control: TRadioButton);
{ The installer calls SetupRadioButton for every radio button. }
end;
{ IWelcomePage represents a page that has a memo field (2/3 of the page's
height and an grouped options. If IMultiChoosePage is supported then also
checkboxes are available. }
IWelcomePage = interface(ISingleChoosePage)
['{9088CC78-0F61-48EC-ABF1-41869EC581CF}']
function Text: WideString;
{ Text returns the text for the Memo on the page. No text means no Memo}
end;
IUserDefinedPage = interface(IInstallerPage)
['{20941184-2F88-4054-9420-AFE7309168E7}']
function SetupPage(Client: TWinControl): TWinControl;
{ The installer calls SetupPage when the page's content should be created.
Returns the control that should be the active control. }
end;
ISummaryPage = interface(IInstallerPage)
['{972C7061-59DE-4A6A-8B74-D94E14CAF856}']
procedure GetSummary(Actions, Comments: TStrings);
{ GetSummary filles the list pair Actions/Comments with the summary
information. For example:
Actions.Add('Install');
Comments.Add('Delphi Package JvCore'); }
end;
IInstallPage = interface(IInstallerPage)
['{5DFD17E9-1DCE-444F-9B6F-FC27B79DFBFF}']
procedure Abort;
{ The package installer calls Abort when the installation process should
be aborted. }
end;
IUninstallPage = interface(IInstallerPage)
['{921DE9FC-F450-4130-A0C4-311558E6777A}']
end;
IInstaller = interface
['{DC4BBDB8-E879-4BC8-A4F6-44A9737CA46E}']
procedure Init(APackageInstaller: IPackageInstaller);
{ called when the package installer is initializing the installer. }
function InstallerName: WideString;
{ Returns the name of the installer. This name is used for the form's
caption. }
function FirstPage: IInstallerPage;
{ Returns the first installer page. From this page the installer will
browse through all pages. }
function CanInstall: Boolean;
{ If there is no installation possible the installer should return False.
The package installer does not display any message box. This is the job
if this method. }
procedure Finish;
{ Is called when the finish button is pressed. }
function AutoInstall: Boolean;
{ Return True if the package installer should step through all pages
automatically until it reaches a IInstallPage or IUninstallPage. }
end;
IPackageInstaller = interface
['{7285179D-BBF1-4FF3-85DD-27CD5E76A6B2}']
procedure UpdatePages;
{ updates the next page and triggers OnPagesChanged. }
procedure RebuildPage;
{ rebuilds the current page and triggers OnPageRecreate. }
procedure Translate(Component: TComponent);
{ translates the formular/frame }
procedure ForcedFinish;
{ sets the installer to the finished mode. }
end;
TPackageInstaller = class(TComponent, IPackageInstaller)
private
FInstaller: IInstaller;
FPrevPages: TInterfaceList;
FUpdateLock: Integer;
FOnPagesChanged: TNotifyEvent;
FOnPageRecreate: TNotifyEvent;
FOnUpdateNavigation: TNotifyEvent;
FOnTranslate: TNotifyEvent;
FOnFinished: TNotifyEvent;
function GetPage: IInstallerPage;
function GetNextPage: IInstallerPage;
function GetPrevPage: IInstallerPage;
public
{ IPackageInstaller }
procedure UpdatePages;
procedure RebuildPage;
procedure Translate(Component: TComponent);
procedure ForcedFinish;
public
constructor Create(AInstaller: IInstaller); reintroduce;
destructor Destroy; override;
procedure GoToNextPage;
procedure GoToPrevPage;
procedure GoToFirstPage;
function CanNextPage: Boolean;
function CanPrevPage: Boolean;
procedure BeginUpdate;
procedure EndUpdate;
property Installer: IInstaller read FInstaller;
property Page: IInstallerPage read GetPage;
property PrevPage: IInstallerPage read GetPrevPage;
property NextPage: IInstallerPage read GetNextPage;
property OnPagesChanged: TNotifyEvent read FOnPagesChanged write FOnPagesChanged;
property OnPageRecreate: TNotifyEvent read FOnPageRecreate write FOnPageRecreate;
property OnUpdateNavigation: TNotifyEvent read FOnUpdateNavigation write FOnUpdateNavigation;
property OnTranslate: TNotifyEvent read FOnTranslate write FOnTranslate;
property OnFinished: TNotifyEvent read FOnFinished write FOnFinished;
end;
var
PackageInstaller: TPackageInstaller;
procedure AddIconFileToImageList(ImageList: TImageList; const Filename: string);
function LoadLongResString(ResStringRec: PResStringRec): string;
implementation
function LoadLongResString(ResStringRec: PResStringRec): string;
var
Buffer: array [0..4095] of char;
begin
if ResStringRec = nil then Exit;
if ResStringRec.Identifier < 64*1024 then
SetString(Result, Buffer,
LoadString(FindResourceHInstance(ResStringRec.Module^),
ResStringRec.Identifier, Buffer, SizeOf(Buffer)))
else
Result := PChar(ResStringRec.Identifier);
end;
procedure AddIconFileToImageList(ImageList: TImageList; const Filename: string);
var
FileInfo: TShFileInfo;
begin
if FileExists(Filename) then
begin
FillChar(FileInfo, SizeOf(FileInfo), 0);
SHGetFileInfo(PChar(Filename), 0, FileInfo, SizeOf(FileInfo),
SHGFI_ICON or SHGFI_SMALLICON);
if FileInfo.hIcon <> 0 then
begin
ImageList_AddIcon(ImageList.Handle, FileInfo.hIcon);
DestroyIcon(FileInfo.hIcon);
end;
end;
end;
{ TPackageInstaller }
procedure TPackageInstaller.BeginUpdate;
begin
Inc(FUpdateLock);
end;
procedure TPackageInstaller.EndUpdate;
begin
Dec(FUpdateLock);
end;
function TPackageInstaller.CanNextPage: Boolean;
begin
Result := (Page <> nil) and Page.CanNext and (Page.NextPage <> nil);
end;
function TPackageInstaller.CanPrevPage: Boolean;
begin
// Result := (FPrevPages.Count > 1) and
// (IInstallerPage(FPrevPages[FPrevPages.Count - 1 - 1]).CanPrev);
Result := (FPrevPages.Count > 1) and Page.CanPrev;
end;
constructor TPackageInstaller.Create(AInstaller: IInstaller);
begin
inherited Create(nil);
FInstaller := AInstaller;
FInstaller.Init(Self);
FPrevPages := TInterfaceList.Create;
end;
destructor TPackageInstaller.Destroy;
begin
FPrevPages.Free;
FInstaller := nil;
inherited Destroy;
end;
function TPackageInstaller.GetNextPage: IInstallerPage;
begin
if CanNextPage then
Result := Page.NextPage;
end;
function TPackageInstaller.GetPage: IInstallerPage;
begin
if FPrevPages.Count = 0 then
FPrevPages.Add(Installer.FirstPage);
Result := IInstallerPage(FPrevPages[FPrevPages.Count - 1]);
end;
function TPackageInstaller.GetPrevPage: IInstallerPage;
begin
if CanPrevPage then
Result := IInstallerPage(FPrevPages[FPrevPages.Count - 1 - 1]);
end;
procedure TPackageInstaller.GoToNextPage;
begin
if CanNextPage then
FPrevPages.Add(Page.NextPage);
end;
procedure TPackageInstaller.GoToPrevPage;
begin
if CanPrevPage then
FPrevPages.Delete(FPrevPages.Count - 1);
end;
procedure TPackageInstaller.UpdatePages;
begin
if FUpdateLock = 0 then
begin
if Assigned(FOnPagesChanged) then
FOnPagesChanged(Self);
if Assigned(FOnUpdateNavigation) then
FOnUpdateNavigation(Self);
end;
end;
procedure TPackageInstaller.RebuildPage;
begin
if FUpdateLock = 0 then
begin
if Assigned(FOnPageRecreate) then
FOnPageRecreate(Self);
if Assigned(FOnUpdateNavigation) then
FOnUpdateNavigation(Self);
end;
end;
procedure TPackageInstaller.GoToFirstPage;
begin
FPrevPages.Clear;
end;
procedure TPackageInstaller.Translate(Component: TComponent);
begin
if Assigned(FOnTranslate) then
FOnTranslate(Component);
end;
procedure TPackageInstaller.ForcedFinish;
begin
if Assigned(FOnFinished) then
FOnFinished(Self);
end;
initialization
finalization
FreeAndNil(PackageInstaller);
end.