mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-15 00:44:01 +02:00
IDE / Designer: fix access violation when switching designer / lfm source. Issue #18506
git-svn-id: trunk@33522 -
This commit is contained in:
parent
24044afdf5
commit
ab94abe6d8
@ -92,6 +92,8 @@ type
|
||||
FGridColor: TColor;
|
||||
FLookupRoot: TComponent;
|
||||
FMediator: TDesignerMediator;
|
||||
FFreeComponent: boolean;
|
||||
FProcessingDesignerEvent: Integer;
|
||||
FOnActivated: TNotifyEvent;
|
||||
FOnCloseQuery: TNotifyEvent;
|
||||
FOnShowObjectInspector: TNotifyEvent;
|
||||
@ -250,7 +252,8 @@ type
|
||||
|
||||
constructor Create(TheDesignerForm: TCustomForm;
|
||||
AControlSelection: TControlSelection);
|
||||
procedure FreeDesigner(FreeComponent: boolean);
|
||||
procedure PrepareFreeDesigner(AFreeComponent: boolean);
|
||||
procedure FinalizeFreeDesigner;
|
||||
destructor Destroy; override;
|
||||
|
||||
procedure Modified; override;
|
||||
@ -312,6 +315,7 @@ type
|
||||
property IsControl: Boolean read GetIsControl write SetIsControl;
|
||||
property LookupRoot: TComponent read FLookupRoot;
|
||||
property Mediator: TDesignerMediator read FMediator write SetMediator;
|
||||
property ProcessingDesignerEvent: Integer read FProcessingDesignerEvent;
|
||||
property OnActivated: TNotifyEvent read FOnActivated write FOnActivated;
|
||||
property OnCloseQuery: TNotifyEvent read FOnCloseQuery write FOnCloseQuery;
|
||||
property OnPersistentDeleted: TOnPersistentDeleted
|
||||
@ -618,7 +622,12 @@ begin
|
||||
FPopupMenuComponentEditor := nil;
|
||||
end;
|
||||
|
||||
procedure TDesigner.FreeDesigner(FreeComponent: boolean);
|
||||
procedure TDesigner.PrepareFreeDesigner(AFreeComponent: boolean);
|
||||
begin
|
||||
FFreeComponent:=AFreeComponent;
|
||||
end;
|
||||
|
||||
procedure TDesigner.FinalizeFreeDesigner;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
@ -634,7 +643,7 @@ begin
|
||||
end;
|
||||
if GlobalDesignHook.LookupRoot = FLookupRoot then
|
||||
GlobalDesignHook.LookupRoot := nil;
|
||||
if FreeComponent then
|
||||
if FFreeComponent then
|
||||
begin
|
||||
// tell hooks about deleting
|
||||
for i := FLookupRoot.ComponentCount - 1 downto 0 do
|
||||
@ -647,7 +656,7 @@ begin
|
||||
if Mediator<>nil then
|
||||
Mediator.Designer:=nil;
|
||||
// free or hide the form
|
||||
TheFormEditor.DeleteComponent(FLookupRoot,FreeComponent);
|
||||
TheFormEditor.DeleteComponent(FLookupRoot,FFreeComponent);
|
||||
FMediator:=nil;
|
||||
end;
|
||||
Free;
|
||||
@ -2199,7 +2208,7 @@ begin
|
||||
MouseDownComponent:=nil;
|
||||
MouseDownSender:=nil;
|
||||
{$IFDEF VerboseDesigner}
|
||||
DebugLn('[TDesigner.MouseLeftUpOnControl] END');
|
||||
DebugLn('[TDesigner.MouseUpOnControl] END');
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
@ -2612,6 +2621,7 @@ begin
|
||||
Result := false;
|
||||
if csDesigning in Sender.ComponentState then begin
|
||||
Result:=true;
|
||||
Inc(FProcessingDesignerEvent);
|
||||
case TheMessage.Msg of
|
||||
LM_PAINT: Result := PaintControl(Sender, TLMPaint(TheMessage));
|
||||
CN_KEYDOWN,CN_SYSKEYDOWN: KeyDown(Sender,TLMKey(TheMessage));
|
||||
@ -2631,6 +2641,7 @@ begin
|
||||
else
|
||||
Result:=false;
|
||||
end;
|
||||
Dec(FProcessingDesignerEvent);
|
||||
end else begin
|
||||
if (TheMessage.Msg=LM_PAINT)
|
||||
or (TheMessage.Msg=CN_KEYDOWN)
|
||||
|
29
ide/main.pp
29
ide/main.pp
@ -633,6 +633,7 @@ type
|
||||
out aBounds: TRect; out DockSibling: string; out DockAlign: TAlign);
|
||||
private
|
||||
FUserInputSinceLastIdle: boolean;
|
||||
FDesignerToBeFreed: TDesigner; // Will be freed in OnIdle.
|
||||
FDisplayState: TDisplayState;
|
||||
FLastFormActivated: TCustomForm;// used to find the last form so you can
|
||||
// display the correct tab
|
||||
@ -752,6 +753,8 @@ type
|
||||
var ComponentUnitInfo: TUnitInfo): TModalResult;
|
||||
|
||||
// methods for 'close unit'
|
||||
procedure FreeDesigner(AnUnitInfo: TUnitInfo; ADesigner: TDesigner;
|
||||
AFreeComponent: boolean);
|
||||
function CloseUnitComponent(AnUnitInfo: TUnitInfo; Flags: TCloseFlags
|
||||
): TModalResult;
|
||||
function CloseDependingUnitComponents(AnUnitInfo: TUnitInfo;
|
||||
@ -3747,7 +3750,9 @@ end;
|
||||
procedure TMainIDE.UpdateIDEComponentPalette;
|
||||
begin
|
||||
IDEComponentPalette.HideControls:=(FLastFormActivated<>nil)
|
||||
and (not (TDesigner(FLastFormActivated.Designer).LookupRoot is TControl));
|
||||
and (FLastFormActivated.Designer<>nil)
|
||||
and (TDesigner(FLastFormActivated.Designer).LookupRoot<>nil)
|
||||
and not ((FLastFormActivated.Designer as TDesigner).LookupRoot is TControl);
|
||||
IDEComponentPalette.UpdateVisible;
|
||||
TComponentPalette(IDEComponentPalette).OnClassSelected := @ComponentPaletteClassSelected;
|
||||
SetupHints;
|
||||
@ -6775,6 +6780,7 @@ begin
|
||||
AnUnitInfo.ComponentName:=NewComponent.Name;
|
||||
AnUnitInfo.ComponentResourceName:=AnUnitInfo.ComponentName;
|
||||
DesignerForm := nil;
|
||||
FLastFormActivated := nil;
|
||||
if not (ofLoadHiddenResource in OpenFlags) then
|
||||
begin
|
||||
DesignerForm := FormEditor1.GetDesignerForm(NewComponent);
|
||||
@ -7483,6 +7489,17 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TMainIDE.FreeDesigner(AnUnitInfo: TUnitInfo; ADesigner: TDesigner;
|
||||
AFreeComponent: boolean);
|
||||
begin
|
||||
AnUnitInfo.LoadedDesigner:=false;
|
||||
ADesigner.PrepareFreeDesigner(AFreeComponent);
|
||||
if ADesigner.ProcessingDesignerEvent > 0 then
|
||||
FDesignerToBeFreed:=ADesigner // Free it later on idle time.
|
||||
else
|
||||
ADesigner.FinalizeFreeDesigner; // Free it now.
|
||||
end;
|
||||
|
||||
{-------------------------------------------------------------------------------
|
||||
function TMainIDE.CloseUnitComponent
|
||||
|
||||
@ -7588,16 +7605,14 @@ begin
|
||||
{$IFDEF VerboseIDEMultiForm}
|
||||
DebugLn(['TMainIDE.CloseUnitComponent hiding component and freeing designer: ',AnUnitInfo.Filename,' ',DbgSName(AnUnitInfo.Component)]);
|
||||
{$ENDIF}
|
||||
AnUnitInfo.LoadedDesigner:=false;
|
||||
OldDesigner.FreeDesigner(false);
|
||||
FreeDesigner(AnUnitInfo, OldDesigner, false);
|
||||
end else begin
|
||||
// free designer and design form
|
||||
{$IFDEF VerboseIDEMultiForm}
|
||||
DebugLn(['TMainIDE.CloseUnitComponent freeing component and designer: ',AnUnitInfo.Filename,' ',DbgSName(AnUnitInfo.Component)]);
|
||||
{$ENDIF}
|
||||
try
|
||||
AnUnitInfo.LoadedDesigner:=false;
|
||||
OldDesigner.FreeDesigner(true);
|
||||
FreeDesigner(AnUnitInfo, OldDesigner, true);
|
||||
finally
|
||||
AnUnitInfo.Component:=nil;
|
||||
end;
|
||||
@ -17061,6 +17076,10 @@ begin
|
||||
ExternalTools.FreeStoppedProcesses;
|
||||
if (SplashForm<>nil) then FreeThenNil(SplashForm);
|
||||
|
||||
if Assigned(FDesignerToBeFreed) then begin
|
||||
FDesignerToBeFreed.FinalizeFreeDesigner;
|
||||
FDesignerToBeFreed:=Nil;
|
||||
end;
|
||||
if FUserInputSinceLastIdle then
|
||||
begin
|
||||
FUserInputSinceLastIdle:=false;
|
||||
|
Loading…
Reference in New Issue
Block a user