侵权投诉
订阅
纠错
加入自媒体

在Wince/WM实现进程间通信

2010-12-02 17:22
flinay
关注

做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");  

声明: 本文由入驻维科号的作者撰写,观点仅代表作者本人,不代表OFweek立场。如有侵权或其他问题,请联系举报。

发表评论

0条评论,0人参与

请输入评论内容...

请输入评论/评论长度6~500个字

您提交的评论过于频繁,请输入验证码继续

暂无评论

暂无评论

文章纠错
x
*文字标题:
*纠错内容:
联系邮箱:
*验 证 码:

粤公网安备 44030502002758号