原文:
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.cnblogs.com/shangdawei/p/4014535.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 子窗口反馈效果(抖动/阴影渐变)》)