Newsgroup: it.comp.lang.visual-basic
Titolo: lock userform e controlli

Ho un form con bottoni, listbox, combobox... ecc
con un button nell'evento click faccio partire un codice che porta via del tempo.
durante questa pausa di elaborazione, spesso l'utente nell'attesa che il codice abbia finito, si mette a cliccare ovunque nel form. questo crea errori!
posso bloccare l'accesso a tutti i controlli presenti nel form, fino a che il codice nel button abbia finito?
Se si, come faccio via codice?
 
ho immaginato ad una progressbar "circular", tipo rotellina, che si pone "in front" al form, bloccando ogni azione form, come spesso avviene su internet con vari siti...    


dienticavo uso VB6

 nel suo ultimo post si è così espresso:

Basta usare un flag public impostato a true finché l'elaborazione è in corso in modo che a ogni evento estraneo ci sia 
un'uscita immediata con relativo avviso all'utente, quando hai finito imposta il flag a false.
Oppure apri un form popup che fa tutt'e due le cose (blocca e avvisa) fino alla fine dell'elaborazione
 
 
 
 
 
 
 
-- 
http://freewarewiki.it
 
http://freewareonline.org
 
http://netuser.altervista.org
 
 

 Se si, come faccio via codice?
 
Il sistema più rapido, senza usare una seconda finestra modal che potrebbe dare fastidio al tuo flusso di eventi (se la apri modeless non risolve), è semplicemente disabilitare l'intera form con Me.Enabled=false.
 
Poi vedi tu come dare feedback all'utente: barra di avanzamento, pannello in primo piano con animazione ecc...

Oltre a quanto detto da Luca io attivo la
clessidra (me.mousepointer=11) finchč
la elaborazione non č finita.
 
Sauro 
 
 

 nel suo ultimo post si è così espresso:

Disabilitare l'intera form principale mi sembra un po' drastica come soluzione, ad es. non la puoi neanche ridurre a 
icona.
Volendo basta mettere un loop subito dopo l'apertura del form popup, basato su una proprietà settata a true nell'evento 
Load e a false nell'evento Unload del form,
tipo questo:
Form1.Show
Do While Form1.Loaded
    DoEvents
Loop


 
 
Questo è pure peggio:
a) Quel loop consuma un sacco di CPU a fare niente
b) A meno che l'elaborazione che deve fare non sta on un componente COM separato per sfruttare il multithreading, dubito riesca ad eseguire *contemporaneamente* il ciclo di lavoro vero e proprio e questo ciclo di attesa

 wrote in message news:9b7c29ae-bfb8-44b4...@googlegroups.com...

Quello che dici mi sembra un po' azzardato, non ci credo. Anche perché il DoEvents non fa altro che attaccarsi alla 
normale coda degli eventi di Windows che restano comunque sempre attivi, e quindi al massimo consumerebbe la stessa CPU 
che userebbe senza loop


 Quello che dici mi sembra un po' azzardato, non ci credo.
 
Non avevo dubbi...
Stai impostando un loop potenzialmente infinito, visto che è sempre attivo fintanto che la seconda finestra è aperta, chi credi che si occupi di eseguire quelle istruzioni, per quanto semplici, n-mila volte al secondo, se non la tua cara, vecchia CPU?! sono proprio le basi, eh...
 
Siccome le chiachiere stanno a zero, crea un semplice progetto con due form, con il comportamento che hai suggerito; il codice di Form1 è:
 
Private Sub Command1_Click()
    Form2.Show
End Sub
 
Private Sub Command2_Click()
    Form2.Show
    Do While Form2.Loaded
        DoEvents
    Loop
End Sub
 
Il codice di Form2 è
 
Public Loaded As Boolean
 
Private Sub Form_Load()
    Loaded = True
End Sub
 
Private Sub Form_Unload(Cancel As Integer)
    Loaded = False
End Sub
 
Compila, apri task manager e guarda la differenza quando premi il primo pulsante, che apre semplicemente la finestra, e il secondo che fa il ciclo di controllo "a manetta" coi DoEvents
 
Vedi tu...

cara, >vecchia CPU?! sono proprio le basi, eh...
Pardon, hai ragione.
Allora io lo farei con un flag public, come detto in precedenza, o con un form modale


che userebbe senza loop
 
Il loop fatto così mette la cpu al 100% (o almeno il core dedicato al thread con
Vb)
 
Per ridurre il consumo di CPU ti basta mettere una chiamata all' Api Sleep nel
loop
 
Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
 
Form1.Show
Do While Form1.Loaded
    Sleep 1
    DoEvents
Loop
 
anche con un solo millisecondo verai che il consumo di cpu passa dal 100% a
quasi zero, e potresti anche eliminare il DoEvents() perchè l'api Sleep
restituisce al so la gestione.
 
Il loop non è la soluzione che userei per il quesito proposto, era solo per
suggerire come fare dei loop, un esempio classico e' la seriale in polling,
senza mai mandare la cpu al 100%.
 
 
-- 
ciao
  Stefano