2011-12-16 11 views
5

Attualmente sto scrivendo un sistema di finestre per un'applicazione Delphi esistente.Delphi - overriding del comportamento hide di TForm.showModal

Attualmente il programma è costituito da un numero di moduli di dimensioni standard che vengono visualizzati in modo modale nell'ordine in cui sono richiesti e nessuno dei quali può essere spostato dall'utente. Il mio obiettivo è quello di consentire a tutte queste forme di essere mobili. In precedenza i moduli venivano impilati uno sopra l'altro, ma poiché nessuno poteva essere spostato, i moduli di sfondo non erano visibili all'utente. La mia soluzione fino ad ora è stata quella di nascondere il modulo 'genitore' quando si apre un nuovo bambino e di risvegliarlo quando viene chiuso quel bambino.

Sfortunatamente dal momento che ogni bambino viene chiamato con showModal, la chiamata il rendere visibile la forma genitoriale non arriva fino a dopo che il processo modale è completato e quindi dopo che il modulo figlio è stato nascosto in modo che l'utente veda un flash intermittente dove no la forma è visibile.

C'è un modo per impedire che i moduli modali vengano nascosti automaticamente al termine del processo? Questo mi permetterebbe di nasconderli manualmente una volta che il modulo genitore sarà nuovamente visibile. Ho provato a pianificare questo evento FormHide di ogni modulo figlio, ma questo non funziona in quanto un modulo figlio viene nascosto anche quando si apre uno dei propri figli.

EDIT:

Ecco quello che ho finora basato su consiglio di Remy sotto

procedure openModalChild(child: TForm; parent: TForm); 
var 
    WindowList: Pointer; 
    SaveFocusCount: Integer; 
    SaveCursor: TCursor; 
    SaveCount: Integer; 
    ActiveWindow: HWnd; 
    Result: integer; 
begin 
    CancelDrag; 
    with child do begin 
    Application.ModalStarted; 
    try 
    ActiveWindow := GetActiveWindow; 
    WindowList := DisableTaskWindows(0); 
    //set the window to fullscreen if required 
    setScreenMode(child); 
    try 
    Show; //show the child form 
    try 
     SendMessage(Handle, CM_ACTIVATE, 0, 0); 
     ModalResult := 0; 
     repeat 
     Application.HandleMessage; 
     //if Forms.Application.FTerminate then ModalResult := mrCancel else 
      if ModalResult <> 0 then closeModal(child as TCustomForm); 
     until ModalResult <> 0; 
     Result := ModalResult; 
     SendMessage(Handle, CM_DEACTIVATE, 0, 0); 
     if GetActiveWindow <> Handle then ActiveWindow := 0; 
    finally 
     parent.Show; 
     Hide; 
    end; 
    finally 
    EnableTaskWindows(WindowList); 
    parent.Show; //reshow the parent form 
    if ActiveWindow <> 0 then SetActiveWindow(ActiveWindow); 
    end; 
    finally 
    Application.ModalFinished; 
    end; 
    end; 
end; 

Questo funziona bene, ma l'unico problema è il ciclo di ripetizione attiva non si rompe mai, anche dopo che il bambino è stato fuggito e quindi la forma genitore non viene mai resettata. Esiste un modo per risolvere questo problema?

+0

Hai provato a rendere visibile il modulo padre dal modulo figlio prima della chiusura? –

+0

Non capisco come nascondere la finestra 'genitore' comporterà la mobilità di entrambe le forme. Descrivi con precisione il tuo obiettivo o elimina la parte superflua dalla domanda. – NGLN

+0

Nascondere il genitore non cambia se uno dei due moduli può spostarsi (è già possibile). I moduli che sto facendo riferimento dovrebbero essere tutti all'interno di una finestra, ma a causa dell'implementazione della progettazione esistente non lo sono. Per dare l'effetto di una finestra ogni bambino appena mostrato viene posizionato e dimensionato identico al suo genitore chiamante e quando chiuso il genitore viene spostato nella posizione del bambino e reso visibile. Visivamente questi appaiono come un'unica finestra con l'eccezione di un breve momento in cui nessuna forma è visibile. – jmc

risposta

10

ShowModal() chiama esplicitamente Show() appena prima di entrare nel relativo ciclo di elaborazione modale e chiama esplicitamente Hide() immediatamente dopo l'uscita dal ciclo. Non è possibile modificarlo senza alterare il codice nel file di origine Forms.pas di VCL.

Se è necessario un controllo più preciso su Windows, senza modificare il codice sorgente VCL, non utilizzare affatto ShowModal(). Utilizzare Show(), Hide(), DisableTaskWindows() e EnableTaskWindows() come necessario. Mi piacerebbe che guardi Forms.pas per vedere come vengono utilizzati. Copia l'implementazione di ShowModal() nella tua funzione, quindi puoi personalizzarla secondo necessità.

+0

Hi Remy - come programmatore Delphi non esperienza, come posso creare una nuova implementazione di ShowModal per una raccolta di moduli? Suppongo che debbano implementare da qualche superclasse di Form che eredita da TForm? Parlando in termini Java/C qui ... – jmc

+0

Lo implementerei come una funzione autonoma che puoi passare un puntatore 'TForm' come parametro. –