📄 jvformplacement.pas
字号:
{-----------------------------------------------------------------------------
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: JvPlacemnt.PAS, released on 2002-07-04.
The Initial Developers of the Original Code are: Fedor Koshevnikov, Igor Pavluk and Serge Korolev
Copyright (c) 1997, 1998 Fedor Koshevnikov, Igor Pavluk and Serge Korolev
Copyright (c) 2001,2002 SGB Software
All Rights Reserved.
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: JvFormPlacement.pas,v 1.58 2005/02/22 08:56:44 marquardt Exp $
unit JvFormPlacement;
{$I jvcl.inc}
interface
uses
{$IFDEF UNITVERSIONING}
JclUnitVersioning,
{$ENDIF UNITVERSIONING}
{$IFDEF HAS_UNIT_VARIANTS}
Variants,
{$ENDIF HAS_UNIT_VARIANTS}
{$IFDEF HAS_UNIT_RTLCONSTS}
RTLConsts,
{$ENDIF HAS_UNIT_RTLCONSTS}
SysUtils, Classes, Windows, Messages, Controls, Forms,
{$IFDEF VCL}
JvWndProcHook,
{$ENDIF VCL}
JvAppStorage, JvComponent, JvJVCLUtils, JvTypes, JvConsts;
type
TJvIniLink = class;
TJvFormPlacement = class;
TJvWinMinMaxInfo = class(TPersistent)
private
FOwner: TJvFormPlacement;
FMinMaxInfo: TMinMaxInfo;
function GetMinMaxInfo(Index: Integer): Integer;
procedure SetMinMaxInfo(Index: Integer; AValue: Integer);
public
function DefaultMinMaxInfo: Boolean;
procedure Assign(Source: TPersistent); override;
published
property MaxPosLeft: Integer index 0 read GetMinMaxInfo write SetMinMaxInfo default 0;
property MaxPosTop: Integer index 1 read GetMinMaxInfo write SetMinMaxInfo default 0;
property MaxSizeHeight: Integer index 2 read GetMinMaxInfo write SetMinMaxInfo default 0;
property MaxSizeWidth: Integer index 3 read GetMinMaxInfo write SetMinMaxInfo default 0;
property MaxTrackHeight: Integer index 4 read GetMinMaxInfo write SetMinMaxInfo default 0;
property MaxTrackWidth: Integer index 5 read GetMinMaxInfo write SetMinMaxInfo default 0;
property MinTrackHeight: Integer index 6 read GetMinMaxInfo write SetMinMaxInfo default 0;
property MinTrackWidth: Integer index 7 read GetMinMaxInfo write SetMinMaxInfo default 0;
end;
TJvFormPlacementVersionCheck = (fpvcNocheck, fpvcCheckGreaterEqual, fpvcCheckEqual);
TJvFormPlacement = class(TJvComponent)
private
FActive: Boolean;
FAppStorage: TJvCustomAppStorage;
FAppStoragePath: string;
FLinks: TList;
FOptions: TPlacementOptions;
FVersion: Integer;
FVersionCheck: TJvFormPlacementVersionCheck;
FSaved: Boolean;
FRestored: Boolean;
FDestroying: Boolean;
FPreventResize: Boolean;
FWinMinMaxInfo: TJvWinMinMaxInfo;
FDefMaximize: Boolean;
{$IFDEF VCL}
FWinHook: TJvWindowHook;
{$ENDIF VCL}
FSaveFormShow: TNotifyEvent;
FSaveFormDestroy: TNotifyEvent;
FSaveFormCloseQuery: TCloseQueryEvent;
{$IFDEF VisualCLX}
FSaveFormConstrainedResize: TConstrainedResizeEvent;
{$ENDIF VisualCLX}
FOnSavePlacement: TNotifyEvent;
FOnRestorePlacement: TNotifyEvent;
procedure SetAppStoragePath(const AValue: string);
procedure SetEvents;
procedure RestoreEvents;
{$IFDEF VCL}
procedure SetHook;
procedure ReleaseHook;
procedure CheckToggleHook;
procedure WndMessage(Sender: TObject; var Msg: TMessage; var Handled: Boolean);
{$ENDIF VCL}
function CheckMinMaxInfo: Boolean;
procedure MinMaxInfoModified;
procedure SetWinMinMaxInfo(AValue: TJvWinMinMaxInfo);
procedure SetPreventResize(AValue: Boolean);
procedure UpdatePreventResize;
procedure UpdatePlacement;
procedure AddLink(ALink: TJvIniLink);
procedure NotifyLinks(Operation: TPlacementOperation);
procedure RemoveLink(ALink: TJvIniLink);
procedure FormShow(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure FormDestroy(Sender: TObject);
{$IFDEF VisualCLX}
procedure FormConstrainedResize(Sender: TObject; var MinWidth, MinHeight,
MaxWidth, MaxHeight: Integer);
{$ENDIF VisualCLX}
function GetForm: TForm;
protected
procedure Loaded; override;
procedure Save; dynamic;
procedure Restore; dynamic;
procedure SavePlacement; virtual;
procedure RestorePlacement; virtual;
property Form: TForm read GetForm;
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
function ConcatPaths(const Paths: array of string): string;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function IsActive: Boolean;
procedure SaveFormPlacement;
procedure RestoreFormPlacement;
function ReadString(const Ident: string; const Default: string = ''): string;
procedure WriteString(const Ident: string; const AValue: string);
function ReadBoolean(const Ident: string; Default: Boolean): Boolean;
procedure WriteBoolean(const Ident: string; AValue: Boolean);
function ReadFloat(const Ident: string; Default: Double = 0): Double;
procedure WriteFloat(const Ident: string; AValue: Double);
function ReadInteger(const Ident: string; Default: Longint = 0): Longint;
procedure WriteInteger(const Ident: string; AValue: Longint);
function ReadDateTime(const Ident: string; Default: TDateTime = 0): TDateTime;
procedure WriteDateTime(const Ident: string; AValue: TDateTime);
procedure EraseSections;
published
property Active: Boolean read FActive write FActive default True;
property AppStorage: TJvCustomAppStorage read FAppStorage write FAppStorage;
property AppStoragePath: string read FAppStoragePath write SetAppStoragePath;
property MinMaxInfo: TJvWinMinMaxInfo read FWinMinMaxInfo write SetWinMinMaxInfo;
property Options: TPlacementOptions read FOptions write FOptions default [fpState, fpSize, fpLocation];
property PreventResize: Boolean read FPreventResize write SetPreventResize default False;
property Version: Integer read FVersion write FVersion default 0;
property VersionCheck: TJvFormPlacementVersionCheck read FVersionCheck write FVersionCheck default fpvcCheckGreaterEqual;
property OnSavePlacement: TNotifyEvent read FOnSavePlacement write FOnSavePlacement;
property OnRestorePlacement: TNotifyEvent read FOnRestorePlacement write FOnRestorePlacement;
end;
TJvStoredValues = class;
TJvStoredValue = class;
TJvFormStorage = class(TJvFormPlacement)
private
FStoredProps: TStringList;
FStoredValues: TJvStoredValues;
FStoredPropsPath: string;
function GetStoredProps: TStrings;
procedure SetStoredProps(AValue: TStrings);
procedure SetStoredValues(AValue: TJvStoredValues);
function GetStoredValue(const Name: string): Variant;
procedure SetStoredValue(const Name: string; AValue: Variant);
function GetDefaultStoredValue(const Name: string; DefValue: Variant): Variant;
procedure SetDefaultStoredValue(const Name: string; DefValue: Variant; const AValue: Variant);
function GetStoredValuesPath: string;
procedure SetStoredValuesPath(const AValue: string);
protected
procedure Loaded; override;
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
procedure SavePlacement; override;
procedure RestorePlacement; override;
procedure SaveProperties; virtual;
procedure RestoreProperties; virtual;
procedure WriteState(Writer: TWriter); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure SetNotification;
property StoredValue[const Name: string]: Variant read GetStoredValue write SetStoredValue;
property DefaultValue[const Name: string; DefValue: Variant]: Variant read GetDefaultStoredValue write SetDefaultStoredValue;
published
property StoredProps: TStrings read GetStoredProps write SetStoredProps;
property StoredValues: TJvStoredValues read FStoredValues write SetStoredValues;
property StoredPropsPath: string read FStoredPropsPath write FStoredPropsPath;
property StoredValuesPath: string read GetStoredValuesPath write SetStoredValuesPath;
end;
TJvIniLink = class(TPersistent)
private
FStorage: TJvFormPlacement;
FOnSave: TNotifyEvent;
FOnLoad: TNotifyEvent;
procedure SetStorage(AValue: TJvFormPlacement);
protected
procedure SaveToIni; virtual;
procedure LoadFromIni; virtual;
public
destructor Destroy; override;
property Storage: TJvFormPlacement read FStorage write SetStorage;
property OnSave: TNotifyEvent read FOnSave write FOnSave;
property OnLoad: TNotifyEvent read FOnLoad write FOnLoad;
end;
TJvStoredValueEvent = procedure(Sender: TJvStoredValue; var AValue: Variant) of object;
TJvStoredValue = class(TCollectionItem)
private
FName: string;
FValue: Variant;
FKeyString: string;
FOnSave: TJvStoredValueEvent;
FOnRestore: TJvStoredValueEvent;
function IsValueStored: Boolean;
function GetStoredValues: TJvStoredValues;
protected
function GetDisplayName: string; override;
procedure SetDisplayName(const AValue: string); override;
public
constructor Create(Collection: TCollection); override;
procedure Assign(Source: TPersistent); override;
procedure Clear;
procedure Save; virtual;
procedure Restore; virtual;
property StoredValues: TJvStoredValues read GetStoredValues;
published
property Name: string read FName write SetDisplayName;
property Value: Variant read FValue write FValue stored IsValueStored;
property KeyString: string read FKeyString write FKeyString;
property OnSave: TJvStoredValueEvent read FOnSave write FOnSave;
property OnRestore: TJvStoredValueEvent read FOnRestore write FOnRestore;
end;
TJvStoredValues = class(TOwnedCollection)
private
FStorage: TJvFormPlacement;
FPath: string;
function GetValue(const Name: string): TJvStoredValue;
procedure SetValue(const Name: string; StoredValue: TJvStoredValue);
function GetStoredValue(const Name: string): Variant;
procedure SetStoredValue(const Name: string; AValue: Variant);
function GetItem(Index: Integer): TJvStoredValue;
procedure SetItem(Index: Integer; StoredValue: TJvStoredValue);
public
constructor Create(AOwner: TPersistent);
function IndexOf(const Name: string): Integer;
procedure SaveValues; virtual;
procedure RestoreValues; virtual;
property Path: string read FPath write FPath;
property Storage: TJvFormPlacement read FStorage write FStorage;
property Items[Index: Integer]: TJvStoredValue read GetItem write SetItem; default;
property Values[const Name: string]: TJvStoredValue read GetValue write SetValue;
property StoredValue[const Name: string]: Variant read GetStoredValue write SetStoredValue;
end;
{$IFDEF UNITVERSIONING}
const
UnitVersioning: TUnitVersionInfo = (
RCSfile: '$RCSfile: JvFormPlacement.pas,v $';
Revision: '$Revision: 1.58 $';
Date: '$Date: 2005/02/22 08:56:44 $';
LogPath: 'JVCL\run'
);
{$ENDIF UNITVERSIONING}
implementation
uses
Consts,
JclStrings,
JvJCLUtils, JvPropertyStorage;
const
siActiveCtrl = 'ActiveControl'; // do not localize
siVersion = 'FormVersion'; // do not localize
cFormNameMask = '%FORM_NAME%'; // do not localize
//=== { TJvFormPlacement } ===================================================
constructor TJvFormPlacement.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FActive := True;
if AOwner is TForm then
FOptions := [fpState, fpSize, fpLocation]
else
FOptions := [];
{$IFDEF VCL}
FWinHook := TJvWindowHook.Create(Self);
FWinHook.AfterMessage := WndMessage;
{$ENDIF VCL}
FWinMinMaxInfo := TJvWinMinMaxInfo.Create;
FWinMinMaxInfo.FOwner := Self;
FLinks := TList.Create;
FVersion := 0;
FVersionCheck := fpvcCheckGreaterEqual;
FAppStoragePath := cFormNameMask;
end;
destructor TJvFormPlacement.Destroy;
begin
while FLinks.Count > 0 do
RemoveLink(FLinks.Last);
FLinks.Free;
if not (csDesigning in ComponentState) then
begin
{$IFDEF VCL}
ReleaseHook;
{$ENDIF VCL}
RestoreEvents;
end;
FWinMinMaxInfo.Free;
inherited Destroy;
end;
procedure TJvFormPlacement.Loaded;
var
Loading: Boolean;
begin
Loading := csLoading in ComponentState;
inherited Loaded;
if not (csDesigning in ComponentState) then
begin
if Loading then
SetEvents;
{$IFDEF VCL}
CheckToggleHook;
{$ENDIF VCL}
end;
end;
procedure TJvFormPlacement.AddLink(ALink: TJvIniLink);
begin
FLinks.Add(ALink);
ALink.FStorage := Self;
end;
procedure TJvFormPlacement.NotifyLinks(Operation: TPlacementOperation);
var
I: Integer;
begin
for I := 0 to FLinks.Count - 1 do
with TJvIniLink(FLinks[I]) do
case Operation of
poSave:
SaveToIni;
poRestore:
LoadFromIni;
end;
end;
procedure TJvFormPlacement.RemoveLink(ALink: TJvIniLink);
begin
ALink.FStorage := nil;
FLinks.Remove(ALink);
end;
function TJvFormPlacement.GetForm: TForm;
begin
if Owner is TCustomForm then
Result := TForm(Owner as TCustomForm)
else
Result := nil;
end;
procedure TJvFormPlacement.SetAppStoragePath(const AValue: string);
begin
if (AValue <> '') and (AnsiLastChar(AValue) <> '\') then
FAppStoragePath := AValue + '\'
else
FAppStoragePath := AValue;
if not (csDesigning in ComponentState) then
begin
if (StrFind(cFormNameMask, FAppStoragePath) <> 0) and
Assigned(Owner) and (Owner is TCustomForm) then
StrReplace(FAppStoragePath, cFormNameMask, Owner.Name, [rfIgnoreCase]);
end;
end;
procedure TJvFormPlacement.SetEvents;
begin
if Owner is TCustomForm then
begin
with TForm(Form) do
begin
FSaveFormShow := OnShow;
OnShow := FormShow;
FSaveFormCloseQuery := OnCloseQuery;
OnCloseQuery := FormCloseQuery;
FSaveFormDestroy := OnDestroy;
OnDestroy := FormDestroy;
{$IFDEF VisualCLX}
FSaveFormConstrainedResize := OnConstrainedResize;
OnConstrainedResize := FormConstrainedResize;
{$ENDIF VisualCLX}
FDefMaximize := (biMaximize in BorderIcons);
end;
if FPreventResize then
UpdatePreventResize;
end;
end;
procedure TJvFormPlacement.RestoreEvents;
begin
if (Owner <> nil) and (Owner is TCustomForm) then
with TForm(Form) do
begin
OnShow := FSaveFormShow;
OnCloseQuery := FSaveFormCloseQuery;
OnDestroy := FSaveFormDestroy;
{$IFDEF VisualCLX}
OnConstrainedResize := FSaveFormConstrainedResize;
{$ENDIF VisualCLX}
end;
end;
{$IFDEF VCL}
procedure TJvFormPlacement.SetHook;
begin
if not (csDesigning in ComponentState) and (Owner <> nil) and
(Owner is TCustomForm) then
FWinHook.Control := Form;
end;
procedure TJvFormPlacement.ReleaseHook;
begin
FWinHook.Control := nil;
end;
procedure TJvFormPlacement.CheckToggleHook;
begin
if CheckMinMaxInfo or PreventResize then
SetHook
else
ReleaseHook;
end;
{$ENDIF VCL}
function TJvFormPlacement.CheckMinMaxInfo: Boolean;
begin
Result := not FWinMinMaxInfo.DefaultMinMaxInfo;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -