PDA

Visualizza versione completa : [VB 6] Impedire la chiusura da evento UNLOAD


Jamester
21-06-2009, 15.38.47
Buongiorno a tutti. Quest'oggi il mio dubbio è il seguente: Ho una form cn dei checkbox nella procedura UNLOAD: il codice e' il seguente


Private Sub Form_Unload(Cancel As Integer)

If Settaggi.Check1.Value = 0 And Settaggi.Check2.Value = 0 Then
Call MsgBox("Prima di uscire dalle opzioni, si prega di selezionare una delle due modalità di esecuzione del programma ", vbOKOnly + vbCritical + vbApplicationModal + vbDefaultButton1, "Baldios's ToolKit 1.0")
Else
'Call MsgBox("Bye ", vbOKOnly + vbCritical + vbApplicationModal + vbDefaultButton1, "Baldios's ToolKit 1.0")
Unload Me
End If
End Sub


ora sia se i valori sono 0 o sono 1 la form si unloada comunque. Invece io vorrei che se si verificasse la prima condizione, il programma lasci la form sullo schermo e la chiuda solo se 1 dei 2 valori sono 1 e nn 0. Cos'e' che nn va?

Stizzo
22-06-2009, 10.46.30
Prova così, dovrebbe andare...

If Settaggi.Check1.Value = 0 And Settaggi.Check2.Value = 0 Then
Call MsgBox("Prima di uscire dalle opzioni, si prega di selezionare una delle due modalità di esecuzione del programma ", vbOKOnly + vbCritical + vbApplicationModal + vbDefaultButton1, "Baldios's ToolKit 1.0")
Exit Sub
Else
'Call MsgBox("Bye ", vbOKOnly + vbCritical + vbApplicationModal + vbDefaultButton1, "Baldios's ToolKit 1.0")
Unload Me
End If
End Sub

Fammi sapere :)

LoryOne
22-06-2009, 14.04.20
Ti stai rispondendo da solo Jamester.
Quel Cancel as Integer nel Form_Unload non è li per caso. Può acquisire un valore, oppure ad esso può essere assegnato; Tra l'altro, il parametro è passato byreference, non byvalue: Ha un senso nel buon vecchio assembly. (ed in VB non fa eccezione)
Aggiungo solo una cosa: L'Unload Me è inutile li dove lo hai messo, perchè l'evento Unload del form viene richiamato sicuramente da qualche altra parte nel tuo programma.

Jamester
22-06-2009, 20.54.18
Ti stai rispondendo da solo Jamester.
Quel Cancel as Integer nel Form_Unload non è li per caso. Può acquisire un valore, oppure ad esso può essere assegnato; Tra l'altro, il parametro è passato byreference, non byvalue: Ha un senso nel buon vecchio assembly. (ed in VB non fa eccezione)
Aggiungo solo una cosa: L'Unload Me è inutile li dove lo hai messo, perchè l'evento Unload del form viene richiamato sicuramente da qualche altra parte nel tuo programma.

Scusa ma asp...ma di cosa stai parlando? dove sta sto cancel as integer? nn capisco :mm:

Cmq il codice suggeritomi nn va uguale. se vado su uscita cn la X del form senza selezionare uno dei due checkbox, esce lo stesso

Semi.genius
22-06-2009, 23.25.04
Forse quello che intende LoryOne è cambiare il valore del parametro di ingresso passato come riferimento di Cancel ad un altro valore per prevnire la chiusura della from. Potrebbe andare, ma sinceramente non ci ho mai provato

IMHO, non lo devi mettere su Unload quel pezzo di codice, perché la funzione Unload indica solo le operazioni da fare PRIMA della chiusura, non la può annullare.

Devi metterlo invece su Form_QueryUnload

perciò toglierei da unload quel codice e metterei

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
Select Case UnloadMode
Case vbFormControlMenu 'cioè intende ha premuto X
...
End Select
End Sub

e al posto dei ... ci metterei:
If Settaggi.Check1.Value = 0 And Settaggi.Check2.Value = 0 Then
Call MsgBox("Prima di uscire dalle opzioni, si prega di selezionare una delle due modalità di esecuzione del programma ", vbOKOnly + vbCritical + vbApplicationModal + vbDefaultButton1, "Baldios's ToolKit 1.0")
Exit Sub
Else
'Call MsgBox("Bye ", vbOKOnly + vbCritical + vbApplicationModal + vbDefaultButton1, "Baldios's ToolKit 1.0")
End If
End Sub

(cioè come quello di Stizzo ma senza unloadMe che ci pensa lui alla fine)

Jamester
22-06-2009, 23.52.26
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
Select Case UnloadMode
Case vbFormControlMenu 'cioè intende ha premuto X
If Settaggi.Check1.Value = 0 And Settaggi.Check2.Value = 0 Then
Call MsgBox("Prima di uscire dalle opzioni, si prega di selezionare una delle due modalità di esecuzione del programma ", vbOKOnly + vbCritical + vbApplicationModal + vbDefaultButton1, "Baldios's ToolKit 1.0")
Exit Sub
Else
End If
'Call MsgBox("Bye ", vbOKOnly + vbCritical + vbApplicationModal + vbDefaultButton1, "Baldios's ToolKit 1.0")
End Select
End Sub


Scritto cosi continua a uscirsene quando cliccco sulla X. Ho azzerato UNLOAD come dettomi

Semi.genius
23-06-2009, 07.56.28
Scritto cosi continua a uscirsene quando cliccco sulla X. Ho azzerato UNLOAD come dettomi

se togli il commento a
'Call MsgBox("Bye ", vbOKOnly + vbCritical + vbApplicationModal + vbDefaultButton1, "Baldios's ToolKit 1.0")

compare la Message box? (solo per sapere se entra effettivamente nel metodo associato all'evento)

LoryOne
23-06-2009, 08.48.12
Semi.genius ha capito: Cancel va impostato ad un valore diverso da 0.

Un po di teoria (quel tanto che basta):
Ogni evento è gestito da una procedura di controllo sullo stato di quello che lo precede ed, all'interno di ogni procedura, si può essere in grado di intervenire sul normale susseguirsi degli eventi. Ogni parametro (strutture e variabili) dato in pasto alle funzioni Win32 è passato byreference, in modo che all'interno della funzione il valore del parametro possa essere ricavato, oppure ad esso possa essere assegnato un valore differente, in modo da ottenere esiti differenti.
Passiamo ora ad uno pseudocodice dimostrativo dove ogni Subprocedure sia public:

(Public) Sub[procedure] IncrementoByReference(ByRef I As Integer)
I = I + 1
End Sub[procedure]

(Public) Sub[procedure] IncrementoByValue(ByVal I As Integer)
I = I + 1
Print I
End Sub[procedure]

(Public) Sub[procedure] Main()
Dim I As Integer

I=1
IncrementoByReference I
Print I -> Ad I è assegnato il valore 2 all'interno di Main
IncrementoByValue I -> Ad I è assegnato il valore 3 all'interno della subprocedure, poichè di I è stato effettuata una copia ed il suo valore è cambiato solo all'interno di IncrementoByValue
Print I -> Ad I è ancora assegnato il valore 2
End Sub[procedure]

Affinchè una form possa essere chiusa, VB fornisce 3 eventi in sequenza sui quali è possibile agire per porre un controllo sul flowing delle istruzioni che portano alla chiusura della form:
Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
Form_Unload(Cancel As Integer)
Form_Terminate()

Sia Cancel, sia UnloadMode sono due parametri passati byreference ad una subprocedure.
Nell' intervento precedente "[VB 6] Scaricare il programma dalla ram", avevo posto l'attenzione sulla corretta sequenza con la quale tali eventi vengono richiamati in VB.

Jamester
23-06-2009, 09.44.26
se togli il commento a
'Call MsgBox("Bye ", vbOKOnly + vbCritical + vbApplicationModal + vbDefaultButton1, "Baldios's ToolKit 1.0")

compare la Message box? (solo per sapere se entra effettivamente nel metodo associato all'evento)

La risposta alla tua domanda e' NO. Non appare il bye ma solo la prima messagebox

Jamester
23-06-2009, 09.45.48
Semi.genius ha capito: Cancel va impostato ad un valore diverso da 0.

Un po di teoria (quel tanto che basta):
Ogni evento è gestito da una procedura di controllo sullo stato di quello che lo precede ed, all'interno di ogni procedura, si può essere in grado di intervenire sul normale susseguirsi degli eventi. Ogni parametro (strutture e variabili) dato in pasto alle funzioni Win32 è passato byreference, in modo che all'interno della funzione il valore del parametro possa essere ricavato, oppure ad esso possa essere assegnato un valore differente, in modo da ottenere esiti differenti.
Passiamo ora ad uno pseudocodice dimostrativo dove ogni Subprocedure sia public:

(Public) Sub[procedure] IncrementoByReference(ByRef I As Integer)
I = I + 1
End Sub[procedure]

(Public) Sub[procedure] IncrementoByValue(ByVal I As Integer)
I = I + 1
Print I
End Sub[procedure]

(Public) Sub[procedure] Main()
Dim I As Integer

I=1
IncrementoByReference I
Print I -> Ad I è assegnato il valore 2 all'interno di Main
IncrementoByValue I -> Ad I è assegnato il valore 3 all'interno della subprocedure, poichè di I è stato effettuata una copia ed il suo valore è cambiato solo all'interno di IncrementoByValue
Print I -> Ad I è ancora assegnato il valore 2
End Sub[procedure]

Affinchè una form possa essere chiusa, VB fornisce 3 eventi in sequenza sui quali è possibile agire per porre un controllo sul flowing delle istruzioni che portano alla chiusura della form:
Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
Form_Unload(Cancel As Integer)
Form_Terminate()

Sia Cancel, sia UnloadMode sono due parametri passati byreference ad una subprocedure.
Nell' intervento precedente "[VB 6] Scaricare il programma dalla ram", avevo posto l'attenzione sulla corretta sequenza con la quale tali eventi vengono richiamati in VB.

Si vede che sicuramente sei più pratico di me pero' detto sinceramente per me quello che hai scritto è arabo quindi non potresti semplicemente e gentilmente scrivere il codice esatto? grazie... :)

LoryOne
23-06-2009, 10.24.34
Codice originario:

Private Sub Form_Unload(Cancel As Integer)
If Settaggi.Check1.Value = 0 And Settaggi.Check2.Value = 0 Then
Call MsgBox("Prima di uscire dalle opzioni, si prega di selezionare una delle due modalità di esecuzione del programma ", vbOKOnly + vbCritical + vbApplicationModal + vbDefaultButton1, "Baldios's ToolKit 1.0")
Else
'Call MsgBox("Bye ", vbOKOnly + vbCritical + vbApplicationModal + vbDefaultButton1, "Baldios's ToolKit 1.0")
Unload Me
End If
End Sub


Leggi il codice che hai scritto, allo stesso modo con cui il computer legge ed esegue le istruzioni passo dopo passo
Codice scomposto:

Private Sub Form_Unload(Cancel As Integer)
If CondizioneVerificata Then -> Apertura Blocco verifica
Codice eseguito in caso di esito positivo
Else
Codice eseguito in caso di esito negativo
End If -> Chiusura blocco di verifica
End Sub


Sostituzione blocchi di scomposizione:
CondizioneVerificata=Settaggi.Check1.Value = 0 And Settaggi.Check2.Value = 0
A=0 And B=0: La condizione verificata è vera solo se entrambe le due checkbox non sono selezionate (proprietà .Value=0)
In caso contrario, si salta al blocco che segue l' Else che termina il blocco eseguito in condizione verificata ed apre il blocco da eseguire in caso contrario.

Ragiona un attimo: Tu vuoi che la form non si chiuda nel caso in cui almeno una delle due checkbox non sia pari a 0.
Il codice che il computer eseguirà in quel caso, sarà quello che segue l'else, in quanto la condizione che tu hai specificato non sarà veritiera in quel caso...

Jamester
23-06-2009, 10.37.10
No la form non si deve chiudere se i valori check1 e check2 sono ENTRAMBI 0. Se uno qualsiasi dei due e' 1 allora si puo' chiudere e salvare magari l'impostazione corrente

Jamester
23-06-2009, 10.42.15
Secondo il mio ragionamento:


Private Sub Form_Unload(Cancel As Integer)
If Settaggi.Check1.Value = 0 And Settaggi.Check2.Value = 0 Then
Call MsgBox("Prima di uscire dalle opzioni, si prega di selezionare una delle due modalità di esecuzione del programma ", vbOKOnly + vbCritical + vbApplicationModal + vbDefaultButton1, "Baldios's ToolKit 1.0")
Else
'Call MsgBox("Bye ", vbOKOnly + vbCritical + vbApplicationModal + vbDefaultButton1, "Baldios's ToolKit 1.0")
Unload Me
End If


Se check1 e check2 sono entrambi 0 quindi chiama la messagebox (e dovrebbe non chiudere la form) altrimenti chiudi la form (con o senza messagebox che alla fine e' inutile l'ho messa sl per prova). Ora logicamente non mi spiego xche anche nel primo caso la chiude lo stesso.

Secondo come ho letto, nn devo metterla in ULOAD ma in QueryUnload in quanto su UNLOAD cmq e' ovvio che la chiude comunque. Pero' anche se l'ho messa in QueryUnload il risultato non cambia. Per la mia logica dovrebbe funzionare per questo nn capisco :anger:

LoryOne
23-06-2009, 10.48.29
Verifica se si verifica la condizione.
Quanto valgono i due .Value ?
Qual'è il risultato della messa in And ? (Tabella della verità)

Jamester
23-06-2009, 11.29.26
Verifica se si verifica la condizione.
Quanto valgono i due .Value ?
Qual'è il risultato della messa in And ? (Tabella della verità)

Visto che quando clicco su uno dei 2 check e' presente un pulsante che salva i settaggi cosi al successivo riavvio del programma li ricarica in automatico, se il file di configurazione nn c'e' ho previsto la messagebox che informa che le config nn ci sono e apre la form dei settaggi. Quindi nn essendoci il file configurazione le checkbox sono per logica 0 tutte e 2

LoryOne
23-06-2009, 11.47.20
Mmmmm, se per logica pensi che la condizione sia verificata, è altrettanto logico pensare che non lo sia e che sia logico che non funzioni come pensi.
Non so darti una mano se non essere sicuro sul risultato della logica combinatoria.
E' dogmatico che se A=0 e B=0, A & B sia = 0
Verifica i .Value

Jamester
23-06-2009, 13.58.04
Non so vedere i value...Scusa ma...visto che tu sei + esperto di me, mi spieghi per quale ragione facciamo tutta questa teoria e non mettere direttamente un codice che funzioni? almeno cosi lo vedo sto codice e me lo studio

LoryOne
23-06-2009, 14.21.32
Non so vedere i value...
Come no ?
Sai usare i messagebox ... devi solo aggiungere codice a quello che hai già scritto. Puoi anche usare debug.print poi leggere la finestra di debug con Ctrl+G
Guarda che non c'è molto da studiare, solo da mettere quel Cancel=1 al posto giusto. Sperimenta.

Jamester
23-06-2009, 14.31.57
Credo che alla fine mi terro' il codice cosi. Tanto a riaprire una form nn ci vuole nulla.

LoryOne
23-06-2009, 16.40.06
Ti ripeto di verificare i .Value
Qui c'è la soluzione.

UHJpdmF0ZSBTdWIgRm9ybV9VbmxvYWQoQ2FuY2VsIEFzIEludG VnZXIpDQpJZiBJc051bGwoQ2hrQm94MC5WYWx1ZSkgQW5kIElz TnVsbChDaGtCb3gxLlZhbHVlKSBUaGVuDQogICAgTXNnQm94IC JTZWxlemlvbmFyZSBhbG1lbm8gdW5hIG9wemlvbmUiDQogICAg Q2FuY2VsID0gMQ0KRW5kIElmDQpFbmQgU3Vi

- E' verificato il dogma
- Il Cancel=1 è messo al posto giusto
- se per logica pensi che la condizione sia verificata, è altrettanto logico pensare che non lo sia e che sia logico che non funzioni come pensi

Porta pazienza, io sono un vecchio pazzo, però la soluzione mi piace fornirla a modo mio ;)