现在的位置: 首页 > 综合 > 正文

WPF进程之间通讯

2012年12月08日 ⁄ 综合 ⁄ 共 2292字 ⁄ 字号 评论关闭

 

参考了这位仁兄的做法,针对wpf做了修改:

http://www.cnblogs.com/speeding/archive/2004/10/24/56033.aspx

准备:

使用COPYDATA,WM_USER只能用于应用程序内部的通讯,跨进程用COPYDATA

  public const int WM_COPYDATA = 0x004A;

查找目标发送窗体:

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

   public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

定义一个结构体

    [StructLayout(LayoutKind.Sequential)]

    public struct CopyDataStruct

    {

        public IntPtr dwData;

        public int cbData;//字符串长度

        [MarshalAs(UnmanagedType.LPStr)]

        public string lpData;//字符串

    }

发送消息方法

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

   private static extern int SendMessage

   (

   IntPtr hWnd,                   //目标窗体句柄

   int Msg,                       //WM_COPYDATA

   int wParam,                                             //自定义数值

   ref  CopyDataStruct lParam             //结构体

   );

封装方法:

        /// <summary>

        /// SendMessage To Window

        /// </summary>

        /// <param name="windowName">window的title,建议加上GUID,不会重复</param>

        /// <param name="strMsg">要发送的字符串</param>

        public static void SendMessage(string windowName, string strMsg)

        {

            if (strMsg == null) return;

            IntPtr hwnd = FindWindow(null, windowName);

            if (hwnd != IntPtr.Zero)

            {

                CopyDataStruct cds;

                cds.dwData = IntPtr.Zero;

                cds.lpData = strMsg;

//注意:长度为字节数

                cds.cbData = System.Text.Encoding.Default.GetBytes(strMsg).Length + 1;

// 消息来源窗体

                int fromWindowHandler = 0;

                SendMessage(hwnd, WM_COPYDATA, fromWindowHandler, ref  cds);

            }

        }

发送举例:

MessageHelper.SendMessage("PopupNotify_06f777cb-958e-4cfb-ba80-b311c8cf94e1",”MMessage”);

接收:

在MainWindow中注册Hook

    void MainWindow_Loaded(object sender, RoutedEventArgs e)

        {

 (PresentationSource.FromVisual(this) as HwndSource).AddHook(new HwndSourceHook(this.WndProc));

        }

接收消息:

   IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)

        {

            if (msg == MessageHelper.WM_COPYDATA)

            {

                CopyDataStruct cds = (CopyDataStruct)System.Runtime.InteropServices.Marshal.PtrToStructure(lParam, typeof(CopyDataStruct));

                 MessageBox.Show(cds.lpData);

            }

            return hwnd;

        }

 

另外:获取目标窗体的句柄时,可以先获取目标process,然后process.MainWIndowHandle就是目标窗体的句柄。但是如果MainWindow的ShowInTaskBar=false,这个办法就失效了,只能用FindWindow。

 Demo 下载

抱歉!评论已关闭.