Corso di Visual C++

Gestione efficiente delle scrollbar

 

Abbiamo detto che un modo efficiente di effettuare lo scrolling della vista è utilizzare la funzione ScrollWindow.

Questa funzione sposta il contenuto della finestra di un numero di pixel a scelta nella direzione delle X e delle Y. L'area di partenza dello scrolling va a far parte del rettangolo della vista da invalidare, quello che verrà ridisegnato durante la successiva chiamata a OnDraw. Anche nel caso in cui questa funzione non sia molto efficiente, si ha comunque un notevole aumento delle prestazioni perché l'area esterna alla regione di clipping ( delimitata dal rettangolo invalidato ) non viene comunque disegnata ( anche se vengono richiamate delle funzioni di disegno che agiscono in quest'area ).

ScrollWindow ha il seguente prototipo:

void ScrollWindow( int xAmount, int yAmount, LPCRECT lpRect = NULL, LPCRECT lpClipRect = NULL );

 

I primi due parametri indicano lo spostamento relativo che deve essere effettuato dal rettangolo specificato da lpRect; se quest'ultimo parametro è NULL allora viene spostata l'intera area client. Se xAmount è positivo allora lo scrolling avviene verso destra, se yAmount è positivo lo scrolling avviene verso il basso.
lpClipRect specifica il rettangolo di clipping da scrollare; solo i bit all'interno di questo rettangolo sono affetti dallo scrolling, quelli esterni no, anche se sono contenuti in lpRect.

Ad esempio per scrollare l'area client della vista di 25 pixel a destra e di 60 verso l'alto, potete utilizzare questa funzione nel seguente modo:

ScrollWindow( 25,-60 );

Costruiamo adesso un'applicazione di esempio che ci faccia mettere in pratica ciò che abbiamo appreso sullo scrolling; per risparmiare spazio implementeremo solo la barra verticale, ma quella orizzontale funziona allo stesso modo.

Il programma visualizzerà un array di stringhe sullo schermo e consentirà lo scrolling del contenuto della vista. Vedremo anche come utilizzare la classe di collezione CStringArray.

Innanzitutto creiamo il progetto Prg20, con tutte le impostazioni di default tranne che selezionare Single Document allo step1 del Wizard.

Aggiungere alla classe vista ( CPrg20View ) la funzione virtuale OnInitialUpdate e i gestori dei messaggi WM_SIZE e WM_VSCROLL; aggiungere le seguenti variabili nella sezione public:

public:

int m_nScrollPos; // posizione corrente della vista

int m_nPageHeight; // dimensione attuale della pagina

CStringArray m_strTesto; // array di testo da visualizzare

int m_nFontHeight; // altezza del font in pixel

int m_nNumRighe; // numero di righe di testo nell'array

Scriviamo ora la funzione OnInitialUpdate:

void CPrg20View::OnInitialUpdate()

{

CView::OnInitialUpdate();

m_nScrollPos=0; // inizialmente siamo in cima al documento

m_nFontHeight=20; // font di altezza 20 pixel.

m_nPageHeight=0; // verrà riinizializzata in OnSize!

m_nNumRighe=48;

for (int i=0; i<m_nNumRighe; i++) // inizializzazione array di stringhe

{

if (i%3 == 0) // 0, 3, 6, 9...

m_strTesto.Add("Software Planet");

else if (i%3 == 1) // 1, 4, 7, 10...

m_strTesto.Add(" www.softwareplanet.net");

else // 2, 5, 8, 11...

m_strTesto.Add("");

}

SetScrollRange(SB_VERT,0, m_nFontHeight*m_nNumRighe);

}

Quasi tutte queste istruzioni le dovreste ormai conoscere bene, quello che vi potrà risultare nuovo sono le tre istruzioni del tipo:

m_strTesto.Add("Software Planet");

In questa istruzione abbiamo utilizzato un oggetto collezione, cioè un oggetto che ci permette, in modo molto semplice, di memorizzare dati strutturati come liste, array e mappe.

Nel caso in esame, l'oggetto è della classe CStringArray e permette di memorizzare un array di oggetti CString.

Per tutte le funzioni membro di questa classe consultare l'help in linea, se volete farne un'utilizzo elementare vi bastano però le seguenti:

Add(CString str): aggiunge un oggetto CString in coda all'array

RemoveAt( int index, int count ); rimuove count elementi a partire dalla posizione index ( il primo elemento è in pos 0 )

RemoveAll(); rimuove tutti gli elementi dall'array

Per avere un elemento in posizione x, si può utilizzare l'operatore di subscription [ ]; proprio come si fa con un normalissimo array, altrimenti è possibile utilizzare la funzione GetAt( int pos ).

L'istruzione if (i%3 == 0) è una semplice operazione di modulo; i%3 ritorna il resto della divisione intera tra i e 3 ( se il resto è 0, significa che i è un multiplo di 3 ). ;-)

Creiamo ora la barra di scorrimento in PreCreateWindow:

BOOL CPrg20View::PreCreateWindow(CREATESTRUCT& cs)

{

cs.style |= WS_VSCROLL; // aggiungiamo lo stile per la barra orizzontale

return CView::PreCreateWindow(cs);

}

Nel prossimo articolo tratteremo le funzioni più importanti: OnSize, OnVScroll e OnDraw.

 

Torna all'indice Generale del corso di Corso di Visual C++ di Software Planet