{*******************************************************************} { } { Developer Express Visual Component Library } { ExpressBars registring unit } { } { Copyright (c) 1998-2007 Developer Express Inc. } { ALL RIGHTS RESERVED } { } { The entire contents of this file is protected by U.S. and } { International Copyright Laws. Unauthorized reproduction, } { reverse-engineering, and distribution of all or any portion of } { the code contained in this file is strictly prohibited and may } { result in severe civil and criminal penalties and will be } { prosecuted to the maximum extent possible under the law. } { } { RESTRICTIONS } { } { THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES } { (DCU, OBJ, DLL, ETC.) ARE CONFIDENTIAL AND PROPRIETARY TRADE } { SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS } { LICENSED TO DISTRIBUTE THE EXPRESSBARS AND ALL ACCOMPANYING VCL } { CONTROLS AS PART OF AN EXECUTABLE PROGRAM ONLY. } { } { THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED } { FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE } { COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE } { AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT } { AND PERMISSION FROM DEVELOPER EXPRESS INC. } { } { CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON } { ADDITIONAL RESTRICTIONS. } { } {*******************************************************************} unit dxBarReg; {$I cxVer.inc} interface uses ImgList, {$IFDEF DELPHI6} DesignEditors, DesignIntf, DesignMenus, VCLEditors, {$ELSE} DsgnIntf, Menus, {$ENDIF} Windows, Classes, Controls, Graphics, cxDesignWindows, dxBar, Contnrs, cxLibraryReg, cxPropEditors; const dxBarVersion = '6.26'; type TdxBarItemImageIndexProperty = class(TImageIndexProperty) private function GetBarManager: TdxBarManager; protected property BarManager: TdxBarManager read GetBarManager; public function GetImages: TCustomImageList; override; end; TdxBarItemLargeImageIndexProperty = class(TdxBarItemImageIndexProperty) public function GetImages: TCustomImageList; override; end; procedure HideClassProperties(AClass: TClass; APropertyNames: array of string); procedure Register; implementation {$R dxBarDesignWindow.dfm} uses Messages, SysUtils, Forms, Dialogs, TypInfo, EditIntf, dxBarCustForm, dxBarPopupMenuEd, dxBarStrs, dxRegEd, cxClasses, cxComponentCollectionEditor; type TdxBarManagerAccess = class(TdxBarManager); { TdxBarDesignHelper } TdxBarDesignHelper = class(TcxDesignHelper, IdxBarDesigner) private FRefCount: Integer; protected function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall; function _AddRef: Integer; stdcall; function _Release: Integer; stdcall; public // IdxBarDesigner function CanDeleteComponent(AComponent: TComponent): Boolean; procedure GetSelection(AList: TList); function GetSelectionStatus(AComponent: TPersistent): TdxBarSelectionStatus; function IsComponentSelected(AComponent: TPersistent): Boolean; procedure SelectComponent(AComponent: TPersistent; ASelectionOperation: TdxBarSelectionOperation = soExclusive); procedure SetSelection(AList: TList); procedure ShowDefaultEventHandler(AItem: TdxBarItem); function UniqueName(const BaseName: string): string; end; { TdxBarDesignWindow } TdxBarDesignWindow = class(TcxDesignWindow) private FActiveDesigner: IDesigner; // FCurrentSelectionList: TComponentList; FCurrentSelectionList: TObjectList; FOnSelectionChanged: TdxNotifyEvent; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; function IsComponentSelected(AComponent: TPersistent): Boolean; procedure Notification(AComponent: TComponent; Operation: TOperation); override; {$IFNDEF DELPHI6} procedure ComponentDeleted(Component: IPersistent); override; procedure SelectionChanged(ASelection: TDesignerSelectionList); override; {$ELSE} procedure ItemDeleted(const ADesigner: IDesigner; Item: TPersistent); override; procedure SelectionChanged(const ADesigner: IDesigner; const ASelection: TDesignerSelectionList); override; {$ENDIF} procedure SelectionsChanged(const ASelection: TDesignerSelectionList); override; property ActiveDesigner: IDesigner read FActiveDesigner; property OnSelectionChanged: TdxNotifyEvent read FOnSelectionChanged write FOnSelectionChanged; end; var FdxBarDesignWindow: TdxBarDesignWindow; { TdxBarDesignHelper } function TdxBarDesignHelper.CanDeleteComponent(AComponent: TComponent): Boolean; begin Result := cxDesignWindows.CanDeleteComponent(Component, AComponent, Designer); end; procedure TdxBarDesignHelper.GetSelection(AList: TList); begin inherited GetSelection(AList); end; function TdxBarDesignHelper.GetSelectionStatus(AComponent: TPersistent): TdxBarSelectionStatus; begin if FdxBarDesignWindow.IsComponentSelected(AComponent) then Result := ssActiveSelected else if IsComponentSelected(AComponent) then Result := ssInactiveSelected else Result := ssUnselected; end; function TdxBarDesignHelper.IsComponentSelected(AComponent: TPersistent): Boolean; begin Result := IsObjectSelected(AComponent); end; procedure TdxBarDesignHelper.SelectComponent(AComponent: TPersistent; ASelectionOperation: TdxBarSelectionOperation = soExclusive); begin case ASelectionOperation of soAdd: SelectObject(AComponent, False); soExclude: UnselectObject(AComponent); soExclusive: SelectObject(AComponent, True, False); end; end; procedure TdxBarDesignHelper.SetSelection(AList: TList); begin inherited SetSelection(AList); end; procedure TdxBarDesignHelper.ShowDefaultEventHandler(AItem: TdxBarItem); var APropInfo: PPropInfo; AMethod: TMethod; AMethodName: string; begin APropInfo := GetPropInfo(AItem.ClassInfo, 'OnChange'); if APropInfo = nil then begin APropInfo := GetPropInfo(AItem.ClassInfo, 'OnClick'); if APropInfo = nil then Exit else AMethodName := 'Click'; end else AMethodName := 'Change'; AMethod := GetMethodProp(AItem, APropInfo); if AMethod.Code <> nil then AMethodName := Designer.GetMethodName(AMethod) else begin AMethodName := AItem.Name + AMethodName; AMethod := Designer.CreateMethod(AMethodName, GetTypeData(APropInfo^.PropType^)); SetMethodProp(AItem, APropInfo, AMethod); Designer.Modified; end; Designer.ShowMethod(AMethodName); end; function TdxBarDesignHelper.UniqueName(const BaseName: string): string; begin Result := Designer.UniqueName(BaseName); end; function TdxBarDesignHelper.QueryInterface(const IID: TGUID; out Obj): HResult; stdcall; begin if GetInterface(IID, Obj) then Result := 0 else Result := E_NOINTERFACE; end; function TdxBarDesignHelper._AddRef: Integer; stdcall; begin Result := InterlockedIncrement(FRefCount); end; function TdxBarDesignHelper._Release: Integer; stdcall; begin Result := InterlockedDecrement(FRefCount); if FRefCount = 0 then Destroy; end; { TdxBarDesignWindow } constructor TdxBarDesignWindow.Create(AOwner: TComponent); begin inherited Create(AOwner); // FCurrentSelectionList := TComponentList.Create(False); FCurrentSelectionList := TObjectList.Create(False); end; destructor TdxBarDesignWindow.Destroy; begin FreeAndNil(FCurrentSelectionList); inherited; end; function TdxBarDesignWindow.IsComponentSelected(AComponent: TPersistent): Boolean; begin Result := FCurrentSelectionList.IndexOf(TComponent(AComponent)) <> -1; end; procedure TdxBarDesignWindow.Notification(AComponent: TComponent; Operation: TOperation); begin inherited; if Operation = opRemove then FCurrentSelectionList.Remove(AComponent); end; {$IFNDEF DELPHI6} procedure TdxBarDesignWindow.ComponentDeleted(Component: IPersistent); function Item: TPersistent; begin Result := ExtractPersistent(Component); end; begin FCurrentSelectionList.Remove(Item); end; {$ELSE} procedure TdxBarDesignWindow.ItemDeleted(const ADesigner: IDesigner; Item: TPersistent); begin FCurrentSelectionList.Remove(Item); end; {$ENDIF} {$IFNDEF DELPHI6} procedure TdxBarDesignWindow.SelectionChanged(ASelection: TDesignerSelectionList); begin if LockCount = 0 then SelectionsChanged(ASelection); end; {$ELSE} procedure TdxBarDesignWindow.SelectionChanged(const ADesigner: IDesigner; const ASelection: TDesignerSelectionList); begin if LockCount = 0 then SelectionsChanged(ASelection); end; {$ENDIF} procedure TdxBarDesignWindow.SelectionsChanged(const ASelection: TDesignerSelectionList); var I: Integer; ANewSelection, AOldSelection, ASelectionChanges: TdxObjectList; ASelectableItem: IdxBarSelectableItem; begin inherited; ASelectionChanges := TdxObjectList.Create(False); AOldSelection := TdxObjectList.Create(False); ANewSelection := TdxObjectList.Create(False); try AOldSelection.CopyFrom(FCurrentSelectionList); ConvertSelectionToList(ASelection, ANewSelection); CleanSelectableItems(ANewSelection); ANewSelection.CopyTo(FCurrentSelectionList); ASelectionChanges.XorList(FCurrentSelectionList, AOldSelection); // add to invalidation single selected object if ASelectionChanges.Count > 0 then begin if AOldSelection.Count = 1 then ASelectionChanges.Add(AOldSelection[0]); if ANewSelection.Count = 1 then ASelectionChanges.Add(ANewSelection[0]); end; for I := ASelectionChanges.Count - 1 downto 0 do begin ASelectableItem := GetSelectableItem(ASelectionChanges[I]); if ASelectableItem <> nil then ASelectableItem.SelectionChanged; end; for I := 0 to AOldSelection.Count - 1 do if AOldSelection[I] is TComponent then TComponent(AOldSelection[I]).RemoveFreeNotification(Self); for I := 0 to FCurrentSelectionList.Count - 1 do if FCurrentSelectionList[I] is TComponent then TComponent(FCurrentSelectionList[I]).FreeNotification(Self); finally ANewSelection.Free; AOldSelection.Free; ASelectionChanges.Free; end; if Assigned(OnSelectionChanged) then OnSelectionChanged(Self); end; { TdxBarManagerEditor } type TdxBarManagerEditor = class(TComponentEditor) public procedure ExecuteVerb(Index: Integer); override; function GetVerb(Index: Integer): string; override; function GetVerbCount: Integer; override; procedure PrepareItem(Index: Integer; const AItem: {$IFDEF DELPHI6}IMenuItem{$ELSE}TMenuItem{$ENDIF}); override; // routines function BarManager: TdxBarManager; end; procedure TdxBarManagerEditor.ExecuteVerb(Index: Integer); begin case Index of 0: BarManager.Customizing(True); 1: BarManager.AddToolBar; 2: BarManager.AddToolBar(True) end; end; function TdxBarManagerEditor.GetVerb(Index: Integer): string; begin case Index of 0: Result := cxGetResourceString(@dxSBAR_CUSTOMIZINGFORM); 1: Result := 'Add Toolbar'; 2: Result := 'Add MainMenu'; 3: Result := '-'; 4: Result := 'ExpressBars ' + dxBarVersion; 5: Result := 'Developer Express Inc.'; end; end; function TdxBarManagerEditor.GetVerbCount: Integer; begin Result := 3 + 3; end; procedure TdxBarManagerEditor.PrepareItem(Index: Integer; const AItem: {$IFDEF DELPHI6}IMenuItem{$ELSE}TMenuItem{$ENDIF}); begin inherited PrepareItem(Index, AItem); if Index in [1, 2] then AItem.Enabled := TdxBarManagerAccess(BarManager).CanAddComponents; if Index = 2 then AItem.Enabled := AItem.Enabled and (BarManager.MainMenuBar = nil); end; function TdxBarManagerEditor.BarManager: TdxBarManager; begin Result := TdxBarManager(Component); end; { TdxBarPopupMenuEditor } type TdxBarPopupMenuEditor = class(TComponentEditor) procedure ExecuteVerb(Index: Integer); override; function GetVerb(Index: Integer): string; override; function GetVerbCount: Integer; override; end; procedure TdxBarPopupMenuEditor.ExecuteVerb(Index: Integer); begin case Index of 0: ShowdxBarSubMenuEditor(TdxBarCustomPopupMenu(Component).ItemLinks); end; end; function TdxBarPopupMenuEditor.GetVerb(Index: Integer): string; begin case Index of 0: Result := cxGetResourceString(@dxSBAR_POPUPMENUEDITOR); end; end; function TdxBarPopupMenuEditor.GetVerbCount: Integer; begin Result := 1; end; { TdxBarsPropertyEditor } type TdxBarsPropertyEditor = class(TPropertyEditor) public procedure Edit; override; function GetAttributes: TPropertyAttributes; override; function GetValue: string; override; end; procedure TdxBarsPropertyEditor.Edit; var BarManager: TdxBarManager; begin BarManager := TdxBarManager(GetComponent(0)); BarManager.Customizing(True); if BarManager.IsCustomizing then dxBarCustomizingForm.SelectPage(0); end; function TdxBarsPropertyEditor.GetAttributes: TPropertyAttributes; begin Result := [paDialog, paReadOnly]; end; function TdxBarsPropertyEditor.GetValue: string; begin Result := Format('(%s)', [TdxBars.ClassName]); end; { TdxCategoriesPropertyEditor } type TdxCategoriesPropertyEditor = class(TPropertyEditor) public procedure Edit; override; function GetAttributes: TPropertyAttributes; override; function GetValue: string; override; end; procedure TdxCategoriesPropertyEditor.Edit; var BarManager: TdxBarManager; begin BarManager := TdxBarManager(GetComponent(0)); BarManager.Customizing(True); if BarManager.IsCustomizing then dxBarCustomizingForm.SelectPage(1); end; function TdxCategoriesPropertyEditor.GetAttributes: TPropertyAttributes; begin Result := [paDialog, paReadOnly]; end; function TdxCategoriesPropertyEditor.GetValue: string; begin Result := Format('(%s)', [TStrings.ClassName]); end; { TdxRegistryPathProperty } type TdxRegistryPathProperty = class(TStringProperty) public procedure Edit; override; function GetAttributes: TPropertyAttributes; override; end; procedure TdxRegistryPathProperty.Edit; var BarManager: TdxBarManager; S: string; begin BarManager := TdxBarManager(GetComponent(0)); S := BarManager.RegistryPath; if dxGetRegistryPath(S) then begin BarManager.RegistryPath := S; Designer.Modified; end; end; function TdxRegistryPathProperty.GetAttributes: TPropertyAttributes; begin Result := inherited GetAttributes + [paDialog]; end; { TdxBarItemLinksPropertyEditor } type TdxBarItemLinksPropertyEditor = class(TPropertyEditor) public procedure Edit; override; function GetAttributes: TPropertyAttributes; override; function GetValue: string; override; end; procedure TdxBarItemLinksPropertyEditor.Edit; begin if not (GetComponent(0) is TdxBar) then ShowdxBarSubMenuEditor(TdxBarItemLinks(GetOrdValue)); end; function TdxBarItemLinksPropertyEditor.GetAttributes: TPropertyAttributes; begin Result := [paReadOnly]; if not (GetComponent(0) is TdxBar) then Include(Result, paDialog); end; function TdxBarItemLinksPropertyEditor.GetValue: string; begin Result := Format('(%s)', [TdxBarItemLinks.ClassName]); end; { TDetachingBarPropertyEditor } const NoneBarCaption = ''; type TDetachingBarPropertyEditor = class(TPropertyEditor) public function GetAttributes: TPropertyAttributes; override; procedure GetValues(Proc: TGetStrProc); override; function GetValue: string; override; procedure SetValue(const Value: string); override; end; function TDetachingBarPropertyEditor.GetAttributes: TPropertyAttributes; begin Result := [paValueList{$IFNDEF DELPHI6}, paReadOnly{$ENDIF}]; end; procedure TDetachingBarPropertyEditor.GetValues(Proc: TGetStrProc); var I: Integer; begin Proc(NoneBarCaption); with TdxBarItem(GetComponent(0)).BarManager do for I := 0 to Bars.Count - 1 do Proc(Bars[I].Caption); end; function TDetachingBarPropertyEditor.GetValue: string; begin with TCustomdxBarSubItem(GetComponent(0)) do if GetDetachingBar = nil then Result := NoneBarCaption else Result := GetDetachingBar.Caption; end; procedure TDetachingBarPropertyEditor.SetValue(const Value: string); begin with TCustomdxBarSubItem(GetComponent(0)) do if (Value = NoneBarCaption) or (BarManager.BarByCaption(Value) = nil) then DetachingBar := -1 else DetachingBar := BarManager.BarByCaption(Value).Index; Modified; end; { TdxBarItemImageIndexProperty } function TdxBarItemImageIndexProperty.GetImages: TCustomImageList; begin Result := BarManager.Images; end; function TdxBarItemImageIndexProperty.GetBarManager: TdxBarManager; begin Result := (GetComponent(0) as TdxBarItem).BarManager; end; { TdxBarItemLargeImageIndexProperty } function TdxBarItemLargeImageIndexProperty.GetImages: TCustomImageList; begin Result := BarManager.LargeImages; end; type { TdxBarScreenTipRepositoryEditor } TdxBarScreenTipRepositoryEditor = class(TComponentEditor) private function GetRepository: TdxBarScreenTipRepository; public procedure ExecuteVerb(Index: Integer); override; function GetVerb(Index: Integer): string; override; function GetVerbCount: Integer; override; property Repository: TdxBarScreenTipRepository read GetRepository; end; procedure TdxBarScreenTipRepositoryEditor.ExecuteVerb(Index: Integer); begin case Index of 0: ShowFormEditorClass(Designer, Component, Repository.Items, 'Items', TfrmComponentCollectionEditor); 3: OpenWebPage('http://www.devexpress.com'); end; end; function TdxBarScreenTipRepositoryEditor.GetRepository: TdxBarScreenTipRepository; begin Result := Component as TdxBarScreenTipRepository; end; function TdxBarScreenTipRepositoryEditor.GetVerb(Index: Integer): string; begin Result := ''; case Index of 0: Result := 'Items Editor...'; 1: Result := '-'; 2: Result := 'ExpressBars ' + dxBarVersion; 3: Result := 'Developer Express Inc.'; end; end; function TdxBarScreenTipRepositoryEditor.GetVerbCount: Integer; begin Result := 4; end; procedure HideClassProperties(AClass: TClass; APropertyNames: array of string); var I: Integer; begin for I := Low(APropertyNames) to High(APropertyNames) do RegisterPropertyEditor(GetPropInfo(AClass, APropertyNames[I]).PropType^, AClass, APropertyNames[I], nil); end; { register } procedure Register; begin {$IFDEF DELPHI9} ForceDemandLoadState(dlDisable); {$ENDIF} RegisterComponents('ExpressBars', [TdxBarManager, TdxBarPopupMenu, TdxBarApplicationMenu, TdxBarDockControl, TdxBarScreenTipRepository]); RegisterNoIcon([ TdxBarGroup, TdxBarButton, TdxBarEdit, TCustomdxBarCombo, TdxBarCombo, TdxBarSeparator, TdxBarSubItem, TdxBarListItem, TdxBarContainerItem, TdxBar, TdxBarScreenTip]); RegisterComponentEditor(TdxBarManager, TdxBarManagerEditor); RegisterComponentEditor(TdxBarCustomPopupMenu, TdxBarPopupMenuEditor); RegisterComponentEditor(TdxBarScreenTipRepository, TdxBarScreenTipRepositoryEditor); {$IFDEF DELPHI6} RegisterPropertyEditor(TypeInfo(TShortCut), TdxBarButton, 'ShortCut', TShortCutProperty); {$ENDIF} RegisterPropertyEditor(TypeInfo(TdxBars), TdxBarManager, 'Bars', TdxBarsPropertyEditor); RegisterPropertyEditor(TypeInfo(TStrings), TdxBarManager, 'Categories', TdxCategoriesPropertyEditor); RegisterPropertyEditor(TypeInfo(string), TdxBarManager, 'RegistryPath', TdxRegistryPathProperty); RegisterPropertyEditor(TypeInfo(TdxBarItemLinks), TdxBar, 'ItemLinks', TdxBarItemLinksPropertyEditor); RegisterPropertyEditor(TypeInfo(TdxBarItemLinks), TdxBarCustomPopupMenu, 'ItemLinks', TdxBarItemLinksPropertyEditor); RegisterPropertyEditor(TypeInfo(TdxBarItemLinks), TdxBarSubItem, 'ItemLinks', TdxBarItemLinksPropertyEditor); RegisterPropertyEditor(TypeInfo(TdxBarItemLinks), TdxBarContainerItem, 'ItemLinks', TdxBarItemLinksPropertyEditor); RegisterPropertyEditor(TypeInfo(Integer), TCustomdxBarSubItem, 'DetachingBar', TDetachingBarPropertyEditor); RegisterPropertyEditor(TypeInfo(Integer), TdxBarItem, 'ImageIndex', TdxbarItemImageIndexProperty); RegisterPropertyEditor(TypeInfo(Integer), TdxBarItem, 'LargeImageIndex', TdxbarItemLargeImageIndexProperty); RegisterPropertyEditor(TypeInfo(TBitmap), TdxBarItem, 'Glyph', TcxBitmapProperty); RegisterPropertyEditor(TypeInfo(TBitmap), TdxBarItem, 'LargeGlyph', TcxBitmapProperty); RegisterPropertyEditor(TypeInfo(TBitmap), TdxBarItemLink, 'UserGlyph', TcxBitmapProperty); // ImageOptions HideClassProperties(TdxBarManager, ['DisabledImages', 'DisabledLargeImages', 'HotImages', 'Images', 'LargeImages', 'ImageListBkColor', 'LargeIcons', 'MakeDisabledImagesFaded', 'StretchGlyphs', 'UseLargeImagesForLargeIcons']); HideClassProperties(TdxBarSeparator, ['Action', 'Align', 'Category', 'Description', 'Enabled', 'HelpContext', 'Hint', 'MergeKind', 'MergeOrder', 'Style', 'ScreenTip', 'OnDestroy']); end; procedure DesignSelectionChanged(ASender: TObject); begin if dxBarCustomizingForm <> nil then dxBarCustomizingForm.DesignSelectionChanged(ASender); end; procedure RegisterBarManager(ASender: TObject); begin if dxBarManagerList.Count = 1 then begin FdxBarDesignWindow := TdxBarDesignWindow.Create(nil); FdxBarDesignWindow.OnSelectionChanged := DesignSelectionChanged; end; TdxBarManagerAccess(ASender).FdxBarDesignHelper := TdxBarDesignHelper.Create(TComponent(ASender)); end; procedure UnregisterBarManager(ASender: TObject); begin if (FdxBarDesignWindow <> nil) and ((dxBarManagerList = nil) or (dxBarManagerList.Count = 0)) then begin FdxBarDesignWindow.Release; FdxBarDesignWindow := nil; end; TdxBarManagerAccess(ASender).FdxBarDesignHelper := nil; end; initialization FOnRegisterBarManager := RegisterBarManager; FOnUnregisterBarManager := UnregisterBarManager; end.