Come accennato in chiusura del Capitolo 7, l'esame del programmino ivi esemplificato dovrebbe sollevare un paio di dubbi in termini di "struttura" -- non ci sono, in questi schemi, le radici implicite di futuri problemi, una volta che il programma dovesse crescere ed espandersi...?
Sì, ci sono almeno due ordini di problemi -- uno piuttosto semplice e chiaro, che affronteremo in questo capitolo, e uno più sottile e profondo, che rimanderemo al prossimo.
Il primo problema, in un certo senso banale, è dovuto alla necessità di avere, nei due sorgenti .RC e .C (o .CPP), valori identici per i nomi delle risorse e i numeri di identificazione dei controlli; tutto bene, per "programmini" di poche righe, ma come potremo tenere sotto controllo questa necessaria identità in un programma appena un po' più sostanziale?
La soluzione più semplice è esattamente
la stessa che si pone all'analogo problema di
usare gli "stessi" valori
in diversi file di sorgenti C (o C++): invece
di ripetere in ciascun file-sorgente il valore
letterale di una costante (col rischio di non
"tenere sotto controllo" questo valore), basta
usare una macro del preprocessore C,
definita (con #define
) in un header file (che,
nello specifico caso di controlli e risorse, è
di solito chiamato resource.h).
(Il C++ offre
anche l'alternativa, analoga ma più elegante e
certo migliore, di definire questi valori letterali con
la parola-chiave const
, sempre in un header
file; tuttavia, la soluzione del #define
è
tutto sommato adeguata, e l'unica possibile nel
caso che ci occupa, quello della collaborazione
fra il compilatore C e il resource-compiler RC).
Il file delle definizioni, resource.h, andrà poi
incluso, con #include
, sia nel .C, sia
nel .RC. Fortunatamente, il resource compiler
RC usa i semplici costrutti del preprocessore
C, per cui le cose si incastrano bene... naturalmente,
non è certo un caso che ciò accada: il
compilatore di risorse, RC, è stato deliberatamente
e appositamente progettato per condividere
macro con i compilatori C e C++ attraverso
l'uso di #define
e #include
,
proprio allo scopo di permettere questo uso.
Per la stessa ragione, RC ignora silenziosamente la
maggior parte della sintassi C, o C++, che
non conosce e gli è irrilevante, come le varie
dichiarazioni di tipi e funzioni, anche se resta
comunque molto consigliabile non aver altro,
in "resource.h", che #define e commenti!.
Sempre allo scopo di facilitare questo approccio,
è possibile usare per i nomi di risorse dei numeri
anzichè delle stringhe; in questo caso, si userà la macro
MAKEINTRESOURCE
(numero) per ottenere la
"stringa" da passare come nome di risorsa alle
API che vogliono appunto valori di questo tipo.
Questi sono, quindi, problemi abbastanza semplici, cui si può dare una soluzione univoca, tradizionale, e chiaramente OK. In futuro, daremo per scontato che sia incluso un header file resource.h, nel quale saranno state definite macro con nomi come "IDD_qualcosa per" le risorse dialogo, nomi come "IDC_qualcosaltro" come identificatori dei vari controlli, eccetera, e useremo direttamente negli esempi delle macro di questo tipo.
Il programma del Capitolo 7, come già accennato, dovrebbe tuttavia suggerire anche riflessioni di un altro tipo. È a questo tipo di problemi che dedicheremo il prossimo capitolo.
Capitolo 7: rispondere ai messaggi
Capitolo 9: problemi di struttura
Elenco dei capitoli