2010-04-14 9 views
31

Wir möchten nur eine Instanz unserer App gleichzeitig ausführen. So beim Start sieht es aus, ob die App läuft und wenn es ist, ruft es SetForegroundWindow auf dem Hauptfenster.Bringen Sie ein anderes Prozessfenster in den Vordergrund, wenn es ShowInTaskbar hat = false

Das ist alles gut und gut ... zum größten Teil ..

Wenn unsere App gestartet wird, nimmt es einen Splash-Bildschirm und ein Anmeldeformular zeigen. Beide Formulare haben ShowInTaskBar = false.

Aus diesem Grund, wenn Sie versuchen, eine andere Kopie der App zu starten, wenn das Anmeldeformular angezeigt wird, wird das Anmeldeformular nicht an die Front gebracht!

Vor allem, weil der Benutzer nichts in der Taskleiste sehen kann, alles, was sie sehen, ist, dass die App duff ist und nicht starten kann. Es gibt keinen Hinweis darauf, dass eine andere Instanz ausgeführt wird.

Gibt es eine Möglichkeit, dieses Problem zu umgehen?

+0

Frage: die Owner-Eigenschaft des Anmeldeformulars nicht Einstellung nicht dies lösen oder tut es hat keine Wirkung? – Asher

Antwort

41

Nun, Code ist hier. Auch wenn die ShowInTaskBarfalse ist, sollten Sie in der Lage sein, es nach vorne zu bringen.

[DllImport("USER32.DLL", CharSet = CharSet.Unicode)] 
    public static extern IntPtr FindWindow(String lpClassName, String lpWindowName); 

    [DllImport("USER32.DLL")] 
    public static extern bool SetForegroundWindow(IntPtr hWnd); 

    public static void bringToFront(string title) { 
     // Get a handle to the Calculator application. 
     IntPtr handle = FindWindow(null, title); 

     // Verify that Calculator is a running process. 
     if (handle == IntPtr.Zero) { 
      return; 
     } 

     // Make Calculator the foreground application 
     SetForegroundWindow(handle); 
    } 

Hinweis: Sie sollten FindWindow die Form der Klasse und nicht namentlich unter Verwendung als die Splash-Screen Formen manchmal nicht Titel oder sogar die Kontrollbox. Verwenden Sie Spy ++, um tiefer zu graben.

Verwenden Sie FindWindow auf Splash. Ich denke, das ist, was Sie tun wollen - bringen Sie den Splash-Screen vor dem Laden des Hauptformulars.

+0

Ich habe einen Aufruf von System.Diagnostics.Process.GetProcessesByName ausgeführt, um den Prozess abzurufen, und dann SetForegroundWindow für den Prozess.MainWindowHandle aufgerufen. Ohne ShowInTaskbar gab es kein MainWindowHandle. FindWindow ist eine gute Möglichkeit, dies zu umgehen. Vielen Dank! –

+0

So viele Möglichkeiten, dies zu tun, war dies der einzige, der für mich arbeitete! – Lee

0
FindWindow(null, title); 

Findet das erste Fenster, das der Abfrage entspricht. Dies kann zu unerwartetem Verhalten führen, wenn ein anderes Fenster denselben Titel verwendet.

Obwohl die Wahrscheinlichkeit, dass dies geschieht, selten oder unmöglich erscheint (Einzelinstanzanwendung), kann dies leicht passieren. Der Windows Explorer verwendet zum Beispiel den Namen des ausgewählten Verzeichnisses als Fenstertitel (obwohl unsichtbar). Wenn der Fenstertitel ein allgemeiner Begriff ist oder mit dem Namen des Anwendungsverzeichnisses übereinstimmt, kann dies ein Problem darstellen.

16

Ich denke, das ist die bessere Lösung, weil seine Wiederherstellungen von minimierten Zustand:

public static class WindowHelper 
{ 
    public static void BringProcessToFront(Process process) 
    { 
     IntPtr handle = process.MainWindowHandle; 
     if (IsIconic(handle)) 
     { 
      ShowWindow(handle, SW_RESTORE); 
     } 

     SetForegroundWindow(handle); 
    } 

    const int SW_RESTORE = 9; 

    [System.Runtime.InteropServices.DllImport("User32.dll")] 
    private static extern bool SetForegroundWindow(IntPtr handle); 
    [System.Runtime.InteropServices.DllImport("User32.dll")] 
    private static extern bool ShowWindow(IntPtr handle, int nCmdShow); 
    [System.Runtime.InteropServices.DllImport("User32.dll")] 
    private static extern bool IsIconic(IntPtr handle); 
} 

Einfacher Aufruf:

WindowHelper.BringProcessToFront(process); 
+1

Diese Antwort wird aktualisiert, da sie auch aus einem minimierten Zustand wiederhergestellt wird. – oppassum

Verwandte Themen