-
При написание редакторов компонента при перекрытии GetVerb и GetVerbCount добавляются пункты к стандартному меню. Что можно к пунктам добавлять подпукты, то есть раскрывающие менюшки, это точно. Я как-то это делал, но куда дел пример, забыл совсем :( Там, вроде, интерфейсы к TMenuItem предоставлялись, или как-то так.
-
Давно это было, игрался с картинками в менюшках (D6), потом методику рисования изменили (D7), а потом и совсем убрали D12, D16. Код переписывать было лень. Работу с Action можно выкинуть.
TBrDefaultEditor = class(TDefaultEditor)
private
procedure ActionExecute(Sender: TObject);
protected
procedure DesignerModified;
procedure PrepareMenuItem(Index: Integer; const Item: TMenuItem); virtual;
procedure GetCaption(Values: TStrings); virtual;
function CreateMenuItem(ParentItem: TMenuItem; Caption: string; Tag: integer; Checked: boolean; OnClick: TNotifyEvent): TMenuItem;
function FindAction(AL: TCustomActionList; AName: string): TContainedAction;
function CreateAction(AName, ACaption, BmpName: string; NumGlyph: integer): TContainedAction;
public
function GetVerb(Index: integer): string; override;
function GetVerbCount: integer; override;
procedure PrepareItem(Index: Integer; const AItem: IMenuItem); override;
constructor Create(AComponent: TComponent; ADesigner: IDesigner); override;
end;
constructor TBrDefaultEditor.Create(AComponent: TComponent; ADesigner: IDesigner);
var SL: TStringList;
i: integer;
begin
inherited Create(AComponent,ADesigner);
SL := TStringList.Create;
try
GetCaption(SL);
for i := 0 to SL.Count -1 do begin
if Pos('=',SL[i]) = 0 then Continue;
CreateAction(ClassName+'_'+IntToStr(i),SL.Names[i], SL.Values[SL.Names[i]],1);
end;
finally
SL.Free;
end;
end;
procedure TBrDefaultEditor.PrepareItem(Index: Integer; const AItem: IMenuItem);
var CompRef: IInterfaceComponentReference;
A: TContainedAction;
M: TMenuItem;
Event: TNotifyEvent;
begin
if Supports(AItem,IInterfaceComponentReference,CompRef) then
if CompRef.GetComponent is TMenuItem then begin
M := TMenuItem(CompRef.GetComponent);
if not Assigned(M.Action) and (Index < GetVerbCount) then begin
A := FindAction(nil,ClassName+'_'+IntToStr(Index));
if Assigned(A) then begin
Event := M.OnClick;
M.Action := A;
M.OnClick := Event;
end;
end;
PrepareMenuItem(Index, M);
end;
end;
procedure TBrDefaultEditor.ActionExecute(Sender: TObject);
begin
end;
procedure TBrDefaultEditor.DesignerModified;
begin
if Designer <> nil then Designer.Modified;
end;
procedure TBrDefaultEditor.GetCaption(Values: TStrings);
begin end;
function TBrDefaultEditor.CreateMenuItem;
begin
Result := TMenuItem.Create(ParentItem);
Result.Caption := Caption;
Result.Tag := Tag;
Result.Checked := Checked;
Result.OnClick := OnClick;
ParentItem.Add(Result);
end;
function TBrDefaultEditor.FindAction(AL: TCustomActionList; AName: string): TContainedAction;
var i: integer;
N: INTAServices;
begin
if not Assigned(AL) then begin
N := NTAServices;
if Assigned(N) then AL := N.ActionList;
end;
if Assigned(AL) then
for i := 0 to AL.ActionCount -1 do
if SameText(AL.Actions[i].Name,AName) then begin
Result := AL.Actions[i];
Exit;
end;
Result := nil;
end;
function TBrDefaultEditor.CreateAction;
var N: INTAServices;
AL: TCustomActionList;
AIndex: integer;
Bmp,Bmp16: TBitMap;
begin
Result := nil;
N := NTAServices;
if Assigned(N) then AL := N.ActionList else AL := nil;
if not Assigned(AL) then Exit;
Result := FindAction(AL,AName);
if Assigned(Result) then Exit;
Result := TAction.Create(AL);
AIndex := -1;
if FindResource(HInstance,PChar(BmpName), RT_BITMAP)>0 then begin
Bmp := TBitMap.Create;
Bmp.LoadFromResourceName(HInstance,BmpName);
Bmp16 := CreateBitMap(16,16);
Bmp16.Canvas.CopyRect(Rect(0,0,16,16),Bmp.Canvas,Rect(0,0,Bmp.Width div NumGlyph,Bmp.Height));
AIndex := N.ImageList.AddMasked(Bmp16,Bmp.Canvas.Pixels[0,Bmp.Height-1]);
Bmp.Free;
Bmp16.Free;
end;
with TAction(Result) do begin
ActionList := AL;
Name := AName;
Caption := ACaption;
ImageIndex := AIndex;
OnExecute := ActionExecute;
end;
end;
function TBrDefaultEditor.GetVerb(Index: integer): string;
var SL: TStringList;
begin
SL := TStringList.Create;
try
GetCaption(SL);
if Index < SL.Count
then Result := SL[Index]
else Result := Inherited GetVerb(Index);
finally
FreeObj(SL);
end;
end;
function TBrDefaultEditor.GetVerbCount: integer;
var SL: TStringList;
begin
SL := TStringList.Create;
try
GetCaption(SL);
Result := SL.Count;
finally
FreeObj(SL);
end;
end;
procedure TBrDefaultEditor.PrepareMenuItem(Index: Integer;const Item: TMenuItem);
begin
end;
И вот редактор для кнопки типа TBitBtn
TBrBitBtnEditors = class(TBrDefaultEditor)
protected
procedure PrepareMenuItem(Index: Integer; const Item: TMenuItem); override;
procedure KindMenuClick(Sender: TObject);
public
procedure GetCaption(Values: TStrings);override;
end;
procedure TBrBitBtnEditors.GetCaption(Values: TStrings);
begin
Values.Add('Kind');
end;
procedure TBrBitBtnEditors.KindMenuClick(Sender: TObject);
begin
TBrBitBtn(Component).Kind := TBrBitBtnKind(TMenuItem(Sender).Tag);
DesignerModified;
end;
procedure TBrBitBtnEditors.PrepareMenuItem(Index: Integer; const Item: TMenuItem);
var i: TBrBitBtnKind;
MenuItem: TMenuItem;
A: TAction;
S, BName: string;
begin
if Index = 0 then
for i := Low(TBrBitBtnKind) to High(TBrBitBtnKind) do begin
S := GetEnumName(TypeInfo(TBrBitBtnKind), ord(i));
BName := BitBtnResNames[i];
MenuItem := TMenuItem.Create(Item);
MenuItem.Tag := Ord(i);
A := CreateAction(ClassName+'_'+S,S,BName,2) as TAction;
MenuItem.Action := A;
if not Assigned(A) then MenuItem.Caption := S;
MenuItem.OnClick := KindMenuClick;
Item.Add(MenuItem);
end;
end;
-
Спасибо, буду пробовать. А вот про картинки не знал.
-
Какая версия стоит ???
-
7-я.
-
Кстати, сегодня утром всё получилось. procedure TStCodeEditorComponentEditor.PrepareItem(Index: Integer; const AItem: IMenuItem); begin inherited; Case Index of 0: ; //'Edit custom shortcuts'; 1: //'Edit bookmarks menu items'; Begin AItem.AddItem('Items "Toggle bookmarks"', 0, False, True, ToggleItemClick); AItem.AddItem('Items "Go to bookmarks"', 0, False, True, GoToItemClick); AItem.AddItem('Items "Show bookmarks"', 0, False, True, ShowBookmarkItemClick); End; 2: //'Edit built in replacer'; Begin AItem.AddItem('Edit menu items', 0, False, True, ReplacerMenuItemsClick); AItem.AddItem('Edit connected buttons', 0, False, True, ReplacerButtonsClick); End; 3: //'Edit menu items "Edit"' Begin AItem.AddItem('Items "Edit"', 0, False, True, ItemsEditClick); AItem.AddItem('Items "Selection protected"', 0, False, True, ProtectedItemClick); End; End; end;
Там надо подключать DesignMenus. Ваш код вообще ещё более широкую задачу решает. ОФФТОП: >DimaBr Вы мне писали, что такой код: procedure TCustomRichEdit.WMNCDestroy(var Message: TWMNCDestroy); begin inherited; end; кривой. Он и мне кривым кажется. Но пример, который повесил, взят из ExtCtrls. Дельфи 7. По-другому если делать, Дельфи гряно ругаются.
|