mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-05-25 17:02:40 +02:00
558 lines
15 KiB
ObjectPascal
558 lines
15 KiB
ObjectPascal
unit sparta_BasicFakeCustom;
|
|
|
|
{$mode delphi}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils,
|
|
LCLType, LCLIntf, Controls, Forms,
|
|
sparta_InterfacesMDI, sparta_FormBackgroundForMDI;
|
|
|
|
type
|
|
|
|
{ TFormImpl }
|
|
|
|
TFormImpl = class(TComponent, IDesignedRealFormHelper, IDesignedForm)
|
|
private
|
|
FDesignedRealForm: IDesignedRealForm;
|
|
FHackLeft: Integer;
|
|
FHackTop: Integer;
|
|
FHackWidth: Integer;
|
|
FHackHeight: Integer;
|
|
FOnChangeHackedBounds: TNotifyEvent;
|
|
protected
|
|
FForm: TCustomForm;
|
|
FUpdate: boolean;
|
|
procedure SetOnChangeHackedBounds(const AValue: TNotifyEvent);
|
|
function GetOnChangeHackedBounds: TNotifyEvent;
|
|
function PositionDelta: TPoint;
|
|
|
|
function GetRealBounds(AIndex: Integer): Integer; virtual;
|
|
procedure SetRealBounds(AIndex: Integer; AValue: Integer); virtual;
|
|
function GetPublishedBounds(AIndex: Integer): Integer; virtual;
|
|
procedure SetPublishedBounds(AIndex: Integer; AValue: Integer); virtual;
|
|
|
|
procedure SetHorzScrollPosition(AValue: Integer); virtual;
|
|
procedure SetVertScrollPosition(AValue: Integer); virtual;
|
|
|
|
// own custom form scrool system
|
|
function GetHorzScrollPosition: Integer; virtual;
|
|
function GetVertScrollPosition: Integer; virtual;
|
|
|
|
procedure SetRealBorderStyle(AVal: TFormBorderStyle); virtual;
|
|
procedure SetRealBorderIcons(AVal: TBorderIcons); virtual;
|
|
procedure SetRealFormStyle(AVal: TFormStyle); virtual;
|
|
procedure SetRealPopupMode(AVal: TPopupMode); virtual;
|
|
procedure SetRealPopupParent(AVal: TCustomForm); virtual;
|
|
|
|
function GetRealBorderStyle: TFormBorderStyle; virtual;
|
|
function GetRealBorderIcons: TBorderIcons; virtual;
|
|
function GetRealFormStyle: TFormStyle; virtual;
|
|
function GetRealPopupMode: TPopupMode; virtual;
|
|
function GetRealPopupParent: TCustomForm; virtual;
|
|
|
|
function GetForm: TCustomForm; virtual;
|
|
function GetUpdate: Boolean; virtual;
|
|
|
|
procedure DoChangeHackedBounds; virtual;
|
|
|
|
function GetLogicalClientRect(ALogicalClientRect: TRect): TRect; virtual;
|
|
public
|
|
property RealLeft: Integer index 0 read GetRealBounds write SetRealBounds;
|
|
property RealTop: Integer index 1 read GetRealBounds write SetRealBounds;
|
|
property RealWidth: Integer index 2 read GetRealBounds write SetRealBounds;
|
|
property RealHeight: Integer index 3 read GetRealBounds write SetRealBounds;
|
|
property RealBorderStyle: TFormBorderStyle read GetRealBorderStyle write SetRealBorderStyle;
|
|
property RealBorderIcons: TBorderIcons read GetRealBorderIcons write SetRealBorderIcons;
|
|
property RealFormStyle: TFormStyle read GetRealFormStyle write SetRealFormStyle;
|
|
|
|
constructor Create(AOwner: TComponent; AForm: TCustomForm); virtual; reintroduce;
|
|
destructor Destroy; override;
|
|
|
|
procedure BeginUpdate; virtual;
|
|
procedure EndUpdate({%H-}AModified: Boolean = False); virtual;
|
|
|
|
procedure ShowWindow; virtual;
|
|
procedure HideWindow; virtual;
|
|
|
|
property Update: Boolean read GetUpdate;
|
|
public
|
|
property Left: Integer index 0 read GetPublishedBounds write SetPublishedBounds;
|
|
property Top: Integer index 1 read GetPublishedBounds write SetPublishedBounds;
|
|
property Width: Integer index 2 read GetPublishedBounds write SetPublishedBounds;
|
|
property Height: Integer index 3 read GetPublishedBounds write SetPublishedBounds;
|
|
public
|
|
function QueryInterface(constref IID: TGUID; out Obj): HResult; override;
|
|
end;
|
|
|
|
{ TFormContainer }
|
|
|
|
TFormContainer = class(TCustomForm, IDesignedRealForm, IDesignedForm, IDesignedFormBackground)
|
|
private
|
|
FDesignedForm: TFormImpl;
|
|
function GetDesignedForm: TFormImpl;
|
|
protected
|
|
property DesignedForm: TFormImpl read GetDesignedForm implements IDesignedForm;
|
|
function GetLogicalClientRect: TRect; override;
|
|
protected
|
|
function GetRealBounds(AIndex: Integer): Integer; virtual;
|
|
procedure SetRealBounds(AIndex: Integer; AValue: Integer); virtual;
|
|
function GetPublishedBounds(AIndex: Integer): Integer; virtual;
|
|
procedure SetPublishedBounds(AIndex: Integer; AValue: Integer); virtual;
|
|
|
|
procedure SetRealBorderStyle(AVal: TFormBorderStyle); virtual;
|
|
procedure SetRealBorderIcons(AVal: TBorderIcons); virtual;
|
|
procedure SetRealFormStyle(AVal: TFormStyle); virtual;
|
|
procedure SetRealPopupMode(AVal: TPopupMode); virtual;
|
|
procedure SetRealPopupParent(AVal: TCustomForm); virtual;
|
|
|
|
function GetRealBorderStyle: TFormBorderStyle; virtual;
|
|
function GetRealBorderIcons: TBorderIcons; virtual;
|
|
function GetRealFormStyle: TFormStyle; virtual;
|
|
function GetRealPopupMode: TPopupMode; virtual;
|
|
function GetRealPopupParent: TCustomForm; virtual;
|
|
protected
|
|
FHandledForm: TCustomForm;
|
|
FBackground: IDesignedFormBackground;
|
|
|
|
procedure SetHandledForm(AForm: TCustomForm);
|
|
public
|
|
constructor CreateNew(AOwner: TComponent; Num: Integer = 0); override;
|
|
destructor Destroy; override;
|
|
|
|
property HandledForm: TCustomForm read FHandledForm write SetHandledForm;
|
|
property Background: IDesignedFormBackground read FBackground implements IDesignedFormBackground;
|
|
published
|
|
property Left: Integer index 0 read GetPublishedBounds write SetPublishedBounds;
|
|
property Top: Integer index 1 read GetPublishedBounds write SetPublishedBounds;
|
|
property Width: Integer index 2 read GetPublishedBounds write SetPublishedBounds;
|
|
property Height: Integer index 3 read GetPublishedBounds write SetPublishedBounds;
|
|
property ClientWidth: Integer index 2 read GetPublishedBounds write SetPublishedBounds;
|
|
property ClientHeight: Integer index 3 read GetPublishedBounds write SetPublishedBounds;
|
|
end;
|
|
|
|
implementation
|
|
|
|
type
|
|
TFormAccess = class(TForm);
|
|
|
|
{ TDesignedFormImpl }
|
|
|
|
function TFormImpl.GetPublishedBounds(AIndex: Integer): Integer;
|
|
begin
|
|
case AIndex of
|
|
0: Result := FForm.Left;
|
|
1: Result := FForm.Top;
|
|
2: Result := FForm.Width;
|
|
3: Result := FForm.Height;
|
|
end;
|
|
//case AIndex of
|
|
// 0: Result := FHackLeft;
|
|
// 1: Result := FHackTop;
|
|
// 2: Result := FHackWidth;
|
|
// 3: Result := FHackHeight;
|
|
//end;
|
|
end;
|
|
|
|
procedure TFormImpl.SetPublishedBounds(AIndex: Integer; AValue: Integer);
|
|
const
|
|
cMinWidth = 135;
|
|
cMaxWidth = 5*1024; // huge Mac monitors have 5K pixels width
|
|
begin
|
|
if AIndex = 2 then
|
|
if AValue < cMinWidth then
|
|
AValue := cMinWidth;
|
|
|
|
if AIndex in [2, 3] then
|
|
if AValue > cMaxWidth then
|
|
AValue := cMaxWidth;
|
|
|
|
case AIndex of
|
|
0: FHackLeft := AValue;
|
|
1: FHackTop := AValue;
|
|
2: FHackWidth := AValue;
|
|
3: FHackHeight := AValue;
|
|
end;
|
|
|
|
DoChangeHackedBounds;
|
|
end;
|
|
|
|
{-----------------------------------------------
|
|
Real values inherited for design form
|
|
{----------------------------------------------}
|
|
|
|
function TFormImpl.GetRealBounds(AIndex: Integer): Integer;
|
|
begin
|
|
case AIndex of
|
|
0: Result := FForm.Left;
|
|
1: Result := FForm.Top;
|
|
2: Result := FForm.Width;
|
|
3: Result := FForm.Height;
|
|
end;
|
|
|
|
//FForm.;
|
|
//Result := 0;// FDesignedRealForm.GetRealBounds(AIndex);
|
|
end;
|
|
|
|
procedure TFormImpl.SetRealBounds(AIndex: Integer; AValue: Integer);
|
|
|
|
procedure AdjustSize;
|
|
var
|
|
LFormRect: TRect;
|
|
LRealValue, LValue: Integer;
|
|
begin
|
|
LFormRect := Rect(0, 0, 0, 0);;
|
|
LCLIntf.GetClientRect(GetForm.Handle, LFormRect);
|
|
LRealValue := GetRealBounds(AIndex);
|
|
{$IF FPC_FULLVERSION < 30101}
|
|
case AIndex of
|
|
0: LValue := LFormRect.Left;
|
|
1: LValue := LFormRect.Top;
|
|
2: LValue := LFormRect.Right;
|
|
3: LValue := LFormRect.Bottom;
|
|
end;
|
|
{$ELSE}
|
|
LValue := LFormRect.Vector[AIndex];
|
|
{$ENDIF}
|
|
|
|
if LValue <> LRealValue then
|
|
FDesignedRealForm.SetRealBounds(AIndex, AValue - (LRealValue - LValue));
|
|
end;
|
|
|
|
begin
|
|
{FDesignedRealForm.SetRealBounds(AIndex, AValue);
|
|
|
|
if AIndex = 2 then
|
|
AdjustSize;}
|
|
end;
|
|
|
|
procedure TFormImpl.SetRealBorderStyle(AVal: TFormBorderStyle);
|
|
begin
|
|
//FDesignedRealForm.SetRealBorderStyle(AVal);
|
|
end;
|
|
|
|
procedure TFormImpl.SetRealBorderIcons(AVal: TBorderIcons);
|
|
begin
|
|
//FDesignedRealForm.SetRealBorderIcons(AVal);
|
|
end;
|
|
|
|
procedure TFormImpl.SetRealFormStyle(AVal: TFormStyle);
|
|
begin
|
|
//FDesignedRealForm.SetRealFormStyle(AVal);
|
|
end;
|
|
|
|
procedure TFormImpl.SetRealPopupMode(AVal: TPopupMode);
|
|
begin
|
|
//FDesignedRealForm.SetRealPopupMode(AVal);
|
|
end;
|
|
|
|
procedure TFormImpl.SetRealPopupParent(AVal: TCustomForm);
|
|
begin
|
|
//FDesignedRealForm.SetRealPopupParent(AVal);
|
|
end;
|
|
|
|
function TFormImpl.GetRealBorderStyle: TFormBorderStyle;
|
|
begin
|
|
Result := bsNone;//FDesignedRealForm.GetRealBorderStyle;
|
|
end;
|
|
|
|
function TFormImpl.GetRealBorderIcons: TBorderIcons;
|
|
begin
|
|
Result := [];//FDesignedRealForm.GetRealBorderIcons;
|
|
end;
|
|
|
|
function TFormImpl.GetRealFormStyle: TFormStyle;
|
|
begin
|
|
Result := fsNormal;//FDesignedRealForm.GetRealFormStyle;
|
|
end;
|
|
|
|
function TFormImpl.GetRealPopupMode: TPopupMode;
|
|
begin
|
|
Result := pmNone//FDesignedRealForm.GetRealPopupMode;
|
|
end;
|
|
|
|
function TFormImpl.GetRealPopupParent: TCustomForm;
|
|
begin
|
|
Result := nil//FDesignedRealForm.GetRealPopupParent;
|
|
end;
|
|
|
|
//////
|
|
|
|
function TFormImpl.GetForm: TCustomForm;
|
|
begin
|
|
Result := FForm;
|
|
end;
|
|
|
|
function TFormImpl.GetUpdate: Boolean;
|
|
begin
|
|
Result := FUpdate;
|
|
end;
|
|
|
|
function TFormImpl.GetOnChangeHackedBounds: TNotifyEvent;
|
|
begin
|
|
Result := FOnChangeHackedBounds;
|
|
end;
|
|
|
|
function TFormImpl.PositionDelta: TPoint;
|
|
|
|
procedure FormBorderDelta;
|
|
begin
|
|
Result.X := GetSystemMetrics(SM_CXSIZEFRAME);
|
|
Result.Y := GetSystemMetrics(SM_CYSIZEFRAME) + GetSystemMetrics(SM_CYCAPTION);
|
|
end;
|
|
|
|
begin
|
|
Result := Point(0, 0);
|
|
{$IFDEF WINDOWS}
|
|
FormBorderDelta;
|
|
{$ENDIF}
|
|
end;
|
|
|
|
procedure TFormImpl.SetOnChangeHackedBounds(const AValue: TNotifyEvent);
|
|
begin
|
|
FOnChangeHackedBounds := AValue;
|
|
end;
|
|
|
|
/////// positions
|
|
|
|
procedure TFormImpl.SetHorzScrollPosition(AValue: Integer);
|
|
begin
|
|
RealLeft := -PositionDelta.x - AValue;
|
|
// ! must. resize problem for controls with Align = Top, Right etc.
|
|
RealWidth := Width;
|
|
RealHeight := Height;
|
|
end;
|
|
|
|
procedure TFormImpl.SetVertScrollPosition(AValue: Integer);
|
|
begin
|
|
RealTop := -PositionDelta.y - AValue;
|
|
// ! must. resize problem for controls with Align = Top, Right etc.
|
|
RealWidth := Width;
|
|
RealHeight := Height;
|
|
end;
|
|
|
|
function TFormImpl.GetHorzScrollPosition: Integer;
|
|
begin
|
|
Result := -(RealLeft {+ PositionDelta.x});
|
|
end;
|
|
|
|
function TFormImpl.GetVertScrollPosition: Integer;
|
|
begin
|
|
Result := -(RealTop {+ PositionDelta.y});
|
|
end;
|
|
|
|
procedure TFormImpl.BeginUpdate;
|
|
begin
|
|
FUpdate := True;
|
|
end;
|
|
|
|
procedure TFormImpl.EndUpdate(AModified: Boolean);
|
|
begin
|
|
FUpdate := False;
|
|
end;
|
|
|
|
procedure TFormImpl.ShowWindow;
|
|
begin
|
|
if FForm.Parent = nil then
|
|
LCLIntf.ShowWindow(FForm.Handle, SW_SHOW);
|
|
end;
|
|
|
|
procedure TFormImpl.HideWindow;
|
|
begin
|
|
if FForm.Parent = nil then
|
|
LCLIntf.ShowWindow(FForm.Handle, SW_HIDE);
|
|
end;
|
|
|
|
function TFormImpl.QueryInterface(constref IID: TGUID; out Obj
|
|
): HResult;
|
|
begin
|
|
Result := inherited QueryInterface(IID, Obj);
|
|
if Result <> S_OK then
|
|
Result := TFormAccess(FForm).QueryInterface(IID, Obj);
|
|
end;
|
|
|
|
procedure TFormImpl.DoChangeHackedBounds;
|
|
begin
|
|
if not FUpdate and Assigned(FOnChangeHackedBounds) then
|
|
FOnChangeHackedBounds(FForm);
|
|
end;
|
|
|
|
function TFormImpl.GetLogicalClientRect(ALogicalClientRect: TRect): TRect;
|
|
begin
|
|
Result:=ALogicalClientRect;
|
|
end;
|
|
|
|
constructor TFormImpl.Create(AOwner: TComponent; AForm: TCustomForm);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FForm := AForm;
|
|
FDesignedRealForm := Self as IDesignedRealForm;
|
|
end;
|
|
|
|
destructor TFormImpl.Destroy;
|
|
begin
|
|
Pointer(FDesignedRealForm) := nil;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
{ TFakeCustomForm }
|
|
|
|
function TFormContainer.GetDesignedForm: TFormImpl;
|
|
begin
|
|
if not Assigned(FDesignedForm) then
|
|
FDesignedForm := TFormImpl.Create(Self, Self);
|
|
|
|
Result := FDesignedForm;
|
|
end;
|
|
|
|
function TFormContainer.GetLogicalClientRect: TRect;
|
|
begin
|
|
Result := DesignedForm.GetLogicalClientRect(inherited GetLogicalClientRect);
|
|
end;
|
|
|
|
function TFormContainer.GetRealBounds(AIndex: Integer): Integer;
|
|
begin
|
|
case AIndex of
|
|
0: Result := inherited Left;
|
|
1: Result := inherited Top;
|
|
2: Result := inherited Width;
|
|
3: Result := inherited Height;
|
|
end;
|
|
end;
|
|
|
|
procedure TFormContainer.SetRealBounds(AIndex: Integer; AValue: Integer);
|
|
begin
|
|
case AIndex of
|
|
0: inherited Left := AValue;
|
|
1: inherited Top := AValue;
|
|
2:
|
|
begin
|
|
inherited Width := AValue;
|
|
if FHandledForm <> nil then
|
|
FHandledForm.Width := AValue;
|
|
end;
|
|
3:
|
|
begin
|
|
inherited Height := AValue;
|
|
if FHandledForm <> nil then
|
|
FHandledForm.Height := AValue;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TFormContainer.GetPublishedBounds(AIndex: Integer): Integer;
|
|
begin
|
|
Result := DesignedForm.GetPublishedBounds(AIndex);
|
|
end;
|
|
|
|
procedure TFormContainer.SetPublishedBounds(AIndex: Integer; AValue: Integer);
|
|
begin
|
|
case AIndex of
|
|
0, 1: DesignedForm.SetPublishedBounds(AIndex, AValue);
|
|
2, 3:
|
|
begin
|
|
DesignedForm.SetPublishedBounds(AIndex, AValue);
|
|
SetRealBounds(AIndex, DesignedForm.GetPublishedBounds(AIndex));
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
constructor TFormContainer.CreateNew(AOwner: TComponent; Num: Integer);
|
|
begin
|
|
FBackground := TfrFormBackgroundForMDI.Create(DesignedForm);
|
|
FBackground._AddRef;
|
|
|
|
inherited CreateNew(AOwner, Num);
|
|
|
|
Left := inherited Left;
|
|
Top := inherited Top;
|
|
Width := inherited Width;
|
|
Height := inherited Height;
|
|
end;
|
|
|
|
destructor TFormContainer.Destroy;
|
|
var
|
|
I: IInterfaceComponentReference;
|
|
begin
|
|
// we need to call "Screen.RemoveForm" to perform
|
|
// references back to nil by IDesignedForm to FDesignedForm
|
|
inherited Destroy;
|
|
|
|
FBackground.QueryInterface(IInterfaceComponentReference, I); // only way to omit SIGSEGV
|
|
I.GetComponent.Free;
|
|
Pointer(I) := nil; // omit _Release (Free is above)
|
|
Pointer(FBackground) := nil; // omit _Release (Free is above)
|
|
|
|
if Assigned(FDesignedForm) then
|
|
FreeAndNil(FDesignedForm);
|
|
end;
|
|
|
|
procedure TFormContainer.SetRealBorderStyle(AVal: TFormBorderStyle);
|
|
begin
|
|
inherited BorderStyle := AVal;
|
|
end;
|
|
|
|
procedure TFormContainer.SetRealBorderIcons(AVal: TBorderIcons);
|
|
begin
|
|
inherited BorderIcons := AVal;
|
|
end;
|
|
|
|
procedure TFormContainer.SetRealFormStyle(AVal: TFormStyle);
|
|
begin
|
|
inherited FormStyle := AVal;
|
|
end;
|
|
|
|
procedure TFormContainer.SetRealPopupMode(AVal: TPopupMode);
|
|
begin
|
|
inherited PopupMode := AVal;
|
|
end;
|
|
|
|
procedure TFormContainer.SetRealPopupParent(AVal: TCustomForm);
|
|
begin
|
|
inherited PopupParent := AVal;
|
|
end;
|
|
|
|
function TFormContainer.GetRealBorderStyle: TFormBorderStyle;
|
|
begin
|
|
Result := inherited BorderStyle;
|
|
end;
|
|
|
|
function TFormContainer.GetRealBorderIcons: TBorderIcons;
|
|
begin
|
|
Result := inherited BorderIcons;
|
|
end;
|
|
|
|
function TFormContainer.GetRealFormStyle: TFormStyle;
|
|
begin
|
|
Result := inherited FormStyle;
|
|
end;
|
|
|
|
function TFormContainer.GetRealPopupMode: TPopupMode;
|
|
begin
|
|
Result := inherited PopupMode;
|
|
end;
|
|
|
|
function TFormContainer.GetRealPopupParent: TCustomForm;
|
|
begin
|
|
Result := inherited PopupParent;
|
|
end;
|
|
|
|
procedure TFormContainer.SetHandledForm(AForm: TCustomForm);
|
|
begin
|
|
if FHandledForm = AForm then
|
|
Exit;
|
|
|
|
if FHandledForm <> nil then
|
|
FHandledForm.Parent := nil;
|
|
|
|
FHandledForm := AForm;
|
|
|
|
if FHandledForm <> nil then
|
|
FHandledForm.Parent := Self;
|
|
end;
|
|
|
|
|
|
end.
|
|
|