Corso di Visual C++

Gestione efficiente delle scrollbar II

 

A questo punto dobbiamo implementare la gestione dei messaggi ( WM_SIZE ) inviati in seguito alla modifica delle dimensioni della finestra ( e quindi della vista ): in questo caso infatti potrebbe accadere che la finestra è in grado di visualizzare tutte le linee e quindi è bene nascondere le barre di scorrimento. Inoltre cambiando le dimensioni della vista devono cambiare anche le dimensioni della casella di scorrimento che indica il rapporto tra la dimensione della pagina e quella totale del documento da visualizzare.

Il gestore OnSize diventa il seguente:

void CPrg20View::OnSize(UINT nType, int cx, int cy)

{

CView::OnSize(nType, cx, cy);

int m_nMax=m_nNumRighe*m_nFontHeight;

// innanzitutto vediamo se abbiamo bisogno delle barre di scorrimento

 

if (cy<m_nMax)

{

m_nPageHeight=cy;

m_nScrollPos = min ( m_nScrollPos, m_nMax-cy );

}

else // non ne abbiamo bisogno

m_nScrollPos=m_nPageHeight=m_nMax=0;

// facciamo scomparire la barra se la grandezza della pagina

// è maggiore di quella del documento

SCROLLINFO si;

si.cbSize = sizeof (SCROLLINFO);

si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS;

si.nMax = m_nMax;

si.nMin = 0;

si.nPage = m_nPageHeight;

si.nPos = m_nScrollPos;

SetScrollInfo ( SB_VERT, &si, TRUE );

}

Il codice è abbastanza autoesplicativo, l'unica cosa che dovete sapere è che i parametri cx e cy passati ad OnSize sono le nuove dimensioni della finestra dopo il resizing.

La funzione che gestisce i messaggi di scrolling provenienti dalle scrollbar l'abbiamo chiamata OnVScroll; questa riceve anche le notifiche provenienti da altre scrollbar ( verticali ) e quindi è necessario testare anche l'ultimo parametro di tipo CScrollbar* nel caso queste siano più di una.

void CPrg20View::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)

{

CView::OnVScroll(nSBCode, nPos, pScrollBar);

int m_nMax=m_nNumRighe*m_nFontHeight;

int offset;

switch (nSBCode)

{

case SB_LINEUP:

if (m_nScrollPos <= 0)

return;

offset= -min(m_nFontHeight,m_nScrollPos);

break;

case SB_LINEDOWN:

if (m_nScrollPos >= m_nMax-m_nPageHeight)

return;

offset= min(m_nFontHeight,m_nMax-m_nScrollPos-m_nPageHeight);

break;

case SB_PAGEUP:

if (m_nScrollPos <= 0)

return;

offset= -min(m_nPageHeight,m_nScrollPos);

break;

case SB_PAGEDOWN:

if (m_nScrollPos >= m_nMax)

return;

offset= min(m_nPageHeight,m_nMax-m_nScrollPos);

break;

case SB_THUMBPOSITION:

offset= (int) nPos-m_nScrollPos;

break;

case SB_THUMBTRACK:

offset= (int) nPos-m_nScrollPos;

break;

default:

return;

}

m_nScrollPos += offset;

SetScrollPos (SB_VERT, m_nScrollPos );

ScrollWindow(0,-offset);

}

In ogni case dello switch verifichiamo che la nuova posizione sia compatibile con le dimensioni dell'area client. Ad esempio nel caso di un clic sulla freccia inferiore della scrollbar riceviamo un messaggio SB_LINEDOWN che nel case viene così gestito:

case SB_LINEDOWN:

if (m_nScrollPos >= m_nMax-m_nPageHeight)

return;

offset= min(m_nFontHeight,m_nMax-m_nScrollPos-m_nPageHeight);

break;

Innanzitutto verifichiamo che la posizione corrente rientri nei limiti dell'area virtuale totale della vista.

Successivamente ci calcoliamo il numero di unità di cui occorre effettuare lo scrolling in posizione verticale; dato che il verso delle y positive è verso il basso, utilizziamo min direttamente senza negarlo. In questo caso però dobbiamo anche testare che sommando l'altezza della riga alla posizione corrente non usciamo fuori dall'area della vista. Per fare ciò testiamo l'altezza della riga con lo spazio tra la posizione del cursore e la fine della pagina; dei due valori prendiamo quello inferiore. Discorso analogo per gli altri tipi di scrolling.

Le ultime tre istruzioni rispettivamente aggiornano la posizione della corrente, aggiornano la posizione della casella di scorrimento ed infine scrollano il contenuto della vista.

Nel prossimo articolo vedremo come terminare il programma implementando la funzione di disegno OnDraw.

 

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