2009-09-21 8 views
1

Je voudrais créer une application Windows Forms qui, lorsqu'elle est exécutée, n'est visible qu'une fois qu'une autre fenêtre externe (notepad.exe) est activée/concentrée. Des indices, je ne sais pas par où commencer.Windows Forms: Définir le formulaire Visibilité Basé sur Focus activé de la fenêtre externe

Si mon formulaire est en cours d'exécution, je voudrais qu'il apparaisse lorsque le Bloc-notes est activé et disparaisse lorsque le Bloc-notes perd le focus.

Répondre

0

Vous pouvez le faire simplement avec des appels API et un temporisateur. Ajoutez cette ligne aux déclarations à l'aide de votre formulaire:

using System.Runtime.InteropServices; 

Ensuite, ajoutez ces déclarations à votre formulaire:

[DllImport("user32.dll", SetLastError = true)] 
private static extern IntPtr FindWindow(string lpClassName, 
    string lpWindowName); 

[DllImport("user32.dll")] 
private static extern IntPtr GetForegroundWindow(); 

Enfin, mettre une minuterie sur votre formulaire et définissez sa propriété Activé pour true. Dans son événement Tick, mettez ce code:

IntPtr hWndNotepad = FindWindow(null, "Whatever.txt - Notepad"); 
IntPtr hWndForegroundWindow = GetForegroundWindow(); 
if (this.Handle != hWndForegroundWindow) 
{ 
    this.Visible = (hWndNotepad == hWndForegroundWindow); 
} 

Je n'ai pas testé ce code, mais cela devrait fonctionner. Le code recherche un fichier spécifique à ouvrir dans le Bloc-notes; un fichier différent entraînerait un texte différent dans la barre de titre, ce code ne fonctionnerait donc pas. Je pense que si vous modifiez l'appel FindWindow à FindWindow("notepad", null) cela fonctionnerait avec n'importe quelle instance ouverte de Bloc-notes (il peut être "notepad.exe" - pas sûr).

Mise à jour: si vous voulez que votre forme soit visible si une instance du Bloc-notes est ouvert, vous pouvez mettre à la place ce code dans votre événement Tick compteur d'émission:

IntPtr hWndForegroundWindow = GetForegroundWindow(); 
bool NotepadIsForeground = false; 
Process[] procs = Process.GetProcessesByName("notepad"); 
foreach (Process proc in procs) 
{ 
    if (proc.MainWindowHandle == hWndForegroundWindow) 
    { 
     NotepadIsForeground = true; 
     break; 
    } 
} 
if (this.Handle != hWndForegroundWindow) 
{ 
    this.Visible = NotepadIsForeground; 
} 

Et vous aurez besoin ceci dans vos directives d'utilisation:

using System.Diagnostics; 

Également pas testé, mais je me débrouille si bien aujourd'hui, alors pourquoi s'embêter?

+0

Cela a fonctionné! C'est la direction dans laquelle je veux aller. Merci Encore une question? Si je clique sur mon formulaire, il clignote continuellement au lieu de rester concentré (alterne entre celui-ci et le bloc-notes). Comment je le répare. –

+0

@zion: oups, vous a dit que je ne l'ai pas testé. Ce qui se passait était que dès que vous avez cliqué sur votre formulaire, * il * est devenu la fenêtre de premier plan, donc la prochaine fois que le minuteur s'est déclenché, votre formulaire s'est rendu invisible à nouveau. J'ai corrigé l'exemple de code. – MusiGenesis

+0

Erp, ne fonctionne toujours pas bien. Donnez-moi une seconde ... – MusiGenesis

0

Vous pouvez essayer les API d'automatisation Windows pour C#. Avec ceux-ci, vous devriez être capable de regarder à travers toutes les fenêtres ouvertes et trouver Notepad. Je n'ai pas regardé l'API, mais le meilleur scénario de base est qu'il y aurait un événement activate/lostfocus pour la fenêtre que vous pourriez gérer. Dans le pire des cas, vous pourriez juste interroger toutes les 100 ms environ et regarder si la fenêtre du bloc-notes a le focus.

Questions connexes