原文: 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.html1 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 子視窗回報效果(抖動/陰影漸變)》)