2010-11-22 9 views
6

Normalmente, cuando abre un cuadro de diálogo con ShowModal, la ejecución del hilo actual se detiene hasta que se cierra el cuadro de diálogo. Quiero mostrar un diálogo modal, pero continuar la ejecución en el hilo actual mientras el cuadro de diálogo aún está abierto.Abrir un cuadro de diálogo modal de forma asincrónica en Delphi

Por "modal" simplemente quiere decir que el usuario no puede interactuar con cualquiera de las otras formas de la aplicación hasta el cuadro de diálogo modal está cerrada.

La función Delphi ShowModal proporciona una definición ligeramente diferente de "modal" a la que yo requiero:

Una forma modal es uno donde la aplicación no puede continuar funcionando hasta que se cierra el formulario.

Actualmente tengo un código como éste:

dialog.Parent:=self; 
dialog.Show; 
// keep doing stuff... 

Esto funciona, excepto que todavía puedo interactuar con la ventana padre (moverlo, cerrarla etc)

¿Cómo muestro una forma que impide al usuario interactuar con la ventana primaria, sin usar ShowModal?

Respuesta

6

Abrir el código fuente de Delphi \ Source \ \ VCL Forms.pas y la aplicación abierta de ShowModal. Luego aprende cómo funciona. No puedo copiar el código fuente aquí, ya que es una IP de CodeGear, pero puede hacerlo fácilmente y reutilizar partes de su código.

+1

Esto parece haber funcionado. Divido ShowModal en dos funciones; ShowModalNonBlocking y CloseModalNonBlocking. Tuve que eliminar algunas líneas de código que no compilaría. Espero que haya una solución mejor, pero esta es la mejor sugerencia que he encontrado hasta ahora. – awmross

+0

Sé que no puede publicar el código, pero ¿puede publicar sugerencias, como "dividir en la línea X"? – Mawg

+1

@Mawg La función "ShowModalNonBlocking" finalizó con una llamada a "Mostrar()". El "CloseModalNonBlocking" se inició al enviar un mensaje de Windows para desactivar el diálogo. ¿Espero que ayude? – awmross

6

Incluso con una forma modal abierta, el hilo principal sigue ejecutando (de lo contrario el formulario modal no podía volver a pintar en sí).

formas modales sin embargo tienen su propio ciclo de eventos, evitando que el bucle de eventos de la aplicación original a partir de la ejecución.

Tienen que (al igual que los cuadros de mensaje de Windows tienen que también), ya que de lo contrario podría tener un evento colarse de nuevo en el bucle principal evento de la creación de otra forma modal o de mensaje.

Y ese tipo de niega toda el punto de ser modal: no puede haber más que una forma de mensaje modal o por hilo de interfaz de usuario.

Así que hay que hacerse esta pregunta:

What actions in the main event loop does this modal form prevent from happening?

Entonces mover esas acciones en un hilo separado.

--jeroen

+1

No estoy de acuerdo. 'ShowModal' funciona desactivando los otros formularios, mostrando el nuevo formulario y luego ejecutando un bucle de mensaje. No veo ninguna razón particular para que el bucle de mensajes * necesite * pertenecer a 'ShowModal'; podría ser el que está en 'TApplication.Run' en su lugar. Ciertamente puede haber múltiples diálogos modales a la vez; simplemente muestre otro formulario dentro de su formulario modal. Sin embargo, solo uno puede ser * activo *; los otros se deshabilitan –

+0

@Rob: pensamiento interesante; cuando el usuario tiene que tratar una ventana modal antes de poder volver a la aplicación principal (http://en.wikipedia.org/wiki/Modal_window), ¿cómo podría esa aplicación principal iniciar una nueva ventana modal posterior desde otro lugar que la primera ventana modal? –

+0

De la misma manera en que la aplicación inició la primera ventana modal: deshabilita todas las ventanas activas y muestra otra ventana. Preferiblemente, usaría la ventana actualmente activa como padre para la nueva. –

5

deshabilitar su forma original, siempre y cuando el diálogo es visible, esto evitará que los usuarios interactúen ella. También puede usar DisableTaskWindows para deshabilitar todos los formularios y no solo el formulario principal. No está documentado, pero puede ver cómo se usa en TCustomForm.ShowModal en 'forms.pas'.

Cuestiones relacionadas