发送 WM_COMMAND 到 TMenuItem

发布于 2024-07-30 18:14:29 字数 431 浏览 5 评论 0原文

在我的 Delphi 窗体的 OnShow 方法中,我确定一旦打开窗体就必须自动打开一个对话框 - 并且我应该能够通过模拟单击菜单项来完成此操作。

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

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

PostMessage(handle, WM_COMMAND, wparam, 0)

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

In my Delphi form's OnShow method, I determine that a dialog must be opened automatically once the form is opened - and I should be able to do this by simulating a click on a menuitem.

However, calling menuitem.Click brings up the dialog before the main form has opened - which is not what I want.

I expect that should do what I want, but I cannot find what parameters to pass for "wparam" to send the click to my menuitem.

PostMessage(handle, WM_COMMAND, wparam, 0)

The MSDN WM_COMMAND docs talk about IDM_* identifiers, but how does that appear in Delphi?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

清醇 2024-08-06 18:14:29

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

--

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

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

或简单地;

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

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

PostMessage(PopupList.Window, WM_COMMAND, MyPopupMenuItem.Command, 0);

(I know this is a very old question but despite being resolved in some way the real question has really gone unanswered.)

--

The command item identifier of a 'TMenuItem' is in the Command property. According to WM_COMMAND's documentation the high word of 'wParam' would be '0' and the low word would be the menu identifier;

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

or simply;

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

With a popup menu item there would be a slight difference: the VCL handles popup menus' messages with a different utility window. The global PopupList variable has the handle to it in its Window property;

PostMessage(PopupList.Window, WM_COMMAND, MyPopupMenuItem.Command, 0);
故人的歌 2024-08-06 18:14:29

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

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

Perhaps you can try to open the dialog in the OnActivate event ?
I am not really sure if the OnActivate gets fired again other than when the form is shown but if it does you can use :

procedure TForm1.FormActivate(Sender: TObject);
begin
  Form2.ShowModal;
  Self.OnActivate := nil;
end;
南薇 2024-08-06 18:14:29

如果您希望表单按照正常的 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;

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

Wouldn't you have to do this with a one-time timer, if you want the form to appear as per a normal Show/ShowModal, get drawn (etc) fully, and then immediately do something else?

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;

with apologies for style, form and any error-trapping :-)

醉生梦死 2024-08-06 18:14:29

或者,使用以下内容处理 Application.OnIdle 事件...

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

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

Alternatively, handle the Application.OnIdle event with something along the lines of ...

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

OnIdle won't fire (for the first time) until the Form is shown and the message queue is empty.

债姬 2024-08-06 18:14:29

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

-标记

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

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

I don't think you can send a message directly to your menu item, but you can just post it to the main window and show your dialog from there. I do this and it works great so that the dialog box (in my case, a login prompt) appears on top of the main window to avoid confusion.

-Mark

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

procedure TMainForm.WMPostStartup(var Message: TMessage);
begin
  Self.Refresh;
  // Now show the dialog box.
end;
一笔一画续写前缘 2024-08-06 18:14:29

我使用的一种方法与 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 发送消息,但您也可以只说当前表单的句柄。

One method I have used, which is very simular to MarkF's solution, is to create a new user defined message type and send a message using that type to yourself when you determine that you need to perform this other process after your main form displays:

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;

The nice thing about this method is that you are in control of the message generation, so can populate ANY lparam or wparam you want to later use by your handler. I sent the message directly through the application.mainform but you could also just say handle for the current form.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文