[C#]自定义消息收发
2016-04-01 12:59
423 查看
原创文章,欢迎转载。转载请注明:转载自 祥的博客
原文链接:/article/7763576.html
最近由于项目要用到C#,所以最近学了一下C#,其中别人的代码里面用了 自定义消息,不过他们的代码是半开源,所以为了验证他们程序的传递机制,我自己写了一个Demo,学习了一下这种机制。
主要是两个函数:
然后,我定义了一个静态的指针列表,用于存放窗口的句柄。
最后定义了3个静态的成员函数,用于窗口句柄的添加、删除,以及向存储句柄的窗口发送消息的函数。
在窗口Load事件对应的处理函数中,添加窗口句柄
删除句柄
在窗口Closed事件对应的处理函数中,删除窗口句柄
发送消息
其中这个 MSG.WM_USER 也是我自定义的一个类,代码如下
原文链接:/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控件上显示收到的消息以及对应的时间,上图所示,我向两个窗体都发送了相同的消息,所以才有那样的效果。相关文章推荐
- C#小知识点
- C#中类型分析中的常见问题 Type
- C# --数组
- C# 特性详解
- C#winform如何最小化主窗口
- C# 元数据描述
- 如何在C#项目中引用dll文件
- C# 工具栏
- C#(WPF和WinForm)在普通类中调用到主线程的方法,SynchronizationContext的用法。
- C#之RabbitMQ系列(一)
- C# 对List<T>取交集、连集及差集
- C# UrlDecode将+替换为空格问题
- 利用C#自带组件强壮程序日志
- 2016-4-1--C#可空类型&&"??"运算符
- C#第一篇之性能优化
- c#软件开发原则
- C#基本功------委托和事件(三)
- C#特性
- C# DllImport“调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配 ”
- C#:办公用品管理软件项目总结