天天看點

Wpf消息循環之消息傳遞

幾天遇見一個問題需要檢查某個wpf程式是否已經運作,如果沒有運作則啟動傳遞參數,如果已運作則需要直接傳遞消息。在沒有運作 情況下傳遞參數很簡單,我們隻需要Process cmd視窗啟動并傳遞參數,在程式中處理。但是如果程式已經啟動有點麻煩,憑着我曾winform的經驗第一時間想到的是win32 api  SendMessage,我們的C#程式隻需要DllImport就可以調用了。經過一番查找和對wpf window和DispatcherObject的Reflector,花了我大半天終于找到了System.Windows.Interop.HwndSource中有AddHock方法可以添加對win32消息機制的監聽。這下就很好辦了我們隻需要注冊MainWindow的這個時間,來監聽win32消息處理我們的0x004A消息。

程式:

檢視代碼   

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

       }  

截個圖:

<a href="http://blog.51cto.com/attachment/201204/185901836.jpg" target="_blank"></a>

很簡單的東西結果被MS封裝的不知哪裡去,讓我查了半天(其實應該是我的無知吧,不管怎麼解決了就是心情舒暢了);

 本文轉自 破狼 51CTO部落格,原文連結:http://blog.51cto.com/whitewolfblog/835234,如需轉載請自行聯系原作者

繼續閱讀