首页 > 代码库 > 进程通信-SendMessage使用方法

进程通信-SendMessage使用方法

进程通信-SendMessage的使用方法

用过SendMessage进行进程通信的同学都知道,这个函数一般都搭配FindWindow使用。通过FindWindow查找进程句柄,然后使用SendMessage 向这个句柄发送信息。这接口使用起来比较简单,但是当初也是费了好大的劲,只为用作记录。

第一步:设计用户界面

         用户界面需要有一下几个元素,设置本地的窗口名称,目标的窗口名称,发送数据,以及接受数据。        

 技术分享

第二步:引用接口

//Win32 API函数 

        [DllImport("User32.dll", EntryPoint = "SendMessage")]

        private static extern int SendMessage(int hWnd, int Msg, int wParam, ref COPYDATASTRUCT lParam);

 

        [DllImport("User32.dll", EntryPoint = "FindWindow")]

        private static extern int FindWindow(string lpClassName, string lpWindowName);

        const int WM_COPYDATA = http://www.mamicode.com/0x004A;

    public struct COPYDATASTRUCT

    {

        public IntPtr dwData;

        public int cbData;

        [MarshalAs(UnmanagedType.LPStr)]

        public string lpData;

    }

 

当初做的时候,将WM_COPYDATA 改为其他值,像c++ 一样,我只需要通过消息定义为WM_USER+1 即可向该消息发送数据。但是做的时候,发现不对,刚接触c# 不知道是我哪里理解不对还是怎么。改成其他值不行的。只能设置成0x004A;

 

第三步:发送消息

private void buttonSend_Click(object sender, EventArgs e)

        {

            string wndName = textBoxDestWindowName.Text;

            string message = textBoxSendData.Text;

            int hWnd = FindWindow(null, wndName);

            if(hWnd != 0)

            {

                byte[] sarr = System.Text.Encoding.Default.GetBytes(message);

                int len = sarr.Length;

                COPYDATASTRUCT cds;

                cds.dwData = http://www.mamicode.com/(IntPtr)Convert.ToInt16(1);//可以是任意值

                cds.cbData = http://www.mamicode.com/len + 1;//指定lpData内存区域的字节数

                cds.lpData = http://www.mamicode.com/message;//发送给目标窗口所在进程的数据

                SendMessage(hWnd, WM_COPYDATA, 0, ref cds);

            }

        }

第四步:接受消息

protected override void DefWndProc(ref Message m)

        {

            switch (m.Msg)

            {

                case WM_COPYDATA:

                    COPYDATASTRUCT cds = new COPYDATASTRUCT();

                    Type t = cds.GetType();

                    cds = (COPYDATASTRUCT)m.GetLParam(t);

                    string strResult = cds.lpData;

                    string strType = cds.dwData.ToString();

                    RecvOneDataPacket(strResult, strType);

                    break;

                default:

                    base.DefWndProc(ref m);

                    break;

            }

        }

 

        private void RecvOneDataPacket(string strResult, string strType)

        {

            //throw new NotImplementedException();

            listBoxRecv.Items.Add(strResult);

        }

 

这个接口在当初做的时候,老是出错,就在这个地方。

cds = (COPYDATASTRUCT)m.GetLParam(t);

我也不知道为什么,也许是因为消息值的定义吧。不清楚,反正以后得注意了。

 技术分享

 

代码地址:https://github.com/liningg/sendmessage

进程通信-SendMessage使用方法