窗口間跨進程通信
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 子窗口反饋效果(抖動/陰影漸變)》)