Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.149.230.44] |
|
Сообщ.
#1
,
|
|
|
Чтобы не писать в каждом проекте один и тот же код решил написать компонент который "будет делать это за меня".
Задача следующая Есть некий сторонний компонент sSkinManager, нужно получить у него список значений, для каждого значения создать свой пункт меню и при клике по этих пунктах изменять значение в sSkinManager. Так вот все работает почти как надо но все таки не так. Вот код моего компонента unit myComponent; interface uses SysUtils, Classes, Menus, acntUtils, sSkinManager; type TmyComponent = class(TComponent) private FMyMainMenuItem: TMenuItem; FSkinManager: TsSkinManager; procedure SetMyMainMenuItem(const Value: TMenuItem); procedure FillMyMainMenuItem(parentMI: TMenuItem); procedure SetSkinManager(const Value: TsSkinManager); { Private declarations } protected { Protected declarations } procedure MenuItemClick(Sender: TObject); public { Public declarations } published { Published declarations } property MyMainMenuItem: TMenuItem read FMyMainMenuItem write SetMyMainMenuItem; property SkinManager: TsSkinManager read FSkinManager write SetSkinManager; end; procedure Register; implementation procedure Register; begin RegisterComponents('Samples', [TmyComponent]); end; { TmyComponent } procedure TmyComponent.FillMyMainMenuItem(parentMI: TMenuItem); var i: Integer; mi: TMenuItem; sl: TStringList; begin if csDesigning in ComponentState then Exit; if Assigned(parentMI) and Assigned(FSkinManager) then begin parentMI.Clear; sl := TStringList.Create; try FSkinManager.GetExternalSkinNames(sl); for i := 0 to sl.Count - 1 do begin mi := TMenuItem.Create(parentMI); mi.Name := 'MyExtMenu_' + IntToStr(i); mi.Caption := sl[i]; mi.Checked := mi.Caption = FSkinManager.SkinName; mi.OnClick := MenuItemClick; mi.RadioItem := True; if (i <> 0) and (i mod 20 = 0) then mi.Break := mbBreak; parentMI.Add(mi); end; finally FreeAndNil(sl); end; end; end; procedure TmyComponent.MenuItemClick(Sender: TObject); begin FSkinManager.SkinName := DelChars(TMenuItem(Sender).Caption, '&'); TMenuItem(Sender).Checked := True; end; procedure TmyComponent.SetMyMainMenuItem(const Value: TMenuItem); begin FMyMainMenuItem := Value; if Value <> nil then begin Value.FreeNotification(Self); FillMyMainMenuItem(value); end; end; procedure TmyComponent.SetSkinManager(const Value: TsSkinManager); begin FSkinManager := Value; end; end. Почти заключается в том что при старте программы пункты меню не создаются автоматом, но если в формкриэйт написать myComponent1.MyMainMenuItem := меню_айтем; то меню создается и все работает отлично. Как мне сделать чтобы пункты меню не создавались при старте проги без всяких там записей в формкриэйт? Добавлено Ах да значение для MyMainMenuItem в IDE установлено такое же какое я устанавливаю в формкриэйт. |
Сообщ.
#2
,
|
|
|
ибо когда загружается форма из ресурса то сначала присваивается MyMainMenuItem а потом SkinManager. и получается что условие if Assigned(parentMI) and Assigned(FSkinManager) then даст отрицательное значение.
|
Сообщ.
#3
,
|
|
|
Как я понял вариант решения только один, это переназвать SkinManager например в aSkinManager тогда он бут грузится раньше и все заработает?
|
Сообщ.
#4
,
|
|
|
нет. намного правильнее это сделать обновление меню и из SetSkinManager.
|
Сообщ.
#5
,
|
|
|
действительно, ступил
|
Сообщ.
#6
,
|
|
|
Зачем такие сложности? Сделай обычный класс, который будет создаваться в OnCreate формы и все
|
Сообщ.
#7
,
|
|
|
Может так
procedure TmyComponent.Loaded; begin inherited Loaded; if Assigned(MyMainMenuItem) then FillMyMainMenuItem(MyMainMenuItem); end; Добавлено А может лучше написать наследника TsSkinManager, который будет выполнять дополнительный функционал |
Сообщ.
#8
,
|
|
|
Цитата DimaBr @ А может лучше написать наследника TsSkinManager, который удет выполнять дополнительный функционал возможно, но имхо лучше отдельный компонент |