如何将事件添加到Windows消息泵队列?

时间:2014-04-23 21:07:08

标签: c# vb.net winforms

使用VB.NET/C# - .Net Framework 3.5。我目前处于WinForms事件的处理程序(例如)。在处理程序中,我想将自己的事件放在Windows消息泵中,但是在其队列的末尾(假设它泵送消息FIFO)。我希望我的处理程序和当前事件的任何其他处理程序执行,然后选择我插入队列并调用其处理程序的自定义事件。关于如何将事件插入到Windows事件队列中的任何示例代码(不关心什么语言)?

2 个答案:

答案 0 :(得分:3)

如果要向队列添加消息,则只需要P / Invoke PostMessage function即可。正如文档所说,这个功能:

  

在与创建指定窗口的线程关联的消息队列中放置(发布)消息,并返回而不等待线程处理消息。

示例P / Invoke声明:

[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("user32", SetLastError = true)]
static extern bool PostMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
  • hWnd是窗口的句柄,窗口过程应该接收消息。在WinForms中,可以使用Handle属性检索此内容。

  • msg是您要发布的消息。当然,你需要弄清楚在这里使用哪一个。如果其中一条标准消息适用于您的目的,那么您可以使用它。否则,只需定义用户定义的消息。用户定义的消息具有一系列值> = WM_USER。所以:

    const uint WM_USER = 0x0400;
    const uint UWM_MYGREATMESSAGE = WM_USER + 1;
    const uint UWM_MYOTHERMESSAGE = WM_USER + 2;
    
  • 显然,wParamlParam包含特定于消息的信息。如果您使用的是标准消息之一,他们的文档将告诉您在此处指定的内容。如果您使用的是用户定义的消息,那么您可以在此处传递任何内容,包括IntPtr.Zero,如果您不需要任何自定义数据。

答案 1 :(得分:2)

我非常喜欢@CodyGray给出的工程实例。 自从我在Delphi中做Win32之后已经有一段时间了:)。

我仍然不能保持手指,不得不分享这个想法我对丹尼斯可能需要什么,因为我觉得它可能会更简单一些。

假设您有一段代码。我们称之为 A 。 假设它由10个语句组成。我们称他们为 a0 通过 a9 。 所以我们的代码块看起来像这样:

{
    a0;
    a1;
    ...
    a4;
    a5;
    ...
    a8;
    a9;
}

现在假设您最终将此块写为Windows窗体控件的事件处理程序:

void button1_Click(object sender, EventArgs e) {
    a0;
    a1;
    ...
    a8;
    a9;
}

突然你意识到你想要立即执行a0到a4并将a5到a9的执行推迟到以后的时间。后来意思是尽快但消息泵闲置后。

您需要做的就是:

void button1_Click(object sender, EventArgs e) {
    a0;
    a1;
    a2;
    a3;
    a4;

    this.BeginInvoke( () => {
        a5;
        a6;
        a7;
        a8;
        a9;
    } );
}