进程间通信 windows消息

进程间通信主要包括管道, 系统IPC(Inter-Process Communication,进程间通信)(包括消息队列,信号,共享存储), 套接字(SOCKET)。

 由于近期工作需要,初略的学习了下相关知识,简单的了解下windows消息方式进行通信。简单举个例子,如下:

一、主要windows API准备:

[DllImport("user32")]
        public static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam);
        [DllImport("user32.dll")]
        public static extern int PostMessage(int hWnd, uint Msg, int wParam, int lParam);
        [DllImport("user32.dll")]
        public static extern uint RegisterWindowMessage(string sMessageName);

 [DllImport("user32.dll")]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

SendMessage:用于向窗体发消息,但是必须等待消息被接收方处理完成才算真正完成。

hWnd:窗体句柄;

Msg:消息名称;

wParam、lParam:消息附加的参数

PostMessage:也是用于向窗体发消息,不过这种方式是只管发送消息,不管消息是否被处理,发送之后便完成。

RegisterWindowMessage:注册消息,目的是在系统声明这个消息,这个消息便是有效的,在系统中被识别。

FindWindow: 找到指定窗体。

lpClassName:类名(测试不好用,可能使用有问题);

lpWindowName:窗体名称,即:Form的Text属性

二、详细实例代码

1、消息发送方窗体:

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;


namespace 消息发送方
{
    public partial class FrmSendMsg : Form
    {
        public FrmSendMsg()
        {
            InitializeComponent();
        }

        uint MyMsg = 1000;

        #region 声明winAPI系统函数

        [DllImport("user32")]
        public static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam);
        [DllImport("user32.dll")]
        public static extern int PostMessage(int hWnd, uint Msg, int wParam, int lParam);
        [DllImport("user32.dll")]
        public static extern uint RegisterWindowMessage(string sMessageName);
        [DllImport("user32.dll")]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        #endregion


        int sendHandleWind = 0;//接收方的窗体句柄
        private void FrmSendMsg_Load(object sender, EventArgs e)
        {
            //窗体加载时注册自定义的消息“testMsg”
            MyMsg = RegisterWindowMessage("testMsg");
           
            //1、使用.net Process操作类,根据进程名获取该进程主窗体的句柄
            Process[] process = Process.GetProcessesByName("主进程");
            if (process != null && process.Length > 0)
            {
                sendHandleWind = process[0].MainWindowHandle.ToInt32();
            }

            else

           {

              //先打开消息接收方窗体,再打开本消息发送方窗体。

           }
            //2、直接根据 winAPI,通过指定的窗体名称,即:Form的Text属性值,获取该窗体句柄
           //sendHandleWind= FindWindow(null,"主消息处理").ToInt32();
        }
     
        private void btnSendMsg2_Click(object sender, EventArgs e)
        {
            //PostMessage方式发送消息,wParam为100,lParam为2,区别消息1,测试在接收方给予不同处理

            //可以防止在发送消息后,接收方响应慢,导致的卡死问题(只负责将消息发送,不管是否响应处理完成!)
            PostMessage(sendHandleWind, MyMsg, 100, 2);
            MessageBox.Show("发送消息2");
        }

        private void btnSendMsg1_Click(object sender, EventArgs e)
        {

            //发送-1,则系统所有的进程或窗体句柄都可以捕获此消息,而sendHandleWind指定了,则只要该消息接收方能接收到此消息。
            // SendMessage(-1, MyMsg, 100, 1);
            SendMessage(sendHandleWind, MyMsg, 100, 1);
            MessageBox.Show("发消息1");
        }

      
    }
}

 

2、消息接收方窗体:

 winAPI函数声明相同,也是在Load方法中对消息进行注册,重点的要重载一个消息处理方法WndProc,如下:

 

       uint benDenMsg = 1;//本地消息
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == MyMsg)
            {

               //此处目的是,将外来捕获的消息,如:MyMsg,是其他进程发送的自定义消息,进行本地消息处理;

              //将消息再次发送给本窗体句柄,则此消息变成了本地内容消息,进入本地消息队列,经过此转递,可以提高性能
                PostMessage(this.Handle.ToInt32(), benDenMsg, m.WParam.ToInt32(), m.LParam.ToInt32());
                return;
            }
            if (m.Msg == benDenMsg)
            {
                if (m.LParam.ToInt32() == 1)
                {

                    //对消息1进行一定的响应处理。。。                    

                }
                if (m.LParam.ToInt32() == 2)
                {
                     //对消息2进行一定的响应处理。。。                    

                }
             
            }
            base.WndProc(ref m);

 

        }

 

 三、总结:

     [本人能力有限,对于其原理理解的也不太深入,将近期的一点经验记录下来,希望能给学习者带来一点帮助。]

      采用winform类似的系统中,进程以windows窗体形式存在的,则采用windows消息方式进行通信,比较方便简单,而且性能和效率比较高。

    

    

 

 

 

 

 

posted @ 2014-02-22 15:26  阿步GoToDoNet  阅读(1376)  评论(0编辑  收藏  举报