-
Для разных приложений потребуется одинаковый набор действий TAction. Хочу создать компонент - потомок TActionList и набор TAction. Можно ли создать такой компонент? То есть как я разумею, он при помещении на форму в Design-time должен создавать набор TAction, которые смогли бы быть доступны свойству Action, например в Button.
-
> Можно ли создать такой компонент?
А почему нет?
> То есть как я разумею, он при помещении на форму в Design-time должен > создавать набор TAction
В конструкторе: if csDesigning in ComponentState then создать_набор;
> которые смогли бы быть доступны свойству Action, например в Button.
При регистрации своих TAction вызовите еще и RegisterActions.
-
> В конструкторе: > if csDesigning in ComponentState then создать_набор;
Маленькая неувязочка, сначала создадим, потом считаем из ресурса, что получим в итоге ? (два набора Action)
-
> В конструкторе: > if csDesigning in ComponentState then создать_набор;
Вот тут то и проблемы. Все создается, но в Design-time при чтении формы (например, после просмотра View as Text) конструктор вызывается заново и пытается создать уже существующий объект, или если TMyAction.Name='', то плодит их :(
-
Ну вот, я угадал !!!
-
Попробуйте так
TMyAction = class(TAction)
private
fLoaded: boolean;
public
procedure Loaded;override;
end;
TЬнActionList = class(TActionList)
public
constructor Create(AOwner: TComponent); override;
procedure Loaded;override;
end;
constructor TЬнActionList.Create(AOwner: TComponent);
var DefAction: TAction;
begin
inherited Create(AOwner);
if csDesigning in ComponentState then begin
DefAction := TMyAction.Create(AOwner);
DefAction.ActionList := self;
end;
end;
procedure TMyActionList.Loaded;
var i: integer;
begin
inherited Loaded;
for i := 0 to ActionCount-1 do
if Actions[i] is TMyAction then
if not TMyAction(Actions[i]).fLoaded then Actions[i].Free;
end;
procedure TMyAction.Loaded;
begin
inherited Loaded;
fLoaded := true;
end;
-
А есть решение? Можно ли как нибудь в конструкторе узнать, например когда компонент помещается на форму или когда читается из ресурса?
-
В конструкторе - нет. Остаётся только создавать безимянные Action-ы
-
> alexnmsk (03.03.08 16:09) [6]
> Можно ли как нибудь ... узнать... когда компонент ... читается из ресурса?
if csLoading in ComponentState then компонент_читается_из_ресурса
То есть, в конструкторе нужна двойная проверка:
if (csDesigning in ComponentState) and not (csLoading in ComponentState) then создать_набор_TAction
-
Или можно так: в конструкторе создаем набор всегда, а в Loaded сначала этот набор грохаем, а потом вызываем inherited.
-
Сорри, фигню сказал в [9].
-
> Попробуйте так
Работает!!! с небольшими изменениями. Проблема с именами
> В конструкторе - нет. Остаётся только создавать безимянные > Action-ы
К сожалению, тогда их не назначить контролам. Ща подумаю что нибудь.
> if csLoading in ComponentState then компонент_читается_из_ресурса
Не появляется csLoading в конструкторе
-
Проверка на csLoading in ComponentState в кончструкторе бессмысленна
-
Готово !
unit MyActionList;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ActnList;
type
TMyAction = class(TAction)
private
fDesignCreate: boolean;
public
procedure SetName(const NewName: TComponentName);override;
end;
TMyActionList = class(TActionList)
public
constructor Create(AOwner: TComponent); override;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Standard',[TMyActionList]);
RegisterNoIcon([TMyAction]);
end;
constructor TMyActionList.Create(AOwner: TComponent);
var DefAction: TMyAction;
i: integer;
begin
inherited Create(AOwner);
if csDesigning in ComponentState then begin
DefAction := TMyAction.Create(AOwner);
DefAction.ActionList := self;
DefAction.fDesignCreate := true;
i := 1;
while 1 = 1 do
try
DefAction.Name := 'MyAction'+IntToStr(I);
Break;
except
Inc(i);
end;
end;
end;
procedure TMyAction.SetName(const NewName: TComponentName);
var C: TComponent;
begin
if not fDesignCreate then begin
C := Owner.FindComponent(NewName);
if Assigned(C) then C.Free;
end;
inherited
end;
initialization
RegisterClass(TMyAction);
end.
-
> DimaBr
Ура!!! Работает! Огробное спасибо, буду разбираться..
-
Елементарно, вот дурак, совсем голову запудрили. Если вам нужно только добавлять несколько Action и на этом функционал вашего компонента заканчивается, то посмотрите в сторону Create ComponentTemplate... Два клика и компонент готов. Причём даже с кодом...
|