home *** CD-ROM | disk | FTP | other *** search
/ PC World Plus! (NZ) 2001 June / HDC50.iso / Runimage / Delphi50 / Doc / DSGNINTF.INT < prev    next >
Encoding:
Text File  |  1999-08-11  |  57.3 KB  |  1,371 lines

  1.  
  2. {*******************************************************}
  3. {                                                       }
  4. {       Borland Delphi Visual Component Library         }
  5. {                                                       }
  6. {       Copyright (c) 1995,99 Inprise Corporation       }
  7. {                                                       }
  8. {*******************************************************}
  9.  
  10. unit DsgnIntf;
  11.  
  12. interface
  13.  
  14. {$N+,S-,R-}
  15.  
  16. uses
  17.   Windows, Activex, SysUtils, Classes, Graphics, Controls, Forms, Contnrs, IniFiles,
  18.   TypInfo, Masks, Menus;
  19.  
  20. type
  21.  
  22.   TEditAction = (eaUndo, eaRedo, eaCut, eaCopy, eaPaste, eaDelete, eaSelectAll,
  23.     eaPrint, eaBringToFront, eaSendToBack, eaAlignToGrid, eaFlipChildrenAll,
  24.     eaFlipChildrenSelected);
  25.  
  26.   TEditState = set of (esCanUndo, esCanRedo, esCanCut, esCanCopy, esCanPaste,
  27.     esCanDelete, esCanZOrder, esCanAlignGrid, esCanEditOle, esCanTabOrder,
  28.     esCanCreationOrder, esCanPrint, esCanSelectAll);
  29.  
  30.   IEventInfos = interface
  31.     ['{11667FF0-7590-11D1-9FBC-0020AF3D82DA}']
  32.     function GetCount: Integer;
  33.     function GetEventValue(Index: Integer): string;
  34.     function GetEventName(Index: Integer): string;
  35.     procedure ClearEvent(Index: Integer);
  36.     property Count: Integer;
  37.   end;
  38.  
  39.   IPersistent = interface
  40.     ['{82330133-65D1-11D1-9FBB-0020AF3D82DA}'] {Java}
  41.     procedure DestroyObject;
  42.     function Equals(const Other: IPersistent): Boolean;
  43.     function GetClassname: string;
  44.     function GetEventInfos: IEventInfos;
  45.     function GetNamePath: string;
  46.     function GetOwner: IPersistent;
  47.     function InheritsFrom(const Classname: string): Boolean;
  48.     function IsComponent: Boolean;  // object is stream createable
  49.     function IsControl: Boolean;
  50.     function IsWinControl: Boolean;
  51.     property Classname: string;
  52.     property Owner: IPersistent;
  53.     property NamePath: string;
  54. //    property PersistentProps[Index: Integer]: IPersistent
  55. //    property PersistentPropCount: Integer;
  56.     property EventInfos: IEventInfos;
  57.   end;
  58.  
  59.   IComponent = interface(IPersistent)
  60.     ['{B2F6D681-5098-11D1-9FB5-0020AF3D82DA}'] {Java}
  61.     function FindComponent(const Name: string): IComponent;
  62.     function GetComponentCount: Integer;
  63.     function GetComponents(Index: Integer): IComponent;
  64.     function GetComponentState: TComponentState;
  65.     function GetComponentStyle: TComponentStyle;
  66.     function GetDesignInfo: TSmallPoint;
  67.     function GetDesignOffset: TPoint;
  68.     function GetDesignSize: TPoint;
  69.     function GetName: string;
  70.     function GetOwner: IComponent;
  71.     function GetParent: IComponent;
  72.     procedure SetDesignInfo(const Point: TSmallPoint);
  73.     procedure SetDesignOffset(const Point: TPoint);
  74.     procedure SetDesignSize(const Point: TPoint);
  75.     procedure SetName(const Value: string);
  76.     property ComponentCount: Integer;
  77.     property Components[Index: Integer]: IComponent;
  78.     property ComponentState: TComponentState;
  79.     property ComponentStyle: TComponentStyle;
  80.     property DesignInfo: TSmallPoint;
  81.     property DesignOffset: TPoint;
  82.     property DesignSize: TPoint;
  83.     property Name: string;
  84.     property Owner: IComponent;
  85.     property Parent: IComponent;
  86.   end;
  87.  
  88.   IImplementation = interface
  89.     ['{F9D448F2-50BC-11D1-9FB5-0020AF3D82DA}']
  90.     function GetInstance: TObject;
  91.   end;
  92.  
  93.   function MakeIPersistent(Instance: TPersistent): IPersistent;
  94.   function ExtractPersistent(const Intf: IUnknown): TPersistent;
  95.   function TryExtractPersistent(const Intf: IUnknown): TPersistent;
  96.  
  97.   function MakeIComponent(Instance: TComponent): IComponent;
  98.   function ExtractComponent(const Intf: IUnknown): TComponent;
  99.   function TryExtractComponent(const Intf: IUnknown): TComponent;
  100.  
  101. var
  102.   MakeIPersistentProc: function (Instance: TPersistent): IPersistent = nil;
  103.   MakeIComponentProc: function (Instance: TComponent): IComponent = nil;
  104.  
  105. type
  106.  
  107. { IDesignerSelections  }
  108. {   Used to transport the selected objects list in and out of the form designer.
  109.     Replaces TDesignerSelectionList in form designer interface.  }
  110.  
  111.   IDesignerSelections = interface
  112.     ['{82330134-65D1-11D1-9FBB-0020AF3D82DA}'] {Java}
  113.     function Add(const Item: IPersistent): Integer;
  114.     function Equals(const List: IDesignerSelections): Boolean;
  115.     function Get(Index: Integer): IPersistent;
  116.     function GetCount: Integer;
  117.     property Count: Integer;
  118.     property Items[Index: Integer]: IPersistent; default;
  119.   end;
  120.  
  121. function CreateSelectionList: IDesignerSelections;
  122.  
  123. type
  124.  
  125.   TDesignerSelectionList = class;
  126.  
  127.   IComponentList = interface
  128.     ['{8ED8AD16-A241-11D1-AA94-00C04FB17A72}']
  129.     function GetComponentList: TDesignerSelectionList;
  130.   end;
  131.  
  132. { TDesignerSelectionList }
  133. {   Used to transport VCL component selections between property editors }
  134.  
  135.   TDesignerSelectionList = class(TInterfacedObject, IDesignerSelections,
  136.     IComponentList)
  137.   public
  138.     constructor Create;
  139.     destructor Destroy; override;
  140.     function Add(Item: TPersistent): Integer;
  141.     function Equals(List: TDesignerSelectionList): Boolean;
  142.     property Count: Integer;
  143.     property Items[Index: Integer]: TPersistent; default;
  144.   end;
  145.  
  146. { IFormDesigner
  147.     BuildLocalMenu - Constructs and returns the popup menu for the currently
  148.     selected component(s).  Base is the popup menu that will receive additional
  149.     menu items.  If Base is nil, a default popup menu is constructed containing
  150.     the default designer menu items, like "Align to Grid".  The menu object
  151.     returned by this function is owned by the designer and will be destroyed
  152.     the next time BuildLocalMenu is called (the next time a Popup menu is
  153.     invoked on the designer).  If you pass in a Base menu, you don't own it
  154.     anymore.  It will be destroyed later.
  155. }
  156. type
  157.   TLocalMenuFilter = (lmModule, lmComponent, lmDesigner);
  158.   TLocalMenuFilters = set of TLocalMenuFilter;
  159.  
  160. const
  161.   cNoLocalMenus = [lmModule, lmComponent, lmDesigner];
  162.   cAllLocalMenus = [];
  163.   cLocalMenusIf: array [boolean] of TLocalMenuFilters =
  164.     (cNoLocalMenus, cAllLocalMenus);
  165.  
  166. type
  167.   IFormDesigner = interface(IDesigner)
  168.     ['{ADDD444D-1B03-11D3-A8F8-00C04FA32F53}']
  169.     function CreateMethod(const Name: string; TypeData: PTypeData): TMethod;
  170.     function GetMethodName(const Method: TMethod): string;
  171.     procedure GetMethods(TypeData: PTypeData; Proc: TGetStrProc);
  172.     function GetPrivateDirectory: string;
  173.     procedure GetSelections(const List: IDesignerSelections);
  174.     function MethodExists(const Name: string): Boolean;
  175.     procedure RenameMethod(const CurName, NewName: string);
  176.     procedure SelectComponent(Instance: TPersistent);
  177.     procedure SetSelections(const List: IDesignerSelections);
  178.     procedure ShowMethod(const Name: string);
  179.     procedure GetComponentNames(TypeData: PTypeData; Proc: TGetStrProc);
  180.     function GetComponent(const Name: string): TComponent;
  181.     function GetComponentName(Component: TComponent): string;
  182.     function GetObject(const Name: string): TPersistent;
  183.     function GetObjectName(Instance: TPersistent): string;
  184.     procedure GetObjectNames(TypeData: PTypeData; Proc: TGetStrProc);
  185.     function MethodFromAncestor(const Method: TMethod): Boolean;
  186.     function CreateComponent(ComponentClass: TComponentClass; Parent: TComponent;
  187.       Left, Top, Width, Height: Integer): TComponent;
  188.     function IsComponentLinkable(Component: TComponent): Boolean;
  189.     procedure MakeComponentLinkable(Component: TComponent);
  190.     procedure Revert(Instance: TPersistent; PropInfo: PPropInfo);
  191.     function GetIsDormant: Boolean;
  192.     function HasInterface: Boolean;
  193.     function HasInterfaceMember(const Name: string): Boolean;
  194.     procedure AddToInterface(InvKind: Integer; const Name: string; VT: Word;
  195.       const TypeInfo: string);
  196.     procedure GetProjectModules(Proc: TGetModuleProc);
  197.     function GetAncestorDesigner: IFormDesigner;
  198.     function IsSourceReadOnly: Boolean;
  199.     function GetContainerWindow: TWinControl;
  200.     procedure SetContainerWindow(const NewContainer: TWinControl);
  201.     function GetScrollRanges(const ScrollPosition: TPoint): TPoint;
  202.     procedure Edit(const Component: IComponent);
  203.     function BuildLocalMenu(Base: TPopupMenu; Filter: TLocalMenuFilters): TPopupMenu;
  204.     procedure ChainCall(const MethodName, InstanceName, InstanceMethod: string;
  205.       TypeData: PTypeData);
  206.     procedure CopySelection;
  207.     procedure CutSelection;
  208.     function CanPaste: Boolean;
  209.     procedure PasteSelection;
  210.     procedure DeleteSelection;
  211.     procedure ClearSelection;
  212.     procedure NoSelection;
  213.     procedure ModuleFileNames(var ImplFileName, IntfFileName, FormFileName: string);
  214.     function GetRootClassName: string;
  215.     property IsDormant: Boolean;
  216.     property AncestorDesigner: IFormDesigner;
  217.     property ContainerWindow: TWinControl;
  218.   end;
  219.  
  220.   IDesignNotification = interface
  221.     ['{3250122F-D336-11D2-B725-00C04FA35D12}']
  222.     procedure ItemDeleted(const AItem: IPersistent);
  223.     procedure ItemInserted(const AItem: IPersistent);
  224.     procedure ItemsModified(const ADesigner: IUnknown);
  225.     procedure SelectionChanged(const ASelection: IDesignerSelections);
  226.     procedure DesignerInitialized(const ADesigner: IUnknown);
  227.     procedure DesignerClosed(const ADesigner: IUnknown);
  228.   end;
  229.  
  230. { IDesignerPopulateMenu
  231.     Allows a design surface an opportunity to add context-sensitive menu items
  232.     to the designer's popup menu.  This is in addition to the component editor
  233.     verbs and the custom module verbs. }
  234.  
  235.   IDesignerPopulateMenu = interface
  236.     ['{66C7D913-EC70-11D2-AAD1-00C04FB16FBC}']
  237.     procedure PopulateMenu(const APopupMenu: TPopupMenu);
  238.   end;
  239.  
  240. { TPropertyEditor
  241.   Edits a property of a component, or list of components, selected into the
  242.   Object Inspector.  The property editor is created based on the type of the
  243.   property being edited as determined by the types registered by
  244.   RegisterPropertyEditor.  The Object Inspector uses a TPropertyEditor
  245.   for all modification to a property. GetName and GetValue are called to display
  246.   the name and value of the property.  SetValue is called whenever the user
  247.   requests to change the value.  Edit is called when the user double-clicks the
  248.   property in the Object Inspector. GetValues is called when the drop-down
  249.   list of a property is displayed.  GetProperties is called when the property
  250.   is expanded to show sub-properties.  AllEqual is called to decide whether or
  251.   not to display the value of the property when more than one component is
  252.   selected.
  253.  
  254.   The following are methods that can be overridden to change the behavior of
  255.   the property editor:
  256.  
  257.     Activate
  258.       Called whenever the property becomes selected in the object inspector.
  259.       This is potentially useful to allow certain property attributes to
  260.       to only be determined whenever the property is selected in the object
  261.       inspector. Only paSubProperties and paMultiSelect, returned from
  262.       GetAttributes, need to be accurate before this method is called.
  263.     AllEqual
  264.       Called whenever there is more than one component selected.  If this
  265.       method returns true, GetValue is called, otherwise blank is displayed
  266.       in the Object Inspector.  This is called only when GetAttributes
  267.       returns paMultiSelect.
  268.     AutoFill
  269.       Called to determine whether the values returned by GetValues can be
  270.       selected incrementally in the Object Inspector.  This is called only when
  271.       GetAttributes returns paValueList.
  272.     Edit
  273.       Called when the '...' button is pressed or the property is double-clicked.
  274.       This can, for example, bring up a dialog to allow the editing the
  275.       component in some more meaningful fashion than by text (e.g. the Font
  276.       property).
  277.     GetAttributes
  278.       Returns the information for use in the Object Inspector to be able to
  279.       show the appropriate tools.  GetAttributes returns a set of type
  280.       TPropertyAttributes:
  281.         paValueList:     The property editor can return an enumerated list of
  282.                          values for the property.  If GetValues calls Proc
  283.                          with values then this attribute should be set.  This
  284.                          will cause the drop-down button to appear to the right
  285.                          of the property in the Object Inspector.
  286.         paSortList:      Object Inspector to sort the list returned by
  287.                          GetValues.
  288.         paSubProperties: The property editor has sub-properties that will be
  289.                          displayed indented and below the current property in
  290.                          standard outline format. If GetProperties will
  291.                          generate property objects then this attribute should
  292.                          be set.
  293.         paDialog:        Indicates that the Edit method will bring up a
  294.                          dialog.  This will cause the '...' button to be
  295.                          displayed to the right of the property in the Object
  296.                          Inspector.
  297.         paMultiSelect:   Allows the property to be displayed when more than
  298.                          one component is selected.  Some properties are not
  299.                          appropriate for multi-selection (e.g. the Name
  300.                          property).
  301.         paAutoUpdate:    Causes the SetValue method to be called on each
  302.                          change made to the editor instead of after the change
  303.                          has been approved (e.g. the Caption property).
  304.         paReadOnly:      Value is not allowed to change.
  305.         paRevertable:    Allows the property to be reverted to the original
  306.                          value.  Things that shouldn't be reverted are nested
  307.                          properties (e.g. Fonts) and elements of a composite
  308.                          property such as set element values.
  309.         paFullWidthName: Tells the object inspector that the value does not
  310.                          need to be rendered and as such the name should be
  311.                          rendered the full width of the inspector.
  312.     GetComponent
  313.       Returns the Index'th component being edited by this property editor.  This
  314.       is used to retrieve the components.  A property editor can only refer to
  315.       multiple components when paMultiSelect is returned from GetAttributes.
  316.     GetEditLimit
  317.       Returns the number of character the user is allowed to enter for the
  318.       value.  The inplace editor of the object inspector will be have its
  319.       text limited set to the return value.  By default this limit is 255.
  320.     GetName
  321.       Returns the name of the property.  By default the value is retrieved
  322.       from the type information with all underbars replaced by spaces.  This
  323.       should only be overridden if the name of the property is not the name
  324.       that should appear in the Object Inspector.
  325.     GetProperties
  326.       Should be overridden to call PropertyProc for every sub-property (or
  327.       nested property) of the property begin edited and passing a new
  328.       TPropertyEdtior for each sub-property.  By default, PropertyProc is not
  329.       called and no sub-properties are assumed.  TClassProperty will pass a
  330.       new property editor for each published property in a class.  TSetProperty
  331.       passes a new editor for each element in the set.
  332.     GetPropType
  333.       Returns the type information pointer for the property(s) being edited.
  334.     GetValue
  335.       Returns the string value of the property. By default this returns
  336.       '(unknown)'.  This should be overridden to return the appropriate value.
  337.     GetValues
  338.       Called when paValueList is returned in GetAttributes.  Should call Proc
  339.       for every value that is acceptable for this property.  TEnumProperty
  340.       will pass every element in the enumeration.
  341.     Initialize
  342.       Called after the property editor has been created but before it is used.
  343.       Many times property editors are created and because they are not a common
  344.       property across the entire selection they are thrown away.  Initialize is
  345.       called after it is determined the property editor is going to be used by
  346.       the object inspector and not just thrown away.
  347.     SetValue(Value)
  348.       Called to set the value of the property.  The property editor should be
  349.       able to translate the string and call one of the SetXxxValue methods. If
  350.       the string is not in the correct format or not an allowed value, the
  351.       property editor should generate an exception describing the problem. Set
  352.       value can ignore all changes and allow all editing of the property be
  353.       accomplished through the Edit method (e.g. the Picture property).
  354.     ListMeasureWidth(Value, Canvas, AWidth)
  355.       This is called during the width calculation phase of the drop down list
  356.       preparation.
  357.     ListMeasureHeight(Value, Canvas, AHeight)
  358.       This is called during the item/value height calculation phase of the drop
  359.       down list's render.  This is very similar to TListBox's OnMeasureItem,
  360.       just slightly different parameters.
  361.     ListDrawValue(Value, Canvas, Rect, Selected)
  362.       This is called during the item/value render phase of the drop down list's
  363.       render.  This is very similar to TListBox's OnDrawItem, just slightly
  364.       different parameters.
  365.     PropDrawName(Canvas, Rect, Selected)
  366.       Called during the render of the name column of the property list.  Its
  367.       functionality is very similar to TListBox's OnDrawItem, but once again
  368.       it has slightly different parameters.
  369.     PropDrawValue(Canvas, Rect, Selected)
  370.       Called during the render of the value column of the property list.  Its
  371.       functionality is similar to PropDrawName.  If multiple items are selected
  372.       and their values don't match this procedure will be passed an empty
  373.       value.
  374.  
  375.   Properties and methods useful in creating a new TPropertyEditor classes:
  376.  
  377.     Name property
  378.       Returns the name of the property returned by GetName
  379.     PrivateDirectory property
  380.       It is either the .EXE or the "working directory" as specified in
  381.       the registry under the key:
  382.         "HKEY_CURRENT_USER\Software\Borland\Delphi\*\Globals\PrivateDir"
  383.       If the property editor needs auxiliary or state files (templates, examples,
  384.       etc) they should be stored in this directory.
  385.     Value property
  386.       The current value, as a string, of the property as returned by GetValue.
  387.     Modified
  388.       Called to indicate the value of the property has been modified.  Called
  389.       automatically by the SetXxxValue methods.  If you call a TProperty
  390.       SetXxxValue method directly, you *must* call Modified as well.
  391.     GetXxxValue
  392.       Gets the value of the first property in the Properties property.  Calls
  393.       the appropriate TProperty GetXxxValue method to retrieve the value.
  394.     SetXxxValue
  395.       Sets the value of all the properties in the Properties property.  Calls
  396.       the approprate TProperty SetXxxxValue methods to set the value.
  397.     GetVisualValue
  398.       This function will return the displayable value of the property.  If
  399.       only one item is selected or all the multi-selected items have the same
  400.       property value then this function will return the actual property value.
  401.       Otherwise this function will return an empty string.}
  402.  
  403.   TPropertyAttribute = (paValueList, paSubProperties, paDialog, paMultiSelect,
  404.     paAutoUpdate, paSortList, paReadOnly, paRevertable, paFullWidthName);
  405.   TPropertyAttributes = set of TPropertyAttribute;
  406.  
  407.   TPropertyEditor = class;
  408.  
  409.   TInstProp = record
  410.     Instance: TPersistent;
  411.     PropInfo: PPropInfo;
  412.   end;
  413.  
  414.   PInstPropList = ^TInstPropList;
  415.   TInstPropList = array[0..1023] of TInstProp;
  416.  
  417.   TGetPropEditProc = procedure(Prop: TPropertyEditor) of object;
  418.  
  419.   TPropertyEditor = class
  420.   protected
  421.     constructor Create(const ADesigner: IFormDesigner; APropCount: Integer); virtual;
  422.     function GetPropInfo: PPropInfo;
  423.     function GetFloatValue: Extended;
  424.     function GetFloatValueAt(Index: Integer): Extended;
  425.     function GetInt64Value: Int64;
  426.     function GetInt64ValueAt(Index: Integer): Int64;
  427.     function GetMethodValue: TMethod;
  428.     function GetMethodValueAt(Index: Integer): TMethod;
  429.     function GetOrdValue: Longint;
  430.     function GetOrdValueAt(Index: Integer): Longint;
  431.     function GetStrValue: string;
  432.     function GetStrValueAt(Index: Integer): string;
  433.     function GetVarValue: Variant;
  434.     function GetVarValueAt(Index: Integer): Variant;
  435.     procedure Modified; 
  436.     procedure SetFloatValue(Value: Extended);
  437.     procedure SetMethodValue(const Value: TMethod);
  438.     procedure SetInt64Value(Value: Int64);
  439.     procedure SetOrdValue(Value: Longint);
  440.     procedure SetStrValue(const Value: string);
  441.     procedure SetVarValue(const Value: Variant);
  442.   public
  443.     destructor Destroy; override;
  444.     procedure Activate; virtual;
  445.     function AllEqual: Boolean; virtual;
  446.     function AutoFill: Boolean; virtual;
  447.     procedure Edit; virtual;
  448.     function GetAttributes: TPropertyAttributes; virtual;
  449.     function GetComponent(Index: Integer): TPersistent;
  450.     function GetEditLimit: Integer; virtual;
  451.     function GetName: string; virtual;
  452.     procedure GetProperties(Proc: TGetPropEditProc); virtual;
  453.     function GetPropType: PTypeInfo;
  454.     function GetValue: string; virtual;
  455.     function GetVisualValue: string;
  456.     procedure GetValues(Proc: TGetStrProc); virtual;
  457.     procedure Initialize; virtual;
  458.     procedure Revert;
  459.     procedure SetValue(const Value: string); virtual;
  460.     function ValueAvailable: Boolean;
  461.     procedure ListMeasureWidth(const Value: string; ACanvas: TCanvas;
  462.       var AWidth: Integer); dynamic;
  463.     procedure ListMeasureHeight(const Value: string; ACanvas: TCanvas;
  464.       var AHeight: Integer); dynamic;
  465.     procedure ListDrawValue(const Value: string; ACanvas: TCanvas;
  466.       const ARect: TRect; ASelected: Boolean); dynamic;
  467.     procedure PropDrawName(ACanvas: TCanvas; const ARect: TRect;
  468.       ASelected: Boolean); dynamic;
  469.     procedure PropDrawValue(ACanvas: TCanvas; const ARect: TRect;
  470.       ASelected: Boolean); dynamic;
  471.     property Designer: IFormDesigner;
  472.     property PrivateDirectory: string;
  473.     property PropCount: Integer;
  474.     property Value: string;
  475.   end;
  476.  
  477.   TPropertyEditorClass = class of TPropertyEditor;
  478.  
  479. { TOrdinalProperty
  480.   The base class of all ordinal property editors.  It established that ordinal
  481.   properties are all equal if the GetOrdValue all return the same value. }
  482.  
  483.   TOrdinalProperty = class(TPropertyEditor)
  484.     function AllEqual: Boolean; override;
  485.     function GetEditLimit: Integer; override;
  486.   end;
  487.  
  488. { TIntegerProperty
  489.   Default editor for all Longint properties and all subtypes of the Longint
  490.   type (i.e. Integer, Word, 1..10, etc.).  Restricts the value entered into
  491.   the property to the range of the sub-type. }
  492.  
  493.   TIntegerProperty = class(TOrdinalProperty)
  494.   public
  495.     function GetValue: string; override;
  496.     procedure SetValue(const Value: string); override;
  497.   end;
  498.  
  499. { TCharProperty
  500.   Default editor for all Char properties and sub-types of Char (i.e. Char,
  501.   'A'..'Z', etc.). }
  502.  
  503.   TCharProperty = class(TOrdinalProperty)
  504.   public
  505.     function GetValue: string; override;
  506.     procedure SetValue(const Value: string); override;
  507.   end;
  508.  
  509. { TEnumProperty
  510.   The default property editor for all enumerated properties (e.g. TShape =
  511.   (sCircle, sTriangle, sSquare), etc.). }
  512.  
  513.   TEnumProperty = class(TOrdinalProperty)
  514.   public
  515.     function GetAttributes: TPropertyAttributes; override;
  516.     function GetValue: string; override;
  517.     procedure GetValues(Proc: TGetStrProc); override;
  518.     procedure SetValue(const Value: string); override;
  519.   end;
  520.  
  521.   TBoolProperty = class(TEnumProperty)
  522.     function GetValue: string; override;
  523.     procedure GetValues(Proc: TGetStrProc); override;
  524.     procedure SetValue(const Value: string); override;
  525.   end;
  526.  
  527. { TInt64Property
  528.   Default editor for all Int64 properties and all subtypes of Int64.  }
  529.  
  530.   TInt64Property = class(TPropertyEditor)
  531.   public
  532.     function AllEqual: Boolean; override;
  533.     function GetEditLimit: Integer; override;
  534.     function GetValue: string; override;
  535.     procedure SetValue(const Value: string); override;
  536.   end;
  537.  
  538. { TFloatProperty
  539.   The default property editor for all floating point types (e.g. Float,
  540.   Single, Double, etc.) }
  541.  
  542.   TFloatProperty = class(TPropertyEditor)
  543.   public
  544.     function AllEqual: Boolean; override;
  545.     function GetValue: string; override;
  546.     procedure SetValue(const Value: string); override;
  547.   end;
  548.  
  549. { TStringProperty
  550.   The default property editor for all strings and sub types (e.g. string,
  551.   string[20], etc.). }
  552.  
  553.   TStringProperty = class(TPropertyEditor)
  554.   public
  555.     function AllEqual: Boolean; override;
  556.     function GetEditLimit: Integer; override;
  557.     function GetValue: string; override;
  558.     procedure SetValue(const Value: string); override;
  559.   end;
  560.  
  561. { TNestedProperty
  562.   A property editor that uses the parent's Designer, PropList and PropCount.
  563.   The constructor and destructor do not call inherited, but all derived classes
  564.   should.  This is useful for properties like the TSetElementProperty. }
  565.  
  566.   TNestedProperty = class(TPropertyEditor)
  567.   public
  568.     constructor Create(Parent: TPropertyEditor); reintroduce;
  569.     destructor Destroy; override;
  570.   end;
  571.  
  572. { TSetElementProperty
  573.   A property editor that edits an individual set element.  GetName is
  574.   changed to display the set element name instead of the property name and
  575.   Get/SetValue is changed to reflect the individual element state.  This
  576.   editor is created by the TSetProperty editor. }
  577.  
  578.   TSetElementProperty = class(TNestedProperty)
  579.   protected
  580.     constructor Create(Parent: TPropertyEditor; AElement: Integer); reintroduce;
  581.   public
  582.     function AllEqual: Boolean; override;
  583.     function GetAttributes: TPropertyAttributes; override;
  584.     function GetName: string; override;
  585.     function GetValue: string; override;
  586.     procedure GetValues(Proc: TGetStrProc); override;
  587.     procedure SetValue(const Value: string); override;
  588.    end;
  589.  
  590. { TSetProperty
  591.   Default property editor for all set properties. This editor does not edit
  592.   the set directly but will display sub-properties for each element of the
  593.   set. GetValue displays the value of the set in standard set syntax. }
  594.  
  595.   TSetProperty = class(TOrdinalProperty)
  596.   public
  597.     function GetAttributes: TPropertyAttributes; override;
  598.     procedure GetProperties(Proc: TGetPropEditProc); override;
  599.     function GetValue: string; override;
  600.   end;
  601.  
  602. { TClassProperty
  603.   Default property editor for all objects.  Does not allow modifying the
  604.   property but does display the class name of the object and will allow the
  605.   editing of the object's properties as sub-properties of the property. }
  606.  
  607.   TClassProperty = class(TPropertyEditor)
  608.   public
  609.     function GetAttributes: TPropertyAttributes; override;
  610.     procedure GetProperties(Proc: TGetPropEditProc); override;
  611.     function GetValue: string; override;
  612.   end;
  613.  
  614. { TMethodProperty
  615.   Property editor for all method properties. }
  616.  
  617.   TMethodProperty = class(TPropertyEditor)
  618.   public
  619.     function AllEqual: Boolean; override;
  620.     procedure Edit; override;
  621.     function GetAttributes: TPropertyAttributes; override;
  622.     function GetEditLimit: Integer; override;
  623.     function GetValue: string; override;
  624.     procedure GetValues(Proc: TGetStrProc); override;
  625.     procedure SetValue(const AValue: string); override;
  626.     function GetFormMethodName: string; virtual;
  627.     function GetTrimmedEventName: string;
  628.   end;
  629.  
  630. { TComponentProperty
  631.   The default editor for TComponents.  It does not allow editing of the
  632.   properties of the component.  It allow the user to set the value of this
  633.   property to point to a component in the same form that is type compatible
  634.   with the property being edited (e.g. the ActiveControl property). }
  635.  
  636.   TComponentProperty = class(TPropertyEditor)
  637.   public
  638.     procedure Edit; override;
  639.     function GetAttributes: TPropertyAttributes; override;
  640.     function GetEditLimit: Integer; override;
  641.     function GetValue: string; override;
  642.     procedure GetValues(Proc: TGetStrProc); override;
  643.     procedure SetValue(const Value: string); override;
  644.   end;
  645.  
  646. { TComponentNameProperty
  647.   Property editor for the Name property.  It restricts the name property
  648.   from being displayed when more than one component is selected. }
  649.  
  650.   TComponentNameProperty = class(TStringProperty)
  651.   public
  652.     function GetAttributes: TPropertyAttributes; override;
  653.     function GetEditLimit: Integer; override;
  654.   end;
  655.  
  656. { TFontNameProperty
  657.   Editor for the TFont.FontName property.  Displays a drop-down list of all
  658.   the fonts known by Windows.  The following global variable will make
  659.   this property editor actually show examples of each of the fonts in the
  660.   drop down list.  We would have enabled this by default but it takes
  661.   too many cycles on slower machines or those with a lot of fonts.  Enable
  662.   it at your own risk. ;-}
  663. var
  664.   FontNamePropertyDisplayFontNames: Boolean = False;
  665.  
  666. type
  667.   TFontNameProperty = class(TStringProperty)
  668.   public
  669.     function GetAttributes: TPropertyAttributes; override;
  670.     procedure GetValues(Proc: TGetStrProc); override;
  671.  
  672.     procedure ListMeasureHeight(const Value: string; ACanvas: TCanvas;
  673.       var AHeight: Integer); override;
  674.     procedure ListMeasureWidth(const Value: string; ACanvas: TCanvas;
  675.       var AWidth: Integer); override;
  676.     procedure ListDrawValue(const Value: string; ACanvas: TCanvas;
  677.       const ARect: TRect; ASelected: Boolean); override;
  678.   end;
  679.  
  680. { TFontCharsetProperty
  681.   Editor for the TFont.Charset property.  Displays a drop-down list of the
  682.   character-set by Windows.}
  683.  
  684.   TFontCharsetProperty = class(TIntegerProperty)
  685.   public
  686.     function GetAttributes: TPropertyAttributes; override;
  687.     function GetValue: string; override;
  688.     procedure GetValues(Proc: TGetStrProc); override;
  689.     procedure SetValue(const Value: string); override;
  690.   end;
  691.  
  692. { TImeNameProperty
  693.   Editor for the TImeName property.  Displays a drop-down list of all
  694.   the IME names known by Windows.}
  695.  
  696.   TImeNameProperty = class(TStringProperty)
  697.   public
  698.     function GetAttributes: TPropertyAttributes; override;
  699.     procedure GetValues(Proc: TGetStrProc); override;
  700.   end;
  701.  
  702. { TColorProperty
  703.   Property editor for the TColor type.  Displays the color as a clXXX value
  704.   if one exists, otherwise displays the value as hex.  Also allows the
  705.   clXXX value to be picked from a list. }
  706.  
  707.   TColorProperty = class(TIntegerProperty)
  708.   public
  709.     procedure Edit; override;
  710.     function GetAttributes: TPropertyAttributes; override;
  711.     function GetValue: string; override;
  712.     procedure GetValues(Proc: TGetStrProc); override;
  713.     procedure SetValue(const Value: string); override;
  714.  
  715.     procedure ListMeasureWidth(const Value: string; ACanvas: TCanvas;
  716.       var AWidth: Integer); override;
  717.     procedure ListDrawValue(const Value: string; ACanvas: TCanvas;
  718.       const ARect: TRect; ASelected: Boolean); override;
  719.     procedure PropDrawValue(ACanvas: TCanvas; const ARect: TRect;
  720.       ASelected: Boolean); override;
  721.   end;
  722.  
  723. { TBrushStyleProperty
  724.   Property editor for TBrush's Style.  Simply provides for custom render. }
  725.  
  726.   TBrushStyleProperty = class(TEnumProperty)
  727.   public
  728.     procedure ListMeasureWidth(const Value: string; ACanvas: TCanvas;
  729.       var AWidth: Integer); override;
  730.     procedure ListDrawValue(const Value: string; ACanvas: TCanvas;
  731.       const ARect: TRect; ASelected: Boolean); override;
  732.     procedure PropDrawValue(ACanvas: TCanvas; const ARect: TRect;
  733.       ASelected: Boolean); override;
  734.   end;
  735.  
  736. { TPenStyleProperty
  737.   Property editor for TPen's Style.  Simply provides for custom render. }
  738.  
  739.   TPenStyleProperty = class(TEnumProperty)
  740.   public
  741.     procedure ListMeasureWidth(const Value: string; ACanvas: TCanvas;
  742.       var AWidth: Integer); override;
  743.     procedure ListDrawValue(const Value: string; ACanvas: TCanvas;
  744.       const ARect: TRect; ASelected: Boolean); override;
  745.     procedure PropDrawValue(ACanvas: TCanvas; const ARect: TRect;
  746.       ASelected: Boolean); override;
  747.   end;
  748.  
  749. { TCursorProperty
  750.   Property editor for the TCursor type.  Displays the cursor as a clXXX value
  751.   if one exists, otherwise displays the value as hex.  Also allows the
  752.   clXXX value to be picked from a list. }
  753.  
  754.   TCursorProperty = class(TIntegerProperty)
  755.   public
  756.     function GetAttributes: TPropertyAttributes; override;
  757.     function GetValue: string; override;
  758.     procedure GetValues(Proc: TGetStrProc); override;
  759.     procedure SetValue(const Value: string); override;
  760.     procedure ListMeasureHeight(const Value: string; ACanvas: TCanvas;
  761.       var AHeight: Integer); override;
  762.     procedure ListMeasureWidth(const Value: string; ACanvas: TCanvas;
  763.       var AWidth: Integer); override;
  764.     procedure ListDrawValue(const Value: string; ACanvas: TCanvas;
  765.       const ARect: TRect; ASelected: Boolean); override;
  766.   end;
  767.  
  768. { TFontProperty
  769.   Property editor for the Font property.  Brings up the font dialog as well as
  770.   allowing the properties of the object to be edited. }
  771.  
  772.   TFontProperty = class(TClassProperty)
  773.   public
  774.     procedure Edit; override;
  775.     function GetAttributes: TPropertyAttributes; override;
  776.   end;
  777.  
  778. { TModalResultProperty }
  779.  
  780.   TModalResultProperty = class(TIntegerProperty)
  781.   public
  782.     function GetAttributes: TPropertyAttributes; override;
  783.     function GetValue: string; override;
  784.     procedure GetValues(Proc: TGetStrProc); override;
  785.     procedure SetValue(const Value: string); override;
  786.   end;
  787.  
  788. { TShortCutProperty
  789.   Property editor the ShortCut property.  Allows both typing in a short
  790.   cut value or picking a short-cut value from a list. }
  791.  
  792.   TShortCutProperty = class(TOrdinalProperty)
  793.   public
  794.     function GetAttributes: TPropertyAttributes; override;
  795.     function GetValue: string; override;
  796.     procedure GetValues(Proc: TGetStrProc); override;
  797.     procedure SetValue(const Value: string); override;
  798.   end;
  799.  
  800. { TMPFilenameProperty
  801.   Property editor for the TMediaPlayer.  Displays an File Open Dialog
  802.   for the name of the media file.}
  803.  
  804.   TMPFilenameProperty = class(TStringProperty)
  805.   public
  806.     procedure Edit; override;
  807.     function GetAttributes: TPropertyAttributes; override;
  808.   end;
  809.  
  810. { TTabOrderProperty
  811.   Property editor for the TabOrder property.  Prevents the property from being
  812.   displayed when more than one component is selected. }
  813.  
  814.   TTabOrderProperty = class(TIntegerProperty)
  815.   public
  816.     function GetAttributes: TPropertyAttributes; override;
  817.   end;
  818.  
  819. { TCaptionProperty
  820.   Property editor for the Caption and Text properties.  Updates the value of
  821.   the property for each change instead on when the property is approved. }
  822.  
  823.   TCaptionProperty = class(TStringProperty)
  824.   public
  825.     function GetAttributes: TPropertyAttributes; override;
  826.   end;
  827.  
  828. { TDateProperty
  829.   Property editor for date portion of TDateTime type. }
  830.  
  831.   TDateProperty = class(TPropertyEditor)
  832.     function GetAttributes: TPropertyAttributes; override;
  833.     function GetValue: string; override;
  834.     procedure SetValue(const Value: string); override;
  835.   end;
  836.  
  837. { TTimeProperty
  838.   Property editor for time portion of TDateTime type. }
  839.  
  840.   TTimeProperty = class(TPropertyEditor)
  841.     function GetAttributes: TPropertyAttributes; override;
  842.     function GetValue: string; override;
  843.     procedure SetValue(const Value: string); override;
  844.   end;
  845.  
  846. { TDateTimeProperty
  847.   Edits both date and time data... simultaneously!  }
  848.  
  849.   TDateTimeProperty = class(TPropertyEditor)
  850.     function GetAttributes: TPropertyAttributes; override;
  851.     function GetValue: string; override;
  852.     procedure SetValue(const Value: string); override;
  853.   end;
  854.  
  855. { TComponentEditor
  856.   A component editor is created for each component that is selected in the
  857.   form designer based on the component's type (see GetComponentEditor and
  858.   RegisterComponentEditor).  When the component is double-clicked the Edit
  859.   method is called.  When the context menu for the component is invoked the
  860.   GetVerbCount and GetVerb methods are called to build the menu.  If one
  861.   of the verbs are selected ExecuteVerb is called.  Paste is called whenever
  862.   the component is pasted to the clipboard.  You only need to create a
  863.   component editor if you wish to add verbs to the context menu, change
  864.   the default double-click behavior, or paste an additional clipboard format.
  865.   The default component editor (TDefaultEditor) implements Edit to searches the
  866.   properties of the component and generates (or navigates to) the OnCreate,
  867.   OnChanged, or OnClick event (whichever it finds first).  Whenever the
  868.   component modifies the component is *must* call Designer.Modified to inform
  869.   the designer that the form has been modified.
  870.  
  871.     Create(AComponent, ADesigner)
  872.       Called to create the component editor.  AComponent is the component to
  873.       be edited by the editor.  ADesigner is an interface to the designer to
  874.       find controls and create methods (this is not use often).
  875.     Edit
  876.       Called when the user double-clicks the component. The component editor can
  877.       bring up a dialog in response to this method, for example, or some kind
  878.       of design expert.  If GetVerbCount is greater than zero, edit will execute
  879.       the first verb in the list (ExecuteVerb(0)).
  880.     ExecuteVerb(Index)
  881.       The Index'ed verb was selected by the use off the context menu.  The
  882.       meaning of this is determined by component editor.
  883.     GetVerb
  884.       The component editor should return a string that will be displayed in the
  885.       context menu.  It is the responsibility of the component editor to place
  886.       the & character and the '...' characters as appropriate.
  887.     GetVerbCount
  888.       The number of valid indices to GetVerb and Execute verb.  The index is assumed
  889.       to be zero based (i.e. 0..GetVerbCount - 1).
  890.     PrepareItem
  891.       While constructing the context menu PrepareItem will be called for
  892.       each verb.  It will be passed the menu item that will be used to represent
  893.       the verb.  The component editor can customize the menu item as it sees fit,
  894.       including adding subitems.  If you don't want that particular menu item
  895.       to be shown, don't free it, simply set its Visible property to False.
  896.     Copy
  897.       Called when the component is being copied to the clipboard.  The
  898.       component's filed image is already on the clipboard.  This gives the
  899.       component editor a chance to paste a different type of format which is
  900.       ignored by the designer but might be recognized by another application.
  901.     IsInInlined
  902.       Determines whether Component is in the Designer which owns it.  Essentially,
  903.       Components should not be able to be added to a Frame instance (collections
  904.       are fine though) so this function checks to determine whether the currently
  905.       selected component is within a Frame instance or not.
  906.     }
  907.  
  908.   IComponentEditor = interface
  909.     ['{ABBE7252-5495-11D1-9FB5-0020AF3D82DA}']
  910.     procedure Edit;
  911.     procedure ExecuteVerb(Index: Integer);
  912.     function GetIComponent: IComponent;
  913.     function GetDesigner: IFormDesigner;
  914.     function GetVerb(Index: Integer): string;
  915.     function GetVerbCount: Integer;
  916.     procedure PrepareItem(Index: Integer; const AItem: TMenuItem);
  917.     procedure Copy;
  918.   end;
  919.  
  920.   TComponentEditor = class(TInterfacedObject, IComponentEditor)
  921.   public
  922.     constructor Create(AComponent: TComponent; ADesigner: IFormDesigner); virtual;
  923.     procedure Edit; virtual;
  924.     procedure ExecuteVerb(Index: Integer); virtual;
  925.     function GetIComponent: IComponent;
  926.     function GetDesigner: IFormDesigner;
  927.     function GetVerb(Index: Integer): string; virtual;
  928.     function GetVerbCount: Integer; virtual;
  929.     function IsInInlined: Boolean;
  930.     procedure PrepareItem(Index: Integer; const AItem: TMenuItem); virtual;
  931.     procedure Copy; virtual;
  932.     property Component: TComponent;
  933.     property Designer: IFormDesigner;
  934.   end;
  935.  
  936.   TComponentEditorClass = class of TComponentEditor;
  937.  
  938.   IDefaultEditor = interface(IComponentEditor)
  939.     ['{5484FAE1-5C60-11D1-9FB6-0020AF3D82DA}']
  940.   end;
  941.  
  942.   TDefaultEditor = class(TComponentEditor, IDefaultEditor)
  943.   protected
  944.     procedure EditProperty(PropertyEditor: TPropertyEditor;
  945.       var Continue, FreeEditor: Boolean); virtual;
  946.   public
  947.     procedure Edit; override;
  948.   end;
  949.  
  950. { Global variables initialized internally by the form designer }
  951.  
  952. type
  953.   TFreeCustomModulesProc = procedure (Group: Integer);
  954.  
  955. var
  956.   FreeCustomModulesProc: TFreeCustomModulesProc;
  957.  
  958. { RegisterPropertyEditor
  959.   Registers a new property editor for the given type.  When a component is
  960.   selected the Object Inspector will create a property editor for each
  961.   of the component's properties.  The property editor is created based on
  962.   the type of the property.  If, for example, the property type is an
  963.   Integer, the property editor for Integer will be created (by default
  964.   that would be TIntegerProperty). Most properties do not need specialized
  965.   property editors.  For example, if the property is an ordinal type the
  966.   default property editor will restrict the range to the ordinal subtype
  967.   range (e.g. a property of type TMyRange = 1..10 will only allow values
  968.   between 1 and 10 to be entered into the property).  Enumerated types will
  969.   display a drop-down list of all the enumerated values (e.g. TShapes =
  970.   (sCircle, sSquare, sTriangle) will be edited by a drop-down list containing
  971.   only sCircle, sSquare and sTriangle).  A property editor need only be
  972.   created if default property editor or none of the existing property editors
  973.   are sufficient to edit the property.  This is typically because the
  974.   property is an object.  The properties are looked up newest to oldest.
  975.   This allows and existing property editor replaced by a custom property
  976.   editor.
  977.  
  978.     PropertyType
  979.       The type information pointer returned by the TypeInfo built-in function
  980.       (e.g. TypeInfo(TMyRange) or TypeInfo(TShapes)).
  981.  
  982.     ComponentClass
  983.       Type of the component to which to restrict this type editor.  This
  984.       parameter can be left nil which will mean this type editor applies to all
  985.       properties of PropertyType.
  986.  
  987.     PropertyName
  988.       The name of the property to which to restrict this type editor.  This
  989.       parameter is ignored if ComponentClass is nil.  This parameter can be
  990.       an empty string ('') which will mean that this editor applies to all
  991.       properties of PropertyType in ComponentClass.
  992.  
  993.     EditorClass
  994.       The class of the editor to be created whenever a property of the type
  995.       passed in PropertyTypeInfo is displayed in the Object Inspector.  The
  996.       class will be created by calling EditorClass.Create. }
  997.  
  998. procedure RegisterPropertyEditor(PropertyType: PTypeInfo; ComponentClass: TClass;
  999.   const PropertyName: string; EditorClass: TPropertyEditorClass);
  1000.  
  1001. type
  1002.   TPropertyMapperFunc = function(Obj: TPersistent;
  1003.     PropInfo: PPropInfo): TPropertyEditorClass;
  1004.  
  1005. procedure RegisterPropertyMapper(Mapper: TPropertyMapperFunc);
  1006.  
  1007. procedure GetComponentProperties(Components: TDesignerSelectionList;
  1008.   Filter: TTypeKinds; Designer: IFormDesigner; Proc: TGetPropEditProc);
  1009.  
  1010. procedure RegisterComponentEditor(ComponentClass: TComponentClass;
  1011.   ComponentEditor: TComponentEditorClass);
  1012.  
  1013. function GetComponentEditor(Component: TComponent;
  1014.   Designer: IFormDesigner): TComponentEditor;
  1015.  
  1016. { Custom modules }
  1017. { A custom module allows containers that descend from classes other than TForm
  1018.   to be created and edited by the form designer. This is useful for other form
  1019.   like containers (e.g. a report designer) or for specialized forms (e.g. an
  1020.   ActiveForm) or for generic component containers (e.g. a TDataModule). It is
  1021.   assumed that the base class registered will call InitInheritedComponent in its
  1022.   constructor which will initialize the component from the associated DFM file
  1023.   stored in the programs resources. See the constructors of TDataModule and
  1024.   TForm for examples of how to write such a constructor.
  1025.  
  1026.   The following designer assumptions are made, depending on the base components
  1027.   ancestor,
  1028.  
  1029.     If ComponentBaseClass descends from TForm,
  1030.  
  1031.        it is designed by creating an instance of the component as the form.
  1032.        Allows designing TForm descendants and modifying their properties as
  1033.        well as the form properties
  1034.  
  1035.     If ComponentBaseClass descends from TWinControl (but not TForm),
  1036.  
  1037.        it is designed by creating an instance of the control, placing it into a
  1038.        design-time form.  The form's client size is the default size of the
  1039.        control.
  1040.  
  1041.     If ComponentBaseClass descends from TDataModule,
  1042.  
  1043.        it is designed by creating an instance of the class and creating a
  1044.        special non-visual container designer to edit the components and display
  1045.        the icons of the contained components.
  1046.  
  1047.   The module will appear in the project file with a colon and the base class
  1048.   name appended after the component name (e.g. MyDataModule: TDataModule).
  1049.  
  1050.   Note it is not legal to register anything that does not descend from one of
  1051.   the above.
  1052.  
  1053.   TCustomModule class
  1054.     An instance of this class is created for each custom module that is
  1055.     loaded. This class is also destroyed whenever the module is unloaded.
  1056.     The Saving method is called prior to the file being saved. When the context
  1057.     menu for the module is invoked the GetVerbCount and GetVerb methods are
  1058.     called to build the menu.  If one of the verbs is selected ExecuteVerb is
  1059.     called.
  1060.     
  1061.     ExecuteVerb(Index)
  1062.       The Index'ed verb was selected by the use off the context menu.  The
  1063.       meaning of this is determined by custom module.
  1064.     GetAttributes
  1065.       cmaVirtualSize:  For TWinControl objects only: including this attribute makes
  1066.         the control "client aligned" in the design window.  Without this
  1067.         attribute, the object is sized independently from the design window.
  1068.       Attributes are a set to allow for future expansion of features.
  1069.     GetVerb(Index)
  1070.       The custom module should return a string that will be displayed in the
  1071.       context menu.  It is the responsibility of the custom module to place
  1072.       the & character and the '...' characters as appropriate.
  1073.     GetVerbCount
  1074.       The number of valid indexs to GetVerb and Execute verb.  The index assumed
  1075.       to be zero based (i.e. 0..GetVerbCount - 1).
  1076.     PrepareItem
  1077.       While constructing the context menu PrepareItem will be called for
  1078.       each verb.  It will be passed the menu item that will be used to represent
  1079.       the verb.  The module editor can customize the menu item as it sees fit,
  1080.       including adding subitems.  If you don't want that particular menu item
  1081.       to be shown don't free it, simply set it's Visible property to False.
  1082.     Saving
  1083.       Called prior to the module being saved.
  1084.     ValidateComponent(Component)
  1085.       ValidateComponent is called whenever a component is created by the
  1086.       user for the designer to contain.  The intent is for this procedure to
  1087.       raise an exception with a descriptive message if the component is not
  1088.       applicable for the container. For example, a TComponent module should
  1089.       throw an exception if the component descends from TControl.
  1090.     Root
  1091.       This is the instance being designed.}
  1092.  
  1093. type
  1094.   TCustomModuleAttribute = (cmaVirtualSize);
  1095.   TCustomModuleAttributes = set of TCustomModuleAttribute;
  1096.  
  1097.   TCustomModule = class
  1098.   public
  1099.     constructor Create(ARoot: IComponent); virtual;
  1100.     procedure ExecuteVerb(Index: Integer); virtual;
  1101.     function CreateDesignerForm(Designer: IDesigner): TCustomForm; virtual;
  1102.     function GetAttributes: TCustomModuleAttributes; virtual;
  1103.     function GetVerb(Index: Integer): string; virtual;
  1104.     function GetVerbCount: Integer; virtual;
  1105.     procedure PrepareItem(Index: Integer; const AItem: TMenuItem); virtual;
  1106.     procedure Saving; virtual;
  1107.     procedure ValidateComponent(Component: IComponent); virtual;
  1108.     class function Nestable: Boolean; virtual;
  1109.     property Root: IComponent;
  1110.   end;
  1111.  
  1112.   TCustomModuleClass = class of TCustomModule;
  1113.  
  1114.   TRegisterCustomModuleProc = procedure (Group: Integer;
  1115.     ComponentBaseClass: TComponentClass;
  1116.     CustomModuleClass: TCustomModuleClass);
  1117.  
  1118.   ICustomModuleSettings = interface
  1119.     ['{50947DAD-E627-11D2-B728-00C04FA35D12}']
  1120.     function IniSection: string;
  1121.   end;
  1122.  
  1123.   ICustomModuleProjectSettings = interface(ICustomModuleSettings)
  1124.     ['{78E12CC2-DBCC-11D2-B727-00C04FA35D12}']
  1125.     procedure SaveProjectState(AFile: TMemIniFile);
  1126.     procedure LoadProjectState(AFile: TMemIniFile);
  1127.   end;
  1128.  
  1129.   ICustomModuleUnitSettings = interface(ICustomModuleSettings)
  1130.     ['{78E12CC1-DBCC-11D2-B727-00C04FA35D12}']
  1131.     procedure SaveUnitState(AFile: TMemIniFile);
  1132.     procedure LoadUnitState(AFile: TMemIniFile);
  1133.   end;
  1134.  
  1135.   IDesignerPersistence = interface
  1136.     ['{D32194C2-EECF-11D2-AAD2-00C04FB16FBC}']
  1137.     procedure Save(const Stream: IStream);
  1138.     procedure Load(const Stream: IStream);
  1139.   end;
  1140.  
  1141. procedure RegisterCustomModule(ComponentBaseClass: TComponentClass;
  1142.   CustomModuleClass: TCustomModuleClass);
  1143.  
  1144. var
  1145.   RegisterCustomModuleProc: TRegisterCustomModuleProc;
  1146.  
  1147. { Routines used by the form designer for package management }
  1148.  
  1149. type
  1150.   TGroupChangeProc = procedure(AGroup: Integer);
  1151.   
  1152. function NewEditorGroup: Integer;
  1153. procedure FreeEditorGroup(Group: Integer);
  1154. procedure NotifyGroupChange(AProc: TGroupChangeProc);
  1155. procedure UnNotifyGroupChange(AProc: TGroupChangeProc);
  1156.  
  1157. var  // number of significant characters in identifiers
  1158.   MaxIdentLength: Byte = 63;
  1159.  
  1160. { Property Categories Classes
  1161.   The following three components make up the category management system.
  1162.   Access to them is usually managed by the following support functions.
  1163.  
  1164.   TPropertyCategoryList
  1165.     Contains and maintains the list of TPropertyCategories.  There are numerous
  1166.     'As a whole' access and manipulation methods for categories as well as
  1167.     simplified access functions.
  1168.   TPropertyCategory
  1169.     Contains and maintains the list of TPropertyFilters.  There are numerous
  1170.     'As a whole' access and manipulation methods for filters as well as data
  1171.     about the category itself.
  1172.   TPropertyFilter
  1173.     Maintains the information about a single filter associated with a particular
  1174.     category.  Along with its filter specific data it also encapsulates the
  1175.     matching algorithm. }
  1176.  
  1177. type
  1178.   TPropertyFilter = class(TObject)
  1179.   public
  1180.     constructor Create(const APropertyName: String; AComponentClass: TClass;
  1181.       APropertyType: PTypeInfo);
  1182.     destructor Destroy; override;
  1183.     function Match(const APropertyName: String; AComponentClass: TClass;
  1184.       APropertyType: PTypeInfo): Boolean;
  1185.     property ComponentClass: TClass;
  1186.     property PropertyType: PTypeInfo;
  1187.   end;
  1188.  
  1189.   TPropertyCategoryClass = class of TPropertyCategory;
  1190.   TPropertyCategory = class(TObject)
  1191.   protected
  1192.     function GetFilter(Index: Integer): TPropertyFilter;
  1193.   public
  1194.     constructor Create;
  1195.     destructor Destroy; override;
  1196.     function Add(AFilter: TPropertyFilter): TPropertyFilter;
  1197.     function Count: integer;
  1198.     function Match(const APropertyName: String; AComponentClass: TClass;
  1199.       APropertyType: PTypeInfo): Boolean;
  1200.     procedure ClearMatches;
  1201.     procedure FreeEditorGroup(AGroup: Integer);
  1202.     class function Name: string; virtual;
  1203.     class function Description: string; virtual;
  1204.     procedure PropDraw(ACanvas: TCanvas; const ARect: TRect;
  1205.       ASelected: Boolean); dynamic;
  1206.     property Filters[Index: Integer]: TPropertyFilter;
  1207.     property MatchCount: Integer;
  1208.     property Visible: Boolean;
  1209.     property Editor: TPropertyEditor;
  1210.   end;
  1211.  
  1212.   TPropertyCategoryVisibleMode = (pcvAll, pcvToggle, pcvNone, pcvNotListed, pcvOnlyListed);
  1213.   TPropertyCategoryList = class(TObject)
  1214.   protected
  1215.     function GetCategory(Index: Integer): TPropertyCategory;
  1216.     function GetHiddenCategories: string;
  1217.     procedure SetHiddenCategories(const Value: string);
  1218.   public
  1219.     constructor Create;
  1220.     destructor Destroy; override;
  1221.     function FindCategory(ACategoryClass: TPropertyCategoryClass): TPropertyCategory;
  1222.     function IndexOf(ACategoryClass: TPropertyCategoryClass): Integer; overload;
  1223.     function IndexOf(const ACategoryName: string): Integer; overload;
  1224.     procedure ClearMatches;
  1225.     procedure FreeEditorGroup(AGroup: Integer);
  1226.     function MiscCategory: TPropertyCategory;
  1227.     function Count: integer;
  1228.     function Match(const APropertyName: String; AComponentClass: TClass;
  1229.       APropertyType: PTypeInfo = nil): Boolean;
  1230.     function ChangeVisibility(AMode: TPropertyCategoryVisibleMode): Boolean; overload;
  1231.     function ChangeVisibility(AMode: TPropertyCategoryVisibleMode;
  1232.       const AClasses: array of TClass): Boolean; overload;
  1233.     property HiddenCategories: string;
  1234.     property Categories[Index: Integer]: TPropertyCategory; default;
  1235.   end;
  1236.  
  1237. { Property Categories Helpers
  1238.  
  1239.   RegisterPropertyInCategory
  1240.     This function comes in four flavors, each taking slightly different set of
  1241.     arguments.  You can specify a category filter by property name; by class
  1242.     type and property name; by property type and property name; and finally
  1243.     just by property type.  Additionally property name may include wild card
  1244.     symbols.  For example: you can add all properties that match 'Data*' to
  1245.     a particular category.  For a full list of what wild card characters
  1246.     are available please refer to the TMask class documentation.
  1247.   RegisterPropertiesInCategory
  1248.     This function will allow you to register a series of property names and/or
  1249.     property types filters in a single statement.
  1250.   IsPropertyInCategory
  1251.     This function comes in two flavors, each taking a slightly different set of
  1252.     arguments.  But in either case you can ask if a property of a certain class
  1253.     falls under the specified category.  The class can be specified by name or
  1254.     by class type.
  1255.   PropertyCategoryList
  1256.     This function will return, and create if necessary, the global property
  1257.     category list.}
  1258.  
  1259. function RegisterPropertyInCategory(ACategoryClass: TPropertyCategoryClass;
  1260.   const APropertyName: string): TPropertyFilter; overload;
  1261. function RegisterPropertyInCategory(ACategoryClass: TPropertyCategoryClass;
  1262.   AComponentClass: TClass; const APropertyName: string): TPropertyFilter; overload;
  1263. function RegisterPropertyInCategory(ACategoryClass: TPropertyCategoryClass;
  1264.   APropertyType: PTypeInfo; const APropertyName: string): TPropertyFilter; overload;
  1265. function RegisterPropertyInCategory(ACategoryClass: TPropertyCategoryClass;
  1266.   APropertyType: PTypeInfo): TPropertyFilter; overload;
  1267.  
  1268. function RegisterPropertiesInCategory(ACategoryClass: TPropertyCategoryClass;
  1269.   const AFilters: array of const): TPropertyCategory; overload;
  1270. function RegisterPropertiesInCategory(ACategoryClass: TPropertyCategoryClass;
  1271.   AComponentClass: TClass; const AFilters: array of string): TPropertyCategory; overload;
  1272. function RegisterPropertiesInCategory(ACategoryClass: TPropertyCategoryClass;
  1273.   APropertyType: PTypeInfo; const AFilters: array of string): TPropertyCategory; overload;
  1274.  
  1275. function IsPropertyInCategory(ACategoryClass: TPropertyCategoryClass;
  1276.   AComponentClass: TClass; const APropertyName: String): Boolean; overload;
  1277. function IsPropertyInCategory(ACategoryClass: TPropertyCategoryClass;
  1278.   const AClassName: string; const APropertyName: String): Boolean; overload;
  1279.  
  1280. function PropertyCategoryList: TPropertyCategoryList;
  1281.  
  1282. { Property Categories
  1283.   The following class defines the standard categories used by Delphi.  These are
  1284.   general purpose and can be used by component developers for property category
  1285.   registration.  Additionally component developers can create new descedents of
  1286.   TPropertyCategory to add completly new categories. }
  1287.  
  1288. type
  1289.   TActionCategory = class(TPropertyCategory)
  1290.   public
  1291.     class function Name: string; override;
  1292.     class function Description: string; override;
  1293.   end;
  1294.  
  1295.   TDataCategory = class(TPropertyCategory)
  1296.   public
  1297.     class function Name: string; override;
  1298.     class function Description: string; override;
  1299.   end;
  1300.  
  1301.   TDatabaseCategory = class(TPropertyCategory)
  1302.   public
  1303.     class function Name: string; override;
  1304.     class function Description: string; override;
  1305.   end;
  1306.  
  1307.   TDragNDropCategory = class(TPropertyCategory)
  1308.   public
  1309.     class function Name: string; override;
  1310.     class function Description: string; override;
  1311.   end;
  1312.  
  1313.   THelpCategory = class(TPropertyCategory)
  1314.   public
  1315.     class function Name: string; override;
  1316.     class function Description: string; override;
  1317.   end;
  1318.  
  1319.   TLayoutCategory = class(TPropertyCategory)
  1320.   public
  1321.     class function Name: string; override;
  1322.     class function Description: string; override;
  1323.   end;
  1324.  
  1325.   TLegacyCategory = class(TPropertyCategory)
  1326.   public
  1327.     class function Name: string; override;
  1328.     class function Description: string; override;
  1329.   end;
  1330.  
  1331.   TLinkageCategory = class(TPropertyCategory)
  1332.   public
  1333.     class function Name: string; override;
  1334.     class function Description: string; override;
  1335.   end;
  1336.  
  1337.   TLocaleCategory = class(TPropertyCategory)
  1338.   public
  1339.     class function Name: string; override;
  1340.     class function Description: string; override;
  1341.   end;
  1342.  
  1343.   TLocalizableCategory = class(TPropertyCategory)
  1344.   public
  1345.     class function Name: string; override;
  1346.     class function Description: string; override;
  1347.   end;
  1348.  
  1349.   TMiscellaneousCategory = class(TPropertyCategory)
  1350.   public
  1351.     class function Name: string; override;
  1352.     class function Description: string; override;
  1353.   end;
  1354.  
  1355.   TVisualCategory = class(TPropertyCategory)
  1356.   public
  1357.     class function Name: string; override;
  1358.     class function Description: string; override;
  1359.   end;
  1360.  
  1361.   TInputCategory = class(TPropertyCategory)
  1362.   public
  1363.     class function Name: string; override;
  1364.     class function Description: string; override;
  1365.   end;
  1366.  
  1367. var
  1368.   BaseRegistryKey: string = '';
  1369.  
  1370. implementation
  1371.