am2000designer.pas
资源名称:am2000.zip [点击查看]
上传用户:powellwoo
上传日期:2007-01-07
资源大小:109k
文件大小:54k
源码类别:
Delphi控件源码
开发平台:
C++ Builder
- {*******************************************************}
- { }
- { AnimatedMenus/2000 }
- { T_AM2000_MenuDesigner Component Unit }
- { }
- { Copyright (c) 1997-99 AnimatedMenus.com }
- { All rights reserved. }
- { }
- {*******************************************************}
- unit am2000designer;
- {$I am2000.inc}
- interface
- uses
- Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
- StdCtrls, CommCtrl, ComCtrls, ExtCtrls,
- Buttons, Menus, Registry, LibHelp, DsgnIntf,
- {$IFDEF Delphi3OrHigher} ExtDlgs, {$ENDIF}
- {$IFDEF Delphi4OrHigher} ImgList, {$ENDIF}
- {$IFDEF Delphi5OrHigher} Contnrs, {$ENDIF}
- am2000menuitem, am2000popupmenu, am2000mainmenu, am2000cache, am2000,
- am2000utils;
- type
- T_AM2000_TreeView4 = class;
- {$IFNDEF Delphi4OrHigher}
- TCustomDrawTarget = (dtControl, dtItem, dtSubItem);
- TCustomDrawStage = (cdPrePaint, cdPostPaint, cdPreErase, cdPostErase);
- TCustomDrawState = set of (cdsSelected, cdsGrayed, cdsDisabled, cdsChecked,
- cdsFocused, cdsDefault, cdsHot, cdsMarked, cdsIndeterminate);
- TTVCustomDrawItemEvent = procedure(Sender: TCustomTreeView; Node: TTreeNode;
- State: TCustomDrawState; var DefaultDraw: Boolean) of object;
- {$ENDIF}
- // menu designer
- T_AM2000_MenuDesigner = class(TPropertyEditor)
- public
- function GetValue: string; override;
- function GetAttributes: TPropertyAttributes; override;
- procedure Edit; override;
- end;
- // component editor
- T_AM2000_ComponentEditor = class(TComponentEditor)
- public
- function GetVerbCount: Integer; override;
- function GetVerb(Index: Integer): String; override;
- procedure ExecuteVerb(Index: Integer); override;
- procedure Edit; override;
- end;
- // dialog for menu designer
- T_AM2000_MenuDesignerDlg = class(TForm)
- Panel1: TPanel;
- ButtonNewMenuItem: TSpeedButton;
- ButtonNewSubMenu: TSpeedButton;
- Bevel1: TBevel;
- ButtonDelete: TSpeedButton;
- Bevel2: TBevel;
- ButtonLevelUp: TSpeedButton;
- ButtonMoveUp: TSpeedButton;
- ButtonMoveDown: TSpeedButton;
- ButtonLevelDown: TSpeedButton;
- PopupMenu20001: TPopupMenu2000;
- DefaultBitmaps1: TMenuItem2000;
- N2: TMenuItem2000;
- None1: TMenuItem2000;
- ButtonArray1: TMenuItem2000;
- OpenDialog1: TOpenDialog;
- SaveDialog1: TSaveDialog;
- NewItem1: TMenuItem2000;
- NewSubmenuItem1: TMenuItem2000;
- MenuItem3: TMenuItem2000;
- ImageListBitmaps1: TMenuItem2000;
- None2: TMenuItem2000;
- ButtonArray2: TMenuItem2000;
- DefaultBitmapsMenu: TPopupMenu2000;
- ImageListMenu: TPopupMenu2000;
- LoadBitmapFromFile1: TMenuItem2000;
- SaveBitmapToFile1: TMenuItem2000;
- AM2000MenuDesigner4: TMenuItem2000;
- ExpandAll1: TMenuItem2000;
- CollapseAll1: TMenuItem2000;
- AM2000MenuDesigner8: TMenuItem2000;
- Open1: TMenuItem2000;
- SaveAs1: TMenuItem2000;
- InsStdMnu: TMenuItem2000;
- AM2000MenuDesigner2: TMenuItem2000;
- DefaultBitmaps: TImageList;
- AM2000MenuDesigner5: TMenuItem2000;
- Delete1: TMenuItem2000;
- Bevel3: TBevel;
- ButtonStayOnTop: TSpeedButton;
- MenuTree: T_AM2000_TreeView4;
- SelectAll2: TMenuItem2000;
- DeselectAll1: TMenuItem2000;
- N1: TMenuItem2000;
- btnCut: TSpeedButton;
- btnCopy: TSpeedButton;
- btnPaste: TSpeedButton;
- Bevel4: TBevel;
- ShortCuts1: TMenuItem2000;
- N3: TMenuItem2000;
- procedure MenuTree1Change(Sender: TObject; Node: TTreeNode);
- procedure FormShow(Sender: TObject);
- procedure FormHide(Sender: TObject);
- procedure CollapseAll1Click(Sender: TObject);
- procedure ExpandAll1Click(Sender: TObject);
- procedure ButtonNewMenuItemClick(Sender: TObject);
- procedure ButtonNewSubMenuClick(Sender: TObject);
- procedure MenuTree1Edited(Sender: TObject; Node: TTreeNode;
- var S: String);
- procedure ButtonDeleteClick(Sender: TObject);
- procedure FormKeyUp(Sender: TObject; var Key: Word;
- Shift: TShiftState);
- procedure ButtonMoveDownClick(Sender: TObject);
- procedure ButtonMoveUpClick(Sender: TObject);
- procedure ButtonLevelUpClick(Sender: TObject);
- procedure ButtonLevelDownClick(Sender: TObject);
- procedure LoadFromFile2Click(Sender: TObject);
- procedure SaveToFile2Click(Sender: TObject);
- procedure SaveAsTemplate1Click(Sender: TObject);
- procedure MenuTree1MouseUp(Sender: TObject; Button: TMouseButton;
- Shift: TShiftState; X, Y: Integer);
- procedure LoadBitmapFromFileClick(Sender: TObject);
- procedure PopupMenu20001Popup(Sender: TObject);
- procedure SaveBitmapToFileClick(Sender: TObject);
- procedure None1Click(Sender: TObject);
- procedure ButtonArray1Click(Sender: TObject);
- procedure ButtonArray2Click(Sender: TObject);
- procedure FormDestroy(Sender: TObject);
- procedure AM2000MenuDesigner6Click(Sender: TObject);
- procedure AM2000MenuDesigner7Click(Sender: TObject);
- procedure MenuTree1Editing(Sender: TObject; Node: TTreeNode;
- var AllowEdit: Boolean);
- procedure ButtonStayOnTopClick(Sender: TObject);
- procedure ImageListMenuPopup(Sender: TObject);
- procedure MenuTreeChanging(Sender: TObject; Node: TTreeNode;
- var AllowChange: Boolean);
- procedure MenuTreeMouseDown(Sender: TObject; Button: TMouseButton;
- Shift: TShiftState; X, Y: Integer);
- procedure MenuTreeCustomDrawItem(Sender: TCustomTreeView;
- Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
- procedure FormCreate(Sender: TObject);
- procedure FormClose(Sender: TObject; var Action: TCloseAction);
- procedure DeselectAll1Click(Sender: TObject);
- procedure btnCutClick(Sender: TObject);
- procedure SelectAll2Click(Sender: TObject);
- procedure FormActivate(Sender: TObject);
- procedure btnCopyClick(Sender: TObject);
- procedure btnPasteClick(Sender: TObject);
- procedure Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,
- Y: Integer);
- procedure ShortCuts1Click(Sender: TObject);
- private
- Updating: Boolean;
- TempFolder: String;
- FMenu: TMenu;
- ShiftFirstIndex: Integer;
- LastSelected: TTreeNode;
- SelectedList, // list of selected nodes
- MenuItemList, // list of menu items in the node
- TreeNodeList // list of tree nodes from MenuItemList
- : TList;
- {$IFDEF Delphi3OrHigher}
- OpenPictureDialog1: TOpenPictureDialog;
- SavePictureDialog1: TSavePictureDialog;
- {$ELSE}
- OpenPictureDialog1: TOpenDialog;
- SavePictureDialog1: TSaveDialog;
- {$ENDIF}
- procedure CheckConstraints;
- procedure InsertTemplateMenuClick(Sender: TObject);
- procedure SetMenu(const Value: TMenu);
- procedure InvalidateNode(Node: TTreeNode);
- procedure InvalidateList;
- procedure wmSelectComponent(var Msg: TMessage); message wm_SelectComponent;
- procedure wmUpdateCaption(var Msg: TMessage); message wm_UpdateCaption;
- procedure wmUpdateBitmap(var Msg: TMessage); message wm_UpdateBitmap;
- procedure UpdateSelections;
- procedure ClearSelections;
- procedure CopySelections;
- protected
- {$IFDEF Delphi4OrHigher}
- Designer: IFormDesigner;
- {$ELSE}
- Designer: TFormDesigner;
- {$ENDIF}
- procedure Loaded; override;
- public
- property Menu: TMenu read FMenu write SetMenu;
- end;
- T_AM2000_TreeView4 = class(TCustomTreeView)
- private
- FCanvas: TCanvas;
- FCanvasChanged: Boolean;
- FOnCustomDrawItem: TTVCustomDrawItemEvent;
- procedure CanvasChanged(Sender: TObject);
- procedure CNNotify(var Message: TWMNotify); message CN_NOTIFY;
- function GetNodeFromItem(const Item: TTVItem): TTreeNode;
- protected
- function CustomDrawItem(Node: TTreeNode; State: TCustomDrawState;
- Stage: TCustomDrawStage
- {$IFDEF Delphi5OrHigher}
- ; var PaintImages: Boolean
- {$ENDIF}
- ): Boolean;
- {$IFDEF Delphi4OrHigher}
- override;
- {$ELSE}
- virtual;
- {$ENDIF}
- function IsCustomDrawn(Target: TCustomDrawTarget; Stage: TCustomDrawStage): Boolean;
- procedure CreateParams(var Params: TCreateParams); override;
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- property Canvas: TCanvas read FCanvas;
- published
- property Items;
- property OnChanging;
- property OnChange;
- property Align;
- property OnDragDrop;
- property OnDragOver;
- property OnStartDrag;
- property OnEndDrag;
- property OnMouseDown;
- property OnMouseMove;
- property OnMouseUp;
- property OnDblClick;
- property OnKeyDown;
- property OnKeyPress;
- property OnKeyUp;
- property OnEdited;
- property OnEditing;
- property PopupMenu;
- property Font;
- property Color;
- property OnCustomDrawItem: TTVCustomDrawItemEvent read FOnCustomDrawItem write FOnCustomDrawItem;
- end;
- var
- MenuDesignerDlg : T_AM2000_MenuDesignerDlg;
- implementation
- uses
- Consts, TypInfo,
- {$IFDEF Delphi2} Ole2, {$ELSE} ShlObj, ActiveX, {$ENDIF}
- {$IFDEF Delphi3orHigher} am2000shortcut, {$ENDIF}
- am2000menubar, am2000const, am2000options;
- {$R *.DFM}
- const
- MENU_REGISTRY_KEY : String = 'SoftwareAnimatedMenus.comAnimatedMenus/2000Folders';
- const
- SOkToDeleteThese = 'Ok to delete these ';
- SSelectedItems = ' selected items?';
- {$IFDEF Delphi2}
- type
- TSHItemID = record
- cb: Word;
- abID: array[0..0] of Byte;
- end;
- PItemIDList = ^TItemIDList;
- TItemIDList = record
- mkid: TSHItemID;
- end;
- TBrowseInfo = record
- hwndOwner: HWND;
- pidlRoot: PItemIDList;
- pszDisplayName: PAnsiChar;
- lpszTitle: PAnsiChar;
- ulFlags: UINT;
- lpfn: Pointer;
- lParam: LPARAM;
- iImage: Integer;
- end;
- function SHBrowseForFolder(var lpbi: TBrowseInfo): PItemIDList;
- stdcall; external 'shell32.dll' name 'SHBrowseForFolderA';
- function SHGetPathFromIDList(pidl: PItemIDList; pszPath: PChar): BOOL;
- stdcall; external 'shell32.dll' name 'SHGetPathFromIDListA';
- {$ENDIF}
- procedure DrawImageList(Item: TMenuItem2000; ImageList: TImageList);
- var
- DX, DY, X, Y: Integer;
- begin
- DX:= ImageList.Width +4;
- DY:= ImageList.Height +4;
- with Item.AsButtonArray do begin
- Count:= ImageList.Count;
- Columns:= 9;
- Rows:= Count div Columns;
- if (Count mod Columns) <> 0 then Rows:= Rows +1;
- Bitmap.Width:= Columns * DX;
- Bitmap.Height:= Rows * DY;
- with Bitmap.Canvas do begin
- Brush.Color:= clFuchsia;
- Brush.Style:= bsSolid;
- FillRect(ClipRect);
- end;
- for X:= 0 to Columns do
- for Y:= 0 to Rows do
- ImageList_Draw(ImageList.Handle, X + Y * Columns, Bitmap.Canvas.Handle,
- X * DX +2, Y * DY +2, ild_Transparent);
- end;
- end;
- { T_AM2000_MenuDesigner }
- procedure T_AM2000_MenuDesigner.Edit;
- begin
- if not Assigned(MenuDesignerDlg) then
- MenuDesignerDlg:= T_AM2000_MenuDesignerDlg.Create(Application);
- MenuDesignerDlg.Designer:= Designer;
- MenuDesignerDlg.Menu:= TMenu(GetComponent(0));
- MenuDesignerDlg.Show;
- end;
- function T_AM2000_MenuDesigner.GetValue: string;
- begin
- Result:= '(Menu2000)';
- end;
- function T_AM2000_MenuDesigner.GetAttributes: TPropertyAttributes;
- begin
- Result:= [paDialog, paReadOnly];
- end;
- { T_AM2000_ComponentEditor }
- procedure T_AM2000_ComponentEditor.Edit;
- begin
- if not Assigned(MenuDesignerDlg) then
- MenuDesignerDlg:= T_AM2000_MenuDesignerDlg.Create(Application);
- MenuDesignerDlg.Designer:= Designer;
- MenuDesignerDlg.Menu:= TMenu(Component);
- MenuDesignerDlg.Show;
- end;
- function T_AM2000_ComponentEditor.GetVerbCount: Integer;
- begin
- Result:= inherited GetVerbCount + 1;
- end;
- function T_AM2000_ComponentEditor.GetVerb(Index: Integer): String;
- begin
- if Index = 0
- then Result:= 'AM2000 Menu Designer...'
- else Result:= inherited GetVerb(Index -1);
- end;
- procedure T_AM2000_ComponentEditor.ExecuteVerb(Index: Integer);
- begin
- if Index = 0 then Edit;
- end;
- { TMenuDesignerDlg }
- procedure T_AM2000_MenuDesignerDlg.CheckConstraints;
- var
- P: Boolean;
- S: TTreeNode;
- function IsClipboardObject: Boolean;
- // checks is object in lcipboard
- begin
- Result:= LowerCase(Copy(Trim(PasteFromClipboard), 1, 6)) = 'object';
- end;
- begin
- S:= MenuTree.Selected;
- P:= (S <> nil) and (S.Parent <> nil);
- ButtonDelete.Enabled:= P and (SelectedList.Count > 0);
- ButtonLevelUp.Enabled:= P and (S.Parent.Parent <> nil);
- ButtonMoveUp.Enabled:= P and ((S.GetPrevSibling <> nil) or (S.Parent.GetPrevSibling <> nil));
- ButtonMoveDown.Enabled:= P and ((S.GetNextSibling <> nil) or (S.Parent.GetNextSibling <> nil));
- ButtonLevelDown.Enabled:= P;
- DefaultBitmaps1.Enabled:= P;
- ImageListBitmaps1.Enabled:= P and (not ButtonArray2.AsButtonArray.Bitmap.Empty);
- LoadBitmapFromFile1.Enabled:= P;
- SaveBitmapToFile1.Enabled:= P;
- NewItem1.Enabled:= P;
- ButtonNewMenuItem.Enabled:= P;
- // cut/copy/paste
- btnPaste.Enabled:= P and IsClipboardFormatAvailable(cf_Text) and IsClipboardObject;
- btnCut.Enabled:= ButtonDelete.Enabled;
- btnCopy.Enabled:= (SelectedList.Count > 0);
- end;
- procedure T_AM2000_MenuDesignerDlg.InvalidateNode(Node: TTreeNode);
- var
- R: TRect;
- begin
- if (Node = nil) or Updating then Exit;
- try
- R:= Node.DisplayRect(False);
- InvalidateRect(MenuTree.Handle, @R, False)
- except
- end;
- end;
- procedure T_AM2000_MenuDesignerDlg.InvalidateList;
- var
- I: Integer;
- begin
- for I:= 0 to SelectedList.Count -1 do
- InvalidateNode(TTreeNode(SelectedList[I]));
- end;
- procedure T_AM2000_MenuDesignerDlg.MenuTree1Change(Sender: TObject;
- Node: TTreeNode);
- var
- M: TMenuItem2000;
- S: String;
- B: Boolean;
- N: TTreeNode;
- begin
- CheckConstraints;
- if (not (Assigned(Node) and Assigned(Node.Data)))
- or (Updating)
- then Exit;
- try
- S:= '';
- if TObject(Node.Data) is TMenuItem2000 then begin
- M:= TMenuItem2000(Node.Data);
- while Assigned(M) and (M.Caption <> '') do begin
- if S <> ''then S:= ' | ' + S;
- S:= M.Caption + S;
- M:= M.Parent;
- end;
- end;
- // set item index at ButtonArray1
- if Assigned(Node.Data) then
- with TMenuItem2000(Node.Data) do begin
- IgnoreRepaintFloating:= True;
- ButtonArray1.AsButtonArray.ItemIndex:= DefaultIndex;
- ButtonArray2.AsButtonArray.ItemIndex:= ImageIndex;
- IgnoreRepaintFloating:= False;
- B:= (DefaultIndex = -1) and (ImageIndex = -1);
- None1.AsButton.Down:= B;
- None2.AsButton.Down:= B;
- end;
- except
- end;
- // custom draw support
- if Node = nil then Exit;
- // shift
- if GetKeyState(vk_Shift) < 0
- then begin
- InvalidateList;
- SelectedList.Clear;
- N:= Node;
- while (N <> nil) and (N.AbsoluteIndex <> ShiftFirstIndex)
- do begin
- SelectedList.Add(N);
- InvalidateNode(N);
- if N.AbsoluteIndex < ShiftFirstIndex
- then N:= N.GetNextVisible
- else N:= N.GetPrevVisible;
- end;
- if N <> nil then begin
- SelectedList.Add(N);
- InvalidateNode(N);
- end;
- end
- else
- // control
- if GetKeyState(vk_Control) < 0
- then begin
- if Node <> nil then begin
- if SelectedList.IndexOf(Node) = -1
- then SelectedList.Add(Node)
- else SelectedList.Remove(Node);
- InvalidateNode(Node);
- end;
- end
- // none
- else begin
- ShiftFirstIndex:= -1;
- InvalidateList;
- SelectedList.Clear;
- SelectedList.Add(Node);
- InvalidateNode(Node);
- end;
- UpdateSelections;
- end;
- procedure T_AM2000_MenuDesignerDlg.MenuTreeChanging(Sender: TObject;
- Node: TTreeNode; var AllowChange: Boolean);
- var
- N: TTreeNode;
- begin
- N:= MenuTree.Selected;
- // check keys
- if (GetKeyState(vk_Shift) < 0)
- and (N <> nil)
- and (ShiftFirstIndex = -1)
- then ShiftFirstIndex:= N.AbsoluteIndex;
- end;
- procedure T_AM2000_MenuDesignerDlg.MenuTreeCustomDrawItem(
- Sender: TCustomTreeView; Node: TTreeNode; State: TCustomDrawState;
- var DefaultDraw: Boolean);
- var
- txtRect, R: TRect;
- Bitmap: HBitmap;
- NumGlyphs, BitmapIndex, DX: Integer;
- mi: TMenuItem2000;
- img: TImageList;
- begin
- DX:= -20;
- Bitmap:= 0;
- BitmapIndex:= -1;
- DefaultDraw:= False;
- with T_AM2000_TreeView4(Sender), Canvas, Node do begin
- txtRect:= DisplayRect(True);
- Font.Assign(T_AM2000_TreeView4(Sender).Font);
- if (SelectedList.IndexOf(Node) <> -1)
- and (Node.Parent <> nil)
- then begin
- Brush.Color:= clHighlight;
- Font.Color:= clHighlightText;
- end
- else begin
- Brush.Color:= T_AM2000_TreeView4(Sender).Color;
- end;
- // selection
- FillRect(DisplayRect(False));
- // caption
- R:= txtRect;
- R.Right:= Width;
- DrawText(Canvas.Handle, PChar(Text), Length(Text), R, dt_SingleLine + dt_VCenter);
- if HasChildren
- then begin // draw button
- Dec(DX, 13);
- R:= Rect(0, 0, 9, 9);
- OffsetRect(R, txtRect.Left -14, (txtRect.Bottom + txtRect.Top) div 2 -5);
- Brush.Color:= T_AM2000_TreeView4(Sender).Color;
- FillRect(R);
- Brush.Color:= clBtnShadow;
- FrameRect(R);
- Pen.Color:= T_AM2000_TreeView4(Sender).Font.Color;
- Pen.Style:= psSolid;
- if Expanded then begin
- PolyLine([Point(R.Left +2, R.Top +4), Point(R.Right -2, R.Top +4)]);
- end
- else begin
- PolyLine([Point(R.Left +4, R.Top +2), Point(R.Left +4, R.Bottom -2)]);
- PolyLine([Point(R.Left +2, R.Top +4), Point(R.Right -2, R.Top +4)]);
- end;
- end;
- mi:= TMenuItem2000(Data);
- if mi = nil then Exit;
- // draw bitmap
- {$IFDEF Delphi4OrHigher}
- img:= TImageList(TMainMenu(FMenu).Images);
- {$ELSE}
- if FMenu is TMainMenu2000
- then
- img:= TMainMenu2000(FMenu).Images
- else
- if FMenu is TPopupMenu2000
- then
- img:= TPopupMenu2000(FMenu).Images
- else
- img:= nil;
- {$ENDIF}
- if (mi is TMenuItem2000)
- and (TMenuItem2000(mi).IsBitmapAssigned)
- then
- Bitmap:= TMenuItem2000(mi).GetBitmapEx.Handle
- else
- if
- (img <> nil) and
- {$IFDEF Delphi4OrHigher}
- (mi.ImageIndex <> -1)
- {$ELSE}
- (mi is TMenuItem2000) and (TMenuItem2000(mi).ImageIndex <> -1)
- {$ENDIF}
- then
- BitmapIndex:= TMenuItem2000(mi).ImageIndex
- else
- {$IFDEF Delphi4OrHigher}
- Bitmap:= mi.Bitmap.Handle;
- {$ELSE}
- Bitmap:= 0;
- {$ENDIF}
- if mi is TMenuItem2000
- then NumGlyphs:= TMenuItem2000(mi).NumGlyphs
- else NumGlyphs:= 0;
- if (Bitmap = 0)
- and (BitmapIndex = -1)
- and mi.Checked
- then
- if mi.RadioItem
- then Bitmap:= bmpRadioItem
- else Bitmap:= bmpCheckMark;
- if (Bitmap <> 0) or (BitmapIndex <> -1)
- then begin
- R:= Rect(0, 0, 16, 16);
- OffsetRect(R, txtRect.Left + DX, (txtRect.Bottom + txtRect.Top) div 2 -9);
- DrawBitmap(Canvas, Bitmap, BitmapIndex, NumGlyphs, 0, [], nil, R, img);
- end;
- // DeleteObject(Bitmap);
- end;
- end;
- procedure T_AM2000_MenuDesignerDlg.MenuTreeMouseDown(Sender: TObject;
- Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
- var
- N: TTreeNode;
- begin
- N:= nil;
- with MenuTree do begin
- if not (htOnButton in GetHitTestInfoAt(X, Y))
- then N:= GetNodeAt(X, Y);
- if (N <> nil)
- and (N = Selected)
- then begin
- if (GetKeyState(vk_Control) < 0)
- and (N = LastSelected)
- then begin
- if SelectedList.IndexOf(N) = -1
- then SelectedList.Add(N)
- else SelectedList.Remove(N);
- TreeView_EndEditLabelNow(N.Handle, True);
- UpdateSelections;
- end
- else
- if SelectedList.IndexOf(N) = -1
- then begin
- InvalidateList;
- SelectedList.Clear;
- SelectedList.Add(N);
- end
- end
- else
- Selected:= N;
- InvalidateNode(LastSelected);
- InvalidateNode(N);
- LastSelected:= N;
- end;
- CheckConstraints;
- end;
- procedure T_AM2000_MenuDesignerDlg.Loaded;
- var
- Reg: TRegistry;
- SI: TSearchRec;
- I, Res, DX, DY, X, Y: Integer;
- mici: T_AM2000_MenuItemCacheItem;
- // BlankColor: ColorRef;
- // hbmp: HBitmap;
- B: Boolean;
- lpbi: TBrowseInfo;
- pid2: PItemIDList;
- z: array [0..MAX_PATH] of Char;
- begin
- inherited;
- // load autobitmaps & autohints
- // BlankColor:= ColorToRGB(clFuchsia);
- Res:= 0;
- for I:= 0 to MenuItemCache.Count -1 do
- with T_AM2000_MenuItemCacheItem(TStringList(MenuItemCache).Objects[I]) do
- if (Bitmap <> 0) and IsDefault
- then Inc(Res);
- with ButtonArray1.AsButtonArray do begin
- X:= 0;
- Y:= 0;
- DX:= 20;
- DY:= 20;
- Columns:= 9;
- Rows:= Res div Columns;
- if Res mod Columns <> 0 then Rows:= Rows +1;
- Bitmap.Width:= Columns * DX;
- Bitmap.Height:= Rows * DY;
- Bitmap.Canvas.Brush.Color:= clBtnFace;
- Bitmap.Canvas.FillRect(Bitmap.Canvas.ClipRect);
- for I:= 0 to MenuItemCache.Count -1 do begin
- mici:= T_AM2000_MenuItemCacheItem(TStringList(MenuItemCache).Objects[I]);
- if (mici.Bitmap <> 0)
- and (mici.IsDefault)
- then begin
- TransBlt(Bitmap.Canvas, X * DX +2, Y * DY + 2, 0, 1, mici.Bitmap);
- if mici.Hint <> ''
- then Hints.Add(mici.Hint)
- else Hints.Add(TStringList(MenuItemCache)[I]);
- Inc(X);
- if X >= Columns then begin
- Inc(Y);
- X:= 0;
- end;
- end;
- end;
- end;
- {$IFDEF Delphi3OrHigher}
- // set flat property
- ButtonNewMenuItem.Flat:= True;
- ButtonNewSubMenu.Flat:= True;
- ButtonDelete.Flat:= True;
- ButtonLevelUp.Flat:= True;
- ButtonMoveUp.Flat:= True;
- ButtonMoveDown.Flat:= True;
- ButtonLevelDown.Flat:= True;
- ButtonStayOnTop.Flat:= True;
- btnCut.Flat:= True;
- btnCopy.Flat:= True;
- btnPaste.Flat:= True;
- {$ENDIF}
- // load menu templates
- Reg:= TRegistry.Create;
- B:= Reg.OpenKey(MENU_REGISTRY_KEY, False);
- if not B then begin
- FillChar(lpbi, SizeOf(lpbi), 0);
- lpbi.hwndOwner:= Application.MainForm.Handle;
- lpbi.lpszTitle:= SBrowseForMenuTemplateFolder;
- pid2:= SHBrowseForFolder(lpbi);
- if pid2 = nil then Exit;
- Reg.OpenKey(MENU_REGISTRY_KEY, True);
- SHGetPathFromIDList(pid2, z);
- TempFolder:= StrPas(z);
- Reg.WriteString('MenuTemplatesFolder', TempFolder);
- CoTaskMemFree(pid2);
- end
- else
- TempFolder:= Reg.ReadString('MenuTemplatesFolder');
- // scan template files
- if (Length(TempFolder) > 0)
- and (TempFolder[Length(TempFolder)] <> '')
- then AppendStr(TempFolder, '');
- Res:= FindFirst(TempFolder + '*.mnu', faAnyFile, SI);
- while Res = 0 do begin
- InsStdMnu.Add(NewItem(ChangeFileExt(SI.Name, ''), 0,
- False, True, InsertTemplateMenuClick, 0, ''));
- Res:= FindNext(SI);
- end;
- FindClose(SI);
- Reg.Free;
- end;
- procedure T_AM2000_MenuDesignerDlg.FormShow(Sender: TObject);
- begin
- // create and initialize dialogs
- {$IFDEF Delphi3OrHigher}
- OpenPictureDialog1:= TOpenPictureDialog.Create(Self);
- SavePictureDialog1:= TSavePictureDialog.Create(Self);
- {$ELSE}
- OpenPictureDialog1:= TOpenDialog.Create(Self);
- SavePictureDialog1:= TSaveDialog.Create(Self);
- {$ENDIF}
- with OpenPictureDialog1 do begin
- DefaultExt:= 'bmp';
- Filter:= SBitmapDialogFilter;
- Options:= [ofHideReadOnly, ofPathMustExist, ofFileMustExist];
- Title:= SOpenBitmapDialogTitle;
- end;
- with SavePictureDialog1 do begin
- DefaultExt:= 'bmp';
- FileName:= 'Untitled-1.bmp';
- Filter:= SBitmapDialogFilter;
- Options:= [ofOverwritePrompt, ofHideReadOnly, ofPathMustExist];
- Title:= SSaveBitmapDialogTitle;
- end;
- end;
- procedure T_AM2000_MenuDesignerDlg.FormHide(Sender: TObject);
- begin
- Designer:= nil;
- end;
- procedure T_AM2000_MenuDesignerDlg.FormCreate(Sender: TObject);
- begin
- Updating:= False;
- SelectedList:= TList.Create;
- MenuItemList:= TList.Create;
- TreeNodeList:= TList.Create;
- end;
- procedure T_AM2000_MenuDesignerDlg.FormDestroy(Sender: TObject);
- begin
- Updating:= True;
- SelectedList.Free;
- MenuItemList.Free;
- TreeNodeList.Free;
- MenuDesignerDlg:= nil;
- end;
- procedure T_AM2000_MenuDesignerDlg.CollapseAll1Click(Sender: TObject);
- begin
- MenuTree.FullCollapse;
- end;
- procedure T_AM2000_MenuDesignerDlg.ExpandAll1Click(Sender: TObject);
- begin
- MenuTree.FullExpand;
- end;
- procedure T_AM2000_MenuDesignerDlg.ButtonNewMenuItemClick(Sender: TObject);
- var
- N, N1: TTreeNode;
- M, M1: TMenuItem2000;
- begin
- N:= MenuTree.Selected;
- if (not Assigned(N))
- or (not Assigned(N.Parent)) then Exit;
- // clear selection
- InvalidateList;
- SelectedList.Clear;
- SelectedList.Add(N);
- InvalidateNode(N);
- M:= TMenuItem2000(N.Data);
- M1:= TMenuItem2000.Create(Menu.Owner);
- M1.Caption:= SDefaultMenuItemCaption;
- if Designer <> nil
- then M1.Name:= Designer.UniqueName('MenuItem');
- if (N.GetNextSibling <> nil) then begin
- N1:= MenuTree.Items.Insert(N.GetNextSibling, SDefaultMenuItemCaption);
- M.Parent.Insert(M.MenuIndex +1, M1);
- end
- else begin
- N1:= MenuTree.Items.Add(N, SDefaultMenuItemCaption);
- M.Parent.Add(M1);
- end;
- if Designer <> nil then begin
- Designer.Modified;
- Designer.SelectComponent(M1);
- end;
- if ActiveMenuBar <> nil
- then PostMessage(ActiveMenuBar.Handle, wm_UpdateMenuBar, upForceRebuild, 0);
- N1.Selected:= True;
- N1.Data:= M1;
- TreeNodeList.Add(N1);
- MenuItemList.Add(N1.Data);
- // customdraw
- InvalidateList;
- SelectedList.Clear;
- SelectedList.Add(N1);
- InvalidateNode(N1);
- if ActiveMenuBar <> nil
- then PostMessage(ActiveMenuBar.Handle, wm_UpdateMenuBar, upForceRebuild, 0);
- N1.EditText;
- CheckConstraints;
- end;
- procedure T_AM2000_MenuDesignerDlg.ButtonNewSubMenuClick(Sender: TObject);
- var
- N: TTreeNode;
- M: TMenuItem2000;
- begin
- if not Assigned(MenuTree.Selected) then Exit;
- N:= MenuTree.Items.AddChild(MenuTree.Selected, SDefaultMenuItemCaption);
- // clear selection
- InvalidateList;
- SelectedList.Clear;
- SelectedList.Add(N);
- InvalidateNode(N);
- M:= TMenuItem2000.Create(Menu.Owner);
- M.Caption:= SDefaultMenuItemCaption;
- if Designer <> nil
- then M.Name:= Designer.UniqueName('MenuItem');
- TMenuItem2000(MenuTree.Selected.Data).Add(M);
- MenuTree.Selected.Expand(False);
- if Designer <> nil then begin
- Designer.SelectComponent(M);
- Designer.Modified;
- end;
- if ActiveMenuBar <> nil
- then PostMessage(ActiveMenuBar.Handle, wm_UpdateMenuBar, upForceRebuild, 0);
- N.Selected:= True;
- N.Data:= M;
- TreeNodeList.Add(N);
- MenuItemList.Add(N.Data);
- // customdraw
- InvalidateList;
- SelectedList.Clear;
- SelectedList.Add(N);
- InvalidateNode(N);
- if ActiveMenuBar <> nil
- then PostMessage(ActiveMenuBar.Handle, wm_UpdateMenuBar, upForceRebuild, 0);
- N.EditText;
- CheckConstraints;
- end;
- procedure T_AM2000_MenuDesignerDlg.MenuTree1Edited(Sender: TObject; Node: TTreeNode;
- var S: String);
- var
- M: TMenuItem2000;
- S1, S2: String;
- begin
- if Node.Parent <> nil then begin
- // generate menu item capion
- M:= TMenuItem2000(Node.Data);
- M.Caption:= S;
- S1:= S;
- while (M.Parent <> nil) do begin
- M:= M.Parent;
- S1:= M.Caption + S1;
- end;
- if Designer <> nil then begin
- // set menu item name
- S1:= GetValidName(S1);
- if S1 = '' then S1:= 'N';
- S2:= Designer.UniqueName(S1);
- if (S1[1] = 'T') and (S2[1] <> 'T')
- then S2:= 'T' + S2;
- TMenuItem2000(Node.Data).Name:= S2;
- Designer.Modified;
- Designer.SelectComponent(TMenuItem2000(Node.Data));
- end;
- if ActiveMenuBar <> nil
- then PostMessage(ActiveMenuBar.Handle, wm_UpdateMenuBar, upForceRebuild, 0);
- end;
- end;
- procedure T_AM2000_MenuDesignerDlg.ButtonDeleteClick(Sender: TObject);
- begin
- if (SelectedList.Count > 1)
- and (MessageDlg(SOkToDeleteThese + IntToStr(SelectedList.Count) + SSelectedItems, mtConfirmation,
- mbOkCancel, 0) <> mrOk)
- then Exit;
- ClearSelections;
- LastSelected:= nil;
- end;
- procedure T_AM2000_MenuDesignerDlg.FormKeyUp(Sender: TObject; var Key: Word;
- Shift: TShiftState);
- var
- S: String;
- begin
- if MenuTree.IsEditing
- then
- case Key of
- vk_Return:
- ButtonNewMenuItemClick(nil);
- vk_Escape:
- if MenuTree.Selected.Text = SDefaultMenuItemCaption
- then ButtonDeleteClick(nil);
- end
- else
- case Key of
- vk_Insert:
- ButtonNewMenuItemClick(nil);
- vk_Delete:
- ButtonDeleteClick(nil);
- vk_F2:
- if ssCtrl in Shift
- then begin
- S:= TMenuItem2000(MenuTree.Selected.Data).Caption;
- MenuTree1Edited(nil, MenuTree.Selected, S);
- end
- else MenuTree.Selected.EditText;
- vk_Up:
- if ssCtrl in Shift
- then ButtonMoveUpClick(nil);
- vk_Down:
- if ssCtrl in Shift
- then ButtonMoveDownClick(nil);
- vk_Right:
- if ssCtrl in Shift
- then ButtonLevelDownClick(nil);
- vk_Left:
- if ssCtrl in Shift
- then ButtonLevelUpClick(nil);
- end;
- CheckConstraints;
- end;
- procedure T_AM2000_MenuDesignerDlg.ButtonMoveDownClick(Sender: TObject);
- var
- N, N1: TTreeNode;
- M, M1: TMenuItem2000;
- begin
- N:= MenuTree.Selected;
- if (not Assigned(N))
- or (not Assigned(N.Parent)) then Exit;
- // clear selection
- InvalidateList;
- SelectedList.Clear;
- SelectedList.Add(N);
- InvalidateNode(N);
- N1:= N.GetNextSibling;
- // updating
- Updating:= True;
- MenuTree.Items.BeginUpdate;
- if Assigned(N1)
- then begin
- N1:= N1.GetNextSibling;
- if Assigned(N1)
- then N.MoveTo(N1, naInsert)
- else N.MoveTo(N.Parent, naAddChild);
- with TMenuItem2000(N.Data) do MenuIndex:= MenuIndex +1;
- end
- else begin
- N1:= N.Parent.GetNextSibling;
- if Assigned(N1) then begin
- N.MoveTo(N1, naAddChildFirst);
- M:= TMenuItem2000(N.Data);
- M1:= M.Parent.Parent.Items[M.Parent.MenuIndex +1];
- M.Parent.Remove(M);
- M1.Insert(0, M);
- end
- end;
- MenuTree.Items.EndUpdate;
- Updating:= False;
- CheckConstraints;
- if ActiveMenuBar <> nil
- then PostMessage(ActiveMenuBar.Handle, wm_UpdateMenuBar, upForceRebuild, 0);
- end;
- procedure T_AM2000_MenuDesignerDlg.ButtonMoveUpClick(Sender: TObject);
- var
- N, N1: TTreeNode;
- M, M1: TMenuItem2000;
- begin
- N:= MenuTree.Selected;
- if (not Assigned(N))
- or (not Assigned(N.Parent)) then Exit;
- // clear selection
- InvalidateList;
- SelectedList.Clear;
- SelectedList.Add(N);
- InvalidateNode(N);
- N1:= N.GetPrevSibling;
- if N1 = N.Parent then Exit;
- // updating
- Updating:= True;
- MenuTree.Items.BeginUpdate;
- if Assigned(N1) then begin
- N.MoveTo(N1, naInsert);
- with TMenuItem2000(N.Data) do MenuIndex:= MenuIndex -1;
- end
- else begin
- N1:= N.Parent.GetPrevSibling;
- if Assigned(N1) then begin
- N.MoveTo(N1, naAddChild);
- M:= TMenuItem2000(N.Data);
- M1:= M.Parent.Parent.Items[M.Parent.MenuIndex -1];
- M.Parent.Remove(M);
- M1.Add(M);
- end;
- end;
- MenuTree.Items.EndUpdate;
- Updating:= False;
- CheckConstraints;
- if ActiveMenuBar <> nil
- then PostMessage(ActiveMenuBar.Handle, wm_UpdateMenuBar, upForceRebuild, 0);
- end;
- procedure T_AM2000_MenuDesignerDlg.ButtonLevelUpClick(Sender: TObject);
- var
- N, N1: TTreeNode;
- M, M1: TMenuItem2000;
- I: Integer;
- begin
- N:= MenuTree.Selected;
- if (not Assigned(N))
- or (not Assigned(N.Parent))
- or (not Assigned(N.Parent.Parent)) then Exit;
- // clear selection
- InvalidateList;
- SelectedList.Clear;
- SelectedList.Add(N);
- InvalidateNode(N);
- N1:= N.Parent.GetNextSibling;
- // updating
- Updating:= True;
- MenuTree.Items.BeginUpdate;
- M:= TMenuItem2000(N.Data);
- M1:= M.Parent.Parent;
- I:= M.Parent.MenuIndex;
- M.Parent.Remove(M);
- if Assigned(N1) then begin
- N.MoveTo(N1, naInsert);
- M1.Insert(I +1, M);
- end
- else begin
- N.MoveTo(N.Parent.Parent, naAddChild);
- M1.Add(M);
- end;
- MenuTree.Items.EndUpdate;
- Updating:= False;
- CheckConstraints;
- if ActiveMenuBar <> nil
- then PostMessage(ActiveMenuBar.Handle, wm_UpdateMenuBar, upForceRebuild, 0);
- end;
- procedure T_AM2000_MenuDesignerDlg.ButtonLevelDownClick(Sender: TObject);
- var
- N, N1: TTreeNode;
- M, M1, M2: TMenuItem2000;
- I: Integer;
- begin
- N:= MenuTree.Selected;
- if (not Assigned(N))
- or (not Assigned(N.Parent)) then Exit;
- // clear selection
- InvalidateList;
- SelectedList.Clear;
- SelectedList.Add(N);
- InvalidateNode(N);
- // treeview...
- N1:= N.GetPrevSibling;
- // updating
- Updating:= True;
- MenuTree.Items.BeginUpdate;
- // menu...
- M:= TMenuItem2000(N.Data);
- M1:= M.Parent;
- I:= M.MenuIndex;
- M.Parent.Remove(M);
- if Assigned(N1)
- then begin
- N.MoveTo(N1, naAddChild);
- M1[I -1].Add(M);
- end
- else begin
- N1:= MenuTree.Items.AddChildFirst(N.Parent, SDefaultMenuItemCaption);
- N.MoveTo(N1, naAddChild);
- M2:= TMenuItem2000.Create(Menu.Owner);
- M2.Caption:= SDefaultMenuItemCaption;
- if Designer <> nil
- then M2.Name:= Designer.UniqueName('MenuItem');
- M2.Add(M);
- M1.Insert(0, M2);
- N1.Data:= M2;
- TreeNodeList.Add(N1);
- MenuItemList.Add(N1.Data);
- end;
- MenuTree.Items.EndUpdate;
- Updating:= False;
- CheckConstraints;
- if ActiveMenuBar <> nil
- then PostMessage(ActiveMenuBar.Handle, wm_UpdateMenuBar, upForceRebuild, 0);
- end;
- procedure T_AM2000_MenuDesignerDlg.wmUpdateCaption(var Msg: TMessage);
- var
- I: Integer;
- begin
- // get menu item index
- I:= MenuItemList.IndexOf(Pointer(Msg.LParam));
- // get tree node
- if I <> -1 then InvalidateNode(TTreeNode(TreeNodeList[I]));
- end;
- procedure T_AM2000_MenuDesignerDlg.wmUpdateBitmap(var Msg: TMessage);
- var
- I: Integer;
- begin
- // get menu item index
- I:= MenuItemList.IndexOf(Pointer(Msg.LParam));
- // get tree node
- if I <> -1 then InvalidateNode(TTreeNode(TreeNodeList[I]));
- end;
- procedure T_AM2000_MenuDesignerDlg.LoadFromFile2Click(Sender: TObject);
- // loads menu from file
- var
- M, M1: TMenuItem2000;
- begin
- if (MenuTree.Selected = nil)
- or (not OpenDialog1.Execute)
- then Exit;
- M:= TMenuItem2000(MenuTree.Selected.Data);
- M1:= TMenuItem2000.Create(Menu.Owner);
- ReadComponentResFile(OpenDialog1.Filename, M1);
- M.Insert(0, M1);
- Menu:= Menu;
- if Designer <> nil
- then Designer.Modified;
- if ActiveMenuBar <> nil
- then PostMessage(ActiveMenuBar.Handle, wm_UpdateMenuBar, upForceRebuild, 0);
- end;
- procedure T_AM2000_MenuDesignerDlg.InsertTemplateMenuClick(Sender: TObject);
- // loads a template menu
- var
- S: String;
- M, M1: TMenuItem2000;
- begin
- S:= TempFolder + TMenuItem2000(Sender).Caption + '.mnu';
- if (MenuTree.Selected = nil)
- or (not FileExists(S))
- then Exit;
- M:= TMenuItem2000(MenuTree.Selected.Data);
- M1:= TMenuItem2000.Create(Menu.Owner);
- ReadComponentResFile(S, M1);
- M.Insert(0, M1);
- Menu:= Menu;
- if Designer <> nil
- then Designer.Modified;
- // update menu bar
- if ActiveMenuBar <> nil
- then PostMessage(ActiveMenuBar.Handle, wm_UpdateMenuBar, upForceRebuild, 0);
- end;
- procedure T_AM2000_MenuDesignerDlg.SaveToFile2Click(Sender: TObject);
- // saves menu to a file
- begin
- if (not SaveDialog1.Execute)
- then Exit;
- with MenuTree.Selected do
- WriteComponentResFile(SaveDialog1.Filename, TMenuItem2000(Data));
- end;
- procedure T_AM2000_MenuDesignerDlg.SaveAsTemplate1Click(Sender: TObject);
- // saves menu as an template
- begin
- SaveDialog1.InitialDir:= TempFolder;
- if not SaveDialog1.Execute
- then Exit;
- with MenuTree.Selected do
- WriteComponentResFile(SaveDialog1.Filename, TMenuItem2000(Data));
- end;
- procedure T_AM2000_MenuDesignerDlg.MenuTree1MouseUp(Sender: TObject;
- Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
- // pops up a right-click menu
- var
- N: TTreeNode;
- begin
- if (Button <> mbRight)
- then Exit;
- N:= MenuTree.GetNodeAt(X, Y);
- if N <> nil
- then
- with MenuTree.ClientToScreen(Point(X, Y)) do
- PopupMenu20001.Popup(X, Y);
- end;
- procedure T_AM2000_MenuDesignerDlg.LoadBitmapFromFileClick(Sender: TObject);
- begin
- if not OpenPictureDialog1.Execute
- then Exit;
- with TMenuItem2000(MenuTree.Selected.Data) do
- Bitmap.LoadFromFile(OpenPictureDialog1.Filename);
- if Designer <> nil
- then Designer.Modified;
- if ActiveMenuBar <> nil
- then PostMessage(ActiveMenuBar.Handle, wm_UpdateMenuBar, upForceRebuild, 0);
- end;
- procedure T_AM2000_MenuDesignerDlg.SaveBitmapToFileClick(Sender: TObject);
- begin
- if not SavePictureDialog1.Execute
- then Exit;
- with TMenuItem2000(MenuTree.Selected.Data) do
- Bitmap.SaveToFile(SavePictureDialog1.Filename);
- end;
- procedure T_AM2000_MenuDesignerDlg.PopupMenu20001Popup(Sender: TObject);
- // restore bitmap indexes
- var
- il: TImageList;
- begin
- if Assigned(MenuTree.Selected) then
- with TMenuItem2000(MenuTree.Selected.Data) do begin
- IgnoreRepaintFloating:= True;
- ButtonArray1.AsButtonArray.ItemIndex:= DefaultIndex;
- IgnoreRepaintFloating:= False;
- None1.AsButton.Down:= (not IsBitmapAssigned);
- end;
- // load bitmaps from menu's imagelist
- il:= nil;
- if Menu is TMainMenu2000 then il:= TImageList(TCustomMainMenu2000(Menu).Images);
- if Menu is TPopupMenu2000 then il:= TImageList(TCustomPopupMenu2000(Menu).Images);
- ImageListBitmaps1.Enabled:= (MenuTree.Selected <> nil)
- and (MenuTree.Selected.Parent <> nil)
- and (il <> nil)
- and (il.Count > 0);
- end;
- procedure T_AM2000_MenuDesignerDlg.None1Click(Sender: TObject);
- // remove the bitmap
- begin
- if None1.AsButton.Down then Exit;
- None1.AsButton.Down:= True;
- None2.AsButton.Down:= True;
- with MenuTree.Selected, TMenuItem2000(Data) do begin
- DefaultIndex:= -1;
- ImageIndex:= -1;
- if IsBitmapAssigned then begin
- Bitmap.Handle:= 0;
- end;
- if Designer <> nil then begin
- Designer.Modified;
- Designer.SelectComponent(TMenuItem2000(Data));
- end;
- if ActiveMenuBar <> nil
- then PostMessage(ActiveMenuBar.Handle, wm_UpdateMenuBar, upForceRebuild, 0);
- end;
- end;
- procedure T_AM2000_MenuDesignerDlg.ButtonArray1Click(Sender: TObject);
- // assigns default bitmaps
- begin
- with ButtonArray1.AsButtonArray, MenuTree.Selected, TMenuItem2000(Data)
- do begin
- DefaultIndex:= ItemIndex;
- ImageIndex:= -1;
- None2.AsButton.Down:= False;
- ButtonArray2.AsButtonArray.ItemIndex:= -1;
- if Designer <> nil then begin
- Designer.SelectComponent(TMenuItem2000(Data));
- Designer.Modified;
- end;
- if ActiveMenuBar <> nil
- then PostMessage(ActiveMenuBar.Handle, wm_UpdateMenuBar, upForceRebuild, 0);
- end;
- end;
- procedure T_AM2000_MenuDesignerDlg.ButtonArray2Click(Sender: TObject);
- // assigns imagelist's bitmap
- begin
- with ButtonArray2.AsButtonArray, MenuTree.Selected, TMenuItem2000(Data)
- do begin
- DefaultIndex:= -1;
- ImageIndex:= ItemIndex;
- None1.AsButton.Down:= False;
- ButtonArray1.AsButtonArray.ItemIndex:= -1;
- if Designer <> nil then begin
- Designer.SelectComponent(TMenuItem2000(Data));
- Designer.Modified;
- end;
- if ActiveMenuBar <> nil
- then PostMessage(ActiveMenuBar.Handle, wm_UpdateMenuBar, upForceRebuild, 0);
- end;
- end;
- procedure T_AM2000_MenuDesignerDlg.SetMenu(const Value: TMenu);
- procedure AddMenu(M: TMenuItem2000; T: TTreeNodes; N: TTreeNode);
- var
- I: Integer;
- N1: TTreeNode;
- begin
- for I:= 0 to M.Count -1 do begin
- N1:= T.AddChild(N, M[I].Caption);
- N1.Data:= M[I];
- TreeNodeList.Add(N1);
- MenuItemList.Add(N1.Data);
- if M[I].Count > 0 then AddMenu(M[I], T, N1);
- end;
- end;
- var
- N: TTreeNode;
- MI: TMenuItem2000;
- begin
- // updating
- Updating:= True;
- MenuTree.Items.BeginUpdate;
- // init menu tree items
- MenuTree.Items.Clear;
- SelectedList.Clear;
- MenuItemList.Clear;
- TreeNodeList.Clear;
- FMenu:= Value;
- if FMenu = nil then Exit;
- try
- MI:= nil;
- if Menu is TCustomMainMenu2000 then MI:= TCustomMainMenu2000(Menu).Items2000;
- if Menu is TCustomPopupMenu2000 then MI:= TCustomPopupMenu2000(Menu).Items2000;
- N:= MenuTree.Items.Add(nil, 'AnimatedMenus/2000');
- N.Data:= MI;
- TreeNodeList.Add(N);
- MenuItemList.Add(N.Data);
- AddMenu(MI, MenuTree.Items, N);
- MenuTree.Items[0].Expand(False);
- except
- end;
- MenuTree.Items.EndUpdate;
- Updating:= False;
- LastSelected:= nil;
- end;
- procedure T_AM2000_MenuDesignerDlg.AM2000MenuDesigner6Click(
- Sender: TObject);
- begin
- // updating
- Updating:= True;
- MenuTree.Items.BeginUpdate;
- MenuTree.FullExpand;
- MenuTree.Items.EndUpdate;
- Updating:= False;
- end;
- procedure T_AM2000_MenuDesignerDlg.AM2000MenuDesigner7Click(
- Sender: TObject);
- begin
- // updating
- Updating:= True;
- MenuTree.Items.BeginUpdate;
- MenuTree.FullCollapse;
- MenuTree.Items.EndUpdate;
- Updating:= False;
- end;
- procedure T_AM2000_MenuDesignerDlg.MenuTree1Editing(Sender: TObject;
- Node: TTreeNode; var AllowEdit: Boolean);
- begin
- AllowEdit:= Node.Parent <> nil;
- end;
- procedure T_AM2000_MenuDesignerDlg.ButtonStayOnTopClick(Sender: TObject);
- begin
- SelectedList.Clear;
- if ButtonStayOnTop.Down
- then FormStyle:= fsStayOnTop
- else FormStyle:= fsNormal;
- if MenuTree.Items.Count > 0 then
- MenuTree.Items[0].Expand(False);
- end;
- procedure T_AM2000_MenuDesignerDlg.ImageListMenuPopup(Sender: TObject);
- var
- il: TImageList;
- begin
- // load bitmaps from menu's imagelist
- il:= nil;
- if Menu is TMainMenu2000 then il:= TImageList(TCustomMainMenu2000(Menu).Images);
- if Menu is TPopupMenu2000 then il:= TImageList(TCustomPopupMenu2000(Menu).Images);
- if (il = nil) or (il.Count = 0)
- then begin
- ImageListBitmaps1.Enabled:= False;
- ButtonArray2.AsButtonArray.Bitmap.Width:= 0;
- end
- else begin
- DrawImageList(ButtonArray2, il);
- ImageListBitmaps1.Enabled:= True;
- end;
- end;
- procedure T_AM2000_MenuDesignerDlg.FormClose(Sender: TObject;
- var Action: TCloseAction);
- begin
- Action:= caFree;
- end;
- procedure T_AM2000_MenuDesignerDlg.wmSelectComponent(var Msg: TMessage);
- begin
- if Designer <> nil
- then begin
- Designer.SelectComponent(TMenuItem2000(Msg.LParam));
- Designer.Modified;
- end;
- end;
- procedure T_AM2000_MenuDesignerDlg.DeselectAll1Click(Sender: TObject);
- begin
- InvalidateList;
- SelectedList.Clear;
- end;
- procedure T_AM2000_MenuDesignerDlg.UpdateSelections;
- var
- I: Integer;
- {$IFDEF Delphi5OrHigher}
- S: TDesignerSelectionList;
- {$ELSE}
- S: TComponentList;
- {$ENDIF}
- begin
- if Designer = nil then Exit;
- if SelectedList.Count > 1
- then begin
- {$IFDEF Delphi5OrHigher}
- S:= TDesignerSelectionList.Create;
- {$ELSE}
- S:= TComponentList.Create;
- {$ENDIF}
- for I:= 0 to SelectedList.Count -1 do
- S.Add(TMenuItem2000(TTreeNode(SelectedList[I]).Data));
- Designer.SetSelections(S);
- S.Free;
- end
- else
- Designer.SelectComponent(TMenuItem2000(TTreeNode(SelectedList[0]).Data));
- end;
- procedure T_AM2000_MenuDesignerDlg.ClearSelections;
- // removes selections
- var
- N: TTreeNode;
- SL1: TList;
- I: Integer;
- function RemoveFromSelList(Node: TTreeNode): Integer;
- // remove node and its children
- var
- I, C: Integer;
- begin
- Result:= 0;
- if (Node = nil) then Exit;
- C:= SL1.Count;
- SL1.Remove(Node);
- I:= 0;
- while I < SL1.Count -1 do begin
- if Node.IndexOf(TTreeNode(SL1[I])) <> -1
- then Dec(I, RemoveFromSelList(TTreeNode(SL1[I])));
- Inc(I);
- end;
- Result:= C - SL1.Count;
- end;
- begin
- // updating
- Updating:= True;
- MenuTree.Items.BeginUpdate;
- SL1:= TList.Create;
- for I:= 0 to SelectedList.Count -1 do
- SL1.Add(SelectedList[I]);
- SelectedList.Clear;
- while SL1.Count > 0 do begin
- N:= TTreeNode(SL1[0]);
- RemoveFromSelList(N);
- TMenuItem2000(N.Data).Free;
- N.Free;
- end;
- SL1.Free;
- MenuTree.Items.EndUpdate;
- Updating:= False;
- CheckConstraints;
- if Designer <> nil
- then Designer.Modified;
- if ActiveMenuBar <> nil
- then PostMessage(ActiveMenuBar.Handle, wm_UpdateMenuBar, upForceRebuild, 0);
- end;
- procedure T_AM2000_MenuDesignerDlg.CopySelections;
- var
- S, S2: String;
- M1, M2: TMemoryStream;
- I: Integer;
- begin
- if SelectedList.Count = 0 then Exit;
- S:= '';
- M1:= TMemoryStream.Create;
- M2:= TMemoryStream.Create;
- for I:= 0 to SelectedList.Count -1 do begin
- // write menu item into m1
- M1.WriteComponent(TMenuItem2000(TTreeNode(SelectedList[I]).Data));
- M1.Seek(0, 0);
- // ObjectResourceToText
- ObjectBinaryToText(M1, M2);
- M2.Seek(0, 0);
- // convert M2 to S2
- SetLength(S2, M2.Size);
- M2.ReadBuffer(PChar(S2)^, M2.Size);
- // add S2 to S
- AppendStr(S, S2);
- end;
- M1.Free;
- M2.Free;
- if S <> '' then CopyToClipboard(S);
- end;
- procedure T_AM2000_MenuDesignerDlg.btnCutClick(Sender: TObject);
- begin
- CopySelections;
- ClearSelections;
- CheckConstraints;
- end;
- procedure T_AM2000_MenuDesignerDlg.btnCopyClick(Sender: TObject);
- begin
- CopySelections;
- CheckConstraints;
- end;
- procedure T_AM2000_MenuDesignerDlg.btnPasteClick(Sender: TObject);
- var
- S: String;
- M1, M2: TMemoryStream;
- N, N1: TTreeNode;
- M, MI1: TMenuItem2000;
- procedure InsertChildNodes(Node: TTreeNode; Item: TMenuItem);
- var
- I: Integer;
- N: TTreeNode;
- begin
- for I:= 0 to Item.Count -1 do begin
- N:= MenuTree.Items.AddChild(Node, Item[I].Caption);
- N.Data:= Item[I];
- TreeNodeList.Add(N);
- MenuItemList.Add(N.Data);
- InsertChildNodes(N, Item[I]);
- end;
- end;
- begin
- // selection
- N:= MenuTree.Selected;
- if (not Assigned(N))
- or (not Assigned(N.Parent)) then Exit;
- // clear selection
- // updating
- Updating:= True;
- MenuTree.Items.BeginUpdate;
- InvalidateList;
- SelectedList.Clear;
- MI1:= nil;
- M1:= TMemoryStream.Create;
- M2:= TMemoryStream.Create;
- try
- // load component
- S:= PasteFromClipboard;
- // store to stream
- M1.WriteBuffer(PChar(S)^, Length(S));
- M1.Seek(0, 0);
- while M1.Position < M1.Size do begin
- MI1:= TMenuItem2000.Create(Menu.Owner);
- // convert into component
- ObjectTextToBinary(M1, M2);
- M2.Seek(0, 0);
- // readcomponent
- M2.ReadComponent(MI1);
- // insert into menu and tree
- M:= TMenuItem2000(N.Data);
- if (N.GetNextSibling <> nil) then begin
- N1:= MenuTree.Items.Insert(N.GetNextSibling, MI1.Caption);
- M.Parent.Insert(M.MenuIndex +1, MI1);
- end
- else begin
- N1:= MenuTree.Items.Add(N, MI1.Caption);
- M.Parent.Add(MI1);
- end;
- N1.Data:= MI1;
- TreeNodeList.Add(N1);
- MenuItemList.Add(N1.Data);
- InsertChildNodes(N1, MI1);
- // select
- SelectedList.Add(N1);
- // remove reference
- MI1:= nil;
- end;
- except
- M1.Free;
- M2.Free;
- MI1.Free;
- MenuTree.Items.EndUpdate;
- Updating:= False;
- raise;
- end;
- M1.Free;
- M2.Free;
- MenuTree.Items.EndUpdate;
- Updating:= False;
- end;
- procedure T_AM2000_MenuDesignerDlg.SelectAll2Click(Sender: TObject);
- var
- I: Integer;
- begin
- SelectedList.Clear;
- with MenuTree.Items do begin
- BeginUpdate;
- for I:= 0 to Count -1 do
- SelectedList.Add(Item[I]);
- EndUpdate;
- end;
- end;
- procedure T_AM2000_MenuDesignerDlg.FormActivate(Sender: TObject);
- begin
- CheckConstraints;
- end;
- procedure T_AM2000_MenuDesignerDlg.Panel1MouseMove(Sender: TObject;
- Shift: TShiftState; X, Y: Integer);
- begin
- // Panel1.ShowHint:= True;
- end;
- { T_AM2000_TreeView4 }
- {$IFNDEF Delphi4OrHigher}
- const
- { =============== GENERIC WM_NOTIFY EVENTS FOR TREEVIEWS ==================== }
- NM_CUSTOMDRAW = NM_FIRST-12;
- NM_HOVER = NM_FIRST-13;
- NM_NCHITTEST = NM_FIRST-14; // uses NMMOUSE struct
- NM_KEYDOWN = NM_FIRST-15; // uses NMKEY struct
- NM_RELEASEDCAPTURE = NM_FIRST-16;
- NM_SETCURSOR = NM_FIRST-17; // uses NMMOUSE struct
- NM_CHAR = NM_FIRST-18; // uses NMCHAR struct
- { ==================== CUSTOM DRAW ========================================== }
- const
- // custom draw return flags
- // values under 0x00010000 are reserved for global custom draw values.
- // above that are for specific controls
- CDRF_DODEFAULT = $00000000;
- CDRF_NEWFONT = $00000002;
- CDRF_SKIPDEFAULT = $00000004;
- CDRF_NOTIFYPOSTPAINT = $00000010;
- CDRF_NOTIFYITEMDRAW = $00000020;
- CDRF_NOTIFYSUBITEMDRAW = $00000020; // flags are the same, we can distinguish by context
- CDRF_NOTIFYPOSTERASE = $00000040;
- // drawstage flags
- // values under = $00010000 are reserved for global custom draw values.
- // above that are for specific controls
- CDDS_PREPAINT = $00000001;
- CDDS_POSTPAINT = $00000002;
- CDDS_PREERASE = $00000003;
- CDDS_POSTERASE = $00000004;
- // the = $000010000 bit means it's individual item specific
- CDDS_ITEM = $00010000;
- CDDS_ITEMPREPAINT = CDDS_ITEM or CDDS_PREPAINT;
- CDDS_ITEMPOSTPAINT = CDDS_ITEM or CDDS_POSTPAINT;
- CDDS_ITEMPREERASE = CDDS_ITEM or CDDS_PREERASE;
- CDDS_ITEMPOSTERASE = CDDS_ITEM or CDDS_POSTERASE;
- CDDS_SUBITEM = $00020000;
- // itemState flags
- CDIS_SELECTED = $0001;
- CDIS_GRAYED = $0002;
- CDIS_DISABLED = $0004;
- CDIS_CHECKED = $0008;
- CDIS_FOCUS = $0010;
- CDIS_DEFAULT = $0020;
- CDIS_HOT = $0040;
- CDIS_MARKED = $0080;
- CDIS_INDETERMINATE = $0100;
- type
- tagNMCUSTOMDRAWINFO = packed record
- hdr: TNMHdr;
- dwDrawStage: DWORD;
- hdc: HDC;
- rc: TRect;
- dwItemSpec: DWORD; // this is control specific, but it's how to specify an item. valid only with CDDS_ITEM bit set
- uItemState: UINT;
- lItemlParam: LPARAM;
- end;
- PNMCustomDraw = ^TNMCustomDraw;
- TNMCustomDraw = tagNMCUSTOMDRAWINFO;
- tagNMTTCUSTOMDRAW = packed record
- nmcd: TNMCustomDraw;
- uDrawFlags: UINT;
- end;
- PNMTTCustomDraw = ^TNMTTCustomDraw;
- TNMTTCustomDraw = tagNMTTCUSTOMDRAW;
- tagNMTVCUSTOMDRAW = packed record
- nmcd: TNMCustomDraw;
- clrText: COLORREF;
- clrTextBk: COLORREF;
- iLevel: Integer;
- end;
- PNMTVCustomDraw = ^TNMTVCustomDraw;
- TNMTVCustomDraw = tagNMTVCUSTOMDRAW;
- {$ENDIF}
- constructor T_AM2000_TreeView4.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- FCanvas:= TControlCanvas.Create;
- TControlCanvas(FCanvas).Control:= Self;
- end;
- destructor T_AM2000_TreeView4.Destroy;
- begin
- FCanvas.Free;
- inherited Destroy;
- end;
- procedure T_AM2000_TreeView4.CreateParams(var Params: TCreateParams);
- const
- TVS_NOTOOLTIPS = $0080;
- begin
- inherited;
- with Params do Style:= Style or TVS_NOTOOLTIPS;
- end;
- function T_AM2000_TreeView4.GetNodeFromItem(const Item: TTVItem): TTreeNode;
- begin
- with Item do
- if (state and TVIF_PARAM) <> 0 then Result:= Pointer(lParam)
- else Result:= Items.GetNode(hItem);
- end;
- procedure T_AM2000_TreeView4.CNNotify(var Message: TWMNotify);
- var
- Node: TTreeNode;
- TmpItem: TTVItem;
- {$IFDEF Delphi5OrHigher}
- PaintImages: Boolean;
- {$ENDIF}
- begin
- with Message do
- case NMHdr^.code of
- NM_CUSTOMDRAW:
- with PNMCustomDraw(NMHdr)^ do
- begin
- Result:= CDRF_DODEFAULT;
- if dwDrawStage = CDDS_PREPAINT then
- begin
- Result:= Result or CDRF_NOTIFYITEMDRAW
- end
- else if dwDrawStage = CDDS_ITEMPREPAINT then
- begin
- FillChar(TmpItem, SizeOf(TmpItem), 0);
- TmpItem.hItem:= HTREEITEM(dwItemSpec);
- Node:= GetNodeFromItem(TmpItem);
- if Node <> nil then
- begin
- FCanvas.Handle:= hdc;
- FCanvas.Font:= Font;
- FCanvas.Brush:= Brush;
- FCanvas.Font.OnChange:= CanvasChanged;
- FCanvas.Brush.OnChange:= CanvasChanged;
- CustomDrawItem(Node,
- TCustomDrawState(Word(uItemState)), cdPrePaint
- {$IFDEF Delphi5OrHigher}
- , PaintImages
- {$ENDIF}
- );
- Result:= Result or CDRF_SKIPDEFAULT;
- FCanvas.Handle:= 0;
- if IsCustomDrawn(dtItem, cdPostPaint) then
- Result:= Result or CDRF_NOTIFYPOSTPAINT;
- end;
- end;
- end;
- else
- inherited;
- end;
- end;
- procedure T_AM2000_TreeView4.CanvasChanged;
- begin
- FCanvasChanged:= True;
- end;
- function T_AM2000_TreeView4.IsCustomDrawn(Target: TCustomDrawTarget; Stage: TCustomDrawStage): Boolean;
- begin
- if Stage = cdPrePaint
- then
- if Target = dtItem
- then Result:= Assigned(FOnCustomDrawItem)
- else Result:= False
- else
- Result:= False;
- end;
- function T_AM2000_TreeView4.CustomDrawItem(Node: TTreeNode; State: TCustomDrawState;
- Stage: TCustomDrawStage
- {$IFDEF Delphi5OrHigher}
- ; var PaintImages: Boolean
- {$ENDIF}
- ): Boolean;
- begin
- Result:= True;
- if Assigned(FOnCustomDrawItem) then FOnCustomDrawItem(Self, Node, State, Result);
- {$IFDEF Delphi5OrHigher}
- PaintImages:= False;
- {$ENDIF}
- end;
- procedure T_AM2000_MenuDesignerDlg.ShortCuts1Click(Sender: TObject);
- {$IFDEF Delphi3OrHigher}
- var
- ShortCutEditor: T_AM2000_ShortCutEditor;
- S: String;
- mi: TMenuItem2000;
- {$ENDIF}
- begin
- {$IFDEF Delphi3OrHigher}
- if (MenuTree.Selected = nil)
- and (SelectedList.Count = 0)
- then Exit;
- if (MenuTree.Selected <> nil)
- then mi:= TMenuItem2000(MenuTree.Selected.Data)
- else mi:= TMenuItem2000(SelectedList[0]);
- ShortCutEditor:= T_AM2000_ShortCutEditor.Create(Self);
- S:= mi.ShortCut;
- if ShortCutEditor.EditShortCuts(S) then begin
- mi.ShortCut:= S;
- if Designer <> nil then begin
- Designer.Modified;
- Designer.SelectComponent(mi);
- end;
- end;
- ShortCutEditor.Free;
- {$ENDIF}
- end;
- end.