3

在我的 Delphi 表单的 OnShow 方法中,我确定一旦打开表单就必须自动打开一个对话框 - 我应该能够通过模拟对菜单项的单击来做到这一点。

但是,调用 menuitem.Click 在主窗体打开之前会弹出对话框——这不是我想要的。

我希望这应该做我想做的事,但我找不到要为“wparam”传递哪些参数以将点击发送到我的菜单项。

PostMessage(handle, WM_COMMAND, wparam, 0)

MSDN WM_COMMAND 文档讨论了 IDM_* 标识符,但它在 Delphi 中是如何出现的?

4

6 回答 6

5

(我知道这是一个非常古老的问题,但尽管以某种方式得到了解决,但真正的问题确实没有得到解答。)
——

'TMenuItem' 的命令项标识符在Command属性中。根据 WM_COMMAND 的文档,“wParam”的高位字为“0”,低位字为菜单标识符;

PostMessage(Handle, WM_COMMAND, MakeWParam(MyMenuItem.Command, 0), 0);

或者简单地说;

PostMessage(Handle, WM_COMMAND, MyMenuItem.Command, 0);


使用弹出菜单项会有细微差别:VCL 使用不同的实用程序窗口处理弹出菜单的消息。全局PopupList变量在其Window属性中有句柄;

PostMessage(PopupList.Window, WM_COMMAND, MyPopupMenuItem.Command, 0);
于 2010-09-17T00:08:17.353 回答
2

也许您可以尝试在 OnActivate 事件中打开对话框?除了显示表单时,我不确定 OnActivate 是否会再次触发,但如果确实如此,您可以使用:

procedure TForm1.FormActivate(Sender: TObject);
begin
  Form2.ShowModal;
  Self.OnActivate := nil;
end;
于 2009-08-11T11:16:52.993 回答
0

如果您希望表单按照正常的 Show/ShowModal 显示,完全绘制(等),然后立即执行其他操作,您是否不必使用一次性计时器来执行此操作?

tmrKickOff :一个 TTimer,100 ms 间隔,在设计时禁用,
触发“tmrKickOffTimer”事件。


在形式上创造,
tmrKickOff.Enabled:=false; //以防万一IDE中发生了什么

在表格展示中,在所有其他内容结束时;
tmrKickOff.Enabled:=true;

在 tmrKickOffTimer
开始
  tmrKickOffTimer.Enabled:=false;
  菜单项点击(无);
结尾;

对风格、形式和任何错误陷阱表示歉意:-)

于 2009-08-11T11:59:09.057 回答
0

或者,使用类似...的方式处理 Application.OnIdle 事件

if not DialogDone then
begin
    MyDialogForm.ShowModal; // or menuItem.Click ....
    DialogDone := true;
end;

在显示表单并且消息队列为空之前,OnIdle 不会触发(第一次)。

于 2009-08-11T11:59:30.723 回答
0

我认为您不能直接向您的菜单项发送消息,但您可以将其发布到主窗口并从那里显示您的对话框。我这样做并且效果很好,因此对话框(在我的情况下是登录提示)出现在主窗口的顶部以避免混淆。

-标记

procedure WMPostStartup(var Message: TMessage); message WM_POSTSTARTUP;

procedure TMainForm.WMPostStartup(var Message: TMessage);
begin
  Self.Refresh;
  // Now show the dialog box.
end;
于 2009-08-11T12:01:39.067 回答
0

我使用的一种方法与 MarkF 的解决方案非常相似,它是创建一个新的用户定义的消息类型,并在您确定需要在主窗体显示后执行此其他过程时使用该类型向您自己发送消息:

const
  wm_SpecialProc = wm_User + 1;

procedure TForm1.WMSpecialProc(var Message:tMessage); message wm_SpecialProc;
begin
  Form2.ShowModal;
end;

procedure TForm1.OnShow(Sender:tObject);
begin
  if true then
    PostMessage(Application.MainForm.Handle,wm_SpecialProc,0,0);
end;

这种方法的好处是您可以控制消息的生成,因此可以填充您希望稍后由处理程序使用的任何 lparam 或 wparam。我直接通过 application.mainform 发送消息,但您也可以只说当前表单的句柄。

于 2009-08-11T16:16:42.613 回答