将WM_COMMAND发送到TMenuItem

时间:2009-08-11 11:04:45

标签: delphi winapi postmessage tmenuitem

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

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

我希望这应该做我想要的,但是我找不到要通过“wparam”将点击发送到我的menuitem的参数。

PostMessage(handle, WM_COMMAND, wparam, 0)

MSDN WM_COMMAND docs谈论IDM_ *标识符,但它在Delphi中是如何出现的?

6 个答案:

答案 0 :(得分:5)

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

'TMenuItem'的命令项标识符位于Command属性中。根据WM_COMMAND的documentation,'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);

答案 1 :(得分:2)

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

procedure TForm1.FormActivate(Sender: TObject);
begin
  Form2.ShowModal;
  Self.OnActivate := nil;
end;

答案 2 :(得分:0)

如果您希望表单按正常的Show / ShowModal显示,完全绘制(等),然后立即,您是否需要使用一次性计时器执行此操作做点什么吗?

tmrKickOff : a TTimer, 100 ms interval, disabled at design time, 
fires off a 'tmrKickOffTimer' event.


in form create,
tmrKickOff.Enabled:=false; //just in case something happened in IDE

in form show, at end of all other stuff;
tmrKickOff.Enabled:=true;

in tmrKickOffTimer
begin
  tmrKickOffTimer.Enabled:=false;
  menuItemClick(nil);
end;

对样式,表单和任何错误捕获道歉: - )

答案 3 :(得分:0)

或者,使用类似......

的内容处理Application.OnIdle事件
if not DialogDone then
begin
    MyDialogForm.ShowModal; // or menuItem.Click ....
    DialogDone := true;
end;

OnIdle将不会触发(第一次),直到显示Form并且消息队列为空。

答案 4 :(得分:0)

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

-Mark

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

procedure TMainForm.WMPostStartup(var Message: TMessage);
begin
  Self.Refresh;
  // Now show the dialog box.
end;

答案 5 :(得分: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发送了消息,但你也可以说当前表单的句柄。