2011-06-03 178 views
3

我在这个应用程序中工作我将在应用程序1中等待一些事件,当这个事件发生时,我将发送消息给应用程序2,它将执行一些操作。广播窗口HWND_BROADCAST消息

首先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

wParam和lParam 参数

会有人给我建议任何其他的替代来实现这种行为!

回答

3

HWND_BROADCAST是相当危险..我知道这是非常不可能的,但如果其他应用程序也处理您的消息呢?

无论如何,这一边,你采取的http://msdn.microsoft.com/en-us/library/ms644953.aspx

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

当通过UIPI阻塞的消息 最后一个错误,与 GetLastError函数检索,被设定为5(访问 被拒绝)。

+0

什么是由UIPI和UAC是什么意思? – 2011-06-03 10:12:56

+0

用户界面特权隔离(UIPI),用户帐户控制(UAC)。 UAC是你应该担心的一个问题,因为默认情况下应用程序在Vista +上运行“无特权”,因为我相信你知道,你是否以管理员身份运行你的应用程序? – 2011-06-03 10:18:08

+0

是的,我正以管理员身份运行我的应用程序,我得到最后一个错误0.With out admin rights it returned 5.You are right。but still I did not receive on application 2. – 2011-06-03 10:20:05

5
  1. 存在着没有这样的事情有问题的代码。只存在不符合你期望的代码。如果你想让我们告诉你上面的代码有什么问题,你应该告诉我们你期望它做什么(好吧,我们可以猜到),但最重要的是,它代替而不是。你有错误吗?它只是默默地失败了吗?这是问题的重要部分,你知道!

  2. 您正在使用像RegisterWindowMessage()和SendNotifyMessage()这样的方法,这些方法不会向我们显示。当我们不知道如何声明SendNotifyMessage()时,我们该如何判断问题是否与SendNotifyMessage()有关?

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

  4. HWND_BROADCAST只发送消息到顶层窗口。你确定你的窗口是顶层窗口吗?

  5. 您不检查应用程序2中对RegisterWindowMessage()的调用是否成功。如何检查首先?

  6. “MYMESSAGE”不是一个很好的消息名称。如何使用更独特的东西,比如你的名字加上姓,或者创建一个GUID并使用它的字符串表示法作为你的消息的名字?

+0

我编辑了我的问题。答案是3! – 2011-06-03 10:28:06

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); 
     } 
    } 
+0

不错。如何传递一个字符串作为参数? – Lara 2017-06-20 04:44:01