esh |
Отправлено: 25.06.2005, 02:34 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 71
|
Как добавить во время выполнения программы к TPopupMenu новые пункты? Понимаю, что сделать это
так, как делает Builder невозможно, но создавать объекты в классе формы мне не нужно, нужно
только добавить пункты, при нажатии на которые меню должно создавать событие, которое будет
обработано в WndProc. Возможно ли такое? Может динамически создавать обекты TMenuItem? |
|
AVC |
Отправлено: 25.06.2005, 09:25 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
Объекты создавать все же придется
Вот пример, выдрано из рабочего кода, на мелочи внимания не обращайте это просто демострация порядка действий
CODE |
//---------------------------------------------------------------------------
// Способ показа
// Создать подменю для всех вариантов показа в PPM_Vid
//---------------------------------------------------------------------------
void __fastcall TF_UniEdit::QryMain_Vid_Prepare (void)
{
TTinyPrompt *plist = FTmpPList;
TPopupMenu *ppm = PPM_Vid;
ppm->Items->Clear();
TB_Vid->Enabled = false;
if (!DM->LoadQMScriptList(FQMScriptName, FTmpPList)) return;
TMenuItem *ppmi;
TTinyOnePrompt *lsti;
for (int i=0; i < plist->Count; i++)
{ lsti = plist->Items[i];
ppmi = new TMenuItem(this);
ppmi->Name = AnsiString("PPMV_") + AnsiString(int(this)) + "_" + AnsiString(i);
ppmi->Caption = lsti->Mnemo;
ppmi->Hint = lsti->Name;
ppmi->OnClick = PPMV_Click;
ppm->Items->Add(ppmi);
}
TB_Vid->Enabled = PPM_Vid->Items->Count > 1;
}
//---------------------------------------------------------------------------
void __fastcall TF_UniEdit::PPMV_Click (TObject *Sender)
{
TMenuItem *mni = dynamic_cast<TMenuItem*>(Sender);
if (!mni) return;
FQMSubScriptName = mni->Hint.Trim().UpperCase();
}
//---------------------------------------------------------------------------
// Выбрать вариант показа
//---------------------------------------------------------------------------
void __fastcall TF_UniEdit::QryMain_Vid (void)
{
AnsiString oldvid = FQMSubScriptName.Trim().UpperCase();
TPoint tpoi = TB_Vid->ClientOrigin;
int x = tpoi.x;
int y = tpoi.y + TB_Vid->Height + 4;
for (int i=0; i < PPM_Vid->Items->Count; i++)
PPM_Vid->Items->Items[i]->Checked =
(PPM_Vid->Items->Items[i]->Hint.Trim().UpperCase() == oldvid);
PPM_Vid->Popup(x, y);
Application->ProcessMessages();
if (FQMSubScriptName.IsEmpty() || (FQMSubScriptName == oldvid))
{ FQMSubScriptName = oldvid;
return;
}
....
}
//---------------------------------------------------------------------------
| |
|
esh |
Отправлено: 25.06.2005, 13:01 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 71
|
Спасибо, суть понял. Основной вопрос: когда освобождается память, выделенная в ppmi = new TMenuItem(this);?
И какое сообщение посылает TMenuItem при клике, как определить ID (WParam) данного пункта? |
|
esh |
Отправлено: 25.06.2005, 14:51 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 71
|
CODE |
// AVC, спасибо, сделал все так. Куски кода из РАЗНЫХ функций
//---------------------------------------------------------------------------
// Удаление лишних пунктов
TMenuItem *Item;
int Positions=TrayMenu->Items->Count-5;
for(int i=0;i < Positions;i++)
{
Item=TrayMenu->Items->Items[2];
delete Item;
}
//---------------------------------------------------------------------------
// Создание пунктов
TMenuItem *NewItem;
for(int i=0;i < Positions;i++)
{
NewItem=new TMenuItem(TrayMenu);
NewItem->Caption=i;
NewItem->Tag=i;
NewItem->OnClick=BackLight1Click;
TrayMenu->Items->Insert(i+2,NewItem);
}
//---------------------------------------------------------------------------
// Обработка сообщений, хотел сделать через WndProc, но это тоже сойдет
TMenuItem *Item=dynamic_cast<TMenuItem*>(Sender);
if(Item->Tag >= TrackBar1->Min && Item->Tag <= TrackBar1->Max)
{
TrackBar1->Position=Item->Tag;
}
}
//---------------------------------------------------------------------------
| |
|