Costruzione di una classe derivata da TAG
Trasformare una qualunque classe precedente in tag è molto semplice; consideriamo il caso della classe DocumentSize, in uso da molti anni in Colibrì; nella dichiarazione della classe DocumentSize (DocumentSize.h) é stato sufficiente affermare la sua discendenza da TAG ed aggiungere alla fine la macro __use_tag_funcs.
class AFX_EXT_CLASS DocumentSize :public TAGS::TAG { public: DocumentSize(); ~DocumentSize(); bool SetPixelSize(int px, int py); bool SetSize(float dx, float dy, int um = unit_default); bool GetSize(float *dx, float *dy, int um = unit_default); bool GetPixelSize(int *dx, int *dy); DOC_AREA *Area(); bool GetResolutions(float *resx, float *resy, int um = unit_default); int GetNearX(float x); int GetNearY(float y); bool GetNearPixel(PointF p_mm, Point *pxl); bool GetPixelPos(Point pxl, PointF *fp, int um = unit_default); \details le dimensioni dei pixel sono l'inverso delle risoluzioni h e v bool GetPixelSize_mm(PointF *px_size); bool Valid(); bool Rotate(float angle); bool operator == (DocumentSize &sz); > __use_tag_funcs __use_private_struct };
La dichiarazione :public TAGS::TAG indica la presenza dell’interfaccia TAG. La macro __use_tag_funcs posta alla fine della classe indica la presenza delle funzioni virtuali Read, Write e New, che dovranno essere scritte nel file sorgente cpp della classe;
Modifiche nel file DocumenSize.cpp: Nella funzione del costruttore è stata aggiunta la macro _tag_register per la registrazione della classe nell’applicazione; la stringa, che definisce l’id assegnato, può essere una qualunque sequenza alfanumerica, ma è opportuno assegnargli un valore mnemonico;
DocumentSize::DocumentSize() { $_init _tag_register(L"DocSize"); }
Aggiunta delle funzioni virtuali: le funzioni Read e Write erano già presenti in DocSize, e non sono state modificate; La funzione New è stata aggiunta mediante una macro in testa al codice sorgente. Di seguito si riporta il frammento di codice relativo alle due funzioni:
BEGIN_READ { fd->Read(&_$str->um); fd->Read(&_$str->area.dx); fd->Read(&_$str->area.dy); fd->Read(&_$str->area.dx_mm); fd->Read(&_$str->area.dy_mm); _calc_resolution(_$str); } END_READ BEGIN_WRITE { fd->Write(_$str->um); fd->Write(_$str->area.dx); fd->Write(_$str->area.dy); fd->Write(_$str->area.dx_mm); fd->Write(_$str->area.dy_mm); } BEGIN_WRITE
Le macro BEGIN_READ .. END_READ e BEGIN_WRITE .. END_WRITE corrispondono alle classiche funzioni di lettura e scrittura della classe su file, e si rimanda all’articolo specifico sulla progettazione delle classi di Colibri.
La macro _new_tag_func è stata inserita dopo il blocco di dichiarazioni posto in testa al file DocumentSize.cpp e definisce la funzione New() della classe
#define CURRENT_REVISION 2 #define CLASS_NAME_STR DocumentSize_STR #define CLASS DocumentSize __new_tag_func
Con queste modifiche la classe potrà ora essere inserita in una tag_list; notare che le modifiche non ne hanno alterato l’utilizzabilità con i precedenti metodi, hanno però aggiunto le nuove funzionalità richieste per l’utilizzo come tag.