Form.ShowDialog dietro le quinte

di il
8 risposte

Form.ShowDialog dietro le quinte

Buonasera a tutti, chiedo ai dotti sperando che non si sian rotti (m'è scappata l'allitterazione).

Come da titolo vorrei capire dove prosegue (behind the scenes) l'esecuzione del codice dopo un'istruzione che visualizza una finestra modale, ad esempio tramite Form.ShowDialog, ma anche tramite un semplice MessageBox.Show, e soprattutto con quale meccanismo il codice riprende da dove si era fermato.

Per rendere la cosa più interessante provate ad esempio ad eseguire sulla classica form con un pulsante questo codice.
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Tasks.Task.Run(Sub()
                           Thread.Sleep(500)
                           Invoke(Sub() MessageBox.Show(Me, "Posso eseguire del codice sul thread della GUI nonostante la visualizzazione di una finestra modale."))
                       End Sub)
        MessageBox.Show(Me, "Questa è una finestra modale.")
        MessageBox.Show(Me, "Posso eseguire del codice sul thread della GUI soltanto dopo la chiusura della finestra modale.")
    End Sub

8 Risposte

  • Re: Form.ShowDialog dietro le quinte

    Antologiko ha scritto:


    Come da titolo vorrei capire dove prosegue (behind the scenes) l'esecuzione del codice dopo un'istruzione che visualizza una finestra modale, ad esempio tramite Form.ShowDialog, ma anche tramite un semplice MessageBox.Show, e soprattutto con quale meccanismo il codice riprende da dove si era fermato.
    Non ho mai decodificato il sorgente, tuttavia lavorando con le API di Windows, suppongo che semplicemente tutti i messaggi diretti all'applicazione vengano gestiti dalla finestra impostata come modale che si trova in primo piano.

    Non capisco però che cosa si vuole arrivare a determinare... non è "magia nera"...
  • Re: Form.ShowDialog dietro le quinte

    Alka ha scritto:


    Non ho mai decodificato il sorgente, tuttavia lavorando con le API di Windows, suppongo che semplicemente tutti i messaggi diretti all'applicazione vengano gestiti dalla finestra impostata come modale che si trova in primo piano.
    Penso anch'io, ma mi piaceva capire con che meccanismo viene bloccato il codice chiamante per poi riprendere dall'istruzione successiva alla chiusura della finestra modale.

    Alka ha scritto:


    Non capisco però che cosa si vuole arrivare a determinare... non è "magia nera"...
    Tranquillo, la domanda non cela alcun arcano fine . E' solo per il piacere di capire come funzionano le cose.
  • Re: Form.ShowDialog dietro le quinte

    Antologiko ha scritto:


    mi piaceva capire con che meccanismo viene bloccato il codice chiamante per poi riprendere dall'istruzione successiva alla chiusura della finestra modale.
    Non è nulla di arcano.

    Il funzionamento tradizionale dell'applicazione si basa sulla gestione ripetitiva e ciclica dei messaggi che vengono inseriti da Windows all'interno di un'apposita coda, per essere poi trasformati in eventi e indirizzati ai rispettivi controlli.

    Nel momento in cui chiami ShowDialog(), il metodo invoca una routine che apre e imposta la finestra modale e si mette ciclicamente in ascolto su tutti i messaggi che provengono all'applicazione, dirottandoli però alla finestra modale.

    Quel ciclo si interrompe solo quando la finestra viene chiusa, pertanto fino a quando la finestra è visibile, il controllo dell'esecuzione non esce dal ciclo e quindi non tornerà mai al metodo che ha invocato ShowDialog().

    Solo quando la finestra viene chiusa o si imposta un valore su ModalResult il ciclo termina, il metodo conclude il proprio lavoro e il controllo passa al metodo chiamante, ossia al punto in cui è stato invocato ShowDialog(), che così può proseguire.

    Alka ha scritto:


    Tranquillo, la domanda non cela alcun arcano fine . E' solo per il piacere di capire come funzionano le cose.
    La mia domanda era riferita a quello strano accrocchio che chiamava ShowDialog() dentro un thread, come se dimostrasse qualcosa di diverso rispetto a ciò che ci si aspetta.

    Ciao!
  • Re: Form.ShowDialog dietro le quinte

    Forse(?) ho capito: la chiamata a ShowDialog avvia una sorta di message loop secondario che elabora i messaggi inviatigli dal ciclo principale.
  • Re: Form.ShowDialog dietro le quinte

    Antologiko ha scritto:


    Forse(?) ho capito: la chiamata a ShowDialog avvia una sorta di message loop secondario che elabora i messaggi inviatigli dal ciclo principale.
    Se arrivano direttamente dal ciclo principale o altrove non lo so, non ho controllato il sorgente, ma grossomodo direi che il resto dovrebbe coincidere.

    Ho guardato per curiosità l'implementazione nel sorgente di Delphi ad esempio, e c'è qualcosa di molto simile, quindi non mi aspetto sia stato realizzato in maniera molto diversa.

    Se vuoi proprio sapere esattamente come è stato fatto, vai a vedere il sorgente.
  • Re: Form.ShowDialog dietro le quinte

    Forse(?) ho capito: la chiamata a ShowDialog avvia una sorta di message loop secondario che elabora i messaggi inviatigli dal ciclo principale.
    Però non mi è chiaro ancora qualcosa. Sempre che sia come ho detto, per rendere inattiva la finestra proprietaria, il ciclo principale forse filtra solo i messaggi diretti alla finestra figlio. Ma pensandoci bene non torna, perché dalla finestra figlio in realtà è possibile chiamare dei metodi della finestra genitore che ne modificano l'aspetto. Questo significa che anche la finestra genitore può ricevere dei messaggi.
    Boh.

    A proposito, buongiorno
  • Re: Form.ShowDialog dietro le quinte

    Grazie come sempre della disponibilità, proverò ad approfondire. L'ideale sarebbe un buon libro.
  • Re: Form.ShowDialog dietro le quinte

    Antologiko ha scritto:


    Sempre che sia come ho detto, per rendere inattiva la finestra proprietaria, il ciclo principale forse filtra solo i messaggi diretti alla finestra figlio. Ma pensandoci bene non torna, perché dalla finestra figlio in realtà è possibile chiamare dei metodi della finestra genitore che ne modificano l'aspetto.
    Questo significa che anche la finestra genitore può ricevere dei messaggi.
    La finestra chiamante e tutto il resto dell'applicazione ricevono per forza i messaggi, e ciò è visibile anche per il solo fatto che vengono ridisegnate (e quindi il messaggio WM_PAINT inviato da Windows viene gestito). Poi funzionano anche i Timer, quindi la questione è più allargata.

    In breve, si può ipotizzare ciò che avviene, ma sicuramente c'è una commistione di diverse casistiche che si intrecciano per garantire che i loop di brokeraggio dei messaggi in arrivo vadano a finire verso la loro corretta gestione, sulla finestra o sul componente giusto.

    Comunque ribadisco: l'unico modo di vederlo in dettaglio è guardare il sorgente.
Devi accedere o registrarti per scrivere nel forum
8 risposte