原创文章,欢迎转载。转载请注明:转载自 祥的博客
原文链接:http://blog.csdn.net/humanking7/article/details/51035974
最近由于项目要用到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);
///
/// 存放窗口的句柄
///
private static List m_hWndList = new List();
///
/// 加载窗口的句柄
///
///
public static void AddHandle(IntPtr hWnd)
{
if (null != hWnd)
{
m_hWndList.Add(hWnd);
Debug.WriteLine("After Add:");
for (int i=0;i"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 m_hWndList = new List();
最后定义了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控件上显示收到的消息以及对应的时间,上图所示,我向两个窗体都发送了相同的消息,所以才有那样的效果。