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,借来用用。

程序:

 


 
 
  1. 查看代码   
  2. using System;   
  3. using System.Collections.Generic;   
  4. using System.Linq;   
  5. using System.Text;   
  6. using System.Runtime.InteropServices;   
  7.  
  8. namespace ConsoleApplication1   
  9. {   
  10.     class Program   
  11.     {   
  12.         static void Main(string[] args)   
  13.         {   
  14.             string ch = "";   
  15.             while (ch.ToLower() != "q")   
  16.             {   
  17.  
  18.                 if (!SendMessage("Window1", @"Hello,I am from Console Program:" + ch))   
  19.                 {   
  20.                    Console.WriteLine("no window");  
  21.  
  22.                 };   
  23.                 ch = Console.ReadLine();   
  24.             }   
  25.         }   
  26.  
  27.         public static bool SendMessage(string windowName, string strMsg)   
  28.         {   
  29.             if (strMsg == nullreturn true;   
  30.             IntPtr hwnd = (IntPtr)FindWindow(null, windowName   );   
  31.             if (hwnd != IntPtr.Zero)   
  32.             {   
  33.                 CopyDataStruct cds;   
  34.                 cds.dwData = IntPtr.Zero;   
  35.                 cds.lpData = strMsg;   
  36.                 cds.cbData = System.Text.Encoding.Default.GetBytes(strMsg).Length + 1;   
  37.                 int fromWindowHandler = 0;   
  38.                 SendMessage(hwnd, 0x004A, fromWindowHandler, ref  cds);   
  39.                 return true;   
  40.             }   
  41.             return false;   
  42.         }   
  43.  
  44.         [DllImport("User32.dll", EntryPoint = "FindWindow")]   
  45.         private static extern int FindWindow(string lpClassName, string lpWindowName);   
  46.  
  47.         [DllImport("User32.dll", EntryPoint = "SendMessage")]   
  48.  
  49.         private static extern int SendMessage   
  50.  
  51.         (   
  52.  
  53.         IntPtr hWnd,   
  54.  
  55.         int Msg,   
  56.  
  57.         int wParam,   
  58.  
  59.         ref  CopyDataStruct lParam   
  60.  
  61.         );   
  62.  
  63.     }   
  64.  
  65.     [StructLayout(LayoutKind.Sequential)]   
  66.  
  67.     public struct CopyDataStruct   
  68.     {   
  69.  
  70.         public IntPtr dwData;   
  71.  
  72.         public int cbData;   
  73.  
  74.         [MarshalAs(UnmanagedType.LPStr)]   
  75.  
  76.         public string lpData;   
  77.  
  78.     }   
  79.  
  80. }  
  81. 复制代码 

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


 
 
  1. 查看代码   
  2.  
  3. IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)   
  4.        {   
  5.  
  6.            if (msg == 0x004A)   
  7.            {   
  8.  
  9.                CopyDataStruct cds = (CopyDataStruct)System.Runtime.InteropServices.Marshal.PtrToStructure(lParam, typeof(CopyDataStruct));   
  10.  
  11.                MessageBox.Show(cds.lpData);   
  12.                this.Visibility = Visibility.Visible;   
  13.            }   
  14.  
  15.            return hwnd;   
  16.  
  17.        }   
  18.  
  19.        private void Window_Loaded(object sender, RoutedEventArgs e)   
  20.        {             
  21.  
  22.            (PresentationSource.FromVisual(this) as System.Windows.Interop.HwndSource).AddHook(new System.Windows.Interop.HwndSourceHook(WndProc));   
  23.        }  
  24. 复制代码 

截个图:

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







 本文转自 破狼 51CTO博客,原文链接:http://blog.51cto.com/whitewolfblog/835234,如需转载请自行联系原作者


相关文章
|
C#
WPF 循环显示列表
原文:WPF 循环显示列表 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/SANYUNI/article/details/79423707 项目需要类似手机上设置时间的控件,可以一直滚动显示的内容连续的。
1501 0
|
C#
Wpf中MediaElement循环播放
原文: Wpf中MediaElement循环播放       前一段时间做了一个项目,里面牵涉到媒体文件的循环播放问题,在网上看了好多例子,都是在xaml中添加为MediaElement添加一个TimeLine,不符合我的项目需...
1283 0
|
C#
在wpf中如何让MediaElement的视频循环播放
原文:在wpf中如何让MediaElement的视频循环播放 MediaElement原始的播放是只播放一遍;如何设置让MediaElement播放 的视频或者音频循环播放,解决如下: 修改MediaElement模版                                       ...
1444 0
|
6月前
|
C# 开发者 Windows
基于Material Design风格开源、易用、强大的WPF UI控件库
基于Material Design风格开源、易用、强大的WPF UI控件库
389 0
|
6月前
|
C#
浅谈WPF之装饰器实现控件锚点
使用过visio的都知道,在绘制流程图时,当选择或鼠标移动到控件时,都会在控件的四周出现锚点,以便于修改大小,移动位置,或连接线等,那此功能是如何实现的呢?在WPF开发中,想要在控件四周实现锚点,可以通过装饰器来实现,今天通过一个简单的小例子,简述如何在WPF开发中,应用装饰器,仅供学习分享使用,如有不足之处,还请指正。
142 1
|
3月前
|
开发框架 缓存 前端开发
循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(11) -- 下拉列表的数据绑定以及自定义系统字典列表控件
循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(11) -- 下拉列表的数据绑定以及自定义系统字典列表控件
|
3月前
|
C# 开发者 Windows
一款基于Fluent设计风格、现代化的WPF UI控件库
一款基于Fluent设计风格、现代化的WPF UI控件库
|
3月前
|
C# Windows
WPF中如何使用HandyCotrol控件库
WPF中如何使用HandyCotrol控件库
195 1
|
3月前
|
C# 前端开发 UED
WPF数据验证实战:内置控件与自定义规则,带你玩转前端数据验证,让你的应用程序更上一层楼!
【8月更文挑战第31天】在WPF应用开发中,数据验证是确保输入正确性的关键环节。前端验证能及时发现错误,提升用户体验和程序可靠性。本文对比了几种常用的WPF数据验证方法,并通过示例展示了如何使用内置验证控件(如`TextBox`)及自定义验证规则实现有效验证。内置控件结合`Validation`类可快速实现简单验证;自定义规则则提供了更灵活的复杂逻辑支持。希望本文能帮助开发者更好地进行WPF数据验证。
117 0
|
3月前
|
C# UED 定位技术
WPF控件大全:初学者必读,掌握控件使用技巧,让你的应用程序更上一层楼!
【8月更文挑战第31天】在WPF应用程序开发中,控件是实现用户界面交互的关键元素。WPF提供了丰富的控件库,包括基础控件(如`Button`、`TextBox`)、布局控件(如`StackPanel`、`Grid`)、数据绑定控件(如`ListBox`、`DataGrid`)等。本文将介绍这些控件的基本分类及使用技巧,并通过示例代码展示如何在项目中应用。合理选择控件并利用布局控件和数据绑定功能,可以提升用户体验和程序性能。
69 0