Событие щелчка всплывающего меню delphi не просто выполняется при щелчке мышью по пункту меню, а выполняется после выполнения некоторой функции
Когда я программно выскакиваю всплывающее меню, используя кнопку button1, а когда всплывающее меню, то щелкаю элемент item1 всплывающего меню, чтобы вызвать обработчик события.
После этого нажмите кнопку2.
Я ожидаю, что появится сообщение "Process Popup".
Но результат "Item1 Clicked!".
Что происходит и как я могу получить результат, который я ожидаю.
//Popup Menu Item1 Click event handler
procedure MyForm.Item1Click(Sender: TObject);
begin
FMsg := 'Item1 Clicked!';
end;
procedure MyForm.ProcessPopup(APoint: TPoint);
begin
PopupMenu1.Popup(APoint.X, APoint.Y);
FMsg := 'Process Popup';
end;
procedure MyForm.Button1Click(Sender: TObject);
begin
ProcessPopup(Mouse.x, Mouse.Y);
end;
procedure MyForm.Button2Click(Sender: TObject);
begin
ShowMessage(FMsg);
end;
2 ответа
Вот что происходит: когда отображается всплывающее меню, оно запускает свой собственный цикл сообщений. При щелчке по пункту меню событие щелчка публикуется в очереди сообщений приложений. IOW, это не действует немедленно. Затем всплывающее меню закрывается, и выполнение продолжается с установкой FMsg на "Process popup". Затем цикл обработки сообщений приложения извлекает сообщение, которое было отправлено щелчком меню, и затем вызывает Item1Click, который присваивает "Item1 clicked" для FMsg.
Как изменить Чтобы получить ожидаемый результат, вам придется помешать нормальной обработке сообщений, например, вызвав Application.ProcessMessages сразу после PopupMenu.Popup. Но я не рекомендую это делать. Лучше переосмыслить свой дизайн.
Если вы установите некоторые контрольные точки и используете F8 для пошагового выполнения кода, вы увидите, что не так.
В любом случае, причина, по которой отображается сообщение: "Item1 Clicked!" потому что в это время установлена переменная FMsg.
Поток вашего кода выглядит так:
//Popup Menu Item1 Click event handler
procedure MyForm.Item1Click(Sender: TObject);
begin
FMsg := 'Item1 Clicked!'; //4. Called after you click on first popup item
end;
procedure MyForm.ProcessPopup(APoint: TPoint);
begin
PopupMenu1.Popup(APoint.X, APoint.Y); //2. This shows the popup menu
FMsg := 'Process Popup'; //3. After that FMsg value is set to 'Process Popup'
end;
procedure MyForm.Button1Click(Sender: TObject);
begin
ProcessPopup(Mouse.x, Mouse.Y); //1. Called first when you ress the mouse button
end;
procedure MyForm.Button2Click(Sender: TObject);
begin
ShowMessage(FMsg); //5. Finally this is called on Buttom2 click
//At this time the value of FMsg is 'Item1 Clicked!' as it
//was set last in Item click event handler
end;
ПРИМЕЧАНИЕ. Вызов "PopMenu1.Popup(APoint.X, APoint.Y)" не останавливает ваш код в ожидании того, на какой элемент всплывающего окна вы нажмете. Я думаю, что вы перепутали функциональность всплывающего меню с модальными формами (диалогами), где код на самом деле ждет модального результата, возвращаемого из такой формы.