我希望我的C#winform應用程序切換到另一個正在運行的實例,如果發生某些事件。切換到同一應用程序的其他實例
例如,如果我有一個只有一個按鈕的應用程序,並且此刻有三個實例正在運行。現在,如果我
- 按一審按鈕,聚焦到二審
- 按二審按鈕,聚焦到第三個實例
- 按在第三實例中的按鈕,集中於一審
我該怎麼做?
我希望我的C#winform應用程序切換到另一個正在運行的實例,如果發生某些事件。切換到同一應用程序的其他實例
例如,如果我有一個只有一個按鈕的應用程序,並且此刻有三個實例正在運行。現在,如果我
我該怎麼做?
,如果你知道其他實例的句柄,你應該只調用Windows API:SetForegroundWindow:
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
可以使用FindWindow函數 API調用來獲取其他實例的句柄,例如:
public static int FindWindow(string windowName)
{
int hWnd = FindWindow(null, windowName);
return hWnd;
}
您可以搜索這些API調用在這裏SO更多的例子,例如發現這一個:
SetForegroundWindow
是一個很好的解決方案。另一種方法是使用名爲Semaphores
的信號發送給其他應用程序。
最後,您可以查找Inter-Process Communication (IPC)
解決方案,該解決方案將允許您在進程之間發送消息。
我寫了一個簡單的.Net XDMessaging庫,使它非常簡單。使用它可以將指令從一個應用程序發送到其他應用程序,並且在最新版本中甚至可以傳遞相繼的對象。這是一個使用頻道概念的多播實現。
應用1:
IXDBroadcast broadcast = XDBroadcast.CreateBroadcast(
XDTransportMode.WindowsMessaging);
broadcast.SendToChannel("commands", "focus");
應用2:
IXDListener listener = XDListener.CreateListener(
XDTransportMode.WindowsMessaging);
listener.MessageReceived+=XDMessageHandler(listener_MessageReceived);
listener.RegisterChannel("commands");
// process the message
private void listener_MessageReceived(object sender, XDMessageEventArgs e)
{
// e.DataGram.Message is the message
// e.DataGram.Channel is the channel name
switch(e.DataGram.Message)
{
case "focus":
// check requires invoke
this.focus();
break;
case "close"
this.close();
break;
}
}
謝謝,給它一個嘗試 – SMUsamaShah
想想SetForegroundWindow的限制。從任何過程你都不能帶來任何窗口。 請參閱:http://msdn.microsoft.com/en-us/library/ms633539(v=vs.85).aspx –
當兩個實例具有相同的窗口名稱時它將如何切換? – SMUsamaShah