Sincronizza Indice |
Scarica il progetto |
Testo dell'articolo |
Stampa l'articolo |
Difficoltà: 2 / 5 Quante volte vi siete trovati con l'esigenza di inserire delle caselle di testo all'interno di un form, per permettere all'utente l'immissione di un numero intero quale l'anno di nascita o altro? Il problema è molto semplice da analizzare: ogni volta che l'utente preme un tasto invia un carattere alla casella di testo; è pertanto necessario controllare se esso è un tasto numerico oppure è una lettera o un simbolo. Se il tasto premuto non è un numero è necessario eliminare il carattere prima che venga visualizzato nella casella di testo.
Tutte le caselle di testo possiedono tre eventirelativi alle pressioni dei tasti da tastiera: questi eventi sono KeyPress, KeyDown e KeyUp. Il primo corrisponde all'invio del carattere alla casella di testo, il secondo indica la pressione di un tasto sulla casella, mentre il terzo indica il rilascio di un tasto premuto. Ogni volta che viene premuto un carattere speciale, non stampabile come ad esempio le freccette, scattano gli eventi KeyDown e KeyUp. Il primo alla pressione del tasto mentre il secondo al rilascio di tale tasto. Se il tasto premuto è un carattere stampabile ovvero una lettera o un numero, vengono generati i tre eventi nell'ordine KeyDown, KeyPress e KeyUp. KeyDown viene generato sempre e comunque per qualsiasi tasto. L'evento KeyPres scatta nel momento in cui deve essere inviato una lettera o un numero alla casella di testo. Il KeyUp scatta sempre al rilascio di qualunque tasto. La soluzione più semplice al problema consiste nell'utilizzare l'evento KeyPress, la cui sintassi è la seguente:
Oggetto indica il nome di una casella di testo. Questo evento passa un parametro KeyAscii per riferimento ovvero ogni cambiamento fatto a tale valore sarà comunicato alle funzioni che utilizzano il valore KeyAscii. Il parametro KeyAscii indica il codice ASCII del carattere che verrà inviato alla casella di testo. Per permettere l'immissione di soli numeri all'interno di una casella di testo ci basterà controllare il parametro KeyAscii dell'evento KeyPress. Se il valore di tale parametro non è compreso nell'insieme dei caratteri numerici il carattere verrà scartato. Per scartare un carattere è necessario impostare il valore di KeyAscii a 0. Vediamo il codice da utilizzare:
La riga che effettua il controllo del tasto premuto è la seconda. Essa controlla se il tasto premuto KeyAscii è minore del codice ASCII del numero 0 oppure è maggiore del codice ASCII del numero 9. In tal caso scarta il tasto impostando il KeyAscii a 0 e manda un avvertimento sonoro attraverso l'istruzione Beep. L'istruzione Asc ci restituisce il codice ASCII del carattere indicato,
quindi Asc("0") ci riporta il codice ASCII del numero 0, ovvero
il valore 48. Asc("9") ci riporta il codice ASCII del numero
9, quindi il valore 57.
Avremmo però peggiorato di molto la leggibilità del codice.
In quest'ultimo caso il codice è maggiormente leggibile di quello precedente. Più TextBox numeriche in una matrice di controlli Difficoltà: 3 / 5 Lo svantaggio principale della soluzione appena vista è che per ogni singola casella di testo numerica sarà necessario riscrivere lo stesso codice. La soluzione più semplice a questo secondo problema consiste nell'utilizzare le matrici di controlli viste nel corso Intermedio. L'unica differenza funzionale a livello di codice consiste nella sintassi dell'evento KeyPress:
Come si vede, oltre il parametro KeyAscii abbiamo anche un parametro Index che indica l'indice del controllo che ha eseguito l'evento KeyPress all'interno della matrice. Il valore di questo parametro corrisponde al valore della Proprietà Index della casella di testo che ha ricevuto la pressione del tasto.
Se inserissimo all'interno di un form due o più TextBox, verrebbe comunque richiamata questa routine di evento. Per cui a livello di codice non avremo nessun cambiamento:
L'utilizzo delle matrici consente la riutilizzabilità di segmenti di codice e l'enorme vantaggio di poter creare tanti controlli dello stesso tipo rispondenti tutti a dei comportamenti comuni. Implementazione della classe NumTextBox Difficoltà: 4 / 5 Ina soluzione più professionale e più flessibile delle
due viste prima è quella detta Multicasting.
Genereremo una nuova classe di nome NumTextBox che amplia le funzionalità
delle normali TextBox. La classe consiste di poche e semplici righe. Tuttavia
non supporta l'utilizzo di elementi appartenenti a matrice.
La prima riga è il cuore di questa classe. Essa definisce una
nuova variabile di tipo TextBox con eventi. L'istruzione WithEvents
permette l'utilizzo di eventi all'interno di un codice dove non sono stati
allocati gli oggetti. CasellaTesto è la variabile pubblica che gestirà
gli eventi delle caselle di testo che utilizzeranno tale classe. Abbiamo
quindi la routine dell'evento KeyPress relativa alla variabile CasellaTesto. La classe si chiude con la funzione Class_Terminate eseguita nel momento in cui un'istanza della classe NumTextBox viene deallocata. Questa funzione rende nuovamente disponibile la memoria occupata dalla variabile CasellaTesto. Passiamo ora all'interfacciamento della classe NumTextBox con il form contenente le caselle di testo normali. Abbiamo due caselle di testo di nome Text3_1 e Text3_2, non in matrice per i motivi già accennati.
Le prime due righe definiscono all'interno del form due variabili di
nome CasellaNumBox1 e CasellaNumBox2 ed allocano la memoria
necessaria all'istanza della classe.
Abbiamo sfruttato anche la funzione Form_Load per attivare prima possibile
la funzionalità della classe NumTextBox. Invero fintanto che non
colleghiamo le nostre caselle di testo normali con la variabile membro
CasellaTesto della classe, non saranno generati gli eventi all'interno
della classe. L'implementazione si conclude con la deallocazione delle due istanze CasellaNumBox1 e CasellaNumBox2. La mancata deallocazione può provocare rallentamenti del sistema e l'occupazione di blocchi di memoria da variabili inaccessibili. Con quest'ultima soluzione possiamo assegnare delle funzioni comuni a
determinati oggetti, senza essere obbligati a formare una matrice di controlli. Rendere una TextBox numerica mediante l'utilizzo dell'API Difficoltà: 3 / 5 L'ultima soluzione è la più efficiente e semplice da attuare. Infatti è possibile definire una TextBox numerica mediante l'impostazione di uno stile mediante l'API. L'esempio in questione utilizza due funzioni API: GetWindowLong e SetWindowLong. La prima servirà per leggere un dato valore dalla casella di testo e la seconda per cambiare tale valore.
La riga 3 definisce una costante di nome GWL_STYLE che verrà utilizzata dalle due funzioni API per ottenere lo stato (il comportamento) di una finestra. La riga 4 definisce una costante di nome ES_NUMBER e verrà utilizzata per impostare lo stile di casella numerica.
All'interno dell'evento Load del form richiameremo le due funzioni per impostare lo stile della casella di testo Text3. Alla riga 7 viene letto il valore iniziale dello stile della finestra il cui handle è Text3.hwnd e tale valore viene memorizzato nella variabile style. Alla riga successiva viene impostato il nuovo stile della casella di
testo impostanto un particolare bit
dello stile mediante l'operazione di OR.
|
L'utilizzo delle classi sta alla base della programmazione ad oggetti vista nella terza lezione del corso Base. Le classi permettono la riutilizzabilità di determinati segmenti di codice. Fibia
FBI e Giuseppe Della Bianca
|
Torna all'indice degli HowTo |