Comment montrer la forme devant en C #

Gens,

S’il vous plaît, est-ce que quelqu’un sait comment afficher un formulaire à partir d’une application par ailleurs invisible et lui demander de se concentrer (c.-à-d. Qu’il apparaît au-dessus d’autres fenêtres)? Je travaille dans C # .NET 3.5.

Je suppose que j’ai pris “complètement la mauvaise approche” … Je ne fais pas Application.Run (new TheForm ()) à la place I (new TheForm ()). ShowModal () … Le formulaire est fondamentalement un dialog modal, avec quelques cases à cocher; une zone de texte et les boutons OK et Annuler. L’utilisateur coche une case et saisit une description (ou autre), puis appuie sur OK, le formulaire disparaît et le processus lit l’entrée saisie par l’utilisateur à partir du formulaire, le supprime et poursuit le traitement.

Cela fonctionne, sauf lorsque le formulaire est affiché, il ne reçoit pas le focus, il apparaît derrière l’application “hôte”, jusqu’à ce que vous cliquiez dessus dans la barre des tâches (ou autre chose). C’est un comportement très ennuyeux, qui, selon moi, causera de nombreux “appels de support”, et la version existante de VB6 n’a pas ce problème, alors je vais en arrière en termes de convivialité … et les utilisateurs ne l’accepteront pas (et ils ne devraient pas non plus).

Alors … je commence à penser que je dois repenser tout le shebang … Je devrais montrer le formulaire à l’avance, en tant qu ‘”application normale” et joindre le rest du traitement à l’événement OK-button-click. Cela devrait fonctionner, mais cela prendra du temps que je n’ai pas (j’ai déjà dépassé mon temps / mon budget) … donc d’abord, j’ai vraiment besoin d’essayer de faire fonctionner l’approche actuelle … même par des gestes rapides. méthodes sales.

Alors s’il vous plaît, est-ce que quelqu’un sait comment “forcer” un formulaire .NET 3.5 (par des moyens équitables ou des oiseaux) pour obtenir le focus? Je pense “magique” appels API Windows (je sais

Twilight Zone: Cela ne semble être un problème au travail, nous utilisons Visual Studio 2008 sur Windows XP SP3 … Je viens tout juste de ne pas reproduire le problème avec un SSCCE (voir ci-dessous) à la maison avec Visual C # 2008 sur Vista Ulimate … Cela fonctionne bien. Hein? WTF?

En outre, je jurerais que le travail hier a montré la forme quand j’ai couru l’EXE, mais pas quand F5’ed (ou Ctrl-F5’ed) directement de l’IDE (que je viens de supporter) … À la maison la forme montre bien de toute façon. Totalement confuster!

Cela peut être pertinent ou non, mais Visual Studio s’est écrasé et a brûlé ce matin alors que le projet fonctionnait en mode débogage et en modifiant le code “à la volée” … cela s’est bloqué, ce que je présumais être une boucle d’erreur sans fin. messages. Le message d’erreur concernait “Je ne peux pas déboguer ce projet car il ne s’agit pas du projet actuel, ou de quelque chose … Je viens de l’assumr avec l’explorateur de processus. Il a redémarré correctement et a même proposé de récupérer les” fichiers perdus. “fichier, une offre que j’ai acceptée.

using System; using System.Windows.Forms; namespace ShowFormOnTop { static class Program { [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); //Application.Run(new Form1()); Form1 frm = new Form1(); frm.ShowDialog(); } } } 

Contexte: je porte une implémentation VB6 existante dans .NET … C’est un “plugin” pour une application SIG “client” appelée MapInfo . Le client existant “travaillait de manière invisible” et mes instructions étaient “de garder la nouvelle version aussi proche que possible de l’ancienne version”, ce qui fonctionne assez bien (après des années de correction); il vient juste d’être écrit dans une langue non supscope, nous devons donc le porter.

À propos de moi: Je suis plutôt un adepte des langages C # et .NET en général, bien que j’aie un certificate d’essuyage des fonds, je suis un programmeur professionnel depuis 10 ans; Donc, je sais en quelque sorte “connaître certaines choses”.

Toute idée serait la bienvenue … et merci à vous tous d’avoir pris le temps de lire jusqu’à présent. La consistance n’est pas (apparemment) mon fort.

À votre santé. Keith

Simplement

 yourForm.TopMost = true; 

Il y a une surcharge de Form.ShowDialog () qui prend un object IWin32Window. Cet IWin32Window est traité comme la fenêtre parente du formulaire.

Si vous avez la fenêtre parent en tant que System.Windows.Forms.Form, continuez et passez-la simplement. Sinon, récupérez le HWND (peut-être par P / Invoking to FindWindow ()) et créez une implémentation factice IWin32Window qui renvoie simplement le HWND ( Plus de détails ).

  1. Vous avez dit que cela fonctionne bien lorsque vous utilisez Application.Run . Pourquoi ne voulez-vous pas utiliser Application.Run , alors?
  2. Avez-vous essayé d’appeler BringToFront() depuis OnLoad ou OnShown ?

Form.Activate() fonctionné dans mon cas.

C’est la solution finale que j’ai écrite après 20 tentatives différentes:

 /* A workaround for showing a form on the foreground and with focus, * even if it is run by a process other than the main one */ public static void ShowInForeground(this Form form, bool showDialog = false) { if (showDialog) { //it's an hack, thanks to http://stackoverflow.com/a/1463479/505893 form.WindowState = FormWindowState.Minimized; form.Shown += delegate(Object sender, EventArgs e) { ((Form)sender).WindowState = FormWindowState.Normal; }; form.ShowDialog(); } else { //it's an hack, thanks to http://stackoverflow.com/a/11941579/505893 form.WindowState = FormWindowState.Minimized; form.Show(); form.WindowState = FormWindowState.Normal; //set focus on the first control form.SelectNextControl(form.ActiveControl, true, true, true, true); } } 

Je l’ai piraté à partir d’une application sur laquelle je travaille. Nous avons une grande application qui charge une série de modules écrits par différentes équipes. Nous avons écrit l’un de ces modules et nous devions ouvrir une boîte de dialog de connexion lors de cette initialisation. Il a été défini sur ‘.TopMost = true’, mais cela n’a pas fonctionné.

Il utilise le WindowsFormsSynchronizationContext pour ouvrir une boîte de dialog, puis récupère le résultat de la boîte de dialog.

Je code rarement, et je soupçonne que c’est peut-être excessif, mais cela pourrait aider quelqu’un s’il est bloqué. J’ai eu du mal à comprendre comment l’état est passé à SendOrPostCallback, car tous les exemples que je pouvais trouver ne l’utilisaient pas.

En outre, cela provient d’une application en cours d’utilisation, mais j’ai supprimé plusieurs bits de code et modifié certains détails. Toutes mes excuses s’il ne comstack pas.

 public bool Dummy() { // create the login dialog DummyDialogForm myDialog = new DummyDialogForm(); // How we show it depends on where we are. We might be in the main thread, or in a background thread // (There may be better ways of doing this??) if (SynchronizationContext.Current == null) { // We are in the main thread. Just display the dialog DialogResult result = myDialog.ShowDialog(); return result == DialogResult.OK; } else { // Get the window handle of the main window of the calling process IntPtr windowHandle = Process.GetCurrentProcess().MainWindowHandle; if (windowHandle == IntPtr.Zero) { // No window displayed yet DialogResult result = myDialog.ShowDialog(); return result == DialogResult.OK; } else { // Parent window exists on separate thread // We want the dialog box to appear in front of the main window in the calling program // We would like to be able to do 'myDialog.ShowDialog(windowHandleWrapper)', but that means doing something on the UI thread object resultState = null; WindowsFormsSynchronizationContext.Current.Send( new SendOrPostCallback(delegate(object state) { resultState = myDialog.ShowDialog(); }), resultState); if (resultState is DialogResult) { DialogResult result = (DialogResult) resultState; return result == DialogResult.OK; } else return false; } } 

}

Activate() travaillé pour moi.

BringToFront() n’a rien fait dans ce cas, je ne sais pas pourquoi.

Il semblerait que ce comportement soit spécifique à XP … Je ne peux donc pas le reproduire sous Vista.

http://www.gamedev.net/community/forums/topic.asp?topic_id=218484

EDIT: PS: C’est l’heure de me coucher (2 heures du matin ;-).

Merci à tous pour vos réponses … il y a un “peu de choses” que je peux essayer … Je pourrais même aller au bureau demain pour les essayer … Ouais, ouais … J’ai eu une vie une fois, mais je l’ai échangée pour une coupe de cheveux et un travail 😉

Salut à tous. Keith

Cela a parfaitement fait le travail:

 formxx.WindowState = FormWindowState.Normal; formxx.BringToFront(); formxx.Topmost=true; formxx.Focus(); 

J’ai un code dans le projet.

 private static extern bool SetForegroundWindow( IntPtr hWnd); public static void ShowToFront(Form form) { FormWindowState oldState = form.WindowState; form.WindowState = FormWindowState.Minimized; form.Show(); form.Activate(); form.TopLevel = false; form.TopLevel = true; form.SelectNextControl(form.ActiveControl, true, true, true, true); SetForegroundWindow(form.Handle); form.Focus(); form.WindowState = oldState; } 

C’est ce que j’utilise pour apporter un formulaire ouvert qui fait partie de ma demande au début. Vous pouvez même l’utiliser avec un bouton. Mais le formulaire doit être ouvert ou l’application va casser.

“YourOpenForm” doit être le nom de votre formulaire à partir de la fenêtre des propriétés.

  private void button1_Click(object sender, EventArgs e) { Application.OpenForms["YourOpenForm"].BringToFront(); } 

Bonne chance!