Mi aplicación puede tardar un tiempo en conectarse a una base de datos. Esta conexión se realiza con una sola llamada de función de biblioteca, es decir, no puedo poner actualizaciones de progreso allí y hacer devoluciones de llamada o algo similar.¿Cómo crear un cuadro de diálogo MFC con una barra de progreso en un hilo separado?
Mi idea era crear un diálogo con una barra de progreso en un hilo separado antes de conectar con la base de datos. Este diálogo cambiará continuamente el estado del progreso con CProgressCtrl::StepIt()
para que el usuario vea que algo está sucediendo.
Después de que el cuadro de diálogo esté configurado y haciendo lo suyo, quiero llamar a la función de conexión de DB desde el hilo principal. Después de completar la función de conexión, quiero detener el hilo de la barra de progreso.
me deja pintar un cuadro:
CMyApp:: ProgressThread
InitInstance() .
| .
| .
+-Create Dialog-+
| |
| Animate
Connect Progress
to Bar
DB |
| |
+-Destroy Dlg---+
| .
| .
¿Es posible? Si es así, ¿cómo?
Tal vez todo funcione con temporizadores, también. Probablemente sería mucho más simple, pero tampoco pude lograr que funcionara.
- Soy consciente de
CProgressCtrl::SetMarquee()
que podría hacer exactamente lo que necesito, pero no puedo usarlo porque la aplicación no tiene soporte para Unicode. - Podría mover la llamada a la conexión db a un hilo separado, pero de esa manera parece que hay muchos cambios en el código y un manejo adicional de los errores de conexión.
Actualización 2
lo tengo trabajando de la manera AlexEzh y Javier De Pedro sugirieron: Poner el stuf DB en su propio hilo.
inicialmente me preocupaba cómo se podía manejar el error, pero en realidad es bastante similar a cómo era antes.
- En el hilo principal, creo una estructura con parámetros de conexión, indicador de resultado y indicador de ejecución de hilo. El último se establece inicialmente en
true
. - Creo un hilo y paso esa estructura como parámetro.
- Creo un cuadro de diálogo que muestra una barra de progreso en el hilo principal.
- También en el hilo principal hay un bucle que se ejecuta mientras se establece thread-running-flag. Llama al
CMyDialog::Animate()
que llama aCProgressCtrl::StepIt()
y luego aSleep()
s un poco. - El subproceso ejecuta el código de conexión db y establece el indicador de ejecución en
false
cuando finaliza. - Cuando el hilo principal sale del lazo puede manejar errores exactamente como lo hacía antes.
Desventaja: Mover el mouse sobre la ventana no funciona. Es invisible. Por lo tanto, no se puede usar ningún botón de cancelar u otros elementos de diálogo interactivos. Sin embargo, puedo vivir con eso.
Dado que te gustó el diagrama, aquí es la forma en que ahora se ve así:
CMyApp:: WorkerThread
InitInstance() .
| .
| .
Create Dialog .
| .
+-Start Thread--+
| |
| Connect
Animate to
Progress DB
Bar |
| |
+-Thread Ends---+
| .
Destroy Dlg .
| .
+1 para el diagrama –
Puede llamar SetMarquee() en una aplicación ANSI, pero no va a ayudar ya que el contador de tiempo que anima a la barra de progreso se llama en el hilo principal también –
En mi afxcmn.h se ve así: ** if (_WIN32_WINNT> = 0x0501) && defined (UNICODE) \ n BOOL SetMarquee (_In_ BOOL fMarqueeMode, _In_ int nInterval); \ n #endif \t // _WIN32_WINNT> = 0x0501 && defined (UNICODE) \ n ** Y es por eso que no puedo llamarlo. – foraidt