2009-11-17 13 views
1

Je commence à avoir un comportement étrange lors du démarrage d'une application Windows et je me demandais si quelqu'un pouvait éclairer ce qui se passe et comment se déplacer il.Fenêtre de formulaires Windows démarrant hors foyer (et derrière le dossier exécutable)

Le problème est avec le démarrage de l'application - il devrait afficher un écran de démarrage puis un formulaire de connexion. Le code pour cela est:

[STAThread] 
    static void Main() 
    { 
     Application.ThreadException += Application_ThreadException; 
     MainForm mainForm = null; 

     Thread splashThread = new Thread(ShowSplash); 

     try 
     { 
      // set up app 
      Application.EnableVisualStyles(); 
      Application.SetCompatibleTextRenderingDefault(false); 

      // Splash screen 
      Splash splash = new Splash(); 
      splashThread.Start(splash); 

      // enable logging 
      log4net.Config.XmlConfigurator.Configure(); 

      // Create main form 
      mainForm = new MainForm(); 

      // kill splash 
      HideForm(splash); 
      splashThread.Abort(); 
     } 
     catch (Exception e) 
     { 
      splashThread.Abort(); 
      MessageBox.Show(e.Message, "An exception occurred: ", MessageBoxButtons.OK, MessageBoxIcon.Error); 
      Environment.Exit(0); 
     } 

     // start 
     Login login = new Login(); 
     login.Show(); 

     if (!mainForm.IsDisposed) 
     { 
      Application.Run(mainForm); 
     } 
    } 

    static void ShowSplash(object splash) 
    { 
     if (!(splash is Splash)) 
      throw new ArgumentException("Splash screen is of wrong type."); 

     Splash splashForm = (Splash) splash; 
     splashForm.ShowDialog(); 
    } 

    // Thread safe hide form 
    private delegate void HideFormCallback(Form form); 
    private static void HideForm(Form form) 
    { 
     if (form == null || form.IsDisposed) 
      return; 

     if (form.InvokeRequired) 
     { 
      HideFormCallback d = HideForm; 
      form.Invoke(d, new object[] { form }); 
     } 
     else 
     { 
      form.Hide(); 
     } 
    } 

Donc, nous commençons un nouveau fil avec l'écran de démarrage, la mise en place du reste de l'application dans l'intervalle, puis tuer l'écran de démarrage juste avant de montrer le formulaire de connexion . Le problème que j'ai est que le formulaire de connexion n'a pas de focus au démarrage de l'application. L'écran de démarrage apparaît et disparaît comme prévu. Le formulaire de connexion apparaît devant toutes les fenêtres ouvertes mais n'a pas le focus - le dossier contenant l'exécutable (que j'ai double-cliqué pour lancer) a toujours le focus même lorsqu'il se trouve derrière le formulaire de connexion.

Si je commente toutes les lignes à faire avec l'écran de démarrage, le formulaire de connexion a le focus lorsqu'il apparaît. Je suppose que le focus revient sur le dossier exécutable lorsque l'écran de démarrage est masqué mais je ne sais pas pourquoi le formulaire de connexion ne reçoit pas le focus lors du lancement. L'appel de .Focus() sur le formulaire de connexion renvoie null, donc cela ne fonctionne pas.

Aucune de ces deux formes ne comporte TopMost ou un tel ensemble.

Si quelqu'un a des suggestions pour ce qui se passe, ce serait très apprécié.

Répondre

3

C'est ce que j'ai fini par faire comme une solution un peu hacky:

void LoginView_Shown(object sender, EventArgs e) 
    { 
     SetForegroundWindow(Handle); 
     this.BringToFront(); 
     Activate();   
    } 

    [DllImport("user32")] 
    public static extern int SetForegroundWindow(IntPtr hwnd);