{ /*************************************************************************** CustomFormEditor.pp ------------------- ***************************************************************************/ *************************************************************************** * * * This source is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This code is distributed in the hope that it will be useful, but * * WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * * General Public License for more details. * * * * A copy of the GNU General Public License is available on the World * * Wide Web at . You can also * * obtain it by writing to the Free Software Foundation, * * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * * *************************************************************************** } unit CustomFormEditor; {$mode objfpc}{$H+} {$I ide.inc} interface { $DEFINE VerboseFormEditor} uses {$IFDEF IDE_MEM_CHECK} MemCheck, {$ENDIF} Classes, AbstractFormeditor, Controls, PropEdits, TypInfo, ObjectInspector, Forms, IDEComp, JITForms, Compreg, ComponentEditors, KeyMapping, EditorOptions, Dialogs; Const OrdinalTypes = [tkInteger,tkChar,tkENumeration,tkbool]; type { TComponentInterface is derived from TIComponentInterface. It gives access to each control that's dropped onto the form } TCustomFormEditor = class; //forward declaration TComponentInterface = class(TIComponentInterface) private FComponent : TComponent; FComponentEditor: TBaseComponentEditor; FDesigner: TComponentEditorDesigner; FFormEditor : TCustomFormEditor; //used to call it's functions Function FSetProp(PRI : PPropInfo; const Value) : Boolean; Function FGetProp(PRI : PPropInfo; var Value) : Boolean; function GetDesigner: TComponentEditorDesigner; protected Function GetPPropInfobyIndex(Index : Integer) : PPropInfo; Function GetPPropInfobyName(Name : ShortString) : PPropInfo; public constructor Create; constructor Create(AComponent: TComponent); destructor Destroy; override; Function GetComponentType : ShortString; override; Function GetComponentHandle : LongInt; override; Function GetParent : TIComponentInterface; override; Function IsTControl : Boolean; override; Function GetPropCount : Integer; override; Function GetPropType(Index : Integer) : TTypeKind; override; Function GetPropTypeInfo(Index : Integer) : PTypeInfo; Function GetPropName(Index : Integer) : ShortString; override; Function GetPropTypeName(Index : Integer) : ShortString; override; Function GetPropTypebyName(Name : ShortString) : TTypeKind; override; Function GetPropValue(Index : Integer; var Value) : Boolean; override; Function GetPropValuebyName(Name: ShortString; var Value) : Boolean; override; Function SetProp(Index : Integer; const Value) : Boolean; override; Function SetPropbyName(Name : ShortString; const Value) : Boolean; override; Function GetControlCount: Integer; override; Function GetControl(Index : Integer): TIComponentInterface; override; Function GetComponentCount: Integer; override; Function GetComponent(Index : Integer): TIComponentInterface; override; Function Select : Boolean; override; Function Focus : Boolean; override; Function Delete : Boolean; override; function GetComponentEditor: TBaseComponentEditor; property Designer: TComponentEditorDesigner read GetDesigner write FDesigner; property Component : TComponent read FComponent; end; { TCustomFormEditor } TControlClass = class of TControl; TCustomFormEditor = class(TAbstractFormEditor) private FModified : Boolean; FComponentInterfaceList: TList; //used to track and find controls FSelectedComponents: TComponentSelectionList; FObj_Inspector: TObjectInspector; function GetPropertyEditorHook: TPropertyEditorHook; protected Procedure RemoveFromComponentInterfaceList(Value :TIComponentInterface); procedure SetSelectedComponents(TheSelectedComponents : TComponentSelectionList); procedure OnObjectInspectorModified(Sender: TObject); procedure SetObj_Inspector(AnObjectInspector: TObjectInspector); virtual; procedure JITFormListReaderError(Sender: TObject; ErrorType: TJITFormError; var Action: TModalResult); virtual; Function GetComponentByHandle(const Value : Longint): TIComponentInterface; override; Function GetSelCount : Integer; override; Function GetSelComponent(Index : Integer) : TIComponentInterface; override; public JITFormList : TJITForms; constructor Create; destructor Destroy; override; Function AddSelected(Value : TComponent) : Integer; Procedure DeleteControl(Value : TComponent; FreeComponent: boolean); Function FormModified : Boolean; override; Function FindComponentByName(const Name : ShortString) : TIComponentInterface; override; Function FindComponent(AComponent: TComponent): TIComponentInterface; override; function GetComponentEditor(AComponent: TComponent): TBaseComponentEditor; Function GetFormComponent: TIComponentInterface; override; function CreateUniqueComponentName(AComponent: TComponent): string; function CreateUniqueComponentName(const AClassName: string; OwnerComponent: TComponent): string; // Function CreateComponent(CI : TIComponentInterface; TypeName : String; Function CreateComponentInterface(AComponent: TComponent): TIComponentInterface; Function CreateComponent(ParentCI : TIComponentInterface; TypeClass : TComponentClass; X,Y,W,H : Integer): TIComponentInterface; override; Function CreateFormFromStream(BinStream: TStream): TIComponentInterface; override; Procedure SetFormNameAndClass(CI: TIComponentInterface; const NewFormName, NewClassName: shortstring); Procedure ClearSelected; function TranslateKeyToDesignerCommand(Key: word; Shift: TShiftState): integer; public property SelectedComponents: TComponentSelectionList read FSelectedComponents write SetSelectedComponents; property Obj_Inspector : TObjectInspector read FObj_Inspector write SetObj_Inspector; property PropertyEditorHook: TPropertyEditorHook read GetPropertyEditorHook; end; implementation uses SysUtils; {TComponentInterface} constructor TComponentInterface.Create; begin inherited Create; end; constructor TComponentInterface.Create(AComponent: TComponent); begin inherited Create; FComponent:=AComponent; end; destructor TComponentInterface.Destroy; begin FreeAndNil(FComponentEditor); inherited Destroy; end; Function TComponentInterface.FSetProp(PRI : PPropInfo; const Value) : Boolean; Begin //writeln('Index = '+inttostr(PRI^.index)); case PRI^.PropType^.Kind of tkBool: Begin //Writeln('Boolean....'); SetOrdProp(FComponent,PRI,longint(Value)); Result := True; end; tkSString, tkLString, tkAString, tkWString : Begin //Writeln('String...'); SetStrProp(FComponent,PRI,ShortString(Value)); Result := True; end; tkInteger, tkInt64 : Begin //Writeln('Int64...'); SetInt64Prop(FComponent,PRI,Int64(Value)); Result := True; end; tkFloat : Begin //Writeln('Float...'); SetFloatProp(FComponent,PRI,Extended(Value)); Result := True; end; tkVariant : Begin //Writeln('Variant...'); SetVariantProp(FComponent,PRI,Variant(Value)); Result := True; end; tkMethod : Begin //Writeln('Method...'); SetMethodProp(FComponent,PRI,TMethod(value)); Result := True; end; else Result := False; end;//case end; Function TComponentInterface.FGetProp(PRI : PPropInfo; var Value) : Boolean; Begin Result := True; case PRI^.PropType^.Kind of tkBool : Longint(Value) := GetOrdProp(FComponent,PRI); tkSString, tkLString, tkAString, tkWString : Begin //Writeln('Get String...'); ShortString(Value) := GetStrProp(FComponent,PRI); Writeln('The string returned is '+String(value)); Writeln('*Get String...'); end; tkInteger, tkInt64 : Begin //Writeln('Get Int64...'); Int64(Value) := GetInt64Prop(FComponent,PRI); end; tkFloat : Begin //Writeln('Get Float...'); Extended(Value) := GetFloatProp(FComponent,PRI); end; tkVariant : Begin //Writeln('Get Variant...'); Variant(Value) := GetVariantProp(FComponent,PRI); end; tkMethod : Begin //Writeln('Get Method...'); TMethod(Value) := GetMethodProp(FComponent,PRI); end; else Result := False; end;//case end; function TComponentInterface.GetDesigner: TComponentEditorDesigner; var OwnerForm: TCustomForm; begin if FDesigner=nil then begin if (Component is TCustomForm) and (TCustomForm(Component).Parent=nil) then OwnerForm:=TCustomForm(Component) else begin OwnerForm:=TCustomForm(Component.Owner); if OwnerForm=nil then begin raise Exception.Create('TComponentInterface.GetDesigner: ' +Component.Name+' Owner=nil'); end; if not (OwnerForm is TCustomForm) then begin raise Exception.Create('TComponentInterface.GetDesigner: ' +Component.Name+' OwnerForm='+OwnerForm.ClassName); end; end; FDesigner:=TComponentEditorDesigner(OwnerForm.Designer); if FDesigner=nil then begin raise Exception.Create('TComponentInterface.GetDesigner: ' +Component.Name+' Designer=nil'); end; if not (FDesigner is TComponentEditorDesigner) then begin raise Exception.Create('TComponentInterface.GetDesigner: ' +Component.Name+' Designer='+ +FDesigner.ClassName); end; end; Result:=FDesigner; end; Function TComponentInterface.GetPPropInfoByIndex(Index:Integer): PPropInfo; var PT : PTypeData; PP : PPropList; PI : PTypeInfo; Begin PI := FComponent.ClassInfo; PT:=GetTypeData(PI); GetMem (PP,PT^.PropCount*SizeOf(Pointer)); GetPropInfos(PI,PP); if Index < PT^.PropCount then Result:=PP^[index] else Result := nil; Freemem(PP); end; Function TComponentInterface.GetPPropInfoByName(Name:ShortString): PPropInfo; var PT : PTypeData; PP : PPropList; PI : PTypeInfo; I : Longint; Begin Name := Uppercase(name); PI := FComponent.ClassInfo; PT:=GetTypeData(PI); GetMem (PP,PT^.PropCount*SizeOf(Pointer)); GetPropInfos(PI,PP); I := -1; repeat inc(i); until (PP^[i]^.Name = Name) or (i = PT^.PropCount-1); if PP^[i]^.Name = Name then Result:=PP^[i] else Result := nil; Freemem(PP); end; Function TComponentInterface.GetComponentType : ShortString; Begin Result:=FComponent.ClassName; end; Function TComponentInterface.GetComponentHandle : LongInt; Begin //return the TWinControl handle? if (Component is TWinControl) then Result := TWinControl(Component).Handle; end; Function TComponentInterface.GetParent : TIComponentInterface; Begin result := nil; if (FComponent is TControl) then if TControl(FComponent).Parent <> nil then begin Result := FFormEditor.FindComponent(TControl(FComponent).Parent); end; end; Function TComponentInterface.IsTControl : Boolean; Begin Result := (FComponent is TControl); end; Function TComponentInterface.GetPropCount : Integer; var PT : PTypeData; Begin PT:=GetTypeData(FComponent.ClassInfo); Result := PT^.PropCount; end; Function TComponentInterface.GetPropType(Index : Integer) : TTypeKind; var PT : PTypeData; PP : PPropList; PI : PTypeInfo; Begin PI:=FComponent.ClassInfo; PT:=GetTypeData(PI); GetMem (PP,PT^.PropCount*SizeOf(Pointer)); GetPropInfos(PI,PP); if Index < PT^.PropCount then Result := PP^[Index]^.PropType^.Kind else Result := tkUnknown; freemem(PP); end; Function TComponentInterface.GetPropTypeInfo(Index : Integer) : PTypeInfo; var PT : PTypeData; PP : PPropList; PI : PTypeInfo; Begin PI:=FComponent.ClassInfo; PT:=GetTypeData(PI); GetMem (PP,PT^.PropCount*SizeOf(Pointer)); GetPropInfos(PI,PP); if Index < PT^.PropCount then Result := PP^[Index]^.PropType else Result := nil; freemem(PP); end; {This returns "Integer" or "Boolean"} Function TComponentInterface.GetPropTypeName(Index : Integer) : ShortString; var PT : PTypeData; PP : PPropList; PI : PTypeInfo; Begin PI:=FComponent.ClassInfo; PT:=GetTypeData(PI); GetMem (PP,PT^.PropCount*SizeOf(Pointer)); GetPropInfos(PI,PP); if Index < PT^.PropCount then Result := PP^[Index]^.PropType^.Name else Result := ''; freemem(PP); end; {This returns "Left" "Align" "Visible"} Function TComponentInterface.GetPropName(Index : Integer) : ShortString; var PT : PTypeData; PP : PPropList; PI : PTypeInfo; Begin PI:=FComponent.ClassInfo; PT:=GetTypeData(PI); GetMem (PP,PT^.PropCount*SizeOf(Pointer)); GetPropInfos(PI,PP); if Index < PT^.PropCount then // Result := PP^[Index]^.PropType^.Name Result := PP^[Index]^.Name else Result := ''; freemem(PP); end; Function TComponentInterface.GetPropTypebyName(Name : ShortString) : TTypeKind; var PT : PTypeData; PP : PPropList; PI : PTypeInfo; I : Longint; Begin PI:=FComponent.ClassInfo; PT:=GetTypeData(PI); GetMem (PP,PT^.PropCount*SizeOf(Pointer)); GetPropInfos(PI,PP); Result := tkUnknown; For I:=0 to PT^.PropCount-1 do If PP^[i]<>Nil then begin if PP^[i]^.Name = Name then begin Result := PP^[i]^.PropType^.Kind; Break; end; end; freemem(PP); end; Function TComponentInterface.GetPropValue(Index : Integer; var Value) : Boolean; var PP : PPropInfo; Begin PP := GetPPropInfoByIndex(Index); Result := FGetProp(PP,Value); end; Function TComponentInterface.GetPropValuebyName(Name: ShortString; var Value) : Boolean; var PRI : PPropInfo; Begin Result := False; PRI := GetPPropInfoByName(Name); if PRI <> nil then Result := FGetProp(PRI,Value); end; Function TComponentInterface.SetProp(Index : Integer; const Value) : Boolean; var PRI : PPropInfo; Begin Result := False; PRI := GetPPropInfoByIndex(Index); if PRI <> nil then Begin Result := FSetProp(PRI,Value); end; end; Function TComponentInterface.SetPropbyName(Name : ShortString; const Value) : Boolean; var PRI : PPropInfo; Begin //Writeln('SetPropByName Name='''+Name+''''); Result := False; PRI := GetPropInfo(FComponent.ClassInfo,Name); if PRI <> nil then Begin Result :=FSetProp(PRI,Value); end; end; Function TComponentInterface.GetControlCount: Integer; Begin // XXX Todo: Result := -1; end; Function TComponentInterface.GetControl(Index : Integer): TIComponentInterface; Begin // XXX Todo: Result := nil; end; Function TComponentInterface.GetComponentCount: Integer; Begin // XXX Todo: Result := -1; end; Function TComponentInterface.GetComponent(Index : Integer): TIComponentInterface; Begin // XXX Todo: Result := nil; end; Function TComponentInterface.Select : Boolean; Begin // XXX Todo: Result := False; end; Function TComponentInterface.Focus : Boolean; Begin Result := False; if (FComponent is TWinControl) and (TWinControl(FComponent).CanFocus) then Begin TWinControl(FComponent).SetFocus; Result := True; end; end; Function TComponentInterface.Delete: Boolean; var OldName, OldClassName: string; Begin {$IFDEF VerboseFormEditor} writeln('TComponentInterface.Delete A ',Component.Name,':',Component.ClassName); {$ENDIF} {$IFNDEF NoCompCatch} try {$ENDIF} OldName:=Component.Name; OldClassName:=Component.ClassName; Component.Free; {$IFNDEF NoCompCatch} except on E: Exception do begin writeln('TComponentInterface.Delete ERROR:', ' "'+OldName+':'+OldClassName+'" ',E.Message); MessageDlg('Error', 'An exception occured during deletion of'#13 +'"'+OldName+':'+OldClassName+'"'#13 +E.Message, mtError,[mbOk],0); end; end; {$ENDIF} FComponent:=nil; {$IFDEF VerboseFormEditor} writeln('TComponentInterface.Delete B '); {$ENDIF} Free; Result := True; end; function TComponentInterface.GetComponentEditor: TBaseComponentEditor; begin if FComponentEditor=nil then begin FComponentEditor:=ComponentEditors.GetComponentEditor(Component,Designer); end; Result:=FComponentEditor; end; { TCustomFormEditor } constructor TCustomFormEditor.Create; begin inherited Create; FComponentInterfaceList := TList.Create; FSelectedComponents := TComponentSelectionList.Create; JITFormList := TJITForms.Create; JITFormList.RegCompList := RegCompList; JITFormList.OnReaderError:=@JITFormListReaderError; end; destructor TCustomFormEditor.Destroy; begin JITFormList.Free; FComponentInterfaceList.Free; FSelectedComponents.Free; inherited; end; procedure TCustomFormEditor.SetSelectedComponents( TheSelectedComponents : TComponentSelectionList); begin FSelectedComponents.Assign(TheSelectedComponents); if FSelectedComponents.Count>0 then begin if FSelectedComponents[0].Owner<>nil then begin Obj_Inspector.PropertyEditorHook.LookupRoot:=FSelectedComponents[0].Owner; end else begin Obj_Inspector.PropertyEditorHook.LookupRoot:=FSelectedComponents[0]; end; end; Obj_Inspector.Selections := FSelectedComponents; end; Function TCustomFormEditor.AddSelected(Value : TComponent) : Integer; Begin FSelectedComponents.Add(Value); Result := FSelectedComponents.Count; Obj_Inspector.Selections := FSelectedComponents; end; Procedure TCustomFormEditor.DeleteControl(Value : TComponent; FreeComponent: boolean); var Temp : TComponentInterface; i: integer; AForm: TCustomForm; Begin Temp := TComponentInterface(FindComponent(Value)); if Temp <> nil then begin RemoveFromComponentInterfaceList(Temp); if (Value is TCustomForm) then begin if FreeComponent then begin AForm:=TCustomForm(Value); i:=AForm.ComponentCount-1; while i>=0 do begin DeleteControl(AForm.Components[i],true); dec(i); if i>AForm.ComponentCount-1 then i:=AForm.ComponentCount-1; end; if PropertyEditorHook.LookupRoot=AForm then PropertyEditorHook.LookupRoot:=nil; if not (AForm is TForm) then writeln('WARNING: TCustomFormEditor.DeleteControl ',AForm.ClassName); JITFormList.DestroyJITForm(TForm(AForm)); end; Temp.Free; end else begin if FreeComponent then Temp.Delete else Temp.Free; end; end; end; Function TCustomFormEditor.FormModified : Boolean; Begin Result := FModified; end; Function TCustomFormEditor.FindComponentByName( const Name : ShortString) : TIComponentInterface; Var Num : Integer; Begin Num := 0; While Num < FComponentInterfaceList.Count do Begin Result := TIComponentInterface(FComponentInterfaceList.Items[Num]); if AnsiCompareText(TComponentInterface(Result).Component.Name,Name)=0 then exit; inc(num); end; Result:=nil; end; Function TCustomFormEditor.FindComponent(AComponent:TComponent): TIComponentInterface; Var Num : Integer; Begin Num := 0; While Num < FComponentInterfaceList.Count do Begin Result := TIComponentInterface(FComponentInterfaceList.Items[Num]); if TComponentInterface(Result).Component = AComponent then exit; inc(num); end; Result:=nil; end; function TCustomFormEditor.GetComponentEditor(AComponent: TComponent ): TBaseComponentEditor; var ACompIntf: TComponentInterface; begin Result:=nil; if AComponent=nil then exit; ACompIntf:=TComponentInterface(FindComponent(AComponent)); if ACompIntf=nil then exit; Result:=ACompIntf.GetComponentEditor; end; Function TCustomFormEditor.CreateComponent(ParentCI : TIComponentInterface; TypeClass : TComponentClass; X,Y,W,H : Integer): TIComponentInterface; Var Temp: TComponentInterface; NewFormIndex: Integer; CompLeft, CompTop, CompWidth, CompHeight: integer; OwnerComponent: TComponent; ParentComponent: TComponent; Begin writeln('[TCustomFormEditor.CreateComponent] Class='''+TypeClass.ClassName+''''); {$IFDEF IDE_MEM_CHECK}CheckHeapWrtMemCnt('TCustomFormEditor.CreateComponent A');{$ENDIF} Temp := TComponentInterface.Create; OwnerComponent:=nil; if Assigned(ParentCI) and ParentCI.IsTControl then begin // add as child control ParentComponent:=TComponentInterface(ParentCI).Component; OwnerComponent:=GetParentForm(TControl(ParentComponent)); if OwnerComponent=nil then OwnerComponent:=ParentComponent; Temp.FComponent := TypeClass.Create(OwnerComponent); // set parent if Temp.IsTControl then begin if (ParentComponent is TWinControl) and (csAcceptsControls in TWinControl(ParentComponent).ControlStyle) then begin TWinControl(Temp.Component).Parent := TWinControl(ParentComponent); writeln('Parent is '''+TWinControl(Temp.Component).Parent.Name+''''); end else begin TControl(Temp.Component).Parent := TControl(ParentComponent).Parent; writeln('Parent is '''+TControl(Temp.Component).Parent.Name+''''); end; end; end else begin // create a toplevel control -> a form ParentComponent:=nil; NewFormIndex := JITFormList.AddNewJITForm; if NewFormIndex >= 0 then Temp.FComponent := JITFormList[NewFormIndex] else begin Result:=nil; exit; end; end; {$IFDEF IDE_MEM_CHECK}CheckHeapWrtMemCnt('TCustomFormEditor.CreateComponent D ');{$ENDIF} Temp.Component.Name := CreateUniqueComponentName(Temp.Component); // set bounds if (Temp.Component is TControl) then Begin CompLeft:=X; CompTop:=Y; CompWidth:=W; CompHeight:=H; if CompWidth<=0 then CompWidth:=TControl(Temp.Component).Width; if CompHeight<=0 then CompHeight:=TControl(Temp.Component).Height; if CompLeft<0 then CompLeft:=(TControl(Temp.Component).Parent.Width + CompWidth) div 2; if CompTop<0 then CompTop:=(TControl(Temp.Component).Parent.Height+ CompHeight) div 2; TControl(Temp.Component).SetBounds(CompLeft,CompTop,CompWidth,CompHeight); end else begin with LongRec(Temp.Component.DesignInfo) do begin Lo:=X; Hi:=Y; end; end; {$IFDEF IDE_MEM_CHECK}CheckHeapWrtMemCnt('TCustomFormEditor.CreateComponent F ');{$ENDIF} // add to component list FComponentInterfaceList.Add(Temp); Result := Temp; end; Function TCustomFormEditor.CreateFormFromStream( BinStream: TStream): TIComponentInterface; var NewFormIndex: integer; i: integer; NewForm: TCustomForm; begin // create JITForm NewFormIndex := JITFormList.AddJITFormFromStream(BinStream); if NewFormIndex < 0 then begin Result:=nil; exit; end; NewForm:=JITFormList[NewFormIndex]; // create a component interface for the form Result:=CreateComponentInterface(NewForm); // create component interfaces for the form components for i:=0 to NewForm.ComponentCount-1 do CreateComponentInterface(NewForm.Components[i]); end; Procedure TCustomFormEditor.SetFormNameAndClass(CI: TIComponentInterface; const NewFormName, NewClassName: shortstring); var AComponent: TComponent; begin AComponent:=TComponentInterface(CI).Component; if (AComponent<>nil) and (AComponent is TForm) then begin JITFormList.RenameFormClass(TForm(AComponent),NewClassName); TForm(AComponent).Name:=NewFormName; end; end; procedure TCustomFormEditor.JITFormListReaderError(Sender: TObject; ErrorType: TJITFormError; var Action: TModalResult); var aCaption, aMsg: string; DlgType: TMsgDlgType; Buttons: TMsgDlgButtons; HelpCtx: Longint; begin aCaption:='Error reading form'; aMsg:=''; DlgType:=mtError; Buttons:=[mbCancel]; HelpCtx:=0; with JITFormList do begin aMsg:=aMsg+'Form: '; if CurReadForm<>nil then aMsg:=aMsg+CurReadForm.Name+':'+CurReadForm.ClassName else aMsg:=aMsg+'?'; if CurReadComponent<>nil then aMsg:=aMsg+#13'Component: ' +CurReadComponent.Name+':'+CurReadComponent.ClassName else if CurReadComponentClass<>nil then aMsg:=aMsg+#13'Component Class: '+CurReadComponentClass.ClassName; end; aMsg:=aMsg+#13+JITFormList.CurReadErrorMsg; case ErrorType of jfeUnknownProperty, jfeReaderError: begin Buttons:=[mbIgnore,mbCancel]; end; end; Action:=MessageDlg(aCaption,aMsg,DlgType,Buttons,HelpCtx); end; function TCustomFormEditor.GetComponentByHandle(const Value: Longint ): TIComponentInterface; begin // ToDo: Result:=nil; end; function TCustomFormEditor.GetSelCount: Integer; begin Result:=FComponentInterfaceList.Count; end; function TCustomFormEditor.GetSelComponent(Index: Integer ): TIComponentInterface; begin Result:=TIComponentInterface(FComponentInterfaceList[Index]); end; function TCustomFormEditor.GetPropertyEditorHook: TPropertyEditorHook; begin Result:=Obj_Inspector.PropertyEditorHook; end; Procedure TCustomFormEditor.RemoveFromComponentInterfaceList( Value :TIComponentInterface); Begin FComponentInterfaceList.Remove(Value); end; Function TCustomFormEditor.GetFormComponent : TIComponentInterface; Begin //this can only be used IF you have one FormEditor per form. I currently don't Result := nil; end; function TCustomFormEditor.CreateUniqueComponentName(AComponent: TComponent ): string; begin Result:=''; if (AComponent=nil) then exit; Result:=AComponent.Name; if (AComponent.Owner=nil) or (Result<>'') then exit; Result:=CreateUniqueComponentName(AComponent.ClassName,AComponent.Owner); end; function TCustomFormEditor.CreateUniqueComponentName(const AClassName: string; OwnerComponent: TComponent): string; var i, j: integer; begin Result:=AClassName; if (OwnerComponent=nil) or (Result='') then exit; i:=1; while true do begin j:=OwnerComponent.ComponentCount-1; Result:=AClassName; if (length(Result)>1) and (Result[1]='T') then Result:=RightStr(Result,length(Result)-1); {$IfNDef VER1_1} //make it more presentable Result := Result[1] + lowercase(Copy(Result,2,length(Result))); {$EndIf} Result:=Result+IntToStr(i); while (j>=0) and (AnsiCompareText(Result,OwnerComponent.Components[j].Name)<>0) do dec(j); if j<0 then exit; inc(i); end; end; Procedure TCustomFormEditor.ClearSelected; Begin FSelectedComponents.Clear; end; function TCustomFormEditor.TranslateKeyToDesignerCommand(Key: word; Shift: TShiftState): integer; begin Result:=EditorOpts.KeyMap.TranslateKey(Key,Shift,[caDesigner]); end; Function TCustomFormEditor.CreateComponentInterface( AComponent: TComponent): TIComponentInterface; Begin Result := TComponentInterface.Create(AComponent); FComponentInterfaceList.Add(Result); end; procedure TCustomFormEditor.OnObjectInspectorModified(Sender: TObject); var CustomForm: TCustomForm; begin if (FSelectedComponents<>nil) and (FSelectedComponents.Count>0) then begin if FSelectedComponents[0] is TCustomForm then CustomForm:=TCustomForm(FSelectedComponents[0]) else if (FSelectedComponents[0].Owner<>nil) and (FSelectedComponents[0].Owner is TCustomForm) then CustomForm:=TCustomForm(FSelectedComponents[0].Owner) else CustomForm:=nil; if (CustomForm<>nil) and (CustomForm.Designer<>nil) then CustomForm.Designer.Modified; end; end; procedure TCustomFormEditor.SetObj_Inspector( AnObjectInspector: TObjectInspector); begin if AnObjectInspector=FObj_Inspector then exit; if FObj_Inspector<>nil then begin FObj_Inspector.OnModified:=nil; end; FObj_Inspector:=AnObjectInspector; if FObj_Inspector<>nil then begin FObj_Inspector.OnModified:=@OnObjectInspectorModified; end; end; end.