Wpf消息循环之消息传递

     几天遇见一个问题需要检查某个wpf程序是否已经运行,如果没有运行则启动传递参数,如果已运行则需要直接传递消息。在没有运行 情况下传递参数很简单,我们只需要Process cmd窗口启动并传递参数,在程序中处理。但是如果程序已经启动有点麻烦,凭着我曾winform的经验第一时间想到的是win32 api  SendMessage,我们的C#程序只需要DllImport就可以调用了。经过一番查找和对wpf window和DispatcherObject的Reflector,花了我大半天终于找到了System.Windows.Interop.HwndSource中有AddHock方法可以添加对win32消息机制的监听。这下就很好办了我们只需要注册MainWindow的这个时间,来监听win32消息处理我们的0x004A消息。

    控制台代码,主要应用的FindWindow 这个win32方法查找我们的窗体,SendMessage发送我们的消息,和winform没有什么差别,对于win32的使用你可以参考毒龙的程序人生关于C#中实现两个应用程序消息通讯的问题。难得查win32 Api直接copy,借来用用。

程序:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string ch = "";
            while (ch.ToLower() != "q")
            {

                if (!SendMessage("Window1", @"Hello,I am from Console Program:" + ch))
                {
                   Console.WriteLine("no window");

                };
                ch = Console.ReadLine();
            }
        }

        public static bool SendMessage(string windowName, string strMsg)
        {
            if (strMsg == null) return true;
            IntPtr hwnd = (IntPtr)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, 0x004A, fromWindowHandler, ref  cds);
                return true;
            }
            return false;
        }

        [DllImport("User32.dll", EntryPoint = "FindWindow")]
        private static extern int FindWindow(string lpClassName, string lpWindowName);

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

        private static extern int SendMessage

        (

        IntPtr hWnd,

        int Msg,

        int wParam,

        ref  CopyDataStruct lParam

        );

    }

    [StructLayout(LayoutKind.Sequential)]

    public struct CopyDataStruct
    {

        public IntPtr dwData;

        public int cbData;

        [MarshalAs(UnmanagedType.LPStr)]

        public string lpData;

    }

}

wpf端程序:主要需要在MainWindow中loaded事件订阅消息监听:这里需要System.Windows.Interop.HwndSource的AddHock方法注册:

程序:

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

           if (msg == 0x004A)
           {

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

               MessageBox.Show(cds.lpData);
               this.Visibility = Visibility.Visible;
           }

           return hwnd;

       }

       private void Window_Loaded(object sender, RoutedEventArgs e)
       {          

           (PresentationSource.FromVisual(this) as System.Windows.Interop.HwndSource).AddHook(new System.Windows.Interop.HwndSourceHook(WndProc));
       }

截个图:

GDVCJ_1PZO7SU((~1}41XSG

很简单的东西结果被MS封装的不知哪里去,让我查了半天(其实应该是我的无知吧,不管怎么解决了就是心情舒畅了);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值