Corso di Visual C++

Gli strumenti per la grafica II

 

Continuiamo l'esempio della scorsa puntata; nel caso siate riusciti a completare da soli l'esercizio, confrontate il mio codice con il vostro ed analizzate le differenze.

  1. Nella funzione OnLButtonDown aggiungete il codice riportato di seguito:

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

{

// TODO: add construction code here

if (m_rectRect.PtInRect(point)) //verifica clic interno al rettangolo

{

if (m_nColor==WHITE_BRUSH)

m_nColor=LTGRAY_BRUSH;

else

m_nColor=WHITE_BRUSH;

}

InvalidateRect(m_rectRect); //forziamo il ridisegno

CView::OnLButtonDown(nFlags, point); //richiamiamo sempre l'implementazione di base!

}

In questo spezzone ( snippet) di codice vediamo alcune nuove interessanti funzioni: PtInRect e InvalidateRect.

La prima serve per testare se un determinato punto è all'interno di un rettangolo ed in tal caso ritorna non-zero, altrimenti zero.

La funzione InvalidateRect fa si che venga forzato il ridisegno dell'area delimitata dal nostro rettangolo.

Se come parametro viene passato il valore costante NULL, viene ridisegnata l'intera area visibile.

Questo argomento è molto importante se siete interessati a scrivere programmi performanti.

Vi sarete infatti chiesti del perché preoccuparsi di ridisegnare solo un pezzettino di finestra quando possiamo più semplicemente ridisegnare tutto.

Come avrete giustamente ipotizzato, il fattore prestazioni in questo caso è molto influente perché solitamente le routine grafiche della GDI non godono di buona fama di velocità e quindi è sempre bene sfruttarle al massimo con il minimo dispendio di risorse.

Per recuperare il rettangolo da ridisegnare nella funzione OnDraw è possibile utilizzare GetClipBox della classe CDC.

Vedrete che questo argomento diventerà fondamentale quando si tratterà di ridisegnare superfici complesse come bitmap o risultati di rendering ed animazioni, dato che potrebbero sorgere problemi di rallentamento e sfarfallio.

Nel codice di OnLButtonDown vengono assegnate a m_nColor delle costanti: LTGRAY_BRUSH e WHITE_BRUSH, queste sono costanti che definiscono dei pennelli standard di riempimento, per avere la lista completa consultare l'help sotto la voce Brush oppure StockObject.

Ad OnLButtonDown vengono passati due parametri che nell'ordine indicano lo stato dei tasti al momento dell'input e le coordinate del cursore al momento del clic rispetto all'angolo superiore sinistro della vista.

Il primo e oscuro parametro nFlags può assumere una combinazione dei seguenti valori:

Per testare ad esempio se al momento del clic erano premuto sia il tasto destro del mouse che il tasto CTRL della tastiera, basta mettere in or le costanti e testare il risultato, es.:

BOOL ris = ( nFlags == (MK_CONTROL | MK_RBUTTON) )

Qui ris risulterà TRUE se la condizione è verificata, FALSE in caso contrario.

Si noti che le parentesi sono state aggiunte per migliorare la leggibilità, ma non modificano la priorità degli operatori logici e di assegnamento.

Provate ora a compilare il progetto e vedete cosa succede...

...niente!?! Come niente?

Beh cercate di scoprire cosa manca, se proprio non ci riuscite rileggete attentamente la puntata precedente e la seconda, se poi vi secca ( ehm...) continuate a leggere. :<(

Forse abbiamo dimenticato l'unica cosa essenziale, disegnare il rettangolo sullo schermo!

  1. Seguite molto attentamente questo passo che è composto da molti passaggi complicati e che porta anche i più esperi

in continui errori:

/////////////////////////////////////////////////////////////////////////////

// CPrg7View drawing

void CPrg7View::OnDraw(CDC* pDC)

{

CPrg7Doc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

// TODO: add draw code for native data here

pDC->SelectStockObject(m_nColor);

pDC->Rectangle(m_rectRect);

}

Le prime tre righe ora non ci servono e possono anche essere cancellate.

Come vedete abbiamo aggiunto due nuove ed oscure funzioni, la prima seleziona il pennello di disegno per il rettangolo, mentre la seconda si occupa del disegno vero e proprio.

Difficile vero?

Ora funziona tutto, però vedete che se ridimensionate la finestra il rettangolo rimane al suo posto quando viene ridisegnata la finestra.

Risolveremo tutto alla prossima puntata, intanto provate ad iniziare ad implementare un bel programma di disegno che traccia solo linee sullo schermo; avete tutto: OnDraw e OnLButtonDown... In bocca al lupo.

Se proprio non resistete ecco qui il progetto Prg7: Prg7.zip

 

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