kea |
Отправлено: 29.12.2005, 11:21 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 80
|
Здравствуйте!
Вызываю PopupMenu либо с компонента TChart либо с компонента TMemo. Как узнать с какого компонета вызван всплывающее меню в обработчике события OnClick для пункта меню?
|
|
gvg |
Отправлено: 29.12.2005, 12:24 |
|
Машинист паровоза
Группа: Участник
Сообщений: 222
|
А Sender в OnContextPopup не пойдет? |
|
kea |
Отправлено: 29.12.2005, 22:28 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 80
|
QUOTE (gvg @ 29/12/2005, 12:24) | А Sender в OnContextPopup не пойдет? |
Спасибо.
Подскажите, пожалуйста, как мне узнать имя конкретного объекта (например, MyChart) в обработчике OnContextPopup. |
|
AVC |
Отправлено: 30.12.2005, 09:13 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
QUOTE |
А Sender в OnContextPopup не пойдет?
|
Не пойдет. Sender = этому popup.
Можно попробовать OnMouseDown (попробовал — плохо)
Нужно искать объект под курсором в момент PopUp
Отредактировано AVC — 30/12/2005, 08:40 |
|
gvg |
Отправлено: 30.12.2005, 09:34 |
|
Машинист паровоза
Группа: Участник
Сообщений: 222
|
Это я немного поторопился. Sender не нужен. OnContextPopup — у компонентов, на которых вызывается меню, т.е. компонент известен. Остается воспользоваться этим. |
|
AVC |
Отправлено: 30.12.2005, 09:41 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
QUOTE (gvg @ 30/12/2005, 08:34) | Это я немного поторопился. Sender не нужен. OnContextPopup — у компонентов, на которых вызывается меню, т.е. компонент известен. Остается воспользоваться этим. |
Как? Он protected. |
|
gvg |
Отправлено: 30.12.2005, 10:30 |
|
Машинист паровоза
Группа: Участник
Сообщений: 222
|
QUOTE (AVC @ 30/12/2005, 09:41) | QUOTE (gvg @ 30/12/2005, 08:34) | Это я немного поторопился. Sender не нужен. OnContextPopup — у компонентов, на которых вызывается меню, т.е. компонент известен. Остается воспользоваться этим. |
Как? Он protected. |
Ну, например, в OnContextPopup присвоить какое либо значение Tag у PopupMenu. Потом, при обработке выбора меню, прочитать это значение... Вариантов — куча. |
|
avc* |
Отправлено: 30.12.2005, 11:07 |
|
Не зарегистрирован
|
Вы не поняли. У стандартного компонента к этому свойству нет доступа — нельзя простым способом подставить свой обработчик. |
|
gvg |
Отправлено: 30.12.2005, 11:44 |
|
Машинист паровоза
Группа: Участник
Сообщений: 222
|
По всей видимости не поняли Вы. Я говорю про событие (event) OnContextPopup, которое наследуется от TControl и доступно. Я же не понимаю другое — про какое свойство Вы говорите? |
|
Admin |
Отправлено: 30.12.2005, 11:47 |
|
Владимир
Группа: Администратор
Сообщений: 1190
|
CODE |
void __fastcall TForm1::PopupMenu1Popup(TObject *Sender)
{
if(PopupMenu1->Tag == 0) ShowMessage("Memo1ContextPopup");
else if(PopupMenu1->Tag == 1) ShowMessage("Panel1ContextPopup");
else ShowMessage("unknown");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Memo1ContextPopup(TObject *Sender,
TPoint &MousePos, bool &Handled)
{
PopupMenu1->Tag = 0;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Panel1ContextPopup(TObject *Sender,
TPoint &MousePos, bool &Handled)
{
PopupMenu1->Tag = 1;
}
//---------------------------------------------------------------------------
|
|
|
Admin |
Отправлено: 30.12.2005, 11:52 |
|
Владимир
Группа: Администратор
Сообщений: 1190
|
Или искать объект под курсором в момент PopUp .
CODE |
void __fastcall TForm1::PopupMenu1Popup(TObject *Sender)
{
TPoint pt = PopupMenu1->PopupPoint;
....
}
|
|
|
gvg |
Отправлено: 30.12.2005, 11:59 |
|
Машинист паровоза
Группа: Участник
Сообщений: 222
|
2Admin — ну да, именно так. Можно и по-другому
CODE |
void __fastcall TForm1::Panel1ContextPopup(TObject *Sender,
TPoint &MousePos, bool &Handled)
{
PopupMenu1->Tag = int( Panel1 );
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Memo1ContextPopup(TObject *Sender,
TPoint &MousePos, bool &Handled)
{
PopupMenu1->Tag = int( Memo1 );
}
//---------------------------------------------------------------------------
void __fastcall TForm1::PopupMenu1Popup(TObject *Sender)
{
ShowMessage( ((TControl*)PopupMenu1->Tag)->Name );
}
| |
|
avc* |
Отправлено: 30.12.2005, 12:19 |
|
Не зарегистрирован
|
QUOTE (gvg @ 30/12/2005, 11:44) | По всей видимости не поняли Вы. Я говорю про событие (event) OnContextPopup, которое наследуется от TControl и доступно. Я же не понимаю другое — про какое свойство Вы говорите? |
И я про это же. Извиняюсь.
Как назло форма, котрая была под рукой, была забита DBGrid'ами — чуть ли не единственный компонент у которого это событие не "расшарено". А ставить на форму Memo и Chart — поленился.
Виноват.
А ведь еще и не пил. |
|
kea |
Отправлено: 30.12.2005, 15:34 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 80
|
Здравствуйте! Спасибо за ответы. Мне тоже первым длом пришла мысль про тэги.
Поздравляю всех с наступающим Новым годом! |
|
kea |
Отправлено: 01.01.2006, 20:44 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 80
|
QUOTE (gvg @ 30/12/2005, 11:59) | 2Admin — ну да, именно так. Можно и по-другому
CODE |
void __fastcall TForm1::Panel1ContextPopup(TObject *Sender,
TPoint &MousePos, bool &Handled)
{
PopupMenu1->Tag = int( Panel1 );
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Memo1ContextPopup(TObject *Sender,
TPoint &MousePos, bool &Handled)
{
PopupMenu1->Tag = int( Memo1 );
}
//---------------------------------------------------------------------------
void __fastcall TForm1::PopupMenu1Popup(TObject *Sender)
{
ShowMessage( ((TControl*)PopupMenu1->Tag)->Name );
}
|
|
Здравствуйте! Поясните, пожалуйста, как работает следующий код:
PopupMenu1->Tag = int( Panel1 );
int( Panel1 ) даст уникальное значение в пределах одной программы?
(просто еще не встречалось приведение имени своено компонента к типу int) |
|
kea |
Отправлено: 04.01.2006, 12:34 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 80
|
Здравствуйте! Ответьте, пожалуйста на мой последний вопрос, а то тема скоро скроется из виду. |
|
Guest |
Отправлено: 04.01.2006, 13:22 |
|
Не зарегистрирован
|
Panel — указатель на экземпляр класса TPannel. Принято считать (в С это задекларировано) что указатель и переменная типа int имеют одинаковый размер в памяти и вообще чуть ли не синонимы.
Будет ли этот указатель иметь ункальное значение в рамках приложения — да если форма на которой расположен TPanel создается один раз. Гарантировано он будет иметь уникальное значение в рамках одной формы пока для неё не вызван деструктор.
|
|
kea |
Отправлено: 04.01.2006, 14:19 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 80
|
QUOTE (Guest @ 04/01/2006, 13:22) | Panel — указатель на экземпляр класса TPannel. Принято считать (в С это задекларировано) что указатель и переменная типа int имеют одинаковый размер в памяти и вообще чуть ли не синонимы.
Будет ли этот указатель иметь ункальное значение в рамках приложения — да если форма на которой расположен TPanel создается один раз. Гарантировано он будет иметь уникальное значение в рамках одной формы пока для неё не вызван деструктор. |
Здравствуйте! Спасибо за ответ. Мне вообщето уникалность нужна в пределах одной формы., которую создаю и делаю модальной по мере необходимости. Это будет обеспечиваться? Числа использовать тоже интереса нет. |
|
Guest |
Отправлено: 04.01.2006, 14:45 |
|
Не зарегистрирован
|
QUOTE |
пределах одной формы ...это будет обеспечиваться?
|
Да.
Это же результат работы распределителя памяти, а он пытается гарантировать что распределенная памать до её освобождения использоваться не будет. |
|
kea |
Отправлено: 04.01.2006, 14:47 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 80
|
Здравствуйте! извините за детский вопрос. А как все же правильно будет записываться преобразование типов:
int(Panel)
или
(int)Panel1 |
|
kea |
Отправлено: 04.01.2006, 14:51 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 80
|
Как применять в операторе switch
switch ( PopupMenu1->Tag )
{
case (что здесь писать): Func(); break;
default: break;
} |
|
Guest |
Отправлено: 04.01.2006, 15:19 |
|
Не зарегистрирован
|
QUOTE |
А как все же правильно будет записываться преобразование типов
|
Преобразование типов — (int)Panel, а конструктор класса int — int(Panel). В контексте вашей проблемы это безразлично.
QUOTE |
case (что здесь писать): Func(); break;
|
Все что угодно, приводимое целому. |
|
kea |
Отправлено: 04.01.2006, 17:04 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 80
|
QUOTE (Guest @ 04/01/2006, 15:19) | QUOTE |
А как все же правильно будет записываться преобразование типов
|
Преобразование типов — (int)Panel, а конструктор класса int — int(Panel). В контексте вашей проблемы это безразлично.
QUOTE |
case (что здесь писать): Func(); break;
|
Все что угодно, приводимое целому. |
Здравствуйте! Меня интересовало как в операторе case прописать тот компонент для которого нужно выполнить конкретное действие.
Конструкция:
switch( PopupMenu1->Tag )
{
case (int)Panel1 : Func(); break;
default: break;
}
не компилируется. Что-то недопонимаю. Подскажите, пожалуйстаю |
|
Guest |
Отправлено: 04.01.2006, 18:17 |
|
Не зарегистрирован
|
QUOTE |
case (что здесь писать): Func(); break;
|
что здесь писать — константное выражение.
Вы можете написать так
if (...->Tag == int(Panel)) func1...
else if (...->Tag == int(Memo)) func2...
|
|
kea |
Отправлено: 04.01.2006, 18:39 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 80
|
QUOTE (Guest @ 04/01/2006, 18:17) | что здесь писать — константное выражение.
|
Спасибо за ответы!
1.то есть switch в данном случае не годится?
2. выражение int( Panel ) эффективнее по количесвту операций и скорости выполнения, чем (int)Panel. Поскольку в втором случае преобразуется указатель на TPanel к типу int и затем создается число типа int, а во первом случае сразу создается число типа int с помощью копирующего конструктора. Как вы думаете?
|
|
AVC |
Отправлено: 05.01.2006, 09:01 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
QUOTE |
выражение int( Panel ) эффективнее по количесвту операций и скорости выполнения, чем (int)Panel. Поскольку в втором случае преобразуется указатель на TPanel к типу int и затем создается число типа int, а во первом случае сразу создается число типа int с помощью копирующего конструктора. Как вы думаете?
|
Вы пишете драйвер? Сколько тысяч раз в секунду вам нужно делать такое преобразование? Если это критично то лучше создать пару переменных нужного типа и сделать преобразования заранее и один раз.
PS. Простой эксперимент показывает, что умный компилятор (что логично) для обоих способов записи порождает одинаковый код (помните — указатель и int это почти синонимы).
CODE |
void somefun(int);
void __fastcall TForm1::Button2Click(TObject *Sender)
{
somefun(int(Memo1));
somefun((int)Memo1);
asm {qwerty}
}
// asm
mov eax,dword ptr [ebx+748]
push eax
call @@somefun$qi
mov edx,dword ptr [ebx+748]
push edx
call @@somefun$qi
| |
|
kea |
Отправлено: 05.01.2006, 12:17 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 80
|
QUOTE (AVC @ 05/01/2006, 09:01) | [QUOTE]
Вы пишете драйвер? Сколько тысяч раз в секунду вам [CODE]
|
Здравствуйте! Спасибо за ответ. Драйверов пока не пишу. Надо повышать свой уровень в написании обычных программ. Вопросы эффективности кода всегда интересовали. У Михаила Фленова в книге "Что умеюют хакеры" про это интересно написано (для Delphi, но все равно интересно). |
|
gvg |
Отправлено: 06.01.2006, 12:30 |
|
Машинист паровоза
Группа: Участник
Сообщений: 222
|
QUOTE (kea @ 04/01/2006, 18:39) | 1.то есть switch в данном случае не годится?
|
1. годится, если использовать также как и присваивание тэга
По использованию тэга для хранения ссылки описано в его хэлпе (к вопросу о размерности int и указателя)
QUOTE |
...It can be used for storing an additional integer value or it can be typecast to any 32-bit value such as a component reference or a pointer. |
Отредактировано gvg — 06/01/2006, 12:31 |
|
kea |
Отправлено: 07.01.2006, 15:19 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 80
|
QUOTE (gvg @ 06/01/2006, 12:30) | QUOTE (kea @ 04/01/2006, 18:39) | 1.то есть switch в данном случае не годится?
|
1. годится, если использовать также как и присваивание тэга
|
Здравствуйте!
Использую приведенную конструкцию case int(Panel1): в операторе switch:
Сразу компилятор выдает ошибку:
E2313: Constant expression required.
Наверное, недопонял. Подскажите. |
|
kea |
Отправлено: 07.01.2006, 15:26 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 80
|
Здравствуйте!
Верочтно, луше определить на глобальном уровне ( в классе формы )
int Panel1Ptr;
В обработчике FormCreate присвоить ему значение
Panel1Ptr = int( Panel1 ).
И уж затем использовать в операторе switch:
case Panel1Ptr: MyFunc(); break;
|
|