C# 跨进程 设置窗口owner
窗口间跨进程通信
1. 发送方
1 public const int WM_InsertChart_Completed = 0x00AA; 2 3 //查找窗口 4 [DllImport("User32.dll", EntryPoint = "FindWindow")] 5 public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); 6 7 //发送信息 8 [DllImport("User32.dll", EntryPoint = "SendMessage")] 9 public static extern int SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam); 10 11 private void PostMessage() 12 { 13 var procs = Process.GetProcessesByName("MyExample"); 14 15 foreach (var process in procs) 16 { 17 SendMessage(process.MainWindowHandle, WM_InsertChart_Completed, IntPtr.Zero, IntPtr.Zero); 18 } 19 }
还有一个PostMessage方法,和SendMessage类似。
2. 接收方
在winform中,不同进程间窗口通信
1 protected override void DefWndProc(ref Message m) 2 { 3 ...... 4 }
在WPF中,如何在俩个不同进程的窗口之间通信.
1 protected override void OnSourceInitialized(EventArgs e) 2 { 3 base.OnSourceInitialized(e); 4 var hwndSource = PresentationSource.FromVisual(this) as HwndSource; 5 hwndSource?.AddHook(new HwndSourceHook(WndProc)); 6 } 7 public const int WM_InsertChart_Completed = 0x00AA; 8 public static IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) 9 { 10 if (msg == WM_InsertChart_Completed ) 11 { 12 ............. 13 } 14 15 return hwnd; 16 }
传递具体的数据,可参考:http://www.360doc.com/content/18/0131/15/45112790_726705014.shtml
跨进程设置窗口owner,并禁用父窗口
此跨进程案例中,以子窗口A与父窗口B为例
1. 获取父窗口B的句柄
windowB的句柄Inptr,可以通过应用程序的名称或者线程Id,获取窗口的句柄。具体可参考 C# 通过进程名/进程Id 操作窗口
注:客户端之间如果有跨线程通信机制(局域网等),可以直接将父窗口B的句柄传给另一进程的子窗口A
2. 设置子窗口A的owner
var helper = new WindowInteropHelper(windowA);
helper.Owner = windowBInptr;
设置后,仅仅是显示在父窗口B的上层。禁用父窗口见下~
3. 通过消息机制禁用父窗口
子窗口A弹出后,向父窗口B发送禁用窗口消息:
其中,消息值的定义,不能窗口自带的消息值。窗口自带的消息列表,可参考 https://www.itsvse.com/thread-2755-1-1.html
1 public const int Msg_SetWindowUnEnabled = 100000; 2 public const int Msg_SetWindowEnabled = 100001; 3 4 public static void SetWindowUnEnabled(IntPtr windowIntPtr) 5 { 6 SendMessage(windowIntPtr, Msg_SetWindowUnEnabled, IntPtr.Zero, IntPtr.Zero); 7 } 8 9 public static void SetWindowEnabled(IntPtr windowIntPtr) 10 { 11 SendMessage(windowIntPtr, Msg_SetWindowEnabled, IntPtr.Zero, IntPtr.Zero); 12 } 13 14 //发送信息 15 [DllImport("User32.dll", EntryPoint = "SendMessage")] 16 public static extern int SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
父窗口监听消息,并处理子窗口A发送的窗口禁用消息
1 protected override void OnSourceInitialized(EventArgs e) 2 { 3 base.OnSourceInitialized(e); 4 var hwndSource = PresentationSource.FromVisual(this) as HwndSource; 5 hwndSource?.AddHook(new HwndSourceHook(WndProc)); 6 } 7 8 public IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) 9 { 10 if (msg == WindowHandleHelper.Msg_SetWindowUnEnabled) 11 { 12 this.IsEnabled = false; 13 } 14 else if (msg == WindowHandleHelper.Msg_SetWindowEnabled) 15 { 16 this.IsEnabled = true; 17 } 18 19 return hwnd; 20 }
4. 跨进程的模态窗口
以上设置将窗口A置于另一进程的窗口B上层,并将窗口B设置为禁用。
如果窗口A需要窗口反馈动画(反馈动画可以是模态,也可以是阴影,见我之前的水文《WPF window 子窗口反馈效果(抖动/阴影渐变)》),怎么办?
待处理--之后会更新
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
node事件循环 EventEmitter 异步I/O Buffer缓冲区 模块
node.js事件循环 node.js单进程,单线程的程序每一个api都支持回调所有的事件机制都是设计模式中的 一共是23种设计模式 http://design-patterns.readthedocs.io/zh_CN/latest/behavioral_patterns/observer.html 一个对象发生改变的时候,将自动通知其他对象,其他对象将相应的做出反应。发生改变的对象为观察目标,被通知的对象为观察者。一个观察目标可以对应多个观察者,而这些观察者之间没有任何联系,可以根据需要增加观察者,使得系统更加容易扩展,依赖关系为一对多,又被称为模型-视图模式 事件驱动程序 web server接收到请求,将其关闭,进行处理,然后接着服务下一个web请求。当请求完成以后,放回处理队列,当到达队列开头的时候,将其结果返回给用户即非阻塞式I/O 事件驱动I/O会有一个主循环来监听事件,当检测到事件以后,触发回调函数 代码 PS C:\Users\mingm\Desktop\test> node main.js 连接成功 数据接收成功 程序执行完毕 PS C:\Users\ming...
- 下一篇
java存储机制(栈、堆、方法区详解)
一、java的六种存储地址及解释 1) 寄存器(register):这是最快的存储区,因为它位于不同于其他存储区的地方——处理器内部。但是寄存器的数量极其有限,所以寄存器由编译器根据需求进行分配。你不能直接控制,也不能在程序中感觉到寄存器存在的任何迹象。 2) 堆栈(stack):位于通用RAM中,但通过它的“堆栈指针”可以从处理器哪里获得支持。堆栈指针若向下移动,则分配新的内存;若向上移动,则释放那些内存。这是一种快速有效的分配存储方法,仅次于寄存器。创建程序时候,JAVA编译器必须知道存储在堆栈内所有数据的确切大小和生命周期,因为它必须生成相应的代码,以便上下移动堆栈指针。这一约束限制了程序的灵活性,所以虽然某些JAVA数据存储在堆栈中——特别是对象引用,但是JAVA对象不存储其中。 3)堆(heap):一种通用性的内存池(也存在于RAM中),用于存放所有的JAVA对象。堆不同于堆栈的好处是:编译器不需要知道要从堆里分配多少存储区域,也不必知道存储的数据在堆里存活多长时间。因此,在堆里分配存储有很大的灵活性。当你需要创建一个对象的时候,只需要new写一行简单的代码,当执行这行代...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- CentOS关闭SELinux安全模块
- CentOS7设置SWAP分区,小内存服务器的救世主
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作