Abbiamo trattato, nei recenti capitoli, parecchie questioni che, benchè molto importanti, possono parere piuttosto "teoriche"; in questo capitolo, e per alcuni capitoli a seguire, ricapitoleremo varie nozioni già viste (e ne introdurremo alcune altre, quindi, mi raccomando, seguite!-) -- il tutto, nel contesto di un piccolo esempio. (Un "esempio- giocattolo", senza dubbio, non certo un'applicazione di valore commerciale... nondimeno, speriamo che la maggior "concretezza" portata da un esempio rispetto a una pura trattazione teorica possa aiutare il lettore nel compito di apprendimento).
L'obbiettivo è quello di mostrare un dialogo che ha quattro bottoni (pushbutton), cliccando ciascuno dei quali si ottiene un qualche effetto visibile. Visto che, dopo tutte queste chiacchiere, vi starete certo chiedendo dove stia la "G" di "GUI", vogliamo esagerare: ciascuno dei bottoni avrà un "look", appunto, "grafico", e, come "effetto visibile", scegliamo lo spostamento di un'altra immaginetta "grafica" entro il nostro dialogo.
Dobbiamo, naturalmente, cominciare progettando
il dialogo stesso, nel file di risorse (con identificatori
che, come abbiamo accennato, definiremo come
macro, con #define
, in un file di header che, per
convenzione, chiameremo resource.h). Ecco una
possibilità, ad esempio:
Nulla di nuovo nell'inizio, ma, immagino, vi starete
chiedendo cosa siano quei nuovi statement PUSHBUTTON
e ICON
fra la BEGIN
e la END
del dialogo...?
Nulla di preoccupante...! Sono solo delle "abbreviazioni", potenzialmente comode, che il Resource Compiler RC ci offre, per esprimere cose che potremmo dire anche in altri modi.
(Nessuno accuserà mai la Microsoft di "minimalismo funzionale"... nei suoi sistemi [e nelle sue applicazioni], magari, non c'è alcun modo ragionevole di fare una data cosa importante X, ma, per un'altra cosa, magari marginale, Y, se c'è un modo, non vi stupite se ce ne sono mezza dozzina, equivalenti, o magari [peggio...] QUASI equivalenti...:-)
PUSHBUTTON
non indica altro che
un CONTROL
, di classe BUTTON
, con i tipici bit di stile
del pushbutton -- qui, inoltre, abbiamo aggiunto, dandolo
esplicitamente, il bit di stile BS_BITMAP
, che, ricorderete
dall'accenno fatto al Capitolo 10,
indica che questo bottone non mostra del testo, bensì,
appunto, una bitmap. L'idea è di sistemare i quattro
bottoni "a croce",
diretti "ai 4 punti cardinali" (aggiustate pure le coordinate
come vi aggrada, naturalmente!).
Analogamente, ICON
indica un CONTROL
di classe STATIC
,
con i tipici bit di stile necessari perchè esso mostri una
icona (usiamo sia bitmap, sia icone, in questo esempio,
per mostrare diverse possibilità).
Naturalmente, non abbiamo ancora detto quali bitmap,
o icone, intendiamo mostrare sui nostri controlli... quello
lo faremo "al volo" nel corso dell'inizializzazione del nostro
dialogo, cioè, nella dialog procedure, in risposta al
messaggio WM_INITDIALOG
. Notare, in particolare,
che non abbiamo nè bitmap, nè icone, fra le risorse
del nostro programma (se ne volete, rivolgetevi a qualcuno
che sappia disegnare meglio di me -- non dovrebbe esservi
molto difficile trovarlo!-); dovremo dunque "andarle a
prendere" da qualche altra parte, come vedremo.
La nostra procedura WinMain
sarà più o meno la
solita, cioè, supponendo di avere già definito in
modo opportuno una procedura di dialogo, sarà
qualcosa del tipo...:
#include "resource.h"
verso l'inizio del file sorgente, per rendere visibile
qui la macro IDD_DIALOG1
.
Per la struttura-base della dialog procedure,
accettiamo, ad esempio, l'impostazione offerta
da windowsx.h, che abbiamo già esaminato;
accertatevi dunque di includere windowsx.h --
oltre, naturalmente, al resto di windows.h, con
i soliti #define
prima dell'include
, e un altro
che ancora non avevamo visto:
Sappiamo già che vogliamo gestire i messaggi:
WM_INITDIALOG
, per inizializzare;
WM_CLOSE
, per terminare;
WM_COMMAND
, per rispondere ai
clic sui nostri pushbutton
HANDLE_MSG
, come abbiamo già accennato,
comprende il "case WM_qualcosa:
", gli
"spezzettamenti" (cracking) veri e propri,
ed eventuali cast, necessari per lo specifico messaggio,
la chiamata alla funzione il cui nome riceve come terzo
parametro (che dev'essere dichiarata con numeri e tipi
di parametri opportuni a seconda del messaggio in gioco),
e il return dall'intera dialog procedure (non sempre torna
il TRUE
che vorremmo per indicare che il messaggio già
l'abbiamo gestito, ma poichè questi messaggi non sono
soggetti a nessuna particolare "gestione di default" che
sia importante per noi prevenire, in questo caso, poco
male; se no, per come la macro è scritta, si potrebbe
rimediare generalmente ponendo un ,TRUE
dopo la sua chiusa
parentesi e prima del punto-e-virgola).
Ci resta, dunque, da scrivere le tre procedure che abbiamo
scelto di chiamare OnDlgClose
, OnDlgInitDialog
, e
OnDlgCommand
, ciascuna con gli opportuni parametri previsti
da windowsx.h. Ma di questo ci occuperemo al prossimo
capitolo.
Capitolo 13: message crackers
Capitolo 15: un esempio (2)
Elenco dei capitoli