home *** CD-ROM | disk | FTP | other *** search
/ Australian Personal Computer 2000 October / tst.iso / programs / borland / RUNIMAGE / DELPHI40 / DOC / DSGNINTF.INT < prev    next >
Encoding:
Text File  |  1998-06-17  |  38.6 KB  |  940 lines

  1.  
  2. {*******************************************************}
  3. {                                                       }
  4. {       Borland Delphi Visual Component Library         }
  5. {                                                       }
  6. {       Copyright (c) 1995,98 Inprise Corporation       }
  7. {                                                       }
  8. {*******************************************************}
  9.  
  10. unit DsgnIntf;
  11.  
  12. interface
  13.  
  14. {$N+,S-,R-}
  15.  
  16. uses Windows, SysUtils, Classes, Graphics, Controls, Forms, TypInfo;
  17.  
  18. type
  19.  
  20.   IEventInfos = interface
  21.     ['{11667FF0-7590-11D1-9FBC-0020AF3D82DA}']
  22.     function GetCount: Integer;
  23.     function GetEventValue(Index: Integer): string;
  24.     function GetEventName(Index: Integer): string;
  25.     procedure ClearEvent(Index: Integer);
  26.     property Count: Integer;
  27.   end;
  28.  
  29.   IPersistent = interface
  30.     ['{82330133-65D1-11D1-9FBB-0020AF3D82DA}'] {Java}
  31.     procedure DestroyObject;
  32.     function Equals(const Other: IPersistent): Boolean;
  33.     function GetClassname: string;
  34.     function GetEventInfos: IEventInfos;
  35.     function GetNamePath: string;
  36.     function GetOwner: IPersistent;
  37.     function InheritsFrom(const Classname: string): Boolean;
  38.     function IsComponent: Boolean;  // object is stream createable
  39.     function IsControl: Boolean;
  40.     function IsWinControl: Boolean;
  41.     property Classname: string;
  42.     property Owner: IPersistent;
  43.     property NamePath: string;
  44. //    property PersistentProps[Index: Integer]: IPersistent
  45. //    property PersistentPropCount: Integer;
  46.     property EventInfos: IEventInfos;
  47.   end;
  48.  
  49.   IComponent = interface(IPersistent)
  50.     ['{B2F6D681-5098-11D1-9FB5-0020AF3D82DA}'] {Java}
  51.     function FindComponent(const Name: string): IComponent;
  52.     function GetComponentCount: Integer;
  53.     function GetComponents(Index: Integer): IComponent;
  54.     function GetComponentState: TComponentState;
  55.     function GetComponentStyle: TComponentStyle;
  56.     function GetDesignInfo: TSmallPoint;
  57.     function GetDesignOffset: TPoint;
  58.     function GetDesignSize: TPoint;
  59.     function GetName: string;
  60.     function GetOwner: IComponent;
  61.     function GetParent: IComponent;
  62.     procedure SetDesignInfo(const Point: TSmallPoint);
  63.     procedure SetDesignOffset(const Point: TPoint);
  64.     procedure SetDesignSize(const Point: TPoint);
  65.     procedure SetName(const Value: string);
  66.     property ComponentCount: Integer;
  67.     property Components[Index: Integer]: IComponent;
  68.     property ComponentState: TComponentState;
  69.     property ComponentStyle: TComponentStyle;
  70.     property DesignInfo: TSmallPoint;
  71.     property DesignOffset: TPoint;
  72.     property DesignSize: TPoint;
  73.     property Name: string;
  74.     property Owner: IComponent;
  75.     property Parent: IComponent;
  76.   end;
  77.  
  78.   IImplementation = interface
  79.     ['{F9D448F2-50BC-11D1-9FB5-0020AF3D82DA}']
  80.     function GetInstance: TObject;
  81.   end;
  82.  
  83.   function MakeIPersistent(Instance: TPersistent): IPersistent;
  84.   function ExtractPersistent(const Intf: IPersistent): TPersistent;
  85.   function TryExtractPersistent(const Intf: IPersistent): TPersistent;
  86.  
  87.   function MakeIComponent(Instance: TComponent): IComponent;
  88.   function ExtractComponent(const Intf: IComponent): TComponent;
  89.   function TryExtractComponent(const Intf: IComponent): TComponent;
  90.  
  91. var
  92.   MakeIPersistentProc: function (Instance: TPersistent): IPersistent = nil;
  93.   MakeIComponentProc: function (Instance: TComponent): IComponent = nil;
  94.  
  95. type
  96.  
  97. { IDesignerSelections  }
  98. {   Used to transport the selected objects list in and out of the form designer.
  99.     Replaces TComponentList in form designer interface.  }
  100.  
  101.   IDesignerSelections = interface
  102.     ['{82330134-65D1-11D1-9FBB-0020AF3D82DA}'] {Java}
  103.     function Add(const Item: IPersistent): Integer;
  104.     function Equals(const List: IDesignerSelections): Boolean;
  105.     function Get(Index: Integer): IPersistent;
  106.     function GetCount: Integer;
  107.     property Count: Integer;
  108.     property Items[Index: Integer]: IPersistent; default;
  109.   end;
  110.  
  111. function CreateSelectionList: IDesignerSelections;
  112.  
  113. type
  114.  
  115.   TComponentList = class;
  116.  
  117.   IComponentList = interface
  118.     ['{8ED8AD16-A241-11D1-AA94-00C04FB17A72}']
  119.     function GetComponentList: TComponentList;
  120.   end;
  121.  
  122. { TComponentList }
  123. {   Used to transport VCL component selections between property editors }
  124.  
  125.   TComponentList = class(TInterfacedObject, IDesignerSelections,
  126.     IComponentList)
  127.   public
  128.     constructor Create;
  129.     destructor Destroy; override;
  130.     function Add(Item: TPersistent): Integer;
  131.     function Equals(List: TComponentList): Boolean;
  132.     property Count: Integer;
  133.     property Items[Index: Integer]: TPersistent; default;
  134.   end;
  135.  
  136. { IFormDesigner }
  137. type
  138.  
  139.   IFormDesigner = interface(IDesigner)
  140.     ['{ABBE7255-5495-11D1-9FB5-0020AF3D82DA}']
  141.     function CreateMethod(const Name: string; TypeData: PTypeData): TMethod;
  142.     function GetMethodName(const Method: TMethod): string;
  143.     procedure GetMethods(TypeData: PTypeData; Proc: TGetStrProc);
  144.     function GetPrivateDirectory: string;
  145.     procedure GetSelections(const List: IDesignerSelections);
  146.     function MethodExists(const Name: string): Boolean;
  147.     procedure RenameMethod(const CurName, NewName: string);
  148.     procedure SelectComponent(Instance: TPersistent);
  149.     procedure SetSelections(const List: IDesignerSelections);
  150.     procedure ShowMethod(const Name: string);
  151.     function UniqueName(const BaseName: string): string;
  152.     procedure GetComponentNames(TypeData: PTypeData; Proc: TGetStrProc);
  153.     function GetComponent(const Name: string): TComponent;
  154.     function GetComponentName(Component: TComponent): string;
  155.     function GetObject(const Name: string): TPersistent;
  156.     function GetObjectName(Instance: TPersistent): string;
  157.     procedure GetObjectNames(TypeData: PTypeData; Proc: TGetStrProc);
  158.     function MethodFromAncestor(const Method: TMethod): Boolean;
  159.     function CreateComponent(ComponentClass: TComponentClass; Parent: TComponent;
  160.       Left, Top, Width, Height: Integer): TComponent;
  161.     function IsComponentLinkable(Component: TComponent): Boolean;
  162.     procedure MakeComponentLinkable(Component: TComponent);
  163.     function GetRoot: TComponent;
  164.     procedure Revert(Instance: TPersistent; PropInfo: PPropInfo);
  165.     function GetIsDormant: Boolean;
  166.     function HasInterface: Boolean;
  167.     function HasInterfaceMember(const Name: string): Boolean;
  168.     procedure AddToInterface(InvKind: Integer; const Name: string; VT: Word;
  169.       const TypeInfo: string);
  170.     procedure GetProjectModules(Proc: TGetModuleProc);
  171.     function GetAncestorDesigner: IFormDesigner;
  172.     function IsSourceReadOnly: Boolean;
  173.     property IsDormant: Boolean;
  174.     property AncestorDesigner: IFormDesigner;
  175.   end;
  176.  
  177. { TPropertyEditor
  178.   Edits a property of a component, or list of components, selected into the
  179.   Object Inspector.  The property editor is created based on the type of the
  180.   property being edited as determined by the types registered by
  181.   RegisterPropertyEditor.  The Object Inspector uses the a TPropertyEditor
  182.   for all modification to a property. GetName and GetValue are called to display
  183.   the name and value of the property.  SetValue is called whenever the user
  184.   requests to change the value.  Edit is called when the user double-clicks the
  185.   property in the Object Inspector. GetValues is called when the drop-down
  186.   list of a property is displayed.  GetProperties is called when the property
  187.   is expanded to show sub-properties.  AllEqual is called to decide whether or
  188.   not to display the value of the property when more than one component is
  189.   selected.
  190.  
  191.   The following are methods that can be overriden to change the behavior of
  192.   the property editor:
  193.  
  194.     Activate
  195.       Called whenever the property becomes selected in the object inspector.
  196.       This is potientially useful to allow certian property attributes to
  197.       to only be determined whenever the property is selected in the object
  198.       inspector. Only paSubProperties and paMultiSelect, returned from
  199.       GetAttributes, need to be accurate before this method is called.
  200.     AllEqual
  201.       Called whenever there are more than one components selected.  If this
  202.       method returns true, GetValue is called, otherwise blank is displayed
  203.       in the Object Inspector.  This is called only when GetAttributes
  204.       returns paMultiSelect.
  205.     AutoFill
  206.       Called to determine whether the values returned by GetValues can be
  207.       selected incrementally in the Object Inspector.  This is called only when
  208.       GetAttributes returns paValueList.
  209.     Edit
  210.       Called when the '...' button is pressed or the property is double-clicked.
  211.       This can, for example, bring up a dialog to allow the editing the
  212.       component in some more meaningful fashion than by text (e.g. the Font
  213.       property).
  214.     GetAttributes
  215.       Returns the information for use in the Object Inspector to be able to
  216.       show the approprate tools.  GetAttributes return a set of type
  217.       TPropertyAttributes:
  218.         paValueList:     The property editor can return an enumerated list of
  219.                          values for the property.  If GetValues calls Proc
  220.                          with values then this attribute should be set.  This
  221.                          will cause the drop-down button to appear to the right
  222.                          of the property in the Object Inspector.
  223.         paSortList:      Object Inspector to sort the list returned by
  224.                          GetValues.
  225.         paSubProperties: The property editor has sub-properties that will be
  226.                          displayed indented and below the current property in
  227.                          standard outline format. If GetProperties will
  228.                          generate property objects then this attribute should
  229.                          be set.
  230.         paDialog:        Indicates that the Edit method will bring up a
  231.                          dialog.  This will cause the '...' button to be
  232.                          displayed to the right of the property in the Object
  233.                          Inspector.
  234.         paMultiSelect:   Allows the property to be displayed when more than
  235.                          one component is selected.  Some properties are not
  236.                          approprate for multi-selection (e.g. the Name
  237.                          property).
  238.         paAutoUpdate:    Causes the SetValue method to be called on each
  239.                          change made to the editor instead of after the change
  240.                          has been approved (e.g. the Caption property).
  241.         paReadOnly:      Value is not allowed to change.
  242.         paRevertable:    Allows the property to be reverted to the original
  243.                          value.  Things that shouldn't be reverted are nested
  244.                          properties (e.g. Fonts) and elements of a composite
  245.                          property such as set element values.
  246.     GetComponent
  247.       Returns the Index'th component being edited by this property editor.  This
  248.       is used to retieve the components.  A property editor can only refer to
  249.       multiple components when paMultiSelect is returned from GetAttributes.
  250.     GetEditLimit
  251.       Returns the number of character the user is allowed to enter for the
  252.       value.  The inplace editor of the object inspector will be have its
  253.       text limited set to the return value.  By default this limit is 255.
  254.     GetName
  255.       Returns a the name of the property.  By default the value is retrieved
  256.       from the type information with all underbars replaced by spaces.  This
  257.       should only be overriden if the name of the property is not the name
  258.       that should appear in the Object Inspector.
  259.     GetProperties
  260.       Should be overriden to call PropertyProc for every sub-property (or nested
  261.       property) of the property begin edited and passing a new TPropertyEdtior
  262.       for each sub-property.  By default, PropertyProc is not called and no
  263.       sub-properties are assumed.  TClassProperty will pass a new property
  264.       editor for each published property in a class.  TSetProperty passes a
  265.       new editor for each element in the set.
  266.     GetPropType
  267.       Returns the type information pointer for the propertie(s) being edited.
  268.     GetValue
  269.       Returns the string value of the property. By default this returns
  270.       '(unknown)'.  This should be overriden to return the appropriate value.
  271.     GetValues
  272.       Called when paValueList is returned in GetAttributes.  Should call Proc
  273.       for every value that is acceptable for this property.  TEnumProperty
  274.       will pass every element in the enumeration.
  275.     Initialize
  276.       Called after the property editor has been created but before it is used.
  277.       Many times property editors are created and because they are not a common
  278.       property across the entire selection they are thrown away.  Initialize is
  279.       called after it is determined the property editor is going to be used by
  280.       the object inspector and not just thrown away.
  281.     SetValue(Value)
  282.       Called to set the value of the property.  The property editor should be
  283.       able to translate the string and call one of the SetXxxValue methods. If
  284.       the string is not in the correct format or not an allowed value, the
  285.       property editor should generate an exception describing the problem. Set
  286.       value can ignore all changes and allow all editing of the property be
  287.       accomplished through the Edit method (e.g. the Picture property).
  288.  
  289.   Properties and methods useful in creating a new TPropertyEditor classes:
  290.  
  291.     Name property
  292.       Returns the name of the property returned by GetName
  293.     PrivateDirectory property
  294.       It is either the .EXE or the "working directory" as specified in
  295.       the registry under the key:
  296.         "HKEY_CURRENT_USER\Software\Borland\Delphi\3.0\Globals\PrivateDir"
  297.       If the property editor needs auxilury or state files (templates, examples,
  298.       etc) they should be stored in this directory.
  299.     Value property
  300.       The current value, as a string, of the property as returned by GetValue.
  301.     Modified
  302.       Called to indicate the value of the property has been modified.  Called
  303.       automatically by the SetXxxValue methods.  If you call a TProperty
  304.       SetXxxValue method directly, you *must* call Modified as well.
  305.     GetXxxValue
  306.       Gets the value of the first property in the Properties property.  Calls
  307.       the appropriate TProperty GetXxxValue method to retrieve the value.
  308.     SetXxxValue
  309.       Sets the value of all the properties in the Properties property.  Calls
  310.       the approprate TProperty SetXxxxValue methods to set the value. }
  311.  
  312.   TPropertyAttribute = (paValueList, paSubProperties, paDialog,
  313.     paMultiSelect, paAutoUpdate, paSortList, paReadOnly, paRevertable);
  314.   TPropertyAttributes = set of TPropertyAttribute;
  315.  
  316.   TPropertyEditor = class;
  317.  
  318.   TInstProp = record
  319.     Instance: TPersistent;
  320.     PropInfo: PPropInfo;
  321.   end;
  322.  
  323.   PInstPropList = ^TInstPropList;
  324.   TInstPropList = array[0..1023] of TInstProp;
  325.  
  326.   TGetPropEditProc = procedure(Prop: TPropertyEditor) of object;
  327.  
  328.   TPropertyEditor = class
  329.   protected
  330.     constructor Create(const ADesigner: IFormDesigner; APropCount: Integer);
  331.     function GetPropInfo: PPropInfo;
  332.     function GetFloatValue: Extended;
  333.     function GetFloatValueAt(Index: Integer): Extended;
  334.     function GetMethodValue: TMethod;
  335.     function GetMethodValueAt(Index: Integer): TMethod;
  336.     function GetOrdValue: Longint;
  337.     function GetOrdValueAt(Index: Integer): Longint;
  338.     function GetStrValue: string;
  339.     function GetStrValueAt(Index: Integer): string;
  340.     function GetVarValue: Variant;
  341.     function GetVarValueAt(Index: Integer): Variant;
  342.     procedure Modified;
  343.     procedure SetFloatValue(Value: Extended);
  344.     procedure SetMethodValue(const Value: TMethod);
  345.     procedure SetOrdValue(Value: Longint);
  346.     procedure SetStrValue(const Value: string);
  347.     procedure SetVarValue(const Value: Variant);
  348.   public
  349.     destructor Destroy; override;
  350.     procedure Activate; virtual;
  351.     function AllEqual: Boolean; virtual;
  352.     function AutoFill: Boolean; virtual;
  353.     procedure Edit; virtual;
  354.     function GetAttributes: TPropertyAttributes; virtual;
  355.     function GetComponent(Index: Integer): TPersistent;
  356.     function GetEditLimit: Integer; virtual;
  357.     function GetName: string; virtual;
  358.     procedure GetProperties(Proc: TGetPropEditProc); virtual;
  359.     function GetPropType: PTypeInfo;
  360.     function GetValue: string; virtual;
  361.     procedure GetValues(Proc: TGetStrProc); virtual;
  362.     procedure Initialize; virtual;
  363.     procedure Revert;
  364.     procedure SetValue(const Value: string); virtual;
  365.     function ValueAvailable: Boolean;
  366.     property Designer: IFormDesigner;
  367.     property PrivateDirectory: string;
  368.     property PropCount: Integer;
  369.     property Value: string;
  370.   end;
  371.  
  372.   TPropertyEditorClass = class of TPropertyEditor;
  373.  
  374. { TOrdinalProperty
  375.   The base class of all ordinal property editors.  It established that ordinal
  376.   properties are all equal if the GetOrdValue all return the same value. }
  377.  
  378.   TOrdinalProperty = class(TPropertyEditor)
  379.     function AllEqual: Boolean; override;
  380.     function GetEditLimit: Integer; override;
  381.   end;
  382.  
  383. { TIntegerProperty
  384.   Default editor for all Longint properties and all subtypes of the Longint
  385.   type (i.e. Integer, Word, 1..10, etc.).  Retricts the value entrered into
  386.   the property to the range of the sub-type. }
  387.  
  388.   TIntegerProperty = class(TOrdinalProperty)
  389.   public
  390.     function GetValue: string; override;
  391.     procedure SetValue(const Value: string); override;
  392.   end;
  393.  
  394. { TCharProperty
  395.   Default editor for all Char properties and sub-types of Char (i.e. Char,
  396.   'A'..'Z', etc.). }
  397.  
  398.   TCharProperty = class(TOrdinalProperty)
  399.   public
  400.     function GetValue: string; override;
  401.     procedure SetValue(const Value: string); override;
  402.   end;
  403.  
  404. { TEnumProperty
  405.   The default property editor for all enumerated properties (e.g. TShape =
  406.   (sCircle, sTriangle, sSquare), etc.). }
  407.  
  408.   TEnumProperty = class(TOrdinalProperty)
  409.   public
  410.     function GetAttributes: TPropertyAttributes; override;
  411.     function GetValue: string; override;
  412.     procedure GetValues(Proc: TGetStrProc); override;
  413.     procedure SetValue(const Value: string); override;
  414.   end;
  415.  
  416.   TBoolProperty = class(TEnumProperty)
  417.     function GetValue: string; override;
  418.     procedure GetValues(Proc: TGetStrProc); override;
  419.     procedure SetValue(const Value: string); override;
  420.   end;
  421.  
  422. { TFloatProperty
  423.   The default property editor for all floating point types (e.g. Float,
  424.   Single, Double, etc.) }
  425.  
  426.   TFloatProperty = class(TPropertyEditor)
  427.   public
  428.     function AllEqual: Boolean; override;
  429.     function GetValue: string; override;
  430.     procedure SetValue(const Value: string); override;
  431.   end;
  432.  
  433. { TStringProperty
  434.   The default property editor for all strings and sub types (e.g. string,
  435.   string[20], etc.). }
  436.  
  437.   TStringProperty = class(TPropertyEditor)
  438.   public
  439.     function AllEqual: Boolean; override;
  440.     function GetEditLimit: Integer; override;
  441.     function GetValue: string; override;
  442.     procedure SetValue(const Value: string); override;
  443.   end;
  444.  
  445. { TNestedProperty
  446.   A property editor that uses the parents Designer, PropList and PropCount.
  447.   The constructor and destructor do not call inherited, but all derived classes
  448.   should.  This is useful for properties like the TSetElementProperty. }
  449.  
  450.   TNestedProperty = class(TPropertyEditor)
  451.   public
  452.     constructor Create(Parent: TPropertyEditor); virtual;
  453.     destructor Destroy; override;
  454.   end;
  455.  
  456. { TSetElementProperty
  457.   A property editor that edits an individual set element.  GetName is
  458.   changed to display the set element name instead of the property name and
  459.   Get/SetValue is changed to reflect the individual element state.  This
  460.   editor is created by the TSetProperty editor. }
  461.  
  462.   TSetElementProperty = class(TNestedProperty)
  463.   protected
  464.     constructor Create(Parent: TPropertyEditor; AElement: Integer); reintroduce;
  465.   public
  466.     function AllEqual: Boolean; override;
  467.     function GetAttributes: TPropertyAttributes; override;
  468.     function GetName: string; override;
  469.     function GetValue: string; override;
  470.     procedure GetValues(Proc: TGetStrProc); override;
  471.     procedure SetValue(const Value: string); override;
  472.    end;
  473.  
  474. { TSetProperty
  475.   Default property editor for all set properties. This editor does not edit
  476.   the set directly but will display sub-properties for each element of the
  477.   set. GetValue displays the value of the set in standard set syntax. }
  478.  
  479.   TSetProperty = class(TOrdinalProperty)
  480.   public
  481.     function GetAttributes: TPropertyAttributes; override;
  482.     procedure GetProperties(Proc: TGetPropEditProc); override;
  483.     function GetValue: string; override;
  484.   end;
  485.  
  486. { TClassProperty
  487.   Default property editor for all objects.  Does not allow modifing the
  488.   property but does display the class name of the object and will allow the
  489.   editing of the object's properties as sub-properties of the property. }
  490.  
  491.   TClassProperty = class(TPropertyEditor)
  492.   public
  493.     function GetAttributes: TPropertyAttributes; override;
  494.     procedure GetProperties(Proc: TGetPropEditProc); override;
  495.     function GetValue: string; override;
  496.   end;
  497.  
  498. { TMethodProperty
  499.   Property editor for all method properties. }
  500.  
  501.   TMethodProperty = class(TPropertyEditor)
  502.   public
  503.     function AllEqual: Boolean; override;
  504.     procedure Edit; override;
  505.     function GetAttributes: TPropertyAttributes; override;
  506.     function GetEditLimit: Integer; override;
  507.     function GetValue: string; override;
  508.     procedure GetValues(Proc: TGetStrProc); override;
  509.     procedure SetValue(const AValue: string); override;
  510.     function GetFormMethodName: string; virtual;
  511.     function GetTrimmedEventName: string;
  512.   end;
  513.  
  514. { TComponentProperty
  515.   The default editor for TComponents.  It does not allow editing of the
  516.   properties of the component.  It allow the user to set the value of this
  517.   property to point to a component in the same form that is type compatible
  518.   with the property being edited (e.g. the ActiveControl property). }
  519.  
  520.   TComponentProperty = class(TPropertyEditor)
  521.   public
  522.     function GetAttributes: TPropertyAttributes; override;
  523.     function GetEditLimit: Integer; override;
  524.     function GetValue: string; override;
  525.     procedure GetValues(Proc: TGetStrProc); override;
  526.     procedure SetValue(const Value: string); override;
  527.   end;
  528.  
  529. { TComponentNameProperty
  530.   Property editor for the Name property.  It restricts the name property
  531.   from being displayed when more than one component is selected. }
  532.  
  533.   TComponentNameProperty = class(TStringProperty)
  534.   public
  535.     function GetAttributes: TPropertyAttributes; override;
  536.     function GetEditLimit: Integer; override;
  537.   end;
  538.  
  539. { TFontNameProperty
  540.   Editor for the TFont.FontName property.  Displays a drop-down list of all
  541.   the fonts known by Windows.}
  542.  
  543.   TFontNameProperty = class(TStringProperty)
  544.   public
  545.     function GetAttributes: TPropertyAttributes; override;
  546.     procedure GetValues(Proc: TGetStrProc); override;
  547.   end;
  548.  
  549. { TFontCharsetProperty
  550.   Editor for the TFont.Charset property.  Displays a drop-down list of the
  551.   character-set by Windows.}
  552.  
  553.   TFontCharsetProperty = class(TIntegerProperty)
  554.   public
  555.     function GetAttributes: TPropertyAttributes; override;
  556.     function GetValue: string; override;
  557.     procedure GetValues(Proc: TGetStrProc); override;
  558.     procedure SetValue(const Value: string); override;
  559.   end;
  560.  
  561. { TImeNameProperty
  562.   Editor for the TImeName property.  Displays a drop-down list of all
  563.   the IME names known by Windows.}
  564.  
  565.   TImeNameProperty = class(TStringProperty)
  566.   public
  567.     function GetAttributes: TPropertyAttributes; override;
  568.     procedure GetValues(Proc: TGetStrProc); override;
  569.   end;
  570.  
  571. { TColorProperty
  572.   Property editor for the TColor type.  Displays the color as a clXXX value
  573.   if one exists, otherwise displays the value as hex.  Also allows the
  574.   clXXX value to be picked from a list. }
  575.  
  576.   TColorProperty = class(TIntegerProperty)
  577.   public
  578.     procedure Edit; override;
  579.     function GetAttributes: TPropertyAttributes; override;
  580.     function GetValue: string; override;
  581.     procedure GetValues(Proc: TGetStrProc); override;
  582.     procedure SetValue(const Value: string); override;
  583.   end;
  584.  
  585. { TCursorProperty
  586.   Property editor for the TCursor type.  Displays the color as a crXXX value
  587.   if one exists, otherwise displays the value as hex.  Also allows the
  588.   clXXX value to be picked from a list. }
  589.  
  590.   TCursorProperty = class(TIntegerProperty)
  591.   public
  592.     function GetAttributes: TPropertyAttributes; override;
  593.     function GetValue: string; override;
  594.     procedure GetValues(Proc: TGetStrProc); override;
  595.     procedure SetValue(const Value: string); override;
  596.   end;
  597.  
  598. { TFontProperty
  599.   Property editor the Font property.  Brings up the font dialog as well as
  600.   allowing the properties of the object to be edited. }
  601.  
  602.   TFontProperty = class(TClassProperty)
  603.   public
  604.     procedure Edit; override;
  605.     function GetAttributes: TPropertyAttributes; override;
  606.   end;
  607.  
  608. { TModalResultProperty }
  609.  
  610.   TModalResultProperty = class(TIntegerProperty)
  611.   public
  612.     function GetAttributes: TPropertyAttributes; override;
  613.     function GetValue: string; override;
  614.     procedure GetValues(Proc: TGetStrProc); override;
  615.     procedure SetValue(const Value: string); override;
  616.   end;
  617.  
  618. { TShortCutProperty
  619.   Property editor the the ShortCut property.  Allows both typing in a short
  620.   cut value or picking a short-cut value from a list. }
  621.  
  622.   TShortCutProperty = class(TOrdinalProperty)
  623.   public
  624.     function GetAttributes: TPropertyAttributes; override;
  625.     function GetValue: string; override;
  626.     procedure GetValues(Proc: TGetStrProc); override;
  627.     procedure SetValue(const Value: string); override;
  628.   end;
  629.  
  630. { TMPFilenameProperty
  631.   Property editor for the TMediaPlayer.  Displays an File Open Dialog
  632.   for the name of the media file.}
  633.  
  634.   TMPFilenameProperty = class(TStringProperty)
  635.   public
  636.     procedure Edit; override;
  637.     function GetAttributes: TPropertyAttributes; override;
  638.   end;
  639.  
  640. { TTabOrderProperty
  641.   Property editor for the TabOrder property.  Prevents the property from being
  642.   displayed when more than one component is selected. }
  643.  
  644.   TTabOrderProperty = class(TIntegerProperty)
  645.   public
  646.     function GetAttributes: TPropertyAttributes; override;
  647.   end;
  648.  
  649. { TCaptionProperty
  650.   Property editor for the Caption and Text properties.  Updates the value of
  651.   the property for each change instead on when the property is approved. }
  652.  
  653.   TCaptionProperty = class(TStringProperty)
  654.   public
  655.     function GetAttributes: TPropertyAttributes; override;
  656.   end;
  657.  
  658. { TDateProperty
  659.   Property editor for date portion of TDateTime type. }
  660.  
  661.   TDateProperty = class(TPropertyEditor)
  662.     function GetAttributes: TPropertyAttributes; override;
  663.     function GetValue: string; override;
  664.     procedure SetValue(const Value: string); override;
  665.   end;
  666.  
  667. { TTimeProperty
  668.   Property editor for time portion of TDateTime type. }
  669.  
  670.   TTimeProperty = class(TPropertyEditor)
  671.     function GetAttributes: TPropertyAttributes; override;
  672.     function GetValue: string; override;
  673.     procedure SetValue(const Value: string); override;
  674.   end;
  675.  
  676. { TDateTimeProperty
  677.   Edits both date and time data... simultaneously!  }
  678.  
  679.   TDateTimeProperty = class(TPropertyEditor)
  680.     function GetAttributes: TPropertyAttributes; override;
  681.     function GetValue: string; override;
  682.     procedure SetValue(const Value: string); override;
  683.   end;
  684.  
  685.   EPropertyError = class(Exception);
  686.  
  687. { TComponentEditor
  688.   A component editor is created for each component that is selected in the
  689.   form designer based on the component's type (see GetComponentEditor and
  690.   RegisterComponentEditor).  When the component is double-clicked the Edit
  691.   method is called.  When the context menu for the component is invoked the
  692.   GetVerbCount and GetVerb methods are called to build the menu.  If one
  693.   of the verbs are selected ExecuteVerb is called.  Paste is called whenever
  694.   the component is pasted to the clipboard.  You only need to create a
  695.   component editor if you wish to add verbs to the context menu, change
  696.   the default double-click behavior, or paste an additional clipboard format.
  697.   The default component editor (TDefaultEditor) implements Edit to searchs the
  698.   properties of the component and generates (or navigates to) the OnCreate,
  699.   OnChanged, or OnClick event (whichever it finds first).  Whenever the
  700.   component modifies the component is *must* call Designer.Modified to inform
  701.   the designer that the form has been modified.
  702.  
  703.     Create(AComponent, ADesigner)
  704.       Called to create the component editor.  AComponent is the component to
  705.       be edited by the editor.  ADesigner is an interface to the designer to
  706.       find controls and create methods (this is not use often).
  707.     Edit
  708.       Called when the user double-clicks the component. The component editor can
  709.       bring up a dialog in responce to this method, for example, or some kind
  710.       of design expert.  If GetVerbCount is greater than zero, edit will execute
  711.       the first verb in the list (ExecuteVerb(0)).
  712.     ExecuteVerb(Index)
  713.       The Index'ed verb was selected by the use off the context menu.  The
  714.       meaning of this is determined by component editor.
  715.     GetVerb
  716.       The component editor should return a string that will be displayed in the
  717.       context menu.  It is the responsibility of the component editor to place
  718.       the & character and the '...' characters as appropriate.
  719.     GetVerbCount
  720.       The number of valid indexs to GetVerb and Execute verb.  The index assumed
  721.       to be zero based (i.e. 0..GetVerbCount - 1).
  722.     Copy
  723.       Called when the component is being copyied to the clipboard.  The
  724.       component's filed image is already on the clipboard.  This gives the
  725.       component editor a chance to paste a different type of format which is
  726.       ignored by the designer but might be recoginized by another application. }
  727.  
  728.   IComponentEditor = interface
  729.     ['{ABBE7252-5495-11D1-9FB5-0020AF3D82DA}']
  730.     procedure Edit;
  731.     procedure ExecuteVerb(Index: Integer);
  732.     function GetIComponent: IComponent;
  733.     function GetDesigner: IFormDesigner;
  734.     function GetVerb(Index: Integer): string;
  735.     function GetVerbCount: Integer;
  736.     procedure Copy;
  737.   end;
  738.  
  739.   TComponentEditor = class(TInterfacedObject, IComponentEditor)
  740.   public
  741.     constructor Create(AComponent: TComponent; ADesigner: IFormDesigner); virtual;
  742.     procedure Edit; virtual;
  743.     procedure ExecuteVerb(Index: Integer); virtual;
  744.     function GetIComponent: IComponent;
  745.     function GetDesigner: IFormDesigner;
  746.     function GetVerb(Index: Integer): string; virtual;
  747.     function GetVerbCount: Integer; virtual;
  748.     procedure Copy; virtual;
  749.     property Component: TComponent;
  750.     property Designer: IFormDesigner;
  751.   end;
  752.  
  753.   TComponentEditorClass = class of TComponentEditor;
  754.  
  755.   IDefaultEditor = interface(IComponentEditor)
  756.     ['{5484FAE1-5C60-11D1-9FB6-0020AF3D82DA}']
  757.   end;
  758.  
  759.   TDefaultEditor = class(TComponentEditor, IDefaultEditor)
  760.   protected
  761.     procedure EditProperty(PropertyEditor: TPropertyEditor;
  762.       var Continue, FreeEditor: Boolean); virtual;
  763.   public
  764.     procedure Edit; override;
  765.   end;
  766.  
  767. { Global variables initialized internally by the form designer }
  768.  
  769. type
  770.   TFreeCustomModulesProc = procedure (Group: Integer);
  771.  
  772. var
  773.   FreeCustomModulesProc: TFreeCustomModulesProc;
  774.  
  775. { RegisterPropertyEditor
  776.   Registers a new property editor for the given type.  When a component is
  777.   selected the Object Inspector will create a property editor for each
  778.   of the component's properties.  The property editor is created based on
  779.   the type of the property.  If, for example, the property type is an
  780.   Integer, the property editor for Integer will be created (by default
  781.   that would be TIntegerProperty). Most properties do not need specialized
  782.   property editors.  For example, if the property is an ordinal type the
  783.   default property editor will restrict the range to the ordinal subtype
  784.   range (e.g. a property of type TMyRange = 1..10 will only allow values
  785.   between 1 and 10 to be entered into the property).  Enumerated types will
  786.   display a drop-down list of all the enumerated values (e.g. TShapes =
  787.   (sCircle, sSquare, sTriangle) will be edited by a drop-down list containing
  788.   only sCircle, sSquare and sTriangle).  A property editor need only be
  789.   created if default property editor or none of the existing property editors
  790.   are sufficient to edit the property.  This is typically because the
  791.   property is an object.  The properties are looked up newest to oldest.
  792.   This allows and existing property editor replaced by a custom property
  793.   editor.
  794.  
  795.     PropertyType
  796.       The type information pointer returned by the TypeInfo built-in function
  797.       (e.g. TypeInfo(TMyRange) or TypeInfo(TShapes)).
  798.  
  799.     ComponentClass
  800.       Type type of the component to which to restrict this type editor.  This
  801.       parameter can be left nil which will mean this type editor applies to all
  802.       properties of PropertyType.
  803.  
  804.     PropertyName
  805.       The name of the property to which to restrict this type editor.  This
  806.       parameter is ignored if ComponentClass is nil.  This paramter can be
  807.       an empty string ('') which will mean that this editor applies to all
  808.       properties of PropertyType in ComponentClass.
  809.  
  810.     EditorClass
  811.       The class of the editor to be created whenever a property of the type
  812.       passed in PropertyTypeInfo is displayed in the Object Inspector.  The
  813.       class will be created by calling EditorClass.Create. }
  814.  
  815. procedure RegisterPropertyEditor(PropertyType: PTypeInfo; ComponentClass: TClass;
  816.   const PropertyName: string; EditorClass: TPropertyEditorClass);
  817.  
  818. type
  819.   TPropertyMapperFunc = function(Obj: TPersistent;
  820.     PropInfo: PPropInfo): TPropertyEditorClass;
  821.  
  822. procedure RegisterPropertyMapper(Mapper: TPropertyMapperFunc);
  823.  
  824. procedure GetComponentProperties(Components: TComponentList;
  825.   Filter: TTypeKinds; Designer: IFormDesigner; Proc: TGetPropEditProc);
  826.  
  827. procedure RegisterComponentEditor(ComponentClass: TComponentClass;
  828.   ComponentEditor: TComponentEditorClass);
  829.  
  830. function GetComponentEditor(Component: TComponent;
  831.   Designer: IFormDesigner): TComponentEditor;
  832.  
  833. { Custom modules }
  834. { A custom module allows containers that descend from classes other than TForm
  835.   to be created and edited by the form designer. This is useful for other form
  836.   like containers (e.g. a report designer) or for specialized forms (e.g. an
  837.   ActiveForm) or for generic component containers (e.g. a TDataModule). It is
  838.   assumed that the base class registered will call InitInheritedComponent in its
  839.   constructor which will initialize the component from the associated DFM file
  840.   stored in the programs resources. See the constructors of TDataModule and
  841.   TForm for examples of how to write such a constructor.
  842.  
  843.   The following designer assumptions are made, depending on the base components
  844.   ancestor,
  845.  
  846.     If ComponentBaseClass descends from TForm,
  847.  
  848.        it is designed by creating an instance of the component as the form.
  849.        Allows designing TForm descendents and modifying their properties as
  850.        well as the form properties
  851.  
  852.     If ComponentBaseClass descends from TWinControl (but not TForm),
  853.  
  854.        it is designed by creating an instance of the control, placing it into a
  855.        design-time form.  The form's client size is in the default size of the
  856.        control.
  857.  
  858.     If ComponentBaseClass descends from TDataModule,
  859.  
  860.        it is designed by creating and instance of the class and creating a
  861.        special non-visual container designer to edit the components and display
  862.        the icons of the contained components.
  863.  
  864.   The module will appear in the project file with a colon and the base class
  865.   name appended after the component name (e.g. MyDataModle: TDataModule).
  866.  
  867.   Note it is not legal to register anything that does not desend from one of
  868.   the above.
  869.  
  870.   TCustomModule class
  871.     This an instance of this class is created for each custom module that is
  872.     loaded. This class is also destroyed whenever the module is unloaded.
  873.     The Saving method is called prior to the file being saved. When the context
  874.     menu for the module is invoked the GetVerbCount and GetVerb methods are
  875.     called to build the menu.  If one of the verbs are selected ExecuteVerb is
  876.     called.
  877.  
  878.     ExecuteVerb(Index)
  879.       The Index'ed verb was selected by the use off the context menu.  The
  880.       meaning of this is determined by custom module.
  881.     GetAttributes
  882.       Only used for TWinControl object to determine if the control is "client
  883.       aligned" in the designer or if the object should sized independently
  884.       from the designer.  This is a set for future expansion.
  885.     GetVerb(Index)
  886.       The custom module should return a string that will be displayed in the
  887.       context menu.  It is the responsibility of the custom module to place
  888.       the & character and the '...' characters as appropriate.
  889.     GetVerbCount
  890.       The number of valid indexs to GetVerb and Execute verb.  The index assumed
  891.       to be zero based (i.e. 0..GetVerbCount - 1).
  892.     Saving
  893.       Called prior to the module being saved.
  894.     ValidateComponent(Component)
  895.       ValidateCompoennt is called whenever a component is created by the
  896.       user for the designer to contain.  The intent is for this procedure to
  897.       raise an exception with a descriptive message if the component is not
  898.       applicable for the container. For example, a TComponent module should
  899.       throw an exception if the component descends from TControl.
  900.     Root
  901.       This is the instance being designed.}
  902.  
  903. type
  904.   TCustomModuleAttribute = (cmaVirtualSize);
  905.   TCustomModuleAttributes = set of TCustomModuleAttribute;
  906.  
  907.   TCustomModule = class
  908.   public
  909.     constructor Create(ARoot: IComponent); virtual;
  910.     procedure ExecuteVerb(Index: Integer); virtual;
  911.     function GetAttributes: TCustomModuleAttributes; virtual;
  912.     function GetVerb(Index: Integer): string; virtual;
  913.     function GetVerbCount: Integer; virtual;
  914.     procedure Saving; virtual;
  915.     procedure ValidateComponent(Component: IComponent); virtual;
  916.     property Root: IComponent;
  917.   end;
  918.  
  919.   TCustomModuleClass = class of TCustomModule;
  920.  
  921.   TRegisterCustomModuleProc = procedure (Group: Integer;
  922.     ComponentBaseClass: TComponentClass;
  923.     CustomModuleClass: TCustomModuleClass);
  924.  
  925. procedure RegisterCustomModule(ComponentBaseClass: TComponentClass;
  926.   CustomModuleClass: TCustomModuleClass);
  927.  
  928. var
  929.   RegisterCustomModuleProc: TRegisterCustomModuleProc;
  930.  
  931. { Routines used by the form designer for package management }
  932.  
  933. function NewEditorGroup: Integer;
  934. procedure FreeEditorGroup(Group: Integer);
  935.  
  936. var  // number of significant characters in identifiers
  937.   MaxIdentLength: Byte = 63;
  938.  
  939. implementation
  940.