View Issue Details

IDProjectCategoryView StatusLast Update
0034775PackagesPackagespublic2019-01-18 13:55
ReportererrnoAssigned ToMichl 
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
PlatformPCOSwindows 64 bitsOS Version7
Product Version2.1 (SVN)Product Build59928 
Target Version2.2Fixed in Version2.1 (SVN) 
Summary0034775: Anchordocking : Showing a docked minimized window causes an access violation.
DescriptionShowing a docked window when the window is minimized causes an access violation.
Steps To Reproduce- in "general docking options" dialog check "Allow dock sites to be minimized" , check also "show header" .
- for example dock the window "code explorer" on the left side of the ide .
- minimze the "code explorer" by clicking on the button in the header .
- in main menu click on "View\Code Explorer"
- acces violation
TagsNo tags attached.
Fixed in Revision59936, 60101
LazTarget-
WidgetsetWin32/Win64
Attached Files
  • anchordocking.patch (5,548 bytes)
    Index: components/anchordocking/anchordocking.pas
    ===================================================================
    --- components/anchordocking/anchordocking.pas	(r�vision 59935)
    +++ components/anchordocking/anchordocking.pas	(copie de travail)
    @@ -104,7 +104,7 @@
       LCLType, LCLIntf, LCLProc,
       Controls, Forms, ExtCtrls, ComCtrls, Graphics, Themes, Menus, Buttons,
       LazConfigStorage, Laz2_XMLCfg, LazFileCache,
    -  AnchorDockStr, AnchorDockStorage, AnchorDockPanel;
    +  AnchorDockStr, AnchorDockStorage, AnchorDockPanel,fgl;
     
     {$IFDEF DebugDisableAutoSizing}
     const ADAutoSizingReason = 'TAnchorDockMaster Delayed';
    @@ -559,6 +559,8 @@
                     var AControl: TControl; DoDisableAutoSizing: boolean) of object;
       TADShowDockMasterOptionsEvent = function(aDockMaster: TAnchorDockMaster): TModalResult;
     
    +  TMapMaximizedSite=specialize TFPGMap<pointer,pointer>;
    +
       TAnchorDockMaster = class(TComponent)
       private
         FAllowDragging: boolean;
    @@ -605,6 +607,7 @@
         // Used by RestoreLayout:
         WorkArea, SrcWorkArea: TRect;
         FOverlappingForm:TAnchorDockOverlappingForm;
    +    FMapMaximizedSite:TMapMaximizedSite;
     
         function GetControls(Index: integer): TControl;
         function GetLocalizedHeaderHint: string;
    @@ -666,6 +669,7 @@
         procedure StopHideOverlappingTimer;
         procedure AsyncSimplify({%H-}Data: PtrInt);
       public
    +    function GetMaximizedSite(AControl: tcontrol): TAnchorDockHostSite;
         procedure ShowOverlappingForm;
         procedure HideOverlappingForm(Sender: TObject);
         constructor Create(AOwner: TComponent); override;
    @@ -2652,6 +2656,13 @@
       SimplifyPendingLayouts;
     end;
     
    +function TAnchorDockMaster.GetMaximizedSite(AControl:tcontrol):TAnchorDockHostSite;
    +begin
    +  if FMapMaximizedSite.IndexOf(AControl)=-1 then
    +     exit(nil);
    +  result:=TAnchorDockHostSite(FMapMaximizedSite[AControl]);
    +end;
    +
     procedure TAnchorDockMaster.ChangeLockButtonClick(Sender: TObject);
     begin
       AllowDragging:=not AllowDragging;
    @@ -2943,6 +2954,7 @@
       FHeaderHighlightFocused:=false;
       FDockSitesCanBeMinimized:=false;
       FOverlappingForm:=nil;
    +  FMapMaximizedSite:=TMapMaximizedSite.Create;
     end;
     
     destructor TAnchorDockMaster.Destroy;
    @@ -2976,6 +2988,7 @@
             TControl(Components[i]).RemoveAllHandlersOfObject(TControl(Components[j]));
       end;
       end;
    +  FreeAndNil(FMapMaximizedSite);
       inherited Destroy;
     end;
     
    @@ -5566,6 +5579,8 @@
           FMinimizedControl:=AControl;
           AControl.Visible:=False;
           AControl.Parent:=nil;
    +      //store the maximized site
    +      DockMaster.FMapMaximizedSite.Add(AControl,self);
         end else begin
           MaxSize:=ReturnAnchoredControlsSize(Splitter,SplitterAnchorKind);
           case SplitterAnchorKind of
    @@ -5584,6 +5599,7 @@
           end;
           AControl.Parent:=self;
           AControl.Visible:=True;
    +      DockMaster.FMapMaximizedSite.Remove(Acontrol);
           FMinimizedControl:=nil;
         end;
         Splitter.Enabled:=AControl.Visible;
    Index: components/anchordocking/design/registeranchordocking.pas
    ===================================================================
    --- components/anchordocking/design/registeranchordocking.pas	(r�vision 59935)
    +++ components/anchordocking/design/registeranchordocking.pas	(copie de travail)
    @@ -299,8 +299,20 @@
     
     procedure TIDEAnchorDockMaster.ShowForm(AForm: TCustomForm;
       BringToFront: boolean);
    +
    +  function GetParentWinControl(Control: TControl; TopForm: Boolean=true): TWinControl;
    +  begin
    +    while (Control <> nil) and (Control.Parent <> nil) do
    +    begin
    +      if (not TopForm) and (Control is TCustomForm) then
    +        Break;
    +      Control := Control.Parent;
    +    end;
    +  result:= control as TWinControl;
    +  end;
    +
     var
    -  Parent: TCustomForm;
    +  Parent: twincontrol;
       Creator: TIDEWindowCreator;
       NewBounds: TRect;
       DockSiblingName: string;
    @@ -312,6 +324,7 @@
       NeedPlacing: Boolean;
       SiteForm: TCustomForm;
       OldActiveControl: TWinControl;
    +  MaximizedSite:TAnchorDockHostSite;
     begin
       //debugln(['TIDEAnchorDockMaster.ShowForm START ',DbgSName(AForm),' BringToFront=',BringToFront,' IsSite=',DockMaster.IsSite(AForm),' IsCustomSite=',DockMaster.IsCustomSite(AForm)]);
       try
    @@ -381,18 +394,22 @@
         AForm.EnableAlign;
     
         if BringToFront then begin
    -      if (OldActiveControl=nil)
    +      Parent:=GetParentWinControl(aform);
    +      MaximizedSite:=DockMaster.GetMaximizedSite(parent);
    +      if MaximizedSite<>nil then
    +         MaximizedSite.MinimizeSite
    +         else
    +         if Parent is TCustomForm then
    +           TCustomForm(Parent).ShowOnTop;
    +      if ((OldActiveControl=nil)
           or (not OldActiveControl.HandleAllocated)
    -      or (FindControl(GetFocus)<>OldActiveControl) then begin
    -        Parent:=GetParentForm(AForm);
    -        Parent.ShowOnTop;
    -        if (OldActiveControl<>nil) and OldActiveControl.CanFocus then
    +      or (FindControl(GetFocus)<>OldActiveControl)) and (parent is TCustomForm) and (OldActiveControl<>nil)
    +      and OldActiveControl.CanFocus then
             begin
    -          Parent.ActiveControl:=OldActiveControl;
    -          Parent.SetFocus;
    +          TCustomForm(Parent).ActiveControl:=OldActiveControl;
    +          TCustomForm(Parent).SetFocus;
             end;
             //debugln(['TIDEAnchorDockMaster.ShowForm AForm.ActiveControl=',dbgsname(AForm.ActiveControl),' ',DbgSName(Parent.ActiveControl),' ',DbgSName(FindControl(GetFocus))]);
    -      end;
         end;
       end;
       //debugln(['TIDEAnchorDockMaster.ShowForm END ',DbgSName(AForm),' ',dbgs(AForm.BoundsRect),' ',DbgSName(FindControl(GetFocus))]);
    
    anchordocking.patch (5,548 bytes)
  • bug34775.xml (5,304 bytes)
  • anchordocking.pas_after_59936.patch (4,099 bytes)
    Index: components/anchordocking/anchordocking.pas
    ===================================================================
    --- components/anchordocking/anchordocking.pas	(revision 59940)
    +++ components/anchordocking/anchordocking.pas	(working copy)
    @@ -691,6 +691,8 @@
                         const OnClickEvent: TNotifyEvent; AParent: TMenuItem = nil): TMenuItem; virtual;
     
         // show / make a control dockable
    +    function unMinimizeAndReturnParent(AControl: TControl; AddDockHeader: boolean):TControl;
    +    procedure unMinimizeParents(AControl: TControl; AddDockHeader: boolean);
         procedure MakeDockable(AControl: TControl; Show: boolean = true;
                                BringToFront: boolean = false;
                                AddDockHeader: boolean = true);
    @@ -3010,7 +3012,7 @@
     begin
       Result:=False;
       Site:=nil;
    -  if not Assigned(AControl) or (FControls.IndexOf(AControl)<0) then Exit;
    +  if not Assigned(AControl) {or (FControls.IndexOf(AControl)<0)} then Exit;
       for i:=0 to ComponentCount-1 do
         if (Components[i] is TAnchorDockHostSite)
         and (TAnchorDockHostSite(Components[i]).MinimizedControl = AControl) then begin
    @@ -3126,6 +3128,30 @@
       end;
     end;
     
    +function TAnchorDockMaster.unMinimizeAndReturnParent(AControl: TControl; AddDockHeader: boolean):TControl;
    +var
    +  Site: TAnchorDockHostSite;
    +begin
    +  result:=AControl.Parent;
    +  if AControl.Parent=nil then
    +    if IsMinimizedControl(AControl, Site) then begin
    +      Site.MinimizeSite;
    +      result:=site;
    +    end else begin
    +      if FControls.IndexOf(AControl)<0 then begin
    +        FControls.Add(AControl);
    +        AControl.FreeNotification(Self);
    +      end;
    +    end
    +end;
    +
    +
    +procedure TAnchorDockMaster.unMinimizeParents(AControl: TControl; AddDockHeader: boolean);
    +begin
    +  while AControl<>nil do
    +    AControl:=unMinimizeAndReturnParent(AControl,AddDockHeader);
    +end;
    +
     procedure TAnchorDockMaster.MakeDockable(AControl: TControl; Show: boolean;
       BringToFront: boolean; AddDockHeader: boolean);
     var
    @@ -3144,39 +3170,32 @@
       Site:=nil;
       AControl.DisableAutoSizing{$IFDEF DebugDisableAutoSizing}('TAnchorDockMaster.DisableControlAutoSizing'){$ENDIF};
       try
    +    unMinimizeParents(AControl,AddDockHeader);
         if AControl is TAnchorDockHostSite then begin
           // already a site
           Site:=TAnchorDockHostSite(AControl);
    -    end else if AControl.Parent=nil then
    -      if IsMinimizedControl(AControl, Site) then begin
    -        Site.AsyncMinimizeSite(0);
    -      end else begin
    -
    -        if FControls.IndexOf(AControl)<0 then begin
    -          FControls.Add(AControl);
    -          AControl.FreeNotification(Self);
    -        end;
    -
    -        // create docksite
    -        Site:=CreateSite;
    +    end else if AControl.Parent=nil then begin
    +      // create docksite
    +      Site:=CreateSite;
    +      try
             try
    -          try
    -            Site.BoundsRect:=AControl.BoundsRect;
    -            ClearLayoutProperties(AControl);
    -            // dock
    -            AControl.ManualDock(Site);
    -            AControl.Visible:=true;
    -            if not AddDockHeader then
    -              Site.Header.Parent:=nil;
    -          except
    -            FreeAndNil(Site);
    -            raise;
    -          end;
    -        finally
    -          if Site<>nil then
    -            Site.EnableAutoSizing{$IFDEF DebugDisableAutoSizing}(ADAutoSizingReason){$ENDIF};
    +          Site.BoundsRect:=AControl.BoundsRect;
    +          ClearLayoutProperties(AControl);
    +          // dock
    +          AControl.ManualDock(Site);
    +          AControl.Visible:=true;
    +          if not AddDockHeader then
    +            Site.Header.Parent:=nil;
    +        except
    +          FreeAndNil(Site);
    +          raise;
             end;
    -    end else if AControl.Parent is TAnchorDockHostSite then begin
    +      finally
    +        if Site<>nil then
    +          Site.EnableAutoSizing{$IFDEF DebugDisableAutoSizing}(ADAutoSizingReason){$ENDIF};
    +      end;
    +    end
    +    else if AControl.Parent is TAnchorDockHostSite then begin
           // AControl is already docked => show site
           Site:=TAnchorDockHostSite(AControl.Parent);
           AControl.Visible:=true;
    
  • anchordocking.pas_after_59936_2.patch (4,832 bytes)
    Index: components/anchordocking/anchordocking.pas
    ===================================================================
    --- components/anchordocking/anchordocking.pas	(r�vision 59940)
    +++ components/anchordocking/anchordocking.pas	(copie de travail)
    @@ -691,6 +691,8 @@
                         const OnClickEvent: TNotifyEvent; AParent: TMenuItem = nil): TMenuItem; virtual;
     
         // show / make a control dockable
    +    function unMinimizeAndReturnParent(AControl: TControl; AddDockHeader: boolean):TControl;
    +    procedure unMinimizeParents(AControl: TControl; AddDockHeader: boolean);
         procedure MakeDockable(AControl: TControl; Show: boolean = true;
                                BringToFront: boolean = false;
                                AddDockHeader: boolean = true);
    @@ -3010,7 +3012,7 @@
     begin
       Result:=False;
       Site:=nil;
    -  if not Assigned(AControl) or (FControls.IndexOf(AControl)<0) then Exit;
    +  if not Assigned(AControl) {or (FControls.IndexOf(AControl)<0)} then Exit;
       for i:=0 to ComponentCount-1 do
         if (Components[i] is TAnchorDockHostSite)
         and (TAnchorDockHostSite(Components[i]).MinimizedControl = AControl) then begin
    @@ -3126,6 +3128,30 @@
       end;
     end;
     
    +function TAnchorDockMaster.unMinimizeAndReturnParent(AControl: TControl; AddDockHeader: boolean):TControl;
    +var
    +  Site: TAnchorDockHostSite;
    +begin
    +  result:=AControl.Parent;
    +  if AControl.Parent=nil then
    +    if IsMinimizedControl(AControl, Site) then begin
    +      Site.MinimizeSite;
    +      result:=site;
    +    end else begin
    +      if FControls.IndexOf(AControl)<0 then begin
    +        FControls.Add(AControl);
    +        AControl.FreeNotification(Self);
    +      end;
    +    end
    +end;
    +
    +
    +procedure TAnchorDockMaster.unMinimizeParents(AControl: TControl; AddDockHeader: boolean);
    +begin
    +  while AControl<>nil do
    +    AControl:=unMinimizeAndReturnParent(AControl,AddDockHeader);
    +end;
    +
     procedure TAnchorDockMaster.MakeDockable(AControl: TControl; Show: boolean;
       BringToFront: boolean; AddDockHeader: boolean);
     var
    @@ -3144,39 +3170,32 @@
       Site:=nil;
       AControl.DisableAutoSizing{$IFDEF DebugDisableAutoSizing}('TAnchorDockMaster.DisableControlAutoSizing'){$ENDIF};
       try
    +    unMinimizeParents(AControl,AddDockHeader);
         if AControl is TAnchorDockHostSite then begin
           // already a site
           Site:=TAnchorDockHostSite(AControl);
    -    end else if AControl.Parent=nil then
    -      if IsMinimizedControl(AControl, Site) then begin
    -        Site.AsyncMinimizeSite(0);
    -      end else begin
    -
    -        if FControls.IndexOf(AControl)<0 then begin
    -          FControls.Add(AControl);
    -          AControl.FreeNotification(Self);
    -        end;
    -
    -        // create docksite
    -        Site:=CreateSite;
    +    end else if AControl.Parent=nil then begin
    +      // create docksite
    +      Site:=CreateSite;
    +      try
             try
    -          try
    -            Site.BoundsRect:=AControl.BoundsRect;
    -            ClearLayoutProperties(AControl);
    -            // dock
    -            AControl.ManualDock(Site);
    -            AControl.Visible:=true;
    -            if not AddDockHeader then
    -              Site.Header.Parent:=nil;
    -          except
    -            FreeAndNil(Site);
    -            raise;
    -          end;
    -        finally
    -          if Site<>nil then
    -            Site.EnableAutoSizing{$IFDEF DebugDisableAutoSizing}(ADAutoSizingReason){$ENDIF};
    +          Site.BoundsRect:=AControl.BoundsRect;
    +          ClearLayoutProperties(AControl);
    +          // dock
    +          AControl.ManualDock(Site);
    +          AControl.Visible:=true;
    +          if not AddDockHeader then
    +            Site.Header.Parent:=nil;
    +        except
    +          FreeAndNil(Site);
    +          raise;
             end;
    -    end else if AControl.Parent is TAnchorDockHostSite then begin
    +      finally
    +        if Site<>nil then
    +          Site.EnableAutoSizing{$IFDEF DebugDisableAutoSizing}(ADAutoSizingReason){$ENDIF};
    +      end;
    +    end
    +    else if AControl.Parent is TAnchorDockHostSite then begin
           // AControl is already docked => show site
           Site:=TAnchorDockHostSite(AControl.Parent);
           AControl.Visible:=true;
    Index: components/anchordocking/design/registeranchordocking.pas
    ===================================================================
    --- components/anchordocking/design/registeranchordocking.pas	(r�vision 59940)
    +++ components/anchordocking/design/registeranchordocking.pas	(copie de travail)
    @@ -313,6 +313,10 @@
       SiteForm: TCustomForm;
       OldActiveControl: TWinControl;
     begin
    +  if not DockMaster.IsCustomSite(AForm) then begin
    +    DockMaster.ShowControl(AForm.Name,BringToFront);
    +    exit;
    +  end;
       //debugln(['TIDEAnchorDockMaster.ShowForm START ',DbgSName(AForm),' BringToFront=',BringToFront,' IsSite=',DockMaster.IsSite(AForm),' IsCustomSite=',DockMaster.IsCustomSite(AForm)]);
       try
         AForm.DisableAlign;
    

Activities

errno

2018-12-28 22:11

reporter   ~0112964

Last edited: 2018-12-28 22:20

View 3 revisions

for precisions , the bug happens when there are two or more windows docked in the same tabcontrol .
The steps to reproduce the bug is :
- in "general docking options" dialog check "Allow dock sites to be minimized" , check also "show header" .
- for example dock the window "code explorer" on the left side of the ide .
 and dock ( in the center) the window "object inspector" in the same dock site .
- minimize the "code explorer" and "object inspector" by clicking on the button in the header .
- in main menu click on "View\Code Explorer"
- acces violation

Andrey Zubarev

2018-12-29 15:43

reporter   ~0112983

Yes, show a minimized controls cause problems. I try fix it

Michl

2018-12-29 20:42

developer   ~0112990

Fixed in trunk revision 59936. Please test and close if ok.

Michl

2018-12-29 20:47

developer   ~0112991

> I try fix it

Sorry for late reply. I hope, you wasn't already working on it. I see the problem and possible solution yesterday, but I was offline then and today.

errno

2018-12-29 23:36

reporter   ~0112995

Last edited: 2018-12-30 00:49

View 4 revisions

I tested rev 59936 , and i see that the changes made in rev 59936 doesn't solve the problem . So i reopen the post .
I don't know if it is related to windows , but it doesn't change anything and i still have the same bug happening .

I post a patch that i have made for the revision prior 59936 anchordocking.patch.
anchordocking.patch makes mainly the following changes :
- the problem is that we loose the maximized TAnchorDockHostSite site when the window is minimized (in TAnchorDockHostSite.AsyncMinimizeSite), so the patch stores the TAnchorDockHostSite site in a map for the minimized window and then restore it when the window is maximized ( in TIDEAnchorDockMaster.ShowForm).

errno

2018-12-29 23:36

reporter  

anchordocking.patch (5,548 bytes)
Index: components/anchordocking/anchordocking.pas
===================================================================
--- components/anchordocking/anchordocking.pas	(r�vision 59935)
+++ components/anchordocking/anchordocking.pas	(copie de travail)
@@ -104,7 +104,7 @@
   LCLType, LCLIntf, LCLProc,
   Controls, Forms, ExtCtrls, ComCtrls, Graphics, Themes, Menus, Buttons,
   LazConfigStorage, Laz2_XMLCfg, LazFileCache,
-  AnchorDockStr, AnchorDockStorage, AnchorDockPanel;
+  AnchorDockStr, AnchorDockStorage, AnchorDockPanel,fgl;
 
 {$IFDEF DebugDisableAutoSizing}
 const ADAutoSizingReason = 'TAnchorDockMaster Delayed';
@@ -559,6 +559,8 @@
                 var AControl: TControl; DoDisableAutoSizing: boolean) of object;
   TADShowDockMasterOptionsEvent = function(aDockMaster: TAnchorDockMaster): TModalResult;
 
+  TMapMaximizedSite=specialize TFPGMap<pointer,pointer>;
+
   TAnchorDockMaster = class(TComponent)
   private
     FAllowDragging: boolean;
@@ -605,6 +607,7 @@
     // Used by RestoreLayout:
     WorkArea, SrcWorkArea: TRect;
     FOverlappingForm:TAnchorDockOverlappingForm;
+    FMapMaximizedSite:TMapMaximizedSite;
 
     function GetControls(Index: integer): TControl;
     function GetLocalizedHeaderHint: string;
@@ -666,6 +669,7 @@
     procedure StopHideOverlappingTimer;
     procedure AsyncSimplify({%H-}Data: PtrInt);
   public
+    function GetMaximizedSite(AControl: tcontrol): TAnchorDockHostSite;
     procedure ShowOverlappingForm;
     procedure HideOverlappingForm(Sender: TObject);
     constructor Create(AOwner: TComponent); override;
@@ -2652,6 +2656,13 @@
   SimplifyPendingLayouts;
 end;
 
+function TAnchorDockMaster.GetMaximizedSite(AControl:tcontrol):TAnchorDockHostSite;
+begin
+  if FMapMaximizedSite.IndexOf(AControl)=-1 then
+     exit(nil);
+  result:=TAnchorDockHostSite(FMapMaximizedSite[AControl]);
+end;
+
 procedure TAnchorDockMaster.ChangeLockButtonClick(Sender: TObject);
 begin
   AllowDragging:=not AllowDragging;
@@ -2943,6 +2954,7 @@
   FHeaderHighlightFocused:=false;
   FDockSitesCanBeMinimized:=false;
   FOverlappingForm:=nil;
+  FMapMaximizedSite:=TMapMaximizedSite.Create;
 end;
 
 destructor TAnchorDockMaster.Destroy;
@@ -2976,6 +2988,7 @@
         TControl(Components[i]).RemoveAllHandlersOfObject(TControl(Components[j]));
   end;
   end;
+  FreeAndNil(FMapMaximizedSite);
   inherited Destroy;
 end;
 
@@ -5566,6 +5579,8 @@
       FMinimizedControl:=AControl;
       AControl.Visible:=False;
       AControl.Parent:=nil;
+      //store the maximized site
+      DockMaster.FMapMaximizedSite.Add(AControl,self);
     end else begin
       MaxSize:=ReturnAnchoredControlsSize(Splitter,SplitterAnchorKind);
       case SplitterAnchorKind of
@@ -5584,6 +5599,7 @@
       end;
       AControl.Parent:=self;
       AControl.Visible:=True;
+      DockMaster.FMapMaximizedSite.Remove(Acontrol);
       FMinimizedControl:=nil;
     end;
     Splitter.Enabled:=AControl.Visible;
Index: components/anchordocking/design/registeranchordocking.pas
===================================================================
--- components/anchordocking/design/registeranchordocking.pas	(r�vision 59935)
+++ components/anchordocking/design/registeranchordocking.pas	(copie de travail)
@@ -299,8 +299,20 @@
 
 procedure TIDEAnchorDockMaster.ShowForm(AForm: TCustomForm;
   BringToFront: boolean);
+
+  function GetParentWinControl(Control: TControl; TopForm: Boolean=true): TWinControl;
+  begin
+    while (Control <> nil) and (Control.Parent <> nil) do
+    begin
+      if (not TopForm) and (Control is TCustomForm) then
+        Break;
+      Control := Control.Parent;
+    end;
+  result:= control as TWinControl;
+  end;
+
 var
-  Parent: TCustomForm;
+  Parent: twincontrol;
   Creator: TIDEWindowCreator;
   NewBounds: TRect;
   DockSiblingName: string;
@@ -312,6 +324,7 @@
   NeedPlacing: Boolean;
   SiteForm: TCustomForm;
   OldActiveControl: TWinControl;
+  MaximizedSite:TAnchorDockHostSite;
 begin
   //debugln(['TIDEAnchorDockMaster.ShowForm START ',DbgSName(AForm),' BringToFront=',BringToFront,' IsSite=',DockMaster.IsSite(AForm),' IsCustomSite=',DockMaster.IsCustomSite(AForm)]);
   try
@@ -381,18 +394,22 @@
     AForm.EnableAlign;
 
     if BringToFront then begin
-      if (OldActiveControl=nil)
+      Parent:=GetParentWinControl(aform);
+      MaximizedSite:=DockMaster.GetMaximizedSite(parent);
+      if MaximizedSite<>nil then
+         MaximizedSite.MinimizeSite
+         else
+         if Parent is TCustomForm then
+           TCustomForm(Parent).ShowOnTop;
+      if ((OldActiveControl=nil)
       or (not OldActiveControl.HandleAllocated)
-      or (FindControl(GetFocus)<>OldActiveControl) then begin
-        Parent:=GetParentForm(AForm);
-        Parent.ShowOnTop;
-        if (OldActiveControl<>nil) and OldActiveControl.CanFocus then
+      or (FindControl(GetFocus)<>OldActiveControl)) and (parent is TCustomForm) and (OldActiveControl<>nil)
+      and OldActiveControl.CanFocus then
         begin
-          Parent.ActiveControl:=OldActiveControl;
-          Parent.SetFocus;
+          TCustomForm(Parent).ActiveControl:=OldActiveControl;
+          TCustomForm(Parent).SetFocus;
         end;
         //debugln(['TIDEAnchorDockMaster.ShowForm AForm.ActiveControl=',dbgsname(AForm.ActiveControl),' ',DbgSName(Parent.ActiveControl),' ',DbgSName(FindControl(GetFocus))]);
-      end;
     end;
   end;
   //debugln(['TIDEAnchorDockMaster.ShowForm END ',DbgSName(AForm),' ',dbgs(AForm.BoundsRect),' ',DbgSName(FindControl(GetFocus))]);
anchordocking.patch (5,548 bytes)

Michl

2018-12-30 13:59

developer   ~0113010

Thank you for the patch! I'll look at it. Can you please add a saved layout for MiniIDE that show that issue. Maybe I saw a other issue.

errno

2018-12-30 21:09

reporter  

bug34775.xml (5,304 bytes)

errno

2018-12-30 21:11

reporter   ~0113022

Last edited: 2018-12-30 21:19

View 4 revisions

layout added bug34775.xml for <anchordocking dir>\minide\miniide1.lpi .

To reproduce the bug , load the layout in the miniIDE and click on the button "view code explorer" or on the button "view object inspector" .

Andrey Zubarev

2018-12-31 00:42

reporter  

anchordocking.pas_after_59936.patch (4,099 bytes)
Index: components/anchordocking/anchordocking.pas
===================================================================
--- components/anchordocking/anchordocking.pas	(revision 59940)
+++ components/anchordocking/anchordocking.pas	(working copy)
@@ -691,6 +691,8 @@
                     const OnClickEvent: TNotifyEvent; AParent: TMenuItem = nil): TMenuItem; virtual;
 
     // show / make a control dockable
+    function unMinimizeAndReturnParent(AControl: TControl; AddDockHeader: boolean):TControl;
+    procedure unMinimizeParents(AControl: TControl; AddDockHeader: boolean);
     procedure MakeDockable(AControl: TControl; Show: boolean = true;
                            BringToFront: boolean = false;
                            AddDockHeader: boolean = true);
@@ -3010,7 +3012,7 @@
 begin
   Result:=False;
   Site:=nil;
-  if not Assigned(AControl) or (FControls.IndexOf(AControl)<0) then Exit;
+  if not Assigned(AControl) {or (FControls.IndexOf(AControl)<0)} then Exit;
   for i:=0 to ComponentCount-1 do
     if (Components[i] is TAnchorDockHostSite)
     and (TAnchorDockHostSite(Components[i]).MinimizedControl = AControl) then begin
@@ -3126,6 +3128,30 @@
   end;
 end;
 
+function TAnchorDockMaster.unMinimizeAndReturnParent(AControl: TControl; AddDockHeader: boolean):TControl;
+var
+  Site: TAnchorDockHostSite;
+begin
+  result:=AControl.Parent;
+  if AControl.Parent=nil then
+    if IsMinimizedControl(AControl, Site) then begin
+      Site.MinimizeSite;
+      result:=site;
+    end else begin
+      if FControls.IndexOf(AControl)<0 then begin
+        FControls.Add(AControl);
+        AControl.FreeNotification(Self);
+      end;
+    end
+end;
+
+
+procedure TAnchorDockMaster.unMinimizeParents(AControl: TControl; AddDockHeader: boolean);
+begin
+  while AControl<>nil do
+    AControl:=unMinimizeAndReturnParent(AControl,AddDockHeader);
+end;
+
 procedure TAnchorDockMaster.MakeDockable(AControl: TControl; Show: boolean;
   BringToFront: boolean; AddDockHeader: boolean);
 var
@@ -3144,39 +3170,32 @@
   Site:=nil;
   AControl.DisableAutoSizing{$IFDEF DebugDisableAutoSizing}('TAnchorDockMaster.DisableControlAutoSizing'){$ENDIF};
   try
+    unMinimizeParents(AControl,AddDockHeader);
     if AControl is TAnchorDockHostSite then begin
       // already a site
       Site:=TAnchorDockHostSite(AControl);
-    end else if AControl.Parent=nil then
-      if IsMinimizedControl(AControl, Site) then begin
-        Site.AsyncMinimizeSite(0);
-      end else begin
-
-        if FControls.IndexOf(AControl)<0 then begin
-          FControls.Add(AControl);
-          AControl.FreeNotification(Self);
-        end;
-
-        // create docksite
-        Site:=CreateSite;
+    end else if AControl.Parent=nil then begin
+      // create docksite
+      Site:=CreateSite;
+      try
         try
-          try
-            Site.BoundsRect:=AControl.BoundsRect;
-            ClearLayoutProperties(AControl);
-            // dock
-            AControl.ManualDock(Site);
-            AControl.Visible:=true;
-            if not AddDockHeader then
-              Site.Header.Parent:=nil;
-          except
-            FreeAndNil(Site);
-            raise;
-          end;
-        finally
-          if Site<>nil then
-            Site.EnableAutoSizing{$IFDEF DebugDisableAutoSizing}(ADAutoSizingReason){$ENDIF};
+          Site.BoundsRect:=AControl.BoundsRect;
+          ClearLayoutProperties(AControl);
+          // dock
+          AControl.ManualDock(Site);
+          AControl.Visible:=true;
+          if not AddDockHeader then
+            Site.Header.Parent:=nil;
+        except
+          FreeAndNil(Site);
+          raise;
         end;
-    end else if AControl.Parent is TAnchorDockHostSite then begin
+      finally
+        if Site<>nil then
+          Site.EnableAutoSizing{$IFDEF DebugDisableAutoSizing}(ADAutoSizingReason){$ENDIF};
+      end;
+    end
+    else if AControl.Parent is TAnchorDockHostSite then begin
       // AControl is already docked => show site
       Site:=TAnchorDockHostSite(AControl.Parent);
       AControl.Visible:=true;

Andrey Zubarev

2018-12-31 00:43

reporter   ~0113028

Please review anchordocking.pas_after_59936.patch it fix bug34775.xml

errno

2018-12-31 01:50

reporter   ~0113031

Last edited: 2018-12-31 18:56

View 5 revisions

@Andrey Zubarev , i have tested your patch anchordocking.pas_after_59936.patch , it fixes the bug for the miniide but it doesn't fix it for the ide .
An exception is raised in TIDEAnchorDockMaster.ShowForm at line 388 in file RegisterAnchordocking.pas of package anchordockindsgn.lpk (line 388= Parent.ShowOnTop) because at the previous line GetParentForm(AForm) returns nil and set Parent equal to nil .

errno

2018-12-31 18:42

reporter   ~0113048

Last edited: 2019-01-04 19:58

View 3 revisions

I post a modified version of anchordocking.pas_after_59936.patch named anchordocking.pas_after_59936_2.patch .
I just added a modification in RegisterAnchordocking.pas (package anchordockindsgn.lpk) .
It fixes now also the bug in the ide .

I noticed also that my patch anchordocking.patch doesn't fix the bug in the miniIde .


NB : if forgot to say in the description anchordocking means both packages anchordocking.lpk and anchordockindsgn.lpk .

can you please review anchordocking.pas_after_59936_2.patch ?

errno

2018-12-31 18:42

reporter  

anchordocking.pas_after_59936_2.patch (4,832 bytes)
Index: components/anchordocking/anchordocking.pas
===================================================================
--- components/anchordocking/anchordocking.pas	(r�vision 59940)
+++ components/anchordocking/anchordocking.pas	(copie de travail)
@@ -691,6 +691,8 @@
                     const OnClickEvent: TNotifyEvent; AParent: TMenuItem = nil): TMenuItem; virtual;
 
     // show / make a control dockable
+    function unMinimizeAndReturnParent(AControl: TControl; AddDockHeader: boolean):TControl;
+    procedure unMinimizeParents(AControl: TControl; AddDockHeader: boolean);
     procedure MakeDockable(AControl: TControl; Show: boolean = true;
                            BringToFront: boolean = false;
                            AddDockHeader: boolean = true);
@@ -3010,7 +3012,7 @@
 begin
   Result:=False;
   Site:=nil;
-  if not Assigned(AControl) or (FControls.IndexOf(AControl)<0) then Exit;
+  if not Assigned(AControl) {or (FControls.IndexOf(AControl)<0)} then Exit;
   for i:=0 to ComponentCount-1 do
     if (Components[i] is TAnchorDockHostSite)
     and (TAnchorDockHostSite(Components[i]).MinimizedControl = AControl) then begin
@@ -3126,6 +3128,30 @@
   end;
 end;
 
+function TAnchorDockMaster.unMinimizeAndReturnParent(AControl: TControl; AddDockHeader: boolean):TControl;
+var
+  Site: TAnchorDockHostSite;
+begin
+  result:=AControl.Parent;
+  if AControl.Parent=nil then
+    if IsMinimizedControl(AControl, Site) then begin
+      Site.MinimizeSite;
+      result:=site;
+    end else begin
+      if FControls.IndexOf(AControl)<0 then begin
+        FControls.Add(AControl);
+        AControl.FreeNotification(Self);
+      end;
+    end
+end;
+
+
+procedure TAnchorDockMaster.unMinimizeParents(AControl: TControl; AddDockHeader: boolean);
+begin
+  while AControl<>nil do
+    AControl:=unMinimizeAndReturnParent(AControl,AddDockHeader);
+end;
+
 procedure TAnchorDockMaster.MakeDockable(AControl: TControl; Show: boolean;
   BringToFront: boolean; AddDockHeader: boolean);
 var
@@ -3144,39 +3170,32 @@
   Site:=nil;
   AControl.DisableAutoSizing{$IFDEF DebugDisableAutoSizing}('TAnchorDockMaster.DisableControlAutoSizing'){$ENDIF};
   try
+    unMinimizeParents(AControl,AddDockHeader);
     if AControl is TAnchorDockHostSite then begin
       // already a site
       Site:=TAnchorDockHostSite(AControl);
-    end else if AControl.Parent=nil then
-      if IsMinimizedControl(AControl, Site) then begin
-        Site.AsyncMinimizeSite(0);
-      end else begin
-
-        if FControls.IndexOf(AControl)<0 then begin
-          FControls.Add(AControl);
-          AControl.FreeNotification(Self);
-        end;
-
-        // create docksite
-        Site:=CreateSite;
+    end else if AControl.Parent=nil then begin
+      // create docksite
+      Site:=CreateSite;
+      try
         try
-          try
-            Site.BoundsRect:=AControl.BoundsRect;
-            ClearLayoutProperties(AControl);
-            // dock
-            AControl.ManualDock(Site);
-            AControl.Visible:=true;
-            if not AddDockHeader then
-              Site.Header.Parent:=nil;
-          except
-            FreeAndNil(Site);
-            raise;
-          end;
-        finally
-          if Site<>nil then
-            Site.EnableAutoSizing{$IFDEF DebugDisableAutoSizing}(ADAutoSizingReason){$ENDIF};
+          Site.BoundsRect:=AControl.BoundsRect;
+          ClearLayoutProperties(AControl);
+          // dock
+          AControl.ManualDock(Site);
+          AControl.Visible:=true;
+          if not AddDockHeader then
+            Site.Header.Parent:=nil;
+        except
+          FreeAndNil(Site);
+          raise;
         end;
-    end else if AControl.Parent is TAnchorDockHostSite then begin
+      finally
+        if Site<>nil then
+          Site.EnableAutoSizing{$IFDEF DebugDisableAutoSizing}(ADAutoSizingReason){$ENDIF};
+      end;
+    end
+    else if AControl.Parent is TAnchorDockHostSite then begin
       // AControl is already docked => show site
       Site:=TAnchorDockHostSite(AControl.Parent);
       AControl.Visible:=true;
Index: components/anchordocking/design/registeranchordocking.pas
===================================================================
--- components/anchordocking/design/registeranchordocking.pas	(r�vision 59940)
+++ components/anchordocking/design/registeranchordocking.pas	(copie de travail)
@@ -313,6 +313,10 @@
   SiteForm: TCustomForm;
   OldActiveControl: TWinControl;
 begin
+  if not DockMaster.IsCustomSite(AForm) then begin
+    DockMaster.ShowControl(AForm.Name,BringToFront);
+    exit;
+  end;
   //debugln(['TIDEAnchorDockMaster.ShowForm START ',DbgSName(AForm),' BringToFront=',BringToFront,' IsSite=',DockMaster.IsSite(AForm),' IsCustomSite=',DockMaster.IsCustomSite(AForm)]);
   try
     AForm.DisableAlign;

Andrey Zubarev

2019-01-04 20:21

reporter   ~0113169

IDE uses its own TIDEAnchorDockMaster.ShowForm function instead DockMaster.ShowControl. Need a person who understands how IDE work. Need a Michl look

In my opinion it works well

Michl

2019-01-17 23:54

developer   ~0113457

Fixed in trunk. Based on patch from erno. Thank you! Please test and close if ok.

errno

2019-01-18 13:55

reporter   ~0113461

Thank you.

Issue History

Date Modified Username Field Change
2018-12-28 21:50 errno New Issue
2018-12-28 22:11 errno Note Added: 0112964
2018-12-28 22:14 errno Note Edited: 0112964 View Revisions
2018-12-28 22:20 errno Note Edited: 0112964 View Revisions
2018-12-29 15:43 Andrey Zubarev Note Added: 0112983
2018-12-29 20:12 Michl Assigned To => Michl
2018-12-29 20:12 Michl Status new => assigned
2018-12-29 20:42 Michl Fixed in Revision => 59936
2018-12-29 20:42 Michl LazTarget => -
2018-12-29 20:42 Michl Note Added: 0112990
2018-12-29 20:42 Michl Status assigned => resolved
2018-12-29 20:42 Michl Fixed in Version => 2.1 (SVN)
2018-12-29 20:42 Michl Resolution open => fixed
2018-12-29 20:42 Michl Target Version => 2.2
2018-12-29 20:47 Michl Note Added: 0112991
2018-12-29 23:36 errno Note Added: 0112995
2018-12-29 23:36 errno Status resolved => assigned
2018-12-29 23:36 errno Resolution fixed => reopened
2018-12-29 23:36 errno File Added: anchordocking.patch
2018-12-29 23:44 errno Note Edited: 0112995 View Revisions
2018-12-29 23:45 errno Note Edited: 0112995 View Revisions
2018-12-30 00:49 errno Note Edited: 0112995 View Revisions
2018-12-30 13:59 Michl Note Added: 0113010
2018-12-30 21:09 errno File Added: bug34775.xml
2018-12-30 21:11 errno Note Added: 0113022
2018-12-30 21:12 errno Note Edited: 0113022 View Revisions
2018-12-30 21:18 errno Note Edited: 0113022 View Revisions
2018-12-30 21:19 errno Note Edited: 0113022 View Revisions
2018-12-31 00:42 Andrey Zubarev File Added: anchordocking.pas_after_59936.patch
2018-12-31 00:43 Andrey Zubarev Note Added: 0113028
2018-12-31 01:50 errno Note Added: 0113031
2018-12-31 01:52 errno Note Edited: 0113031 View Revisions
2018-12-31 02:03 errno Note Edited: 0113031 View Revisions
2018-12-31 02:05 errno Note Edited: 0113031 View Revisions
2018-12-31 18:42 errno Note Added: 0113048
2018-12-31 18:42 errno File Added: anchordocking.pas_after_59936_2.patch
2018-12-31 18:47 errno Note Edited: 0113048 View Revisions
2018-12-31 18:56 errno Note Edited: 0113031 View Revisions
2019-01-04 19:58 errno Note Edited: 0113048 View Revisions
2019-01-04 20:21 Andrey Zubarev Note Added: 0113169
2019-01-17 23:54 Michl Fixed in Revision 59936 => 59936, 60101
2019-01-17 23:54 Michl Note Added: 0113457
2019-01-17 23:54 Michl Status assigned => resolved
2019-01-17 23:54 Michl Resolution reopened => fixed
2019-01-18 13:55 errno Note Added: 0113461
2019-01-18 13:55 errno Status resolved => closed