zoukankan      html  css  js  c++  java
  • 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 == nullreturn 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(
    thisas System.Windows.Interop.HwndSource).AddHook(new System.Windows.Interop.HwndSourceHook(WndProc)); 
           }

    截个图:

    GDVCJ_1PZO7SU((~1}41XSG

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


    作者:破  狼
    出处:http://www.cnblogs.com/whitewolf/
    本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。该文章也同时发布在我的独立博客中-个人独立博客博客园--破狼51CTO--破狼

  • 相关阅读:
    [CF666E] Forensic Examination
    [BZOJ3739] DZY loves math VIII
    [BZOJ3561] DZY Loves Math VI
    VS中的类模板
    php中的this,self,parent
    js中的 Table 对象
    CEF中弹出窗口的处理
    VC禁止或允许拖拽改变窗口尺寸
    MFC系统自动生成的停靠窗格关掉后,如何重新显示?
    VS2010 如何自动生成UML图
  • 原文地址:https://www.cnblogs.com/whitewolf/p/1971300.html
Copyright © 2011-2022 走看看