Corso di Visual C++

Un programma per tracciare linee

 

Completiamo l'esempio della scorsa puntata implementando il codice che ci permette di avere sempre centrato il rettangolo nell'area visibile.

Ciò che ci occorre è sapere quando viene ridimensionata la finestra e quindi ricalcolare le coordinate del rettangolo per far si che rifletta la nuova posizione in modo corretto.

Il messaggio che viene spedito in occasione di un 'resizing' è WM_SIZE, tale messaggio viene spedito anche quando la finestra viene minimizzata o ripristinata, nonché alla prima visualizzazione subito dopo aver chiamato la funzione OnInitialUpdate e prima di richiamare OnDraw.

Una volta mappato il messaggio provato a scrivere il codice seguente:

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

{

CView::OnSize(nType, cx, cy); //richiamo funzione membro classe base

//calcolo centro area visibile

CPoint ptCentro(cx/2,cy/2);

//calcolo origine (angolo sup-sx del rettangolo)

CPoint ptOrigine(ptCentro.x-m_sizeRect.cx/2,ptCentro.y-m_sizeRect.cy/2);

//costruzione del rettangolo specificando origine e dimensione

m_rectRect=CRect(ptOrigine,m_sizeRect);

}

Come vedete è perfino più semplice di OnInitialUpdate, infatti qui le dimensioni della finestra non le dobbiamo calcolare, ma ci vengono passate come parametro.

Provate ora ad eliminare OnInitialUpdate, cosa succede? Viene eseguito correttamente il programma? Perché ?

Altro parametro passato alla funzione è nType ed indica l'azione che ha causato il resizing; tra i valori più significati troviamo:

SIZE_MAXIMIZED La finestra è stato massimizzata.

SIZE_MINIMIZED La finestra è stata minimizzata.SIZE_RESTORED la finestra è stata ridimensionata, ma non è ne massimizzata, ne minimizzata.

Per chi non l'avesse preso dalla scorsa puntata ecco qui il progetto Prg7: Scarica Prg7.zip - 35k

Proviamo ora scrivere un programma che ci permette di disegnare delle linee sullo schermo.

Tanto per iniziare create un nuovo progetto e chiamatelo Prg10.

Ci serviranno due variabili membro di appoggio per contenere le coordinate dei punti iniziali e finali delle linee.

1) Aggiungete nel file header della vista (CPrg10View.h) le seguenti dichiarazioni:

private:

CPoint m_ptInizio, m_ptFine;

Ora quello che vogliamo fare è cliccare con il pulsante destro del mouse per settare l'origine della linea, muoverci e quindi cliccare con il pulsante destro per settare il punto di fine, in tale istante comparirà la nostra linea.

2) Nel costruttore di class aggiungete le inizializzazioni dei punti di appoggio:

CPrg10View::CPrg10View()

{

m_ptInizio=m_ptFine=CPoint(0,0);

}

D'ora in poi eliminerò sempre i commenti del Wizard, visto che occupano solo spazio web inutile.

3) Mappate ora i messaggi WM_LBUTTONDOWN e WM_RBUTTONDOWN e aggiungete nelle funzioni create dal Wizard il codice seguente:

void CPrg10View::OnLButtonDown(UINT nFlags, CPoint point)

{

CView::OnLButtonDown(nFlags, point);

m_ptInizio=point;

}

void CPrg10View::OnRButtonDown(UINT nFlags, CPoint point)

{

CView::OnRButtonDown(nFlags, point);

m_ptFine=point;

CClientDC dc(this);

dc.MoveTo(m_ptInizio);

dc.LineTo(m_ptFine);

}

4) Proviamo ora a cambiare la funzione OnRButtonDown e facciamo si che se al momento del clic sul pulsante destro rileviamo anche alcuni tasti di sistema e ci comportiamo di conseguenza per tracciare linee colorate nel seguente modo:

Tasto CTRL premuto => linea rossa

Tasto SHIFT premuto => linea blu

Nessun tasto premuto => linea colore verde.

Ecco la nuova funzione:

void CPrg10View::OnRButtonDown(UINT nFlags, CPoint point)

{

CView::OnRButtonDown(nFlags, point);

m_ptFine=point;

CClientDC dc(this);

CPen pen;

COLORREF color;

if (nFlags & MK_CONTROL)

color=RGB(255,0,0);

else if (nFlags & MK_SHIFT)

color=RGB(0,0,255);

else

color=RGB(0,255,0);

pen.CreatePen(PS_SOLID,1,color);

CPen *pOldPen=dc.SelectObject(&pen);

dc.MoveTo(m_ptInizio);

dc.LineTo(m_ptFine);

dc.SelectObject(pOldPen);

}

Qui vediamo come fare a disegnare all'esterno della funzione OnDraw utilizzando un contesto di dispositivo creato sullo stack ed inoltre vediamo anche come utilizzare l'oggetto CPen della GDI.

Per chi non chi volesse dargli un'occhiata, ecco qui il progetto Prg10: Scarica Prg10.zip - 35k

Vi consiglio prima di rimandarvi alla prossima puntata di andare a vedere nell'help in linea a cosa serve SelectObject e perché viene utilizzata; in tal modo vi sarà più semplice capire un discorsetto che faremo molto presto.

Alla prossima spiegherò in dettaglio la funzione OnRButtonDown che abbiamo implementato ed inoltre approfondiremo le nostre conoscenze con qualche altro oggetto GDI.

 

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