广播Windows HWND_BROADCAST消息

时间:2011-06-03 09:33:38

标签: c# winapi ipc

我在这个应用程序中的应用程序中工作我将等待应用程序1中的某个事件,当这个事件发生时,我将发送消息到应用程序2,它将执行某些操作。

第一个API声明

private const int HWND_BROADCAST = 0xffff;

 [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern int RegisterWindowMessage(string lpString);

[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern bool SendNotifyMessage(int hWnd, int Msg, int wParam, int lParam);

申请1代码

private string msgstr = "MYMESSAGE";              
public int  msg = RegisterWindowMessage(msgstr);
                if (msg == 0)
                {
                    MessageBox.Show(Marshal.GetLastWin32Error().ToString());
                }

                //SendNotifyMessage(HWND_BROADCAST, msg, 4848484, 8484865);

                SendNotifyMessage(HWND_BROADCAST, msg, 0, 0);

                MessageBox.Show(Marshal.GetLastWin32Error().ToString());

申请2代码

 static readonly int msg = RegisterWindowMessage("MYMESSAGE");
     protected override void WndProc(ref Message m)
        {
            if (m.Msg == msg)
            {
                MessageBox.Show(m.Msg.ToString() + " = from wndproc");
            }
            base.WndProc(ref m);
         }

有人会指出这段代码有什么问题。 我怀疑SendNotifyMessage存在问题

  

lparam和wparam   参数

有人会建议我采取其他任何方法来实现此行为!

3 个答案:

答案 0 :(得分:5)

  1. 不存在有问题的代码。只有代码不能按预期执行。如果您希望我们告诉您上述代码的问题,您应该告诉我们您的预期,(好吧,我们可以猜到),但最重要的是,它取而代之的是。你收到错误了吗?它只是默默无法工作吗?你知道,这是一个问题的重要部分!

  2. 您正在使用RegisterWindowMessage()和SendNotifyMessage()之类的方法,这些方法是您未向我们展示的定义。当我们不知道如何声明SendNotifyMessage()时,我们如何判断问题是否与SendNotifyMessage()有关?

  3. 您的应用程序2有一个WndProc,您希望在其中接收窗口的消息。它是否已正确注册?你确定它有效吗?它是否收到其他窗口消息?如果您从应用程序2中发送它,它会收到“MYMESSAGE”吗?

  4. HWND_BROADCAST仅向顶级窗口发送消息。您确定您的窗口是顶级窗口吗?

  5. 您没有检查应用程序2中对RegisterWindowMessage()的调用是否成功。先检查一下怎么样?

  6. “MYMESSAGE”不是一个非常好的消息名称。如何使用更独特的东西,比如你的名字和姓氏,或创建一个guid并使用它的字符串表示作为你的信息的名称?

答案 1 :(得分:3)

HWND_BROADCAST非常危险。我知道这不太可能,但如果另一个应用程序也处理了你的消息怎么办?

无论如何,除此之外,您是否已阅读http://msdn.microsoft.com/en-us/library/ms644953.aspx

调试代码问题的最基本方法(因为它基于WINAPI)将使用GetLastError。您应该始终检查方法的返回值以查看它们是否成功,因此请确保它返回零(这意味着它有效)。如果不是,并且您收到拒绝访问等错误,请尝试使用UAC禁用或作为管理员(Vista +)运行。

  

当UIPI阻止消息时   最后一个错误,用。检索   GetLastError,设置为5(访问   被拒绝)。

答案 2 :(得分:2)

以下代码效果很好,

服务器端。

public partial class Server : Form
    {
        private UInt32 msg;
        public Server()
        {
            InitializeComponent();

        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            msg = RegisterWindowMessage("THIS_IS_MY_UNIQUE_MESSAGE");
        }

        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern uint RegisterWindowMessage(string lpString);

        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern bool SendNotifyMessage(IntPtr hWnd, uint msg, int wParam, int lParam);

        private void SendMessage(object sender, EventArgs e)
        {
            var retval = SendNotifyMessage(new IntPtr(-1), msg, 0, 0);
        }


    }

客户端

public partial class Client : Form
    {
        public Client()
        {
            InitializeComponent();
        }

        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern uint RegisterWindowMessage(string lpString);


        private static UInt32 GetMessage()
        {
            return RegisterWindowMessage("THIS_IS_MY_UNIQUE_MESSAGE");
        }

        protected override void WndProc(ref Message m)
        {
            if (m.Msg == (int)GetMessage())
            {
                MessageBox.Show(@"Hello, from server");
            }
            base.WndProc(ref m);
        }
    }