377 lines
12 KiB
ObjectPascal
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.
|
|
|