Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> дубликат TMenuItem 
:(
    Опции темы
Vit
Дата 6.2.2005, 06:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Vitaly Nevzorov
****


Профиль
Группа: Экс. модератор
Сообщений: 10964
Регистрация: 25.3.2002
Где: Chicago

Репутация: 48
Всего: 207



Есть меню, в нём есть пункт (типа TMenuItem естественно), надо в другом меню создать точно такой же пункт со такими же свойствами (Caption, tag, onClick и т.д.). По ряду причин в данном конкретном случае Action воспользоваться не получится... Есть способ это сделать как-то быстрее чем тупое приравнивание двух десятков свойств?


PS. Уже когда писал топик понял, что скорее всего нет из-за свойства Shortcut которое вроде как логично должно быть уникальным, хотя я его как раз и не использую... Тем ни менее... может у кого есть какие мысли.


--------------------
With the best wishes, Vit
I have done so much with so little for so long that I am now qualified to do anything with nothing
Самый большой Delphi FAQ на русском языке здесь: www.drkb.ru
PM MAIL WWW ICQ   Вверх
Pakshin A. S.
Дата 6.2.2005, 11:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: 21
Всего: 61



Теоритически можно так:
Код

var
MenuI: TMenuItem;
begin
MenuI:=ShowMes1;
MenuI.Parent:=nil; // но это зепрещено....
N21.Insert(0, MenuI);

Но Parent - readonly

Все получается только при удалении пункта ShowMes1
PM   Вверх
Pakshin A. S.
Дата 6.2.2005, 11:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: 21
Всего: 61



Итак, часть проблемы решена:
Изменил Menus.pas:
Код

procedure TMenuItem.Insert(Index: Integer; Item: TMenuItem);
begin
{Здесь}  if Item.FParent <> nil then Item.FParent:=nil;
 if FItems = nil then FItems := TList.Create;
 if (Index - 1 >= 0) and (Index - 1 < FItems.Count) then
   if Item.GroupIndex < TMenuItem(FItems[Index - 1]).GroupIndex then
     Item.GroupIndex := TMenuItem(FItems[Index - 1]).GroupIndex;
 VerifyGroupIndex(Index, Item.GroupIndex);
 FItems.Insert(Index, Item);
 Item.FParent := Self;
 Item.FOnChange := SubItemChanged;
 if FHandle <> 0 then RebuildHandle;
 MenuChanged(Count = 1);
end;

Теперь со спокойной совестью можно написать вот такое:
Код

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls, Menus;

type
 TForm1 = class(TForm)
   MainMenu1: TMainMenu;
   N11: TMenuItem;
   N21: TMenuItem;
   ShowMes1: TMenuItem;
   Button1: TButton;
   procedure ShowMes1Click(Sender: TObject);
   procedure Button1Click(Sender: TObject);
   procedure FormClose(Sender: TObject; var Action: TCloseAction);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.ShowMes1Click(Sender: TObject);
begin
ShowMessage('asdf')
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
N21.Insert(0, ShowMes1); // !!!
end;

end.

Вроде работает... особо времени тестить не было... smile

Теперь появилась другая проблема: При закрытии проги вылетает ошибка... как избежать пока не понял...

Прикрепляю dcu "испорченного" модуля:
Добавлено @ 11:54
Чтобы избежать ошибки при выходе из программы, нам надо удалить "братьев-близнецов":
Код

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
N21.Delete(0);
N11.Delete(0);
end;


Присоединённый файл ( Кол-во скачиваний: 1 )
Присоединённый файл  Menus.dcu
PM   Вверх
Alex
Дата 6.2.2005, 13:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4147
Регистрация: 25.3.2002
Где: Москва

Репутация: 80
Всего: 162



А вот, что вышло у меня:
Код

procedure CopyComponentProp(Source: TObject; Receiver: TObject; aExcept: array of string);
// Копирование всех одинаковых по названию свойств/методов одного компонента в
// другой за исключение "Name", "Left", "Top" и тех которые заданы в aExcept
var
 I: Integer;
 Props: PPropList;
 TypeData: PTypeData;
begin
 if (Source = nil) or (Source.ClassInfo = nil) then Exit;
 TypeData := GetTypeData(Source.ClassInfo);
 if (TypeData = nil) or (TypeData^.PropCount = 0) then Exit;
 GetMem(Props, TypeData^.PropCount * sizeof(Pointer));
 try
   GetPropInfos(Source.ClassInfo, Props);
   for I := 0 to TypeData^.PropCount-1 do begin
     with Props^[I]^ do begin
       if (AnsiIndexText(Name, ['Name', 'Left', 'Top']) =  -1 ) and
          (AnsiIndexText(Name, aExcept                ) =  -1 ) and
          (GetPropInfo  (Receiver.ClassInfo, Name     ) <> nil) then try
         case PropType^^.Kind of
           tkInteger, tkChar,
           tkEnumeration, tkFloat,
           tkString, tkSet, tkWChar,
           tkLString, tkWString,
           tkVariant, tkArray,
           tkRecord, tkInterface,
           tkInt64, tkDynArray:   SetPropValue (Receiver, Name, GetPropValue (Source, Name));
           tkMethod:              SetMethodProp(Receiver, Name, GetMethodProp(Source, Name));
           tkClass:               SetOrdProp   (Receiver, Name, GetOrdProp   (Source, Name));
         end;
       except
         raise Exception.CreateFmt('Произошла ошибка при копировании свойства/метода "%s" тип "%d".', [Name, Integer(PropType^^.Kind)]);
       end;
     end;
   end;
 finally
   FreeMem(Props);
 end;
end;



--------------------
Написать можно все - главное четко представлять, что ты хочешь получить в конце. 
PM Skype   Вверх
Alex
Дата 6.2.2005, 13:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4147
Регистрация: 25.3.2002
Где: Москва

Репутация: 80
Всего: 162



Пример использования:

Присоединённый файл ( Кол-во скачиваний: 7 )
Присоединённый файл  CopyComponentProp.rar


--------------------
Написать можно все - главное четко представлять, что ты хочешь получить в конце. 
PM Skype   Вверх
Sharl
Дата 6.2.2005, 15:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 32
Регистрация: 16.8.2003

Репутация: нет
Всего: нет



А если использовать

Destination.Assign(Source); ???



PM MAIL   Вверх
Vit
Дата 6.2.2005, 15:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Vitaly Nevzorov
****


Профиль
Группа: Экс. модератор
Сообщений: 10964
Регистрация: 25.3.2002
Где: Chicago

Репутация: 48
Всего: 207



Цитата(Sharl @ 6.2.2005, 06:00)
А если использовать

Destination.Assign(Source); ???



А если попробовать? smile


--------------------
With the best wishes, Vit
I have done so much with so little for so long that I am now qualified to do anything with nothing
Самый большой Delphi FAQ на русском языке здесь: www.drkb.ru
PM MAIL WWW ICQ   Вверх
Alex
Дата 6.2.2005, 16:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4147
Регистрация: 25.3.2002
Где: Москва

Репутация: 80
Всего: 162



Цитата(Sharl @ 6.2.2005, 15:00)
А если использовать

Destination.Assign(Source); ???

Ну попробуй smile


--------------------
Написать можно все - главное четко представлять, что ты хочешь получить в конце. 
PM Skype   Вверх
Sharl
Дата 6.2.2005, 20:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 32
Регистрация: 16.8.2003

Репутация: нет
Всего: нет



Цитата
Ну попробуй 

Ой smile всего лишь

Код


procedure TMenuItem.AssignTo(Dest: TPersistent);
begin
 if Dest is TCustomAction then
   with TCustomAction(Dest) do
   begin
     Enabled := Self.Enabled;
     HelpContext := Self.HelpContext;
     Hint := Self.Hint;
     ImageIndex := Self.ImageIndex;
     Caption := Self.Caption;
     Visible := Self.Visible;
     OnExecute := Self.OnClick;
   end
 else inherited AssignTo(Dest);
end;


smile
PM MAIL   Вверх
Pakshin A. S.
Дата 6.2.2005, 20:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: 21
Всего: 61



Вот об этом и говорил Vit, что приходится перебирать свойства... smile
PM   Вверх
Guest
Дата 8.2.2005, 13:11 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Цитата
нет из-за свойства Shortcut которое вроде как логично должно быть уникальным

прежде всего логично, что уникальным должен быть HANDLE иначе выскочит ошибка "Menu inserted twice" из чего следует что два ОДИНАКОВЫХ пункта в меню быть не может, только с некоторыми совпадающими свойствами. То есть придется создавать новый пункт меню и копировать необходимые свойства вручную.
  Вверх
Pakshin A. S.
Дата 8.2.2005, 21:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: 21
Всего: 61



А вот гость и не прав!!!
Эта ошибка вылетает только тогда, когда в процедуре Insert FParent не равно nil... что я собственно и подправил... smile smile
Вооще-то, мой исковерканный стандартный можуль вроде хорошо дублирует менюшки... вроде все работает... только есть небольшие проблемы при закрытии (см. выше)
Кстати, никому эта идея не понравилась, ибо нет скачиваний... smile
PM   Вверх
Vit
Дата 9.2.2005, 07:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Vitaly Nevzorov
****


Профиль
Группа: Экс. модератор
Сообщений: 10964
Регистрация: 25.3.2002
Где: Chicago

Репутация: 48
Всего: 207



Цитата(Pakshin @ 8.2.2005, 12:18)
Кстати, никому эта идея не понравилась, ибо нет скачиваний... 


Править VCL - это самое крайнее средство, уж лучше перебором...
Цитата(Sharl @ 6.2.2005, 11:10)
Ой  всего лишь


Код


procedure TMenuItem.AssignTo(Dest: TPersistent);
begin
if Dest is TCustomAction then
  with TCustomAction(Dest) do
  begin
    Enabled := Self.Enabled;
    HelpContext := Self.HelpContext;
    Hint := Self.Hint;
    ImageIndex := Self.ImageIndex;
    Caption := Self.Caption;
    Visible := Self.Visible;
    OnExecute := Self.OnClick;
  end
else inherited AssignTo(Dest);
end;


А почему вы так уверены что мне только эти свойства и события понадобятся? Там их гораздо больше....



--------------------
With the best wishes, Vit
I have done so much with so little for so long that I am now qualified to do anything with nothing
Самый большой Delphi FAQ на русском языке здесь: www.drkb.ru
PM MAIL WWW ICQ   Вверх
Alex
Дата 24.6.2005, 04:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4147
Регистрация: 25.3.2002
Где: Москва

Репутация: 80
Всего: 162



В арсенале доступна обновленная версия процедуры для копирования свойств и методов одного компонента в другой
http://forum.vingrad.ru/index.php?showtopi...ndpost&p=450550


--------------------
Написать можно все - главное четко представлять, что ты хочешь получить в конце. 
PM Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0940 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.