windows 应用程序是靠消息驱动的,在WinForm开发中经常会通过重写WndProc或DefWndProc方法来截获消息,以添加自己的处理。
当然我们也可以定义自己的消息,发送,然后截获处理。
其意义这里不做讨论,这里仅提供一种处理问题的方法。
通过下边这个例子,可以大致了解其过程,当然这个例子没有什么实际意义:
在一个Form中有两个按钮:
给自己发消息
给别人发消息
点击【给自己发消息】,发送消息到自身窗口,弹出提示框
点击【给别人发消息】,发送消息到标题为RecieveMsgform的窗口,并在窗口的label控件显示信息。
public partial class DefMsgForm : Form
{
//Windows提供的自定义消息最小值
const int WM_USER = 0x0400;
//定义一个自定义消息,因为需要新的Windows特性也使用了WM_User,微软建议要比这个值大100以上
const int WM_MyMessage = WM_USER + 101;
//使用SendMessageAPI发送消息
[DllImport("user32")]
static extern int SendMessage(IntPtr hWnd, uint Msg, uint wParam, uint lParam);
//使用FindWindow找到要发消息的窗口
//这个函数有两个参数,第一个是要找的窗口的类,第二个是要找的窗口的标题。在搜索的时候不一定两者都知道,但至少要知道其中的一个
//在Win32 API中还有一个FindWindowEx,它非常适合寻找子窗口。
[DllImport("user32", EntryPoint = "FindWindow")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
//构造函数
public DefMsgForm()
{
InitializeComponent();
}
//当按钮被点击的时候,发送一个自定义消息
private void button1_Click(object sender, EventArgs e)
{
//给自己发消息
SendMessage(this.Handle, WM_MyMessage, 100, 200);
}
protected override void DefWndProc(ref Message m)
{
base.DefWndProc(ref m);
}
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
//判断是不是自定义消息
if (m.Msg == WM_MyMessage)
{
MessageBox.Show("我接收到消息了");
}
}
private void button2_Click(object sender, EventArgs e)
{
//找到标题为RecieveMsgform的窗口,并给它发消息
IntPtr fHandle = FindWindow(null, "RecieveMsgform");
if (fHandle != IntPtr.Zero)
{
SendMessage(fHandle, WM_MyMessage, 100, 200);
}
else
{
MessageBox.Show("没有找到要发送消息的窗口!");
}
}
}
//接收消息的窗口
public partial class RecieveMsgform : Form
{
const int WM_USER = 0x0400;
//自定义消息
const int WM_MyMessage = WM_USER + 101;
public RecieveMsgform()
{
InitializeComponent();
}
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
//接到自定义消息,显示信息
if (m.Msg == WM_MyMessage)
{
label1.Text = "我收到消息了";
}
}
}
通过贴出的代码,可以大致了解到自定义消息的具体使用。
附SendMessage与PostMessage的区别:
SendMessage把消息直接发送到窗口,并调用此窗口的相应消息处理函数,等消息处理函数结束后SendMessage才返回,SendMessage函数有返回值;
PostMessage将消息发送到与创建窗口的线程相关联的消息队列后立即返回;PostMessage函数没有返回值。