您的位置:首页 > 编程语言 > C#

[C#]自定义消息收发

2016-04-01 12:59 423 查看
原创文章,欢迎转载。转载请注明:转载自 祥的博客

原文链接:/article/7763576.html

最近由于项目要用到C#,所以最近学了一下C#,其中别人的代码里面用了 自定义消息,不过他们的代码是半开源,所以为了验证他们程序的传递机制,我自己写了一个Demo,学习了一下这种机制。

主要是两个函数:

//发送消息
public static extern void PostMessage(IntPtr hWnd, int msg, int wParam, int lParam);
//处理消息
protected override void DefWndProc(ref System.Windows.Forms.Message m)




发送消息

我自己写了一个类,专门用来进行类之间的消息传递

源代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Runtime.InteropServices;//DLLImport

namespace WindowsFormsApplication1
{

//用于向窗口发送消息的类
public class MsgGenerator
{
[DllImport("user32.dll")]
public static extern void PostMessage(IntPtr hWnd, int msg, int wParam, int lParam);

/// <summary>
/// 存放窗口的句柄
/// </summary>
private static List<IntPtr> m_hWndList = new List<IntPtr>();

/// <summary>
/// 加载窗口的句柄
/// </summary>
/// <param name="hWnd"></param>
public static void AddHandle(IntPtr hWnd)
{
if (null != hWnd)
{
m_hWndList.Add(hWnd);

Debug.WriteLine("After Add:");
for (int i=0;i<m_hWndList.Count;i++)
{
Debug.WriteLine("List[{0}] = {1}",i,m_hWndList[i]);
}
Debug.WriteLine("Over!\n");

}
}

public static void RemoveHandle(IntPtr hWnd)
{
if (null != hWnd)
{
m_hWndList.Remove(hWnd);
}

Debug.WriteLine("After Remove:");
for (int i = 0; i < m_hWndList.Count; i++)
{
Debug.WriteLine("List[{0}] = {1}", i, m_hWndList[i]);
}
Debug.WriteLine("Over!\n");
}

public static void PostMsg2All(int msg, int wParam, int lParam)
{
for (int i = 0; i < m_hWndList.Count; i++)
{
if (null != m_hWndList[i])
{
PostMessage(m_hWndList[i], msg, wParam, lParam);
}
}
}
}
}


详解

首先要导出 Windows API 的发送消息函数

[DllImport("user32.dll")]
public static extern void PostMessage(IntPtr hWnd, int msg, int wParam, int lParam);


然后,我定义了一个静态的指针列表,用于存放窗口的句柄。

private static List<IntPtr> m_hWndList = new List<IntPtr>();


最后定义了3个静态的成员函数,用于窗口句柄的添加、删除,以及向存储句柄的窗口发送消息的函数。

//添加窗口句柄
public static void AddHandle(IntPtr hWnd);
//删除窗口句柄
public static void RemoveHandle(IntPtr hWnd);
//给存储句柄对应的窗口发送消息
public static void PostMsg2All(int msg, int wParam, int lParam);


成员函数使用

添加句柄

在窗口Load事件对应的处理函数中,添加窗口句柄

MsgGenerator.AddHandle(this.Handle);//将窗口句柄加入MsgGenerator


删除句柄

在窗口Closed事件对应的处理函数中,删除窗口句柄

MsgGenerator.RemoveHandle(this.Handle);


发送消息

MsgGenerator.PostMsg2All((MSG.WM_USER + 1), 90, 8000);


接收消息

接收消息要重写 DefWndProc() 函数,而且要注意不要干扰其他消息的响应。

源代码

protected override void DefWndProc(ref System.Windows.Forms.Message m)
{
switch (m.Msg)
{
case (MSG.WM_USER + 1):
string message = string.Format("收到消息的参数:{0},{1}\n收到的时间:{2}", m.WParam, m.LParam, DateTime.Now.ToLongTimeString().ToString());
//MessageBox.Show(message, this.Text);
Label_Child.Text = message;

break;
default:
base.DefWndProc(ref m);//一定要调用基类函数,以便系统处理其它消息。
break;
}
}


其中这个 MSG.WM_USER 也是我自定义的一个类,代码如下

namespace WindowsFormsApplication1
{
public class MSG
{
public const int WM_USER = 0x0400;//自定义消息
}
}


解释

我的接收到我自定义的消息后,我就让窗口在Label控件上显示收到的消息以及对应的时间,上图所示,我向两个窗体都发送了相同的消息,所以才有那样的效果。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: