Introduzione alle API Win32

Capitolo 22: controlli: gli EDIT

I controlli "Edit" sono il modo più semplice, comodo e normale per consentire all'utente di immettere o modificare del testo; inoltre, possono anche essere usati allo scopo di mostrare del testo, senza permetterne la modifica -- in questo caso, il vantaggio che offrono rispetto ai controlli "Static" è quello di consentire le operazioni di clipboard (o di "appunti" che dir si voglia), cioè il testo mostrato può essere selezionato e copiato su clipboard al fine di "incollarlo" in seguito altrove.

I bit di stile di un controllo Edit controllano gran parte del suo funzionamento. ES_READONLY serve per rendere il controllo "a sola lettura": il testo è mostrato, ma l'utente non può cambiarlo. ES_LEFT, ES_CENTER, ed ES_RIGHT, definiscono l'allineamento del testo. ES_LOWERCASE, ed ES_UPPERCASE, fanno sì che il controllo trasformi automaticamente tutti i caratteri scrittivi in minuscole, rispettivamente in maiuscole; ES_PASSWORD fa sì che i caratteri siano mostrati come asterischi, ma essi non sono trasformati in asterischi -- il programma può accedere al "vero" testo immesso dall'utente (questo permette l'immissione di password senza che possa vederle qualcun altro che si trova accanto all'utente che le sta scrivendo; si può anche programmare il controllo per usare un carattere diverso da asterisco, e naturalmente ciò si ottiene spedendogli un apposito messaggio). ES_NUMBER permette all'utente di immettere solo cifre.

ES_MULTILINE permette di avere un controllo di edit per molteplici linee di testo (il default è una sola linea). Spesso, questo si associa all'ulteriore bit di stile ES_WANTRETURN, che fa sì che, se l'utente usa il tasto Enter nell'immissione di testo, questo sia interpretato come un "a-capo"; normalmente, la pressione di Enter equivale invece ad un clic sul bottone di default del dialogo.

Un edit multilinea può avere diversi comportamenti di "scrolling": per default, "nessuno" -- se l'utente immette più testo di quanto ne possa mostrare una riga del controllo, ci sarà un automatico "word wrap" alla riga seguente, e, se non c'è più spazio per altre righe, un "beep" di errore. Ma si può avere uno scroll automatico, sia in orizzontale di 10 caratteri alla volta (ES_AUTOHSCROLL), sia in verticale di una "pagina" alla volta (ES_AUTOVSCROLL); l'edit multilinea può anche venir dotato di esplicite barre di scroll, con i bit di stile WS_HSCROLL per la orizzontale, WS_VSCROLL per la verticale -- come indicano i nomi di questi bit di stile, essi sono d'altra parte applicabili a qualsiasi finestra (WS_ sta per "window style"); delle scroll bar (che sono a loro volta dei controlli) parleremo più avanti.

(L'unico di questi bit di stile ad essere applicabile agli edit non multi-linea è ES_AUTOHSCROLL; su alcune vecchie versioni di Windows, inoltre, gli edit non multi-linea possono non gestire i bit di stile ES_CENTER ed ES_RIGHT, presentando invece sempre del testo allineato a sinistra). Un bit di stile generico che è usato molto spesso con i controlli di edit, sia multi linea sia a linea singola, è WS_BORDER, che dà un "bordo" rettangolare al controllo.

Con tutti questi bit di stile a disposizione, può non essere molto chiaro il loro comportamento, e le varie possibili interazioni. Un modo di esplorare queste cose è quello di scrivere un piccolo programma che ha come specifico scopo appunto quello esplorativo.

Fortunatamente, Windows ci permette di cambiare "al volo" vari bit di stile di una finestra (in particolare, di un controllo), attraverso l'API SetWindowLong, che già abbiamo visto, con indice GWL_STYLE per i bit di stile "normali" (WS_qualcosa, ES_qualcosa, ...) e GWL_EXSTYLE per i bit di stile "estesi" (WS_EX_ecc); similmente, GetWindowLong ci permette di ottenere a runtime i bit di stile di una finestra, usando gli stessi indici. Quindi, è abbastanza agevole realizzare un piccolo programma sperimentale che ci permetta di verificare l'effetto di varie combinazioni di bit di stile.

Faremo, dunque, un dialogo con tante AUTOCHECKBOX, una per ciascun bit di stile che ci interessa, e un singolo Edit cui applicare la combinazione; in risposta ad ogni clic su di uno dei bottoni con AUTOCHECKBOX, la nostra dialog procedure (nella gestione del relativo WM_COMMAND) provvederà a settare o resettare il corrispondende bit di stile nell'Edit.

Il file Esperim.Rc sarà dunque qualcosa del tipo di...:

#include "windows.h" #include "resource.h" IDD_DIALOG1 DIALOG 100, 100, 200, 210 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Stili per controlli Edit" FONT 8, "MS Sans Serif" BEGIN LTEXT "Stile:",IDC_ETIC,10,6,20,10 LTEXT "",IDC_STIL,30,6,40,10 EDITTEXT IDC_EDIT,10,20,180,28 AUTOCHECKBOX "ES_READONLY",ES_READONLY,10,50,90,10 AUTOCHECKBOX "ES_CENTER",ES_CENTER,10,60,90,10 AUTOCHECKBOX "ES_RIGHT",ES_RIGHT,10,70,90,10 AUTOCHECKBOX "ES_LOWERCASE",ES_LOWERCASE,10,80,90,10 AUTOCHECKBOX "ES_UPPERCASE",ES_UPPERCASE,10,90,90,10 AUTOCHECKBOX "ES_PASSWORD",ES_PASSWORD,10,100,90,10 AUTOCHECKBOX "ES_NUMBER",ES_NUMBER,10,110,90,10 AUTOCHECKBOX "ES_MULTILINE",ES_MULTILINE,10,120,90,10 AUTOCHECKBOX "ES_WANTRETURN",ES_WANTRETURN,10,130,90,10 AUTOCHECKBOX "ES_AUTOHSCROLL",ES_AUTOHSCROLL,10,140,90,10 AUTOCHECKBOX "ES_AUTOVSCROLL",ES_AUTOVSCROLL,10,150,90,10 AUTOCHECKBOX "WS_BORDER",0x8008,10,170,90,10 AUTOCHECKBOX "WS_HSCROLL",0x8002,10,180,90,10 AUTOCHECKBOX "WS_VSCROLL",0x8001,10,190,90,10 END

Abbiamo definito una AUTOCHECKBOX (che significa, ricordiamolo, un Button con l'opportuno stile) per ogni bit di stile che interessa esplorare; come ID del controllo, abbiamo usato lo stesso valore del bit di stile. È importante evitare duplicati per gli ID, e per questo basterà che le costanti IDC_ definite nel nostro resource.h non siano potenze di due -- infatti, tutte le costanti "bit di stile", avendo un solo bit settato, saranno, appunto, potenze di due. Ad esempio, questo resource.h va benissimo...:

#define IDD_DIALOG1 101 #define IDC_EDIT 3 #define IDC_ETIC 5 #define IDC_STIL 6 Il controllo IDC_EDIT è, naturalmente, quello a cui applicheremo gli stili di interesse; IDC_ETIC è una semplice scritta, che non cambieremo, mentre, in IDC_STIL, manterremo un display esadecimale dei "bit di stile correnti" del controllo, così da poter esaminare in dettaglio la situazione.

I tre check-box corrispondenti ai bit di stile WS_ che ci interessano hanno un ID particolare; infatti, per gli ID si possono usare solo 16 bit, mentre il valore "naturale" dei bit WS_BORDER, eccetera, è di 0x00800000, ecc; abbiamo codificato questo caso settando il bit più alto dell'ID -- il nostro codice dovrà accuratamente shiftare il resto dell'ID a sinistra di 20 bit, se il bit più alto è settato, per ottenere il corrispondente valore di "bit mask".

Si noti, ancora, la mancanza di un checkbox che corrisponda ad ES_LEFT. Esaminando winuser.h (lo header file di sistema che, fra l'altro, definisce tutte queste costanti di stile), potremo vedere che ES_LEFT è definito come valore zero. Ciò significa che non vi è un "vero" bit di stile dedicato a codificare "allineamento a sinistra": l'allineamento a sinistra è il default che si ottiene se non è richiesto, nè ES_RIGHT, nè ES_CENTER. La macro di "pseudo-bit-di-stile" ES_LEFT è dunque definita al puro scopo di permetterci di non dover tenere conto di questo in continuazione -- di solito, possiamo programmare "come se" ES_LEFT, ES_RIGHT, ed ES_CENTER fossero tre bit fra di loro mutualmente esclusivi, anche se, in realtà, l'allineamento è codificato in due bit soli.

Abbiamo già dato quasi tutti gli elementi necessari per scrivere il programmino sperimentale; sarebbe ora estremamente istruttivo, per il lettore, provare a scriverlo sulla base di quanto sin qua visto, e soprattutto, naturalmente, cercare di capire le ragioni di eventuali problemi incontrati nel farlo funzionare... allo scopo di incoraggiare questo sperimentalismo, dunque, termineremo qui questo capitolo, e svilupperemo il codice del programma solo nel corso del prossimo.


Capitolo 21: l'esempio rivisitato (2)
Capitolo 23: un piccolo esperimento
Elenco dei capitoli