当我以编程方式弹出弹出菜单时,使用button1单击,当加速meun时,然后单击弹出菜单项的item1来调用事件处理程序。
然后单击按钮2。
我希望消息显示为“处理弹出窗口”。
但结果是'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;
答案 0 :(得分:0)
如果您设置一些断点并使用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)”不会阻止您的代码等待您点击哪个弹出项目。我认为你将弹出菜单功能与模态表单(Dialogs)混合在一起,其中代码实际上等待从这种表单返回的模态结果。
答案 1 :(得分:0)
这是怎么回事: 显示弹出菜单时,它会运行自己的消息循环。 单击菜单项时,单击事件将发布到应用程序消息队列。 IOW,它不会立即采取行动。 然后解除弹出菜单并继续执行,将FMsg设置为“处理弹出窗口”。 然后,应用程序消息循环将获取菜单单击发布的消息,然后调用Item1Click,将“Item1单击”分配给FMsg。
如何改变 要获得预期的结果,您必须干扰正常的消息处理,例如在PopupMenu.Popup之后调用Application.ProcessMessages。但我不建议这样做。 更好地重新考虑你的设计。