Corso di Visual C++

Gestione delle scrollbar

 

Innanzitutto vediamo quali sono i messaggi spediti da una barra di scorrimento:

Di ogni messaggio in cui compare UP o DOWN ne esiste un corrispondente con LEFT o RIGHT spedito da una barra orizzontale; in tutti i casi le costanti anche se con nome diverso hanno lo stesso valore, questo consente di usare ad esempio SB_LINEUP al posto di SB_LINELEFT e viceversa.

Solitamente in risposta ai messaggi SB_LINEUP o SB_LINEDOWN si scrolla il contenuto della finestra di un numero di pixel pari all'altezza di una riga di testo o di qualcos'altro scelto opportunamente; nel caso di SB_PAGEUP o SB_PAGEDOWN si scrolla la finestra di un numero di pixel pari all'altezza della area client della vista o poco meno.

I messaggi SB_THUMBTRACK sono spesso inviati in rapida sequenza e quindi se non si riesce ad aggiornare la vista in modo molto veloce è meglio gestire SB_THUMBPOSITION che arriva al momento del rilascio del pulsante del mouse sulla casella di scorrimento ( thumb ). Basta ad esempio osservare molti wordprocessor famosi che non scrollano la pagina interattivamente, ma ad esempio il NotePad si. Quello che succede però con quest'ultimo è che documenti molto grandi reagiscono allo scrolling in modo molto fastidioso e scorrelato dalla posizione del thumb.

Per effettuare lo scrolling ci sono due metodi: uno usato dai programmatori in erba ed uno usato da quelli professionisti.

Per non avere rimorsi ve li mostro entrambi, ma vi farò vedere solo come implementare il secondo.

I programmatori in erba solitamente, al momento dell'arrivo del messaggio di scorrimento, aggiornano la posizione della barra e invalidano l'area della finestra affinché venga ridisegnata. Nel gestore di disegno della vista poi fanno si che il disegno parta dall'attuale posizione indicata dalle barre orizzontali e verticali. Se il programmatore hai poi almeno un po' di contegno farà si che non disegnerà quello che non è visibile nella vista.

Facciamo un esempio: avete un wordprocessor con 1000 righe di testo e ogni pagina ( l'area client della vista ) ne può contenere 100. Pensate che ora arriva un messaggio SB_PAGEDOWN, a questo punto settate la posizione della scrollbar verticale a 99 o 98 ( in modo che l'utente riesca ad avere in testa alla pagina le ultime righe di quella precedente ) e invalidate la vista.

Nella funzione di disegno ora iniziate quindi a disegnare dalla riga 98 e continuate fino alla 197 ( spero ), non vale la pena ridisegnare più di 100 linee perché l'area client non riuscirebbe comunque a contenerle.

Questo approccio nel caso di ridisegno dell'intera pagina si rivela molto buono ( probabilmente il migliore ), ma cosa succederebbe se invece del messaggio SB_PAGEDOWN arrivasse SB_LINEDOWN ?... Molto di più di quanto immaginate.
Data la logica del vostro gestore ora voi aggiornereste la barra e ridisegnereste le 100 righe, ma se guardate bene, 99 di queste già erano presenti sullo schermo! State quindi sprecando tempo a ridisegnare delle linee che già avete sullo schermo. Nel caso del wordprocessor ciò non è troppo sbagliato, ma immaginate se dovreste effettuare il raytracing di un'immagine di 10 Mega ogni volta che volete ridisegnare 10 pixel !

A questo punto i programmatori professionisti stanno alzando il dito per dare il loro suggerimento e il solito chiacchierone urla ad alta voce "ScrollWindow !!".

ScrollWindow è proprio la funzione che fa per noi, effettua lo spostamento veloce di un blocco di pixel ed invalida l'area da ridisegnare.

Di questa funzione ne parleremo nel prossimo articolo, per ora avete il materiale sul quale esercitarvi.

 

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