Anchordocking: Showing a docked minimized window causes an access violation. Issue #34775. Based on patch from erno.

git-svn-id: trunk@60101 -
This commit is contained in:
michl 2019-01-17 22:53:02 +00:00
parent 4c178a150f
commit d6b9c94c3f

View File

@ -100,11 +100,11 @@ unit AnchorDocking;
interface interface
uses uses
Math, Classes, SysUtils, types, Math, Classes, SysUtils, types, fgl,
LCLType, LCLIntf, LCLProc, LCLType, LCLIntf, LCLProc,
Controls, Forms, ExtCtrls, ComCtrls, Graphics, Themes, Menus, Buttons, Controls, Forms, ExtCtrls, ComCtrls, Graphics, Themes, Menus, Buttons,
LazConfigStorage, Laz2_XMLCfg, LazFileCache, LazConfigStorage, Laz2_XMLCfg, LazFileCache,
AnchorDockStr, AnchorDockStorage, AnchorDockPanel, fgl; AnchorDockStr, AnchorDockStorage, AnchorDockPanel;
{$IFDEF DebugDisableAutoSizing} {$IFDEF DebugDisableAutoSizing}
const ADAutoSizingReason = 'TAnchorDockMaster Delayed'; const ADAutoSizingReason = 'TAnchorDockMaster Delayed';
@ -559,6 +559,8 @@ type
procedure Assign(Source: TAnchorDockSettings); procedure Assign(Source: TAnchorDockSettings);
end; end;
TMapMinimizedControls = specialize TFPGMap <Pointer, Pointer>;
TAnchorDockMaster = class; TAnchorDockMaster = class;
{ TAnchorDockMaster { TAnchorDockMaster
@ -606,6 +608,7 @@ type
FSiteClass: TAnchorDockHostSiteClass; FSiteClass: TAnchorDockHostSiteClass;
FSplitterClass: TAnchorDockSplitterClass; FSplitterClass: TAnchorDockSplitterClass;
FSplitterWidth: integer; FSplitterWidth: integer;
FMapMinimizedControls: TMapMinimizedControls; // minimized controls and previous parent
fNeedSimplify: TFPList; // list of TControl fNeedSimplify: TFPList; // list of TControl
fNeedFree: TFPList; // list of TControl fNeedFree: TFPList; // list of TControl
fSimplifying: boolean; fSimplifying: boolean;
@ -2839,6 +2842,7 @@ begin
FHideHeaderCaptionFloatingControl:=true; FHideHeaderCaptionFloatingControl:=true;
FSplitterWidth:=4; FSplitterWidth:=4;
FScaleOnResize:=true; FScaleOnResize:=true;
FMapMinimizedControls:=TMapMinimizedControls.Create;
fNeedSimplify:=TFPList.Create; fNeedSimplify:=TFPList.Create;
fNeedFree:=TFPList.Create; fNeedFree:=TFPList.Create;
fDisabledAutosizing:=TFPList.Create; fDisabledAutosizing:=TFPList.Create;
@ -2876,6 +2880,7 @@ begin
FreeAndNil(fNeedSimplify); FreeAndNil(fNeedSimplify);
FreeAndNil(FControls); FreeAndNil(FControls);
FreeAndNil(fNeedFree); FreeAndNil(fNeedFree);
FreeAndNil(FMapMinimizedControls);
FreeAndNil(fDisabledAutosizing); FreeAndNil(fDisabledAutosizing);
{$IFDEF VerboseAnchorDocking} {$IFDEF VerboseAnchorDocking}
for i:=0 to ComponentCount-1 do begin for i:=0 to ComponentCount-1 do begin
@ -2917,17 +2922,16 @@ end;
function TAnchorDockMaster.IsMinimizedControl(AControl: TControl; out function TAnchorDockMaster.IsMinimizedControl(AControl: TControl; out
Site: TAnchorDockHostSite): Boolean; Site: TAnchorDockHostSite): Boolean;
var var
i: Integer; AIndex: Integer;
begin begin
Result:=False; AIndex:=FMapMinimizedControls.IndexOf(AControl);
Site:=nil; if AIndex<0 then begin
if not Assigned(AControl) or (FControls.IndexOf(AControl)<0) then Exit; Result:=False;
for i:=0 to ComponentCount-1 do Site:=nil;
if (Components[i] is TAnchorDockHostSite) end else begin
and (TAnchorDockHostSite(Components[i]).MinimizedControl = AControl) then begin Result:=True;
Site:=TAnchorDockHostSite(Components[i]); Site:=TAnchorDockHostSite(FMapMinimizedControls[AControl]);
Exit(True); end;
end;
end; end;
function TAnchorDockMaster.IsSite(AControl: TControl): boolean; function TAnchorDockMaster.IsSite(AControl: TControl): boolean;
@ -3174,6 +3178,10 @@ end;
procedure TAnchorDockMaster.MakeVisible(AControl: TControl; SwitchPages: boolean); procedure TAnchorDockMaster.MakeVisible(AControl: TControl; SwitchPages: boolean);
begin begin
while AControl<>nil do begin while AControl<>nil do begin
if FMapMinimizedControls.IndexOf(AControl)>=0 then begin
AControl:=TAnchorDockHostSite(FMapMinimizedControls[AControl]);
TAnchorDockHostSite(AControl).MinimizeSite;
end;
AControl.Visible:=true; AControl.Visible:=true;
if SwitchPages and (AControl is TAnchorDockPage) then if SwitchPages and (AControl is TAnchorDockPage) then
TAnchorDockPageControl(AControl.Parent).PageIndex:= TAnchorDockPageControl(AControl.Parent).PageIndex:=
@ -4473,6 +4481,7 @@ procedure TAnchorDockHostSite.RemoveControlFromLayout(AControl: TControl);
end; end;
if (sibling is TAnchorDockHostSite) then if (sibling is TAnchorDockHostSite) then
if (sibling as TAnchorDockHostSite).Minimized then begin if (sibling as TAnchorDockHostSite).Minimized then begin
DockMaster.FMapMinimizedControls.Remove((sibling as TAnchorDockHostSite).FMinimizedControl);
(sibling as TAnchorDockHostSite).FMinimizedControl.Parent:=(sibling as TAnchorDockHostSite); (sibling as TAnchorDockHostSite).FMinimizedControl.Parent:=(sibling as TAnchorDockHostSite);
(sibling as TAnchorDockHostSite).FMinimizedControl.Visible:=True; (sibling as TAnchorDockHostSite).FMinimizedControl.Visible:=True;
(sibling as TAnchorDockHostSite).FMinimizedControl:=nil; (sibling as TAnchorDockHostSite).FMinimizedControl:=nil;
@ -4552,6 +4561,7 @@ procedure TAnchorDockHostSite.RemoveControlFromLayout(AControl: TControl);
OnlySiteLeft.Align:=alClient; OnlySiteLeft.Align:=alClient;
Header.Parent:=Self; Header.Parent:=Self;
if OnlySiteLeft.Minimized then begin if OnlySiteLeft.Minimized then begin
DockMaster.FMapMinimizedControls.Remove(OnlySiteLeft.FMinimizedControl);
OnlySiteLeft.FMinimizedControl.Parent:=OnlySiteLeft; OnlySiteLeft.FMinimizedControl.Parent:=OnlySiteLeft;
OnlySiteLeft.FMinimizedControl.Visible:=True; OnlySiteLeft.FMinimizedControl.Visible:=True;
OnlySiteLeft.FMinimizedControl:=nil; OnlySiteLeft.FMinimizedControl:=nil;
@ -4612,7 +4622,8 @@ end;
procedure TAnchorDockHostSite.RemoveMinimizedControl; procedure TAnchorDockHostSite.RemoveMinimizedControl;
begin begin
FMinimizedControl := nil; FMinimizedControl:=nil;
DockMaster.FMapMinimizedControls.Remove(FMinimizedControl);
end; end;
procedure TAnchorDockHostSite.RemoveSpiralSplitter(AControl: TControl); procedure TAnchorDockHostSite.RemoveSpiralSplitter(AControl: TControl);
@ -5498,6 +5509,7 @@ begin
FMinimizedControl:=AControl; FMinimizedControl:=AControl;
AControl.Visible:=False; AControl.Visible:=False;
AControl.Parent:=nil; AControl.Parent:=nil;
DockMaster.FMapMinimizedControls.Add(AControl,Self);
end else begin end else begin
MaxSize:=ReturnAnchoredControlsSize(Splitter,SplitterAnchorKind); MaxSize:=ReturnAnchoredControlsSize(Splitter,SplitterAnchorKind);
case SplitterAnchorKind of case SplitterAnchorKind of
@ -5517,6 +5529,7 @@ begin
AControl.Parent:=self; AControl.Parent:=self;
AControl.Visible:=True; AControl.Visible:=True;
FMinimizedControl:=nil; FMinimizedControl:=nil;
DockMaster.FMapMinimizedControls.Remove(AControl);
end; end;
Splitter.Enabled:=AControl.Visible; Splitter.Enabled:=AControl.Visible;
UpdateHeaderAlign; UpdateHeaderAlign;