Sbedit.pas
上传用户:hylc_2004
上传日期:2014-01-23
资源大小:46800k
文件大小:28k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. {*******************************************************}
  2. {                                                       }
  3. {         Delphi VCL Extensions (RX)                    }
  4. {                                                       }
  5. {         Copyright (c) 1995, 1996 AO ROSNO             }
  6. {         Copyright (c) 1997 Master-Bank                }
  7. {                                                       }
  8. {*******************************************************}
  9. unit SbEdit;
  10. {$I RX.INC}
  11. interface
  12. uses
  13.   Windows, RTLConsts, DesignIntf, DesignWindows, DesignEditors, VCLEditors,
  14.   SysUtils, Messages, Classes, Graphics, Controls, Forms, Dialogs,
  15.   StdCtrls, Buttons, Grids, SpeedBar,  Menus, Placemnt, RxConst, RxCtrls, VCLUtils;
  16. type
  17. { TSpeedbarEditor }
  18.   TSelectData = record
  19.     bRowCount: Integer;
  20.     bRow: Integer;
  21.     sRowCount: Integer;
  22.     sRow: Integer;
  23.   end;
  24.   TSpeedbarEditor = class(TDesignWindow)
  25.     SectionsBox: TGroupBox;
  26.     NewSection: TButton;
  27.     DelSection: TButton;
  28.     ButtonsBox: TGroupBox;
  29.     UpBtn: TSpeedButton;
  30.     DownBtn: TSpeedButton;
  31.     AddButton: TButton;
  32.     RemoveButton: TButton;
  33.     CloseBtn: TButton;
  34.     SectionName: TEdit;
  35.     SectionNameLabel: TLabel;
  36.     SectionList: TDrawGrid;
  37.     ButtonsList: TDrawGrid;
  38.     LabelHint: TLabel;
  39.     PopupMenu: TPopupMenu;
  40.     CopyMenu: TMenuItem;
  41.     PasteMenu: TMenuItem;
  42.     CutMenu: TMenuItem;
  43.     FormPlacement1: TFormPlacement;
  44.     procedure DelSectionClick(Sender: TObject);
  45.     procedure AddButtonClick(Sender: TObject);
  46.     procedure RemoveButtonClick(Sender: TObject);
  47.     procedure CloseBtnClick(Sender: TObject);
  48.     procedure UpBtnClick(Sender: TObject);
  49.     procedure DownBtnClick(Sender: TObject);
  50.     procedure FormClose(Sender: TObject; var Action: TCloseAction);
  51.     procedure SectionNameExit(Sender: TObject);
  52.     procedure SectionListSelectCell(Sender: TObject; Col, Row: Longint;
  53.       var CanSelect: Boolean);
  54.     procedure SectionListDrawCell(Sender: TObject; Col, Row: Longint;
  55.       Rect: TRect; State: TGridDrawState);
  56.     procedure ButtonsListDblClick(Sender: TObject);
  57.     procedure ButtonsListKeyDown(Sender: TObject; var Key: Word;
  58.       Shift: TShiftState);
  59.     procedure ButtonsListMouseDown(Sender: TObject; Button: TMouseButton;
  60.       Shift: TShiftState; X, Y: Integer);
  61.     procedure ButtonsListMouseMove(Sender: TObject; Shift: TShiftState; X,
  62.       Y: Integer);
  63.     procedure ButtonsListMouseUp(Sender: TObject; Button: TMouseButton;
  64.       Shift: TShiftState; X, Y: Integer);
  65.     procedure ButtonsListSelectCell(Sender: TObject; Col, Row: Longint;
  66.       var CanSelect: Boolean);
  67.     procedure FormCreate(Sender: TObject);
  68.     procedure FormDestroy(Sender: TObject);
  69.     procedure NewSectionClick(Sender: TObject);
  70.     procedure SectionNameKeyDown(Sender: TObject; var Key: Word;
  71.       Shift: TShiftState);
  72.     procedure ButtonsListDrawCell(Sender: TObject; Col, Row: Longint;
  73.       Rect: TRect; State: TGridDrawState);
  74.     procedure SectionListMouseDown(Sender: TObject; Button: TMouseButton;
  75.       Shift: TShiftState; X, Y: Integer);
  76.     procedure SectionListDragDrop(Sender, Source: TObject; X, Y: Integer);
  77.     procedure SectionListDragOver(Sender, Source: TObject; X, Y: Integer;
  78.       State: TDragState; var Accept: Boolean);
  79.     procedure SectionListKeyDown(Sender: TObject; var Key: Word;
  80.       Shift: TShiftState);
  81.     procedure CopyMenuClick(Sender: TObject);
  82.     procedure PasteMenuClick(Sender: TObject);
  83.     procedure CutMenuClick(Sender: TObject);
  84.     procedure FormShow(Sender: TObject);
  85.   private
  86.     { Private declarations }
  87.     FButton: TBtnControl;
  88.     FImage: TButtonImage;
  89.     FBar: TSpeedBar;
  90.     FDrag: Boolean;
  91.     FDragItem: TSpeedItem;
  92.     FLocked: Integer;
  93.     FSelectData: TSelectData;
  94.     procedure Copy;
  95.     procedure Cut;
  96.     procedure Paste;
  97.     procedure OnPasteItem(Item: TObject);
  98.     procedure SaveSelection;
  99.     procedure RestoreSelection;
  100.     procedure SelectButton(Section: Integer; Item: TSpeedItem; SelectBar: Boolean);
  101.     procedure UpdateEnabled(BtnRow, Section: Integer);
  102.     function CheckSpeedBar: Boolean;
  103.     function ConfirmDelete: Boolean;
  104.     function CurrentSection: Integer;
  105.     function GetForm: TCustomForm;
  106.     procedure SetSection(Section: Integer);
  107.     procedure UpdateData;
  108.     procedure UpdateListHeight;
  109.     procedure SetSpeedBar(Value: TSpeedBar);
  110.     function ItemByRow(Row: Integer): TSpeedItem;
  111.     function SectionByRow(Row: Integer): TSpeedbarSection;
  112.     function ItemBySectionRow(Section, Row: Integer): TSpeedItem;
  113.     procedure CMSpeedBarChanged(var Message: TMessage); message CM_SPEEDBARCHANGED;
  114.   protected
  115.     procedure Activated; override;
  116.     function UniqueName(Component: TComponent): string; override;
  117.   public
  118.     { Public declarations }
  119.     procedure ItemsModified(const Designer : IDesigner); override;
  120.     procedure DesignerClosed(const ADesigner: IDesigner; AGoingDormant: Boolean); override;
  121.     function GetEditState: TEditState; override;
  122.     function EditAction(Action: TEditAction) : Boolean; override;
  123.     property SpeedBar: TSpeedBar read FBar write SetSpeedBar;
  124.     property OwnerForm: TCustomForm read GetForm;
  125.   end;
  126. { TSpeedbarCompEditor }
  127.   TSpeedbarCompEditor = class(TComponentEditor)
  128.     procedure ExecuteVerb(Index: Integer); override;
  129.     function GetVerb(Index: Integer): string; override;
  130.     function GetVerbCount: Integer; override;
  131.   end;
  132. implementation
  133. uses TypInfo, MaxMin, RXLConst, RxProps, RxDsgn;
  134. {$R *.DFM}
  135. {$IFDEF WIN32}
  136.  {$D-}
  137. {$ENDIF}
  138. {$IFDEF RX_D4}
  139. type
  140.   TDesigner = IDesigner;
  141.   TFormDesigner = IDesigner;
  142. {$ENDIF}
  143. { Utility routines }
  144. function FindEditor(Speedbar: TSpeedbar): TSpeedbarEditor;
  145. var
  146.   I: Integer;
  147. begin
  148.   Result := nil;
  149.   for I := 0 to Screen.FormCount - 1 do begin
  150.     if Screen.Forms[I] is TSpeedbarEditor then begin
  151.       if TSpeedbarEditor(Screen.Forms[I]).SpeedBar = SpeedBar then
  152.       begin
  153.         Result := TSpeedbarEditor(Screen.Forms[I]);
  154.         Break;
  155.       end;
  156.     end;
  157.   end;
  158. end;
  159. procedure ShowSpeedbarDesigner(Designer: TDesigner; Speedbar: TSpeedbar);
  160. var
  161.   Editor: TSpeedbarEditor;
  162. begin
  163.   if Speedbar = nil then Exit;
  164.   Editor := FindEditor(Speedbar);
  165.   if Editor <> nil then begin
  166.     Editor.Show;
  167.     if Editor.WindowState = wsMinimized then Editor.WindowState := wsNormal;
  168.   end
  169.   else begin
  170.     Editor := TSpeedbarEditor.Create(Application);
  171.     try
  172.       Editor.Designer := TFormDesigner(Designer);
  173.       Editor.Speedbar := Speedbar;
  174.       Editor.Show;
  175.     except
  176.       Editor.Free;
  177.       raise;
  178.     end;
  179.   end;
  180. end;
  181. { TSpeedbarCompEditor }
  182. procedure TSpeedbarCompEditor.ExecuteVerb(Index: Integer);
  183. begin
  184.   case Index of
  185.     0: ShowSpeedbarDesigner(Designer, TSpeedbar(Component));
  186.   end;
  187. end;
  188. function TSpeedbarCompEditor.GetVerb(Index: Integer): string;
  189. begin
  190.   case Index of
  191.     0: Result := LoadStr(srSpeedbarDesigner);
  192.   end;
  193. end;
  194. function TSpeedbarCompEditor.GetVerbCount: Integer;
  195. begin
  196.   Result := 1;
  197. end;
  198. { TSpeedbarEditor }
  199. const
  200.   MaxBtnListHeight = 158;
  201. function TSpeedbarEditor.UniqueName(Component: TComponent): string;
  202. var
  203.   Temp: string;
  204. begin
  205.   Result := '';
  206.   if (Component <> nil) then Temp := Component.ClassName
  207.   else Temp := TSpeedItem.ClassName;
  208.   if (UpCase(Temp[1]) = 'T') and (Length(Temp) > 1) then
  209.     System.Delete(Temp, 1, 1);
  210.   Result := Designer.UniqueName(Temp);
  211. end;
  212. function TSpeedbarEditor.GetEditState: TEditState;
  213. begin
  214.   Result := [];
  215.   if RemoveButton.Enabled then begin
  216.     Result := [esCanDelete, esCanCut, esCanCopy];
  217.   end;
  218.   if AddButton.Enabled and ClipboardComponents then
  219.     Include(Result, esCanPaste);
  220. end;
  221. function TSpeedbarEditor.EditAction(Action: TEditAction) : Boolean;
  222. begin
  223.   Result := True;
  224.   case Action of
  225.     eaCut: Cut;
  226.     eaCopy: Copy;
  227.     eaPaste: Paste;
  228.     eaDelete: RemoveButtonClick(Self);
  229.   end;
  230. end;
  231. procedure TSpeedbarEditor.SelectButton(Section: Integer; Item: TSpeedItem;
  232.   SelectBar: Boolean);
  233. var
  234.   FCompList: IDesignerSelections;
  235.   Sect: TSpeedbarSection;
  236. begin
  237.   if CheckSpeedBar and Active then begin
  238.     //Designer.GetSelections(FCompList);
  239.     FCompList := CreateSelectionList;
  240.     if not SelectBar then begin
  241.       if (ActiveControl = SectionList) or (ActiveControl = SectionName) then
  242.       begin
  243.         Sect := SectionByRow(Section);
  244.         if Sect <> nil then FCompList.Add(Sect);
  245.       end;
  246.       if (FCompList.Count = 0) and (Item <> nil) then FCompList.Add(Item);
  247.     end;
  248.     if (FBar <> nil) and (FCompList.Count = 0) then FCompList.Add(FBar);
  249.     SetSelection(FCompList);
  250.   end;
  251. end;
  252. procedure TSpeedbarEditor.DesignerClosed(const ADesigner: IDesigner; AGoingDormant: Boolean);
  253. begin
  254.   if ADesigner.Root = OwnerForm then Free;
  255. end;
  256. procedure TSpeedbarEditor.ItemsModified(const Designer : IDesigner);
  257. begin
  258.   if not (csDestroying in ComponentState) then UpdateData;
  259. end;
  260. procedure TSpeedbarEditor.Activated;
  261. begin
  262.   SelectButton(CurrentSection, ItemByRow(ButtonsList.Row), False);
  263.   PasteMenu.Enabled := CheckSpeedBar and (FBar.SectionCount > 0) and
  264.     ClipboardComponents;
  265. end;
  266. function TSpeedbarEditor.ConfirmDelete: Boolean;
  267. begin
  268.   Result := MessageDlg(LoadStr(srConfirmSBDelete), mtWarning, mbYesNoCancel, 0) = mrYes;
  269. end;
  270. procedure TSpeedbarEditor.SaveSelection;
  271. begin
  272.   with FSelectData do begin
  273.     bRowCount := ButtonsList.RowCount;
  274.     bRow := ButtonsList.Row;
  275.     sRowCount := SectionList.RowCount;
  276.     sRow := SectionList.Row;
  277.   end;
  278. end;
  279. procedure TSpeedbarEditor.RestoreSelection;
  280. var
  281.   NewSRow, NewBRow: Integer;
  282. begin
  283.   NewSRow := FSelectData.sRow;
  284.   if (SectionList.RowCount > FSelectData.sRowCount) or
  285.     (NewSRow > SectionList.RowCount - 1) then
  286.     NewSRow := SectionList.RowCount - 1;
  287.   if NewSRow < 0 then NewSRow := 0;
  288.   SectionList.Row := NewSRow;
  289.   SetSection(SectionList.Row); { set ButtonsList to current section }
  290.   NewBRow := FSelectData.bRow;
  291.   if (ButtonsList.RowCount > FSelectData.bRowCount) or
  292.     (NewBRow > ButtonsList.RowCount - 1) then
  293.     NewBRow := ButtonsList.RowCount - 1;
  294.   if NewBRow < 0 then NewBRow := 0;
  295.   ButtonsList.Row := NewBRow;
  296. end;
  297. procedure TSpeedbarEditor.UpdateEnabled(BtnRow, Section: Integer);
  298. var
  299.   EnableSect, EnableBtn: Boolean;
  300. begin
  301.   EnableSect := CheckSpeedBar and (FBar.SectionCount > 0);
  302.   EnableBtn := EnableSect and (BtnRow >= 0) and (ItemBySectionRow(Section,
  303.     BtnRow) <> nil);
  304.   DelSection.Enabled := EnableSect;
  305.   SectionName.Enabled := EnableSect;
  306.   AddButton.Enabled := EnableSect;
  307.   RemoveButton.Enabled := EnableBtn;
  308.   CopyMenu.Enabled := EnableBtn;
  309.   CutMenu.Enabled := EnableBtn;
  310.   PasteMenu.Enabled := EnableSect and ClipboardComponents;
  311.   UpBtn.Enabled := EnableBtn and (BtnRow > 0);
  312.   DownBtn.Enabled := EnableBtn and (BtnRow < ButtonsList.RowCount - 1);
  313. end;
  314. function TSpeedbarEditor.CheckSpeedBar: Boolean;
  315. begin
  316.   Result := (FBar <> nil) and (FBar.Owner <> nil) and (FBar.Parent <> nil)
  317.     and (Designer.Root <> nil);
  318. end;
  319. function TSpeedbarEditor.CurrentSection: Integer;
  320. begin
  321.   if CheckSpeedBar and (FBar.SectionCount > 0) then
  322.     Result := SectionList.Row
  323.   else Result := -1;
  324. end;
  325. procedure TSpeedbarEditor.SetSection(Section: Integer);
  326. var
  327.   I: Integer;
  328. begin
  329.   if CheckSpeedBar then begin
  330.     I := Section;
  331.     if (I >= 0) and (I < FBar.SectionCount) then begin
  332.       SectionName.Text := TSpeedbarSection(FBar.Sections[I]).Caption;
  333.       ButtonsList.RowCount := FBar.ItemsCount(I);
  334.     end
  335.     else begin
  336.       SectionName.Text := '';
  337.       ButtonsList.RowCount := 0;
  338.     end;
  339.     SectionList.DefaultColWidth := SectionList.ClientWidth;
  340.     ButtonsList.DefaultColWidth := ButtonsList.ClientWidth;
  341.   end;
  342. end;
  343. procedure TSpeedbarEditor.UpdateData;
  344. begin
  345.   Inc(FLocked);
  346.   try
  347.     SaveSelection;
  348.     if CheckSpeedBar then SectionList.RowCount := FBar.SectionCount
  349.     else SectionList.RowCount := 0;
  350.     RestoreSelection; { set section }
  351.   finally
  352.     Dec(FLocked);
  353.   end;
  354.   UpdateEnabled(ButtonsList.Row, SectionList.Row);
  355.   SelectButton(CurrentSection, ItemByRow(ButtonsList.Row), False);
  356. end;
  357. function TSpeedbarEditor.GetForm: TCustomForm;
  358. begin
  359.   Result := TCustomForm(Designer.Root); { GetParentForm(FBar) }
  360. end;
  361. procedure TSpeedbarEditor.UpdateListHeight;
  362. var
  363.   Cnt: Integer;
  364.   MaxHeight: Integer;
  365. begin
  366.   Canvas.Font := Font;
  367.   MaxHeight := MulDiv(MaxBtnListHeight, Screen.PixelsPerInch, 96);
  368.   ButtonsList.DefaultRowHeight := FBar.BtnHeight + 2;
  369.   Cnt := Max(1, Max(ButtonsList.ClientHeight, MaxHeight) div
  370.     (FBar.BtnHeight + 2));
  371.   ButtonsList.ClientHeight := Min(ButtonsList.DefaultRowHeight * Cnt,
  372.     MaxHeight);
  373.   SectionList.DefaultRowHeight := Canvas.TextHeight('Wg') + 2;
  374. end;
  375. procedure TSpeedbarEditor.SetSpeedBar(Value: TSpeedBar);
  376. var
  377.   I: Integer;
  378. begin
  379.   if FBar <> Value then begin
  380.     if FBar <> nil then FBar.SetEditing(0);
  381.     FBar := Value;
  382.     if FBar <> nil then FBar.SetEditing(Handle);
  383.     Inc(FLocked);
  384.     try
  385.       if FBar <> nil then UpdateListHeight;
  386.       if FBar.SectionCount = 0 then NewSectionClick(Self)
  387.       else
  388.         for I := 0 to FBar.SectionCount - 1 do begin
  389.           if FBar.Sections[I].Name = '' then begin
  390.             FBar.Sections[I].Name := UniqueName(FBar.Sections[I]);
  391.             Designer.Modified;
  392.           end;
  393.         end;
  394.       if ButtonsList.RowCount > 0 then ActiveControl := ButtonsList
  395.       else ActiveControl := SectionList;
  396.       UpdateData;
  397.       ButtonsList.Row := 0;
  398.     finally
  399.       Dec(FLocked);
  400.     end;
  401.     SectionList.Row := 0;
  402.   end;
  403. end;
  404. procedure TSpeedbarEditor.CMSpeedBarChanged(var Message: TMessage);
  405. begin
  406.   if Pointer(Message.LParam) = FBar then begin
  407.     case Message.WParam of
  408.       SBR_CHANGED: Designer.Modified;
  409.       SBR_DESTROYED: Close;
  410.       SBR_BTNSIZECHANGED: if FBar <> nil then UpdateListHeight;
  411.     end;
  412.   end
  413.   else if (Message.WParam = SBR_BTNSELECT) and CheckSpeedBar then begin
  414.     SelectButton(-1, nil, True);
  415.     Designer.Modified;
  416.   end;
  417. end;
  418. function TSpeedbarEditor.ItemBySectionRow(Section, Row: Integer): TSpeedItem;
  419. begin
  420.   if CheckSpeedBar then Result := FBar.Items(Section, Row)
  421.   else Result := nil;
  422. end;
  423. function TSpeedbarEditor.SectionByRow(Row: Integer): TSpeedbarSection;
  424. begin
  425.   if CheckSpeedBar and (Row >= 0) and (Row < FBar.SectionCount) then
  426.     Result := FBar.Sections[Row]
  427.   else Result := nil;
  428. end;
  429. function TSpeedbarEditor.ItemByRow(Row: Integer): TSpeedItem;
  430. begin
  431.   Result := ItemBySectionRow(CurrentSection, Row);
  432. end;
  433. procedure TSpeedbarEditor.NewSectionClick(Sender: TObject);
  434. var
  435.   S: string;
  436.   I: Integer;
  437. begin
  438.   if CheckSpeedBar then begin
  439.     I := 0;
  440.     repeat
  441.       S := Format(LoadStr(srNewSectionName), [I]);
  442.       Inc(I);
  443.     until FBar.SearchSection(S) < 0;
  444.     I := NewSpeedSection(FBar, S);
  445.     if I >= 0 then FBar.Sections[I].Name := UniqueName(FBar.Sections[I]);
  446.     ActiveControl := SectionName;
  447.     Designer.Modified;
  448.   end;
  449. end;
  450. procedure TSpeedbarEditor.DelSectionClick(Sender: TObject);
  451. var
  452.   Sect: Integer;
  453.   Item: TSpeedItem;
  454. begin
  455.   if CheckSpeedBar and ConfirmDelete then begin
  456.     Sect := SectionList.Row;
  457.     if (Sect >= 0) and (Sect < FBar.SectionCount) then begin
  458.       Self.ValidateRename(FBar.Sections[Sect],
  459.         FBar.Sections[Sect].Name, '');
  460.       try
  461.         while FBar.ItemsCount(Sect) > 0 do begin
  462.           Item := FBar.Items(Sect, 0);
  463.           if Item <> nil then begin
  464.             OwnerForm.RemoveComponent(Item);
  465.             Item.Free;
  466.           end;
  467.         end;
  468.         FBar.RemoveSection(Sect);
  469.       finally
  470.         Designer.Modified;
  471.       end;
  472.     end;
  473.   end;
  474. end;
  475. procedure TSpeedbarEditor.Copy;
  476. var
  477.   CompList: IDesignerSelections;
  478.   Item: TSpeedItem;
  479. begin
  480.   CompList := CreateSelectionList;
  481.   try
  482.     Item := ItemByRow(ButtonsList.Row);
  483.     if Item <> nil then begin
  484.       Item.InvalidateItem;
  485.       CompList.Add(Item);
  486.       CopyComponents(OwnerForm, CompList);
  487.       Item.UpdateSection;
  488.     end;
  489.   finally
  490.     //CompList.Free;
  491.   end;
  492. end;
  493. procedure TSpeedbarEditor.Paste;
  494. var
  495.   CompList: IDesignerSelections;
  496. begin
  497.   if CheckSpeedBar then begin
  498.     CompList := CreateSelectionList;
  499.     try
  500.       FBar.OnAddItem := OnPasteItem;
  501.       try
  502.         PasteComponents(OwnerForm, FBar, CompList);
  503.       finally
  504.         FBar.OnAddItem := nil;
  505.       end;
  506.       UpdateData;
  507.     finally
  508.       //CompList.Free;
  509.     end;
  510.   end;
  511. end;
  512. procedure TSpeedbarEditor.Cut;
  513. begin
  514.   Copy;
  515.   RemoveButtonClick(Self);
  516. end;
  517. procedure TSpeedbarEditor.OnPasteItem(Item: TObject);
  518. begin
  519.   if (Item <> nil) then begin
  520.     if CheckSpeedBar and (Item is TSpeedItem) then begin
  521.       TSpeedItem(Item).ASection := CurrentSection;
  522.       TSpeedItem(Item).Visible := False;
  523.     end
  524.   end;
  525. end;
  526. procedure TSpeedbarEditor.AddButtonClick(Sender: TObject);
  527. var
  528.   I: Integer;
  529.   Item: TSpeedItem;
  530. begin
  531.   I := CurrentSection;
  532.   if I < 0 then Exit;
  533.   Item := TSpeedItem.Create(OwnerForm);
  534.   if Item <> nil then
  535.     try
  536.       FBar.AddItem(I, Item);
  537.       Item.Name := UniqueName(Item);
  538.       Designer.Modified;
  539.       if (Sender <> nil) then ActivateInspector(#0);
  540.     except
  541.       Item.Free;
  542.       raise;
  543.     end
  544.   else raise ESpeedbarError.CreateRes(srSBItemNotCreate);
  545. end;
  546. procedure TSpeedbarEditor.RemoveButtonClick(Sender: TObject);
  547. var
  548.   Item: TSpeedItem;
  549. begin
  550.   Item := ItemByRow(ButtonsList.Row);
  551.   if Item <> nil then begin
  552.     Self.ValidateRename(Item, Item.Name, '');
  553.     OwnerForm.RemoveComponent(Item);
  554.     Item.Free;
  555.     Designer.Modified;
  556.   end;
  557. end;
  558. procedure TSpeedbarEditor.CloseBtnClick(Sender: TObject);
  559. begin
  560.   Close;
  561. end;
  562. procedure TSpeedbarEditor.UpBtnClick(Sender: TObject);
  563. var
  564.   I, Sect: Integer;
  565. begin
  566.   if CheckSpeedBar and FBar.FindItem(ItemByRow(ButtonsList.Row), Sect, I) then
  567.   begin
  568.     if I > 0 then begin
  569.       FBar.Sections[Sect].List.Move(I, I - 1);
  570.       Designer.Modified;
  571.       ButtonsList.Invalidate;
  572.       ButtonsList.Row := ButtonsList.Row - 1;
  573.     end;
  574.   end;
  575. end;
  576. procedure TSpeedbarEditor.DownBtnClick(Sender: TObject);
  577. var
  578.   I, Sect: Integer;
  579. begin
  580.   if CheckSpeedBar and FBar.FindItem(ItemByRow(ButtonsList.Row), Sect, I) then
  581.   begin
  582.     if I < FBar.ItemsCount(Sect) - 1 then begin
  583.       FBar.Sections[Sect].List.Move(I, I + 1);
  584.       Designer.Modified;
  585.       ButtonsList.Invalidate;
  586.       ButtonsList.Row := ButtonsList.Row + 1;
  587.     end;
  588.   end;
  589. end;
  590. procedure TSpeedbarEditor.CopyMenuClick(Sender: TObject);
  591. begin
  592.   Copy;
  593. end;
  594. procedure TSpeedbarEditor.PasteMenuClick(Sender: TObject);
  595. begin
  596.   Paste;
  597. end;
  598. procedure TSpeedbarEditor.CutMenuClick(Sender: TObject);
  599. begin
  600.   Cut;
  601. end;
  602. procedure TSpeedbarEditor.SectionNameExit(Sender: TObject);
  603. var
  604.   I: Integer;
  605. begin
  606.   if CheckSpeedBar and (FBar.SectionCount > 0) then begin
  607.     I := CurrentSection;
  608.     if I >= 0 then begin
  609.       FBar.Sections[I].Caption := SectionName.Text;
  610.       Designer.Modified;
  611.     end;
  612.   end;
  613. end;
  614. procedure TSpeedbarEditor.SectionListSelectCell(Sender: TObject; Col,
  615.   Row: Longint; var CanSelect: Boolean);
  616. begin
  617.   CanSelect := False;
  618.   if CheckSpeedBar and (Row < FBar.SectionCount) and (Row >= 0) then begin
  619.     if FLocked = 0 then begin
  620.       SetSection(Row);
  621.       UpdateEnabled(ButtonsList.Row, Row);
  622.       ButtonsList.Invalidate;
  623.       SelectButton(Row, ItemBySectionRow(Row, ButtonsList.Row), False);
  624.     end;
  625.     CanSelect := True;
  626.   end;
  627. end;
  628. procedure TSpeedbarEditor.SectionListDrawCell(Sender: TObject; Col,
  629.   Row: Longint; Rect: TRect; State: TGridDrawState);
  630. begin
  631.   if CheckSpeedBar then begin
  632.     if (Row < FBar.SectionCount) and (Row >= 0) then begin
  633.       DrawCellText(Sender as TDrawGrid, Col, Row,
  634.         FBar.Sections[Row].Caption, Rect, taLeftJustify, vaCenter
  635.         {$IFDEF RX_D4}, TDrawGrid(Sender).IsRightToLeft {$ENDIF});
  636.     end;
  637.   end;
  638. end;
  639. procedure TSpeedbarEditor.SectionListKeyDown(Sender: TObject;
  640.   var Key: Word; Shift: TShiftState);
  641. begin
  642.   case Key of
  643.     VK_RETURN: if SectionByRow(SectionList.Row) <> nil then ActivateInspector(#0);
  644.     VK_DELETE: DelSectionClick(Self);
  645.     VK_INSERT, VK_ADD: NewSectionClick(Self);
  646.     else Exit;
  647.   end;
  648.   Key := 0;
  649. end;
  650. procedure TSpeedbarEditor.ButtonsListKeyDown(Sender: TObject;
  651.   var Key: Word; Shift: TShiftState);
  652. begin
  653.   case Key of
  654.     VK_RETURN: if ItemByRow(ButtonsList.Row) <> nil then ActivateInspector(#0);
  655.     VK_DELETE: RemoveButtonClick(Self);
  656.     VK_INSERT, VK_ADD: AddButtonClick(Self);
  657.     else Exit;
  658.   end;
  659.   Key := 0;
  660. end;
  661. procedure TSpeedbarEditor.ButtonsListDblClick(Sender: TObject);
  662. type
  663.   PParamData = ^TParamData;
  664.   TParamData = record
  665.     Flags: TParamFlags;
  666.     ParamNameAndType: array[0..100] of Char;
  667.   end;
  668. const
  669. {$IFDEF CBUILDER}
  670.   sSender: string[7] = '*Sender';
  671. {$ELSE}
  672.   sSender: string[6] = 'Sender';
  673. {$ENDIF}
  674.   sObject: string[7] = 'TObject';
  675. var
  676.   Btn: TSpeedItem;
  677.   I, Num: Integer;
  678.   MethodName: string;
  679.   Method: TMethod;
  680.   TypeData: PTypeData;
  681.   ParamData: PParamData;
  682.   PropInfo: PPropInfo;
  683.   Candidates: TPropInfoList;
  684. begin
  685.   Btn := ItemByRow(ButtonsList.Row);
  686.   if Btn = nil then Exit;
  687.   Candidates := TPropInfoList.Create(Btn, [tkMethod]);
  688.   try
  689.     for I := Candidates.Count - 1 downto 0 do begin
  690.       PropInfo := Candidates[I];
  691.       if CompareText(PropInfo^.Name, 'OnClick') = 0 then begin
  692.         Method := GetMethodProp(Btn, PropInfo);
  693.         MethodName := TFormDesigner(Designer).GetMethodName(Method);
  694.         if MethodName = '' then begin
  695.           MethodName := Btn.Name + 'Click';
  696.           Num := 0;
  697.           while TFormDesigner(Designer).MethodExists(MethodName) do begin
  698.             MethodName := Btn.Name + 'Click' + IntToStr(Num);
  699.             Inc(Num);
  700.           end;
  701.           TypeData := AllocMem(SizeOf(TTypeData));
  702.           try
  703.             TypeData^.MethodKind := mkProcedure;
  704.             TypeData^.ParamCount := 1;
  705.             ParamData := PParamData(@TypeData^.ParamList);
  706.             with ParamData^ do begin
  707.               Flags := [];
  708.               ParamNameAndType[0] := Char(Length(sSender));
  709.               Move(sSender[1], ParamNameAndType[1], Length(sSender));
  710.               ParamNameAndType[Length(sSender) + 1] := char(Length(sObject));
  711.               Move(sObject[1], ParamNameAndType[Length(sSender) + 2],
  712.                 Length(sObject));
  713.             end;
  714.             Method := TFormDesigner(Designer).CreateMethod(MethodName, TypeData);
  715.             Method.Data := OwnerForm;
  716.           finally
  717.             FreeMem(TypeData, SizeOf(TTypeData));
  718.           end;
  719.           Btn.OnClick := TNotifyEvent(Method);
  720.           Designer.Modified;
  721.         end;
  722.         if (MethodName <> '') and TFormDesigner(Designer).MethodExists(MethodName) then
  723.           TFormDesigner(Designer).ShowMethod(MethodName);
  724.         Break;
  725.       end;
  726.     end;
  727.   finally
  728.     Candidates.Free;
  729.   end;
  730. end;
  731. procedure TSpeedbarEditor.ButtonsListMouseDown(Sender: TObject;
  732.   Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  733. var
  734.   Item: TSpeedItem;
  735. begin
  736.   if (X < FBar.BtnWidth + 2) and (Button = mbLeft) then
  737.   begin
  738.     Item := ItemByRow(ButtonsList.Row);
  739.     if Item <> nil then begin
  740.       FDrag := True;
  741.       if Item.Visible then FDragItem := nil
  742.       else begin
  743.         FDragItem := Item;
  744.         if FButton = nil then begin
  745.           FButton := TBtnControl.Create(Self);
  746.           TBtnControl(FButton).AssignSpeedItem(Item);
  747.         end;
  748.       end;
  749.     end;
  750.   end;
  751. end;
  752. procedure TSpeedbarEditor.ButtonsListMouseMove(Sender: TObject;
  753.   Shift: TShiftState; X, Y: Integer);
  754. var
  755.   P: TPoint;
  756. begin
  757.   if FDrag and (FButton <> nil) and (FDragItem <> nil) then begin
  758.     P := (Sender as TControl).ClientToScreen(Point(X, Y));
  759.     X := P.X - (FButton.Width {div 2});
  760.     Y := P.Y - (FButton.Height {div 2});
  761.     FButton.Activate(Bounds(X, Y, FBar.BtnWidth, FBar.BtnHeight));
  762.   end
  763.   else if FDrag then SetCursor(Screen.Cursors[crNoDrop]);
  764. end;
  765. procedure TSpeedbarEditor.ButtonsListMouseUp(Sender: TObject;
  766.   Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  767. var
  768.   P: TPoint;
  769. begin
  770.   if FDrag and (Button = mbLeft) then
  771.   try
  772.     if (FDragItem <> nil) and (FButton <> nil) then begin
  773.       Dec(X, FButton.Width {div 2});
  774.       Dec(Y, FButton.Height {div 2});
  775.       P := (Sender as TControl).ClientToScreen(Point(X, Y));
  776.       FButton.Free;
  777.       FButton := nil;
  778.       if CheckSpeedBar and (FBar = FindSpeedBar(P)) then begin
  779.         P := FBar.ScreenToClient(P);
  780.         if FBar.AcceptDropItem(FDragItem, P.X, P.Y) then begin
  781.           Designer.Modified;
  782.         end;
  783.       end;
  784.     end
  785.     else SetCursor(Screen.Cursors[ButtonsList.Cursor]);
  786.   finally
  787.     FDrag := False;
  788.     FDragItem := nil;
  789.   end;
  790. end;
  791. procedure TSpeedbarEditor.ButtonsListSelectCell(Sender: TObject; Col,
  792.   Row: Longint; var CanSelect: Boolean);
  793. var
  794.   Item: TSpeedItem;
  795. begin
  796.   Item := ItemByRow(Row);
  797.   CanSelect := not FDrag and (Item <> nil);
  798.   if FLocked = 0 then begin
  799.     if CanSelect then begin
  800.       UpdateEnabled(Row, SectionList.Row);
  801.       SelectButton(CurrentSection, Item, False);
  802.     end
  803.     else if not FDrag then begin
  804.       UpdateEnabled(-1, SectionList.Row);
  805.       SelectButton(-1, nil, True);
  806.     end;
  807.   end;
  808. end;
  809. procedure TSpeedbarEditor.FormCreate(Sender: TObject);
  810. begin
  811.   FImage := TButtonImage.Create;
  812.   FButton := nil;
  813.   FBar := nil;
  814.   FDrag := False;
  815.   if NewStyleControls then Font.Style := [];
  816.   with FormPlacement1 do begin
  817.     UseRegistry := True;
  818.     IniFileName := SDelphiKey;
  819.   end;
  820. end;
  821. procedure TSpeedbarEditor.FormDestroy(Sender: TObject);
  822. begin
  823.   FImage.Free;
  824. end;
  825. procedure TSpeedbarEditor.FormClose(Sender: TObject; var Action: TCloseAction);
  826. begin
  827.   Action := caFree;
  828.   FButton.Free;
  829.   FButton := nil;
  830.   if FBar <> nil then begin
  831.     FBar.SetEditing(0);
  832.     SelectButton(-1, nil, True);
  833.     FBar.Invalidate;
  834.   end;
  835.   FBar := nil;
  836. end;
  837. procedure TSpeedbarEditor.SectionNameKeyDown(Sender: TObject;
  838.   var Key: Word; Shift: TShiftState);
  839. begin
  840.   if Key = (VK_RETURN) then begin
  841.     SectionNameExit(SectionName);
  842.     Key := 0;
  843.     ActiveControl := SectionList;
  844.   end;
  845. end;
  846. procedure TSpeedbarEditor.ButtonsListDrawCell(Sender: TObject; Col,
  847.   Row: Longint; Rect: TRect; State: TGridDrawState);
  848. var
  849.   I: Integer;
  850. begin
  851.   I := CurrentSection;
  852.   if (I >= 0) and (Row < FBar.ItemsCount(I)) then
  853.     DrawCellButton(Sender as TDrawGrid, Rect, ItemByRow(Row), FImage
  854.       {$IFDEF RX_D4}, TDrawGrid(Sender).IsRightToLeft {$ENDIF});
  855. end;
  856. procedure TSpeedbarEditor.SectionListMouseDown(Sender: TObject;
  857.   Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  858. var
  859.   ACol, ARow: Longint;
  860. begin
  861.   if (Button = mbLeft) then
  862.     with (Sender as TDrawGrid) do begin
  863.       MouseToCell(X, Y, ACol, ARow);
  864.       Tag := Row;
  865.       BeginDrag(False);
  866.     end;
  867. end;
  868. procedure TSpeedbarEditor.SectionListDragDrop(Sender, Source: TObject; X,
  869.   Y: Integer);
  870. var
  871.   Col, Row: Longint;
  872. begin
  873.   try
  874.     (Sender as TDrawGrid).MouseToCell(X, Y, Col, Row);
  875.     FBar.Sections[(Sender as TDrawGrid).Tag].Index := Row;
  876.     Designer.Modified;
  877.     UpdateData;
  878.     SectionList.Row := Row;
  879.   finally
  880.     (Sender as TDrawGrid).Tag := 0;
  881.   end;
  882. end;
  883. procedure TSpeedbarEditor.SectionListDragOver(Sender, Source: TObject; X,
  884.   Y: Integer; State: TDragState; var Accept: Boolean);
  885. var
  886.   Col, Row: Longint;
  887. begin
  888.   (Sender as TDrawGrid).MouseToCell(X, Y, Col, Row);
  889.   Accept := (Row >= 0) and (Row <> (Sender as TDrawGrid).Tag);
  890. end;
  891. procedure TSpeedbarEditor.FormShow(Sender: TObject);
  892. begin
  893.   if FBar <> nil then UpdateListHeight;
  894.   SectionList.DefaultColWidth := SectionList.ClientWidth;
  895.   ButtonsList.DefaultColWidth := ButtonsList.ClientWidth;
  896. end;
  897. end.