在Wince/WM实现进程间通信

来源:网络

点击:1821

A+ A-

所属频道:新闻中心

关键词: Wince/WM,进程通信

    做WM上的进程间通信,使用WindowMessage实现两个进程间的通信,感觉MessageWindow不太好用,所以就用别的方法实现接收WindowsMessage。

    先来封装一下需要使用的功能,命名为Cls_Message:

    view plaincopy to clipboardprint?
    using System;  
    using System.Collections.Generic;  
    using System.Text;  
    using System.Runtime.InteropServices;  
    using Microsoft.WindowsCE.Forms;  
    using System.Windows.Forms;  
    class Cls_Message  
    {  
        private struct COPYDATASTRUCT  
        {  
            public int dwData;  
            public int cbData;  
            public IntPtr lpData;  
        }  
        //-------------------------------------------------------------------------------  
        private const int WM_COPYDATA = 0x004A;  
        private const int GWL_WNDPROC = -4;  
        private const int LMEM_FIXED = 0x0000;  
        private const int LMEM_ZEROINIT = 0x0040;  
        private const int LPTR = (LMEM_FIXED | LMEM_ZEROINIT);  
        private  IntPtr oldWndProc = IntPtr.Zero;  
        private  WndProcDelegate newWndProc;  
        private IntPtr formHandle;  
        //-------------------------------------------------------------------------------  
        delegate IntPtr WndProcDelegate(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);  
        [DllImport("coredll.dll")]  
        static extern IntPtr CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);  
        [DllImport("coredll.dll", EntryPoint = "GetWindowLong")]  
        private static extern IntPtr GetWindowLong(IntPtr hWnd, int nIndex);  
        [DllImport("coredll.dll")]  
        static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr newWndProc);  
        [DllImport("coredll.dll", EntryPoint = "FindWindow")]  
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);  
        [DllImport("coredll.dll")]  
        private static extern int SendMessageW(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);  
        [DllImport("coredll.dll")]  
        private static extern IntPtr LocalAlloc(int flag, int size);  
        [DllImport("coredll.dll")]  
        private static extern IntPtr LocalFree(IntPtr p);  
        /// <summary>  
        /// 初始化消息类  
        /// </summary>  
        /// <param name="handle">接受消息的窗体的句柄</param>  
        public Cls_Message(IntPtr formHandle)  
        {  
            this.formHandle = formHandle;  
            newWndProc = new WndProcDelegate(WndProc);  
            oldWndProc = GetWindowLong(formHandle, GWL_WNDPROC);  
            int success = SetWindowLong(formHandle, GWL_WNDPROC, Marshal.GetFunctionPointerForDelegate(newWndProc));  
        }  
        /// <summary>  
        /// 消息处理  
        /// </summary>  
        private IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)  
        {  
            if (msg == WM_COPYDATA)  
            {  
                COPYDATASTRUCT st = (COPYDATASTRUCT)Marshal.PtrToStructure(lParam, typeof(COPYDATASTRUCT));  
                string str = Marshal.PtrToStringUni(st.lpData);  
                MessageBox.Show(str);  
            }  
            return CallWindowProc(oldWndProc, this.formHandle, msg, wParam, lParam);  
        }  
          
        static private IntPtr AllocHGlobal(int cb)  
        {  
            IntPtr hMemory = new IntPtr();  
            hMemory = LocalAlloc(LPTR, cb);  
            return hMemory;  
        }  
        static private void FreeHGlobal(IntPtr hMemory)  
        {  
            if (hMemory != IntPtr.Zero)  
                LocalFree(hMemory);  
        }  
        /// <summary>  
        /// 发送消息  
        /// </summary>  
        /// <param name="formTitle">目标窗体的名称</param>  
        /// <param name="message">消息内容</param>  
        static public void SendMessage(String formTitle,String message)  
        {  
            IntPtr hWndDest = FindWindow(null, formTitle);  
            COPYDATASTRUCT oCDS = new COPYDATASTRUCT();  
            oCDS.cbData = (message.Length + 1) * 2;  
            oCDS.lpData = LocalAlloc(LPTR, oCDS.cbData);  
            Marshal.Copy(message.ToCharArray(), 0, oCDS.lpData, message.Length);  
            oCDS.dwData = 1;  
            IntPtr lParam = AllocHGlobal(oCDS.cbData);  
            Marshal.StructureToPtr(oCDS, lParam, false);  
            SendMessageW(hWndDest, WM_COPYDATA, IntPtr.Zero, lParam);  
            LocalFree(oCDS.lpData);  
            FreeHGlobal(lParam);  
        }  

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Runtime.InteropServices;
    using Microsoft.WindowsCE.Forms;
    using System.Windows.Forms;
    class Cls_Message
    {
        private struct COPYDATASTRUCT
        {
            public int dwData;
            public int cbData;
            public IntPtr lpData;
        }
        //-------------------------------------------------------------------------------
        private const int WM_COPYDATA = 0x004A;
        private const int GWL_WNDPROC = -4;
        private const int LMEM_FIXED = 0x0000;
        private const int LMEM_ZEROINIT = 0x0040;
        private const int LPTR = (LMEM_FIXED | LMEM_ZEROINIT);
        private  IntPtr oldWndProc = IntPtr.Zero;
        private  WndProcDelegate newWndProc;
        private IntPtr formHandle;
        //-------------------------------------------------------------------------------
        delegate IntPtr WndProcDelegate(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
        [DllImport("coredll.dll")]
        static extern IntPtr CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
        [DllImport("coredll.dll", EntryPoint = "GetWindowLong")]
        private static extern IntPtr GetWindowLong(IntPtr hWnd, int nIndex);
        [DllImport("coredll.dll")]
        static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr newWndProc);
        [DllImport("coredll.dll", EntryPoint = "FindWindow")]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
        [DllImport("coredll.dll")]
        private static extern int SendMessageW(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
        [DllImport("coredll.dll")]
        private static extern IntPtr LocalAlloc(int flag, int size);
        [DllImport("coredll.dll")]
        private static extern IntPtr LocalFree(IntPtr p);
        /// <summary>
        /// 初始化消息类
        /// </summary>
        /// <param name="handle">接受消息的窗体的句柄</param>
        public Cls_Message(IntPtr formHandle)
        {
            this.formHandle = formHandle;
            newWndProc = new WndProcDelegate(WndProc);
            oldWndProc = GetWindowLong(formHandle, GWL_WNDPROC);
            int success = SetWindowLong(formHandle, GWL_WNDPROC, Marshal.GetFunctionPointerForDelegate(newWndProc));
        }
        /// <summary>
        /// 消息处理
        /// </summary>
        private IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
        {
            if (msg == WM_COPYDATA)
            {
                COPYDATASTRUCT st = (COPYDATASTRUCT)Marshal.PtrToStructure(lParam, typeof(COPYDATASTRUCT));
                string str = Marshal.PtrToStringUni(st.lpData);
                MessageBox.Show(str);
            }
            return CallWindowProc(oldWndProc, this.formHandle, msg, wParam, lParam);
        }
       
        static private IntPtr AllocHGlobal(int cb)
        {
            IntPtr hMemory = new IntPtr();
            hMemory = LocalAlloc(LPTR, cb);
            return hMemory;
        }
        static private void FreeHGlobal(IntPtr hMemory)
        {
            if (hMemory != IntPtr.Zero)
                LocalFree(hMemory);
        }
        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="formTitle">目标窗体的名称</param>
        /// <param name="message">消息内容</param>
        static public void SendMessage(String formTitle,String message)
        {
            IntPtr hWndDest = FindWindow(null, formTitle);
            COPYDATASTRUCT oCDS = new COPYDATASTRUCT();
            oCDS.cbData = (message.Length + 1) * 2;
            oCDS.lpData = LocalAlloc(LPTR, oCDS.cbData);
            Marshal.Copy(message.ToCharArray(), 0, oCDS.lpData, message.Length);
            oCDS.dwData = 1;
            IntPtr lParam = AllocHGlobal(oCDS.cbData);
            Marshal.StructureToPtr(oCDS, lParam, false);
            SendMessageW(hWndDest, WM_COPYDATA, IntPtr.Zero, lParam);
            LocalFree(oCDS.lpData);
            FreeHGlobal(lParam);
        }
    }
     


    接下来贴出调用代码,实现自发自收,如果要发给别的进程,只需要把SendMessage的第一个参数改为目标窗体的名称即可(当然目标窗体也必须引用了Cls_Message实现收信息处理):

    view plaincopy to clipboardprint?
    Cls_Message clsMessage;//初始化  
    public Form1()  
    {  
        InitializeComponent();  
    }  
    private void Form1_Load(object sender, EventArgs e)  
    {  
        clsMessage = new Cls_Message(this.Handle);//使本窗体能够接收WindowMessage  
    }  
    private void button1_Click(object sender, EventArgs e)  
    {  
        Cls_Message.SendMessage("Form1", "hello form1");  

    (审核编辑: 智汇小新)

    声明:除特别说明之外,新闻内容及图片均来自网络及各大主流媒体。版权归原作者所有。如认为内容侵权,请联系我们删除。