I controlli di Edit possono spedire vari messaggi
di notifica (tramite la solita WM_COMMAND
) al
dialogo che li contiene.
Ogni volta che l'utente modifica il testo dell'edit
control, il controllo anzitutto spedisce alla
finestra-genitrice un
WM_COMMAND
con codice di notifica EN_UPDATE
;
come al solito, LOWORD(wParam)
contiene l'ID,
e lParam
la handle, del controllo di edit.
In risposta a questa notifica, il dialogo può, ad esempio,
apportare delle modifiche al testo contenuto nel controllo;
dopo di che, il controllo spedisce al
dialogo una ulteriore notifica, EN_CHANGE
, dopo
avere mostrato il nuovo testo.
Se il controllo ha barre di scroll, orizzontale e/o
verticale, e l'utente usa una di esse, allora il
controllo, subito prima di mostrare il nuovo testo,
notifica il dialogo con EN_HSCROLL
e
EN_VSCROLL
rispettivamente.
Quando il controllo ottiene il focus (tipicamente
perchè l'utente ci ha cliccato su, ma potrebbe
esserci anche arrivato in altro modo, come, ad
esempio, con un tab), la notifica è EN_SETFOCUS
;
quando il controllo perde il focus, è invece
EN_KILLFOCUS
(quest'ultima occasione è un
buon momento per "validare" il testo che l'utente
ha posto nell'edit, se esso deve rispettare un
qualche vincolo sintattico o semantico -- attenti,
però, che un Enter, salvo che l'edit non
abbia stile ES_WANTRETURN
, può causare
"il clic del bottone di
default" senza aver prodotto EN_KILLFOCUS
!).
EN_MAXTEXT
è la notifica "il testo ha raggiunto
il massimo ammesso"; può essere gestita, in
alternativa al settaggio del bit di
stile ES_AUTOHSCROLL
ecc,
per eseguire "scrolling" secondo modalità
particolari sotto il totale controllo del programma.
Parecchi sono pure i messaggi che possono essere spediti al controllo di edit, per ottenere da esso delle informazioni, o modificarne le operazioni.
WM_UNDO
, ad esempio, è la richiesta di "disfare"
l'ultima modifica apportata al testo (si può prima
spedire EM_CANUNDO
, che ritornerà 0
se l'undo
non è possibile in questo stato). WM_COPY
,
WM_PASTE
, e WM_CUT
, operano sulla clipboard
("appunti") nel modo prevedibile -- in particolare,
la "zona" del testo del controllo su cui essi hanno
effetto è la "selezione corrente", che è
anche quella parte del testo del controllo che viene
mostrata all'utente con "highlight".
La selezione corrente
può anche essere cancellata, senza effetto sulla
clipboard, spedendo all'edit un WM_CLEAR
. Il
messaggio EM_SETSEL
permette di impostare la
"selezione corrente": start
è in wParam, end
in lParam, e inoltre: start=0
, end=-1
, per fare
la selezione di tutto il testo presente; start=-1
,
per fare una selezione vuota; il "caret" (il
cursore tipico dei testi) è posto al più grande
fra i due valori start
ed end
.
Per chiedere quale sia la selezione corrente,
EM_GETSEL
, con wParam
posto all'indirizzo
di una DWORD
di "inizio", lParam
a quello di una
DWORD
di "fine" (per entrambi è accettabile il
valore 0
, se quel dato non interessa); come per
EM_SETSEL
, gli indici partono da 0
, e la end
è
l'indice del primo carattere non selezionato,
dopo la selezione corrente.
EM_REPLACESEL
cambia il testo della selezione
corrente, con una stringa (terminata da 0 binario,
come al solito) il cui indirizzo iniziale è lParam
;
wParam
, se diverso da zero, dice al controllo di
tenere memorizzato il testo precedente al fine di
permettere un eventuale undo.
Ci sono più di altre due dozzine di codici di
messaggio EM_xxx
, che permettono operazioni
assai precise e dettagliate; non sarebbe però
appropriato, entro i limiti di un tutorial, entrare
nei dettagli di tutte queste operazioni.
Dovendo scrivere un editor, o implementare operazioni molto particolari, sarà certo il caso di ripassarsi tutti i dettagli e le possibilità in un opportuno testo di riferimento (come, ad esempio, la documentazione in linea dell'SDK, disponibile gratuitamente per consultazione e download dal sito Microsoft, purtroppo solo in inglese). Si vedono, a volte, esempi di subclassing portati su controlli di edit, che sembrano ignorare totalmente le enormi potenzialità dei controlli stessi già nel loro stato-base (per non dire dei controlli di Rich Edit, che sono un vasto sovrainsieme di quelli di Edit, aggiungendo varie altre funzioni oltre a quelle di poter mantenere molteplici font e colori, e testo anche al di là dei 64k che normalmente limitano un controllo di Edit).
Fra le cose di una certa importanza generale,
notiamo, tuttavia, il messaggio EM_SETREADONLY
,
con lParam=0
e wParam
pari a TRUE
perchè
l'edit divenga readonly, a FALSE
per farlo invece
divenire read-write; questo ci risparmia, nel caso
assai comune che si voglia cambiare dinamicamente
questo bit di stato, la necessità di usare la nostra
funzione ricreaWindow
(visto che, come abbiamo
visto, il bit di stile settato con SetWindowLong
non
ha, di per sè, alcun effetto).
È inoltre il caso di tenere presenti le API
SetDlgItemInt
e GetDlgItemInt
, che si sposano
particolarmente bene con lo stile ES_NUMBER
per un controllo di edit: esse, infatti, rendono
più comodo il comune compito di comunicare
(scrivere, o leggere) il testo di un tale controllo
visto come codifica decimale di un numero intero.
Non ci sono, purtroppo, equivalenti per altre basi,
come l'esadecimale; ove occorra, ciò va invece
ottenuto attraverso "subclassing".
Gli usi che vengono subito in mente per un dialogo dotato di controlli di edit sono, naturalmente, dei più vari, ma un buon esempio (che, come è in effetti tipico delle applicazioni, enfatizza, non il controllo di edit in quanto tale, ma l'uso che si fa del testo così immesso dall'utente) può essere uno sul quale si sentono spesso fare domande sui newsgroup: "come posso fare il grafico di una funzione immessa dall'utente"?
Il problema si scompone agevolmente in varie parti:
Capitolo 25: ri-creare una finestra
Capitolo 27: l'interprete: l'interfaccia
Elenco dei capitoli