📄 designeditors.pas
字号:
{ TCustomModule
This class provides a default implementation of the ICustomModule interface.
There is no assumption by the designer that a custom module derives form
this class only that it derive from TBaseCustomModule and implement the
ICustomModule interface. This class is provided to help you implement a
class that meets those requirements. }
TCustomModule = class(TBaseCustomModule, ICustomModule)
private
FRoot: TComponent;
FDesigner: IDesigner;
FFinder: TClassFinder;
public
constructor Create(ARoot: TComponent; const ADesigner: IDesigner); override;
destructor Destroy; override;
procedure ExecuteVerb(Index: Integer); virtual;
function GetAttributes: TCustomModuleAttributes; virtual;
function GetVerb(Index: Integer): string; virtual;
function GetVerbCount: Integer; virtual;
procedure Saving; virtual;
procedure PrepareItem(Index: Integer; const AItem: IMenuItem); virtual;
procedure ValidateComponent(Component: TComponent); virtual;
function ValidateComponentClass(ComponentClass: TComponentClass): Boolean; virtual;
function Nestable: Boolean; virtual;
property Root: TComponent read FRoot;
property Designer: IDesigner read FDesigner;
end;
{ ClassInheritsFrom
Returns true if ClassType, or one of its ancestors, name matches
ClassName. This allows checking ancestor by name instead of by class
reference. }
function ClassInheritsFrom(ClassType: TClass; const ClassName: string): Boolean;
{ AncestorNameMatches
Returns true if either ClassType descends from AncestorClass or doesn't
contain an ancestor class by the same name as AncestorClass. This ensures that
if ClassType has an ancestor by the same name it is AncestorClass. }
function AncestorNameMatches(ClassType: TClass; AncestorClass: TClass): Boolean;
{ Find the top level component (form, module, etc) }
type
TGetTopLevelComponentFunc = function(Ignoring: TComponent = nil): TComponent;
var
GetTopLevelComponentFunc: TGetTopLevelComponentFunc;
resourcestring
sClassNotApplicable = 'Class %s is not applicable to this module';
sNotAvailable = '(Not available)';
function PossibleStream(const S: string): Boolean;
{ Routines used by the form designer for package management }
type
TGroupChangeProc = procedure(AGroup: Integer);
IDesignGroupChange = interface
['{8B5614E7-A726-4622-B2A7-F79340B1B78E}']
procedure FreeEditorGroup(Group: Integer);
end;
function NewEditorGroup: Integer;
procedure FreeEditorGroup(Group: Integer);
procedure NotifyGroupChange(AProc: TGroupChangeProc);
procedure UnnotifyGroupChange(AProc: TGroupChangeProc);
var
GReferenceExpandable: Boolean = True;
GShowReadOnlyProps: Boolean = True;
implementation
uses DesignConst, Consts, RTLConsts, Contnrs, Proxies;
function PossibleStream(const S: string): Boolean;
var
I: Integer;
begin
Result := True;
for I := 1 to Length(S) - 6 do
begin
if ((S[I] in ['O','o']) and (CompareText(Copy(S, I, 6), 'OBJECT') = 0)) or
((S[I] in ['I','i']) and (CompareText(Copy(S, I, 6), 'INLINE') = 0)) then
Exit;
if not (S[I] in [' ',#9, #13, #10]) then Break;
end;
Result := False;
end;
{ TPropertyEditor }
constructor TPropertyEditor.Create(const ADesigner: IDesigner;
APropCount: Integer);
begin
inherited Create(ADesigner, APropCount);
FDesigner := ADesigner;
GetMem(FPropList, APropCount * SizeOf(TInstProp));
FPropCount := APropCount;
end;
destructor TPropertyEditor.Destroy;
begin
if FPropList <> nil then
FreeMem(FPropList, FPropCount * SizeOf(TInstProp));
end;
procedure TPropertyEditor.Activate;
begin
end;
function TPropertyEditor.AllEqual: Boolean;
begin
Result := FPropCount = 1;
end;
procedure TPropertyEditor.Edit;
type
TGetStrFunc = function(const Value: string): Integer of object;
var
I: Integer;
Values: TStringList;
AddValue: TGetStrFunc;
begin
if not AutoFill then Exit;
Values := TStringList.Create;
Values.Sorted := paSortList in GetAttributes;
try
AddValue := Values.Add;
GetValues(TGetStrProc(AddValue));
if Values.Count > 0 then
begin
I := Values.IndexOf(Value) + 1;
if I = Values.Count then I := 0;
Value := Values[I];
end;
finally
Values.Free;
end;
end;
function TPropertyEditor.AutoFill: Boolean;
begin
Result := Assigned(GetPropInfo^.SetProc);
end;
function TPropertyEditor.GetAttributes: TPropertyAttributes;
begin
Result := [paMultiSelect, paRevertable];
end;
function TPropertyEditor.GetComponent(Index: Integer): TPersistent;
begin
Result := FPropList^[Index].Instance;
end;
function TPropertyEditor.GetFloatValue: Extended;
begin
Result := GetFloatValueAt(0);
end;
function TPropertyEditor.GetFloatValueAt(Index: Integer): Extended;
begin
with FPropList^[Index] do Result := GetFloatProp(Instance, PropInfo);
end;
function TPropertyEditor.GetMethodValue: TMethod;
begin
Result := GetMethodValueAt(0);
end;
function TPropertyEditor.GetMethodValueAt(Index: Integer): TMethod;
begin
with FPropList^[Index] do Result := GetMethodProp(Instance, PropInfo);
end;
function TPropertyEditor.GetEditLimit: Integer;
begin
Result := 2047;
end;
function TPropertyEditor.GetName: string;
begin
Result := FPropList^[0].PropInfo^.Name;
end;
function TPropertyEditor.GetOrdValue: Longint;
begin
Result := GetOrdValueAt(0);
end;
function TPropertyEditor.GetOrdValueAt(Index: Integer): Longint;
begin
with FPropList^[Index] do Result := GetOrdProp(Instance, PropInfo);
end;
function TPropertyEditor.GetPrivateDirectory: string;
begin
Result := '';
if Designer <> nil then
Result := Designer.GetPrivateDirectory;
end;
procedure TPropertyEditor.GetProperties(Proc: TGetPropProc);
begin
end;
function TPropertyEditor.GetPropInfo: PPropInfo;
begin
Result := FPropList^[0].PropInfo;
end;
function TPropertyEditor.GetPropType: PTypeInfo;
begin
Result := FPropList^[0].PropInfo^.PropType^;
end;
function TPropertyEditor.GetStrValue: string;
begin
Result := GetStrValueAt(0);
end;
function TPropertyEditor.GetStrValueAt(Index: Integer): string;
begin
with FPropList^[Index] do Result := GetStrProp(Instance, PropInfo);
end;
function TPropertyEditor.GetVarValue: Variant;
begin
Result := GetVarValueAt(0);
end;
function TPropertyEditor.GetVarValueAt(Index: Integer): Variant;
begin
with FPropList^[Index] do Result := GetVariantProp(Instance, PropInfo);
end;
function TPropertyEditor.GetValue: string;
begin
Result := srUnknown;
end;
function TPropertyEditor.GetVisualValue: string;
begin
if AllEqual then
Result := GetValue
else
Result := '';
end;
procedure TPropertyEditor.GetValues(Proc: TGetStrProc);
begin
end;
procedure TPropertyEditor.Initialize;
begin
end;
procedure TPropertyEditor.Modified;
begin
if Designer <> nil then
Designer.Modified;
end;
procedure TPropertyEditor.SetFloatValue(Value: Extended);
var
I: Integer;
begin
for I := 0 to FPropCount - 1 do
with FPropList^[I] do SetFloatProp(Instance, PropInfo, Value);
Modified;
end;
procedure TPropertyEditor.SetMethodValue(const Value: TMethod);
var
I: Integer;
begin
for I := 0 to FPropCount - 1 do
with FPropList^[I] do SetMethodProp(Instance, PropInfo, Value);
Modified;
end;
procedure TPropertyEditor.SetOrdValue(Value: Longint);
var
I: Integer;
begin
for I := 0 to FPropCount - 1 do
with FPropList^[I] do SetOrdProp(Instance, PropInfo, Value);
Modified;
end;
procedure TPropertyEditor.SetPropEntry(Index: Integer;
AInstance: TPersistent; APropInfo: PPropInfo);
begin
with FPropList^[Index] do
begin
Instance := AInstance;
PropInfo := APropInfo;
end;
end;
procedure TPropertyEditor.SetStrValue(const Value: string);
var
I: Integer;
begin
for I := 0 to FPropCount - 1 do
with FPropList^[I] do SetStrProp(Instance, PropInfo, Value);
Modified;
end;
procedure TPropertyEditor.SetVarValue(const Value: Variant);
var
I: Integer;
begin
for I := 0 to FPropCount - 1 do
with FPropList^[I] do SetVariantProp(Instance, PropInfo, Value);
Modified;
end;
procedure TPropertyEditor.Revert;
var
I: Integer;
begin
if Designer <> nil then
for I := 0 to FPropCount - 1 do
with FPropList^[I] do Designer.Revert(Instance, PropInfo);
end;
procedure TPropertyEditor.SetValue(const Value: string);
begin
end;
function TPropertyEditor.ValueAvailable: Boolean;
var
I: Integer;
S: string;
begin
Result := True;
for I := 0 to FPropCount - 1 do
begin
if (FPropList^[I].Instance is TComponent) and
(csCheckPropAvail in TComponent(FPropList^[I].Instance).ComponentStyle) then
begin
try
S := GetValue;
AllEqual;
except
Result := False;
end;
Exit;
end;
end;
end;
function TPropertyEditor.GetInt64Value: Int64;
begin
Result := GetInt64ValueAt(0);
end;
function TPropertyEditor.GetInt64ValueAt(Index: Integer): Int64;
begin
with FPropList^[Index] do Result := GetInt64Prop(Instance, PropInfo);
end;
procedure TPropertyEditor.SetInt64Value(Value: Int64);
var
I: Integer;
begin
for I := 0 to FPropCount - 1 do
with FPropList^[I] do SetInt64Prop(Instance, PropInfo, Value);
Modified;
end;
function TPropertyEditor.GetIntfValue: IInterface;
begin
Result := GetIntfValueAt(0);
end;
function TPropertyEditor.GetIntfValueAt(Index: Integer): IInterface;
begin
with FPropList^[Index] do Result := GetInterfaceProp(Instance, PropInfo);
end;
procedure TPropertyEditor.SetIntfValue(const Value: IInterface);
var
I: Integer;
begin
for I := 0 to FPropCount - 1 do
with FPropList^[I] do SetInterfaceProp(Instance, PropInfo, Value);
Modified;
end;
function TPropertyEditor.GetEditValue(out Value: string): Boolean;
begin
Result := False;
try
Value := GetValue;
Result := Assigned(GetPropInfo^.SetProc);
except
on E: EPropWriteOnly do Value := sNotAvailable;
on E: Exception do Value := Format('(%s)', [E.Message]);
end;
end;
function TPropertyEditor.HasInstance(Instance: TPersistent): Boolean;
var
I: Integer;
begin
Result := True;
for I := 0 to FPropCount - 1 do
if FPropList^[I].Instance = Instance then Exit;
Result := False;
end;
type
TComponentHack = class(TComponent);
procedure TPropertyEditor.WriteComponentSimulation(Component: TComponent);
function FindAncestor(const Name: string): TComponent;
var
I: Integer;
begin
for I := 0 to FAncestorList.Count - 1 do
begin
Result := FAncestorList[I];
if SameText(Result.Name, Name) then Exit;
end;
Result := nil;
end;
var
OldAncestor: TPersistent;
OldRoot, OldRootAncestor: TComponent;
OldAncestorList: TList;
TempAncestor: TPersistent;
begin
if FDoneLooking then
Exit;
OldAncestor := FAncestor;
OldRootAncestor := FRootAncestor;
try
if Assigned(FAncestorList) then
FAncestor := FindAncestor(Component.Name);
// If we are at the component we were looking for, then we
// can stop at this point
if FLookingFor = Component then
begin
FDoneLooking := True
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -