2010-10-07 8 views
7

Yo a todos. Actualmente tengo un problema con mi enfoque cuando uso una pantalla de inicio. Estoy usando VS2008, con .NET framework 2.0. Además, he vinculado mi proyecto con VisualBasic.dll ya que uso ApplicationServices para administrar mi aplicación de instancia única y la pantalla de bienvenida.La pantalla de bienvenida no devuelve el foco al formulario principal

Aquí hay un fragmento de código simplificado de lo que probé para depurar.

namespace MyProject 
{ 
    public class Bootstrap 
    { 
     /// <summary> 
     /// Main entry point of the application. It creates a default 
     /// Configuration bean and then creates and show the MDI 
     /// Container. 
     /// </summary> 
     [STAThread] 
     static void Main(string[] args) 
     { 
      // Creates a new App that manages the Single Instance background work 
      Application.EnableVisualStyles(); 
      Application.SetCompatibleTextRenderingDefault(false); 
      App myApp = new App(); 
      myApp.Run(args); 
     } 
    } 

    public class App : WindowsFormsApplicationBase 
    { 
     public App() 
      : base() 
     { 
      // Make this a single-instance application 
      this.IsSingleInstance = true; 
      this.EnableVisualStyles = true; 

      // There are some other things available in the VB application model, for 
      // instance the shutdown style: 
      this.ShutdownStyle = Microsoft.VisualBasic.ApplicationServices.ShutdownMode.AfterMainFormCloses; 

      // Add StartupNextInstance handler 
      this.StartupNextInstance += new StartupNextInstanceEventHandler(this.SIApp_StartupNextInstance); 
     } 

     protected override void OnCreateSplashScreen() 
     { 
      this.SplashScreen = new MyMainForm(); 
      this.SplashScreen.StartPosition = FormStartPosition.CenterScreen; 
     } 
     protected override void OnCreateMainForm() 
     { 
      // Do your initialization here 
      //... 
      System.Threading.Thread.Sleep(5000); // Test 
      // Then create the main form, the splash screen will automatically close 
      this.MainForm = new Form1(); 
     } 
     /// <summary> 
     /// This is called for additional instances. The application model will call this 
     /// function, and terminate the additional instance when this returns. 
     /// </summary> 
     /// <param name="eventArgs"></param> 
     protected void SIApp_StartupNextInstance(object sender, 
      StartupNextInstanceEventArgs eventArgs) 
     { 
      // Copy the arguments to a string array 
      string[] args = new string[eventArgs.CommandLine.Count]; 
      eventArgs.CommandLine.CopyTo(args, 0); 

      // Create an argument array for the Invoke method 
      object[] parameters = new object[2]; 
      parameters[0] = this.MainForm; 
      parameters[1] = args; 

      // Need to use invoke to b/c this is being called from another thread. 
      this.MainForm.Invoke(new MyMainForm.ProcessParametersDelegate(
       ((MyMainForm)this.MainForm).ProcessParameters), 
       parameters); 
     } 
    } 
} 

Ahora, lo que sucede es que, cuando comienzo a la aplicación, la pantalla de bienvenida muestra como se esperaba, pero cuando es destruido, no devuelve el foco al formulario principal (Form1 en la prueba). MainForm simplemente parpadea en naranja en la barra de tareas. Si ejecuto la aplicación desde el IDE (VS2008), el enfoque funciona bien. Estoy usando XP Pro. Además, el formulario principal no se encuentra en la parte superior de las demás ventanas. Si hago un comentario sobre el método OnCreateSplashScreen(), la aplicación obtiene el foco normalmente.

Para probar la ejecución normal, estoy usando el símbolo del sistema VS para iniciar mi aplicación. Estoy usando la versión de lanzamiento de mi proyecto.

¿Alguna idea?

Edit: También manejo el evento StartUpNextInstance para enviar mis argumentos de línea de comandos a mi formulario principal. Para propósitos de prueba, fue eliminado aquí.

Editar: Se ha añadido un poco más de código. Ahora tienes toda la extensión de mi bootstrap.

+0

Éste es mi código. SO toma esto bastante en serio, se requiere atribución. Debe incluir un enlace al código original y el nombre del autor. –

+0

Tomé este código hace mucho tiempo (creo que las fechas son meses) y solo lo agregué al SplashScreen. Lo siento si fue tuyo para empezar. ¿Cómo puedo agregar su atribución y enlace? – Olyan

Respuesta

3

La pregunta no está en detalle.

1) ¿Cuál es la relación entre SplashScreen y la forma principal de la aplicación?

2) ¿Cómo se cierra automáticamente SplashScreen?

Estoy seguro de que el problema aquí es que el formulario principal ya comenzó a cargarse en segundo plano, mientras que SplashScreen aún no se ha cerrado. Debido a un mal momento, el formulario principal se carga en segundo plano y el SplashScreen se descarga ... de ahí el flash en la barra de tareas.

Haga que aparezcan de manera controlada en serie. Hay muchas maneras. No puedo sugerir exactamente cómo ya que apenas se ha proporcionado ningún detalle. Al igual que lo que está haciendo VB en el proyecto, el número de hilos están trabajando, ¿cuáles son las formas personalizadas utilizadas aquí .. etc

EDIT:

algoritmo para implementar pantalla de bienvenida (en mi humilde opinión) :)

1) Crear un formulario personalizado - pantalla de bienvenida

2) Ejecútelo en una secuencia separada. Implementa su comportamiento como quieras.

3) En su formulario de pantalla de presentación, escriba un controlador para capturar un controlador de eventos de descarga personalizado que cierra el formulario de pantalla de bienvenida.

4) Ahora, de vuelta en el hilo principal, cree su formulario de aplicación principal. Establezca su propiedad Visible en falso.

5) Escriba el controlador par del evento Load del formulario principal.En este controlador, ejecute un evento para abrir la pantalla y descargar. Luego, haz visible la forma principal.

+0

En realidad, el marco VisualBasic hace el trabajo automáticamente con respecto a SplashScreen. Lo muestra automáticamente y cuando se muestra el formulario principal, destruye la pantalla de bienvenida. Solo tengo el hilo principal en ejecución. Mi proceso de carga se realiza en OnCreateMainForm donde // se realiza la inicialización aquí. – Olyan

+0

Ese VB FW podría ser el problema. Como dijiste, destruye la pantalla de bienvenida cuando se carga la forma principal, y luego el foco puede haber cambiado a la pantalla de bienvenida durante su acción cercana. No lo sé, pero debe verificar VB FW utilizando. ¿Lo estás usando solo para splash?También se puede hacer en C# sin VB FW. – Nayan

+0

Empecé a usarlo para la aplicación SingleInstance. Es un encanto para eso. Pasa mis argumentos de línea de comando a la aplicación abierta y todo. Solo agregué la pantalla emergente hace unos días, ya que mi inicialización puede tener algunos mensajes para mostrar al usuario a través de MessageBox, por lo que necesitaba un elemento GUI para estar presente. – Olyan

0

¿Qué sucede si establece el foco explícitamente en su evento de carga Form1?

+0

He intentado poner esto. Enfoque() dentro del evento mostrado, no solucionó el problema. Pero ahora estoy confundido. A veces, el enfoque funciona bien, a veces no funciona. – Olyan

0

Por alguna razón oscura, el enfoque parece estar funcionando correctamente. Voy a tratar de incorporar más de mi ejecución normal de mi programa principal en MyMainForm y tratar de encontrar lo que realmente hace que el cambio de enfoque falle. Los mantendré a todos informados.

+0

¡Digo que es tu buena suerte! :) ¡Haznos saber! – Nayan

+0

Parece que perdí un día debido a VS. Simplemente eliminé las carpetas bin y obj, recompuse todo con mi solución original, todo funciona bien. Perdón por todo este lío. – Olyan

+0

Bueno, vuelvo con la misma pregunta. Por una razón desconocida, funcionó solo temporalmente. Y no cambié ningún código. Lo que sucedió para que funcione durante ese breve período de tiempo, no tengo ni idea. Y estoy realmente sin ideas. – Olyan

3

Debe llamar al método Activate() en su formulario principal para mostrarlo correctamente.

2

En algunas de mis implementaciones de formularios splash en un hilo diferente, he visto esta situación también.

generalmente si llamo a this.Activate(); como mi primera línea de código en la carga de formulario, tiende a funcionar como se esperaba. poner esto después de ocultar el splash por lo general no funciona correctamente.

otros métodos que pueden ayudar.

this.BringToFront(); 
this.TopMost = true; //setting this to true and back to false sometimes can help 
0

intente llamar form1.show() después this.MainForm = new Form1(); Se trabajó para mí.

0

Tuve el mismo problema y quería una solución fácil para esto.

Intenté arriba pero no suerte, pero las ideas de arriba son información útil.

Probé mi truco y funciona para mí.

Este es mi código Programs.cs que funciona muy bien:

static class Program 
{ 
    /// <summary> 
    /// The main entry point for the application. 
    /// </summary> 
    [STAThread] 
    static void Main() 
    { 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     var mainWindow = new frmMain(); 
     splashScreen.DisplaySplashScreen(mainWindow, 10000); 
     **mainWindow.TopMost = true;** 
     Application.Run(mainWindow); 
    } 
} 

Aviso permiso mainWindow.TopMost = true;

que estaba trabajando lo suficiente, pero yo no quería que los mainWindow a permanecer en la cima.

Así que en caso he añadido Shownthis.TopMost = false;

private void frmMain_Shown(object sender, EventArgs e) 
    { 
     this.TopMost = false; 
    } 

Ahora mi solicitud está trabajando como quería que funcione.

Nota: Recién publicado para ayudar a cualquier otro usuario que enfrente el mismo problema al que me enfrenté.

Happy Coding :)

Cuestiones relacionadas