Corso di Visual C++

Approfondimenti su CDC

 

In Prg10 abbiamo creato un contesto di dispositivo locale mediante CClientDC dc(this); questa dichiarazione abbiamo detto che fa si che nella variabile dc sia contenuta un copia del contesto di dispositivo dell'area client della vista. Tale area della vista è l'area effettivamente utilizzabile per il disegno dalla classe di vista (CPrg10View).

Gli altri contesti di dispositivi che dobbiamo esplorare sono CPaintDC, CWindowDC e CMetaFileDC; le differenze in breve sono le seguenti:

CPaintDC funziona come CClientDC, ma deve essere utilizzata sono nella funzione OnPaint, CWindowDC crea un contesto di dispositivo attraverso il quale è possibile utilizzare, come superficie di disegno, l'intera finestra Frame (comprese le barre degli strumenti, di stato, del titolo, i menu...).

Si può quindi notare che CWindowDC può essere utilizzata in risposta a WM_PAINT in CMainFrame, mentre CPaintDC in risposta allo stesso messaggio, però nella classe derivata da CView.

 

CMetaFileDC permette di costruire oggetti di tipo WindowsMetafile e disegnarli sullo schermo. Un oggetto WMF è un oggetto comandi per operazioni di disegno ( disegno di linee, cerchi, archi...) e viene utilizzato in occasioni abbastanza particolari. (per lo più disegno di figure geometriche con necessità di scalarle, copiarle, ruotarle...).

Il puntatore passato al costruttore è un puntatore alla finestra genitrice del CDC, se tale parametro è NULL si può accedere al CDC del desktop del Windows (non fatelo, è cattiva educazione! ).

Ciò che viene fatto dalla chiamata a CClientDC dc(this) è l'invocazione della funzione GetDC() di CDC per ottenere il contesto di dispositivo, tale contesto viene agganciato alla variabile dc dichiarata; una volta che questa variabile esce dallo scope (~fine della funzione) viene chiamata la funzione ReleaseDC dal distruttore.

Nel caso di CPaintDC vengono chiamate anche BeginPaint ed EndPaint, rispettivamente prima e dopo le operazioni di disegno ( dal costruttore e dal distruttore della classe CPaintDC).

Volete vedere il sostituto di CClientDC utilizzando l' API di Win32 per disegnare un rettangolo?

CWnd* pWnd = AfxGetMainWnd(); // recupero puntatore della finestra madre

HWND hWnd = pWnd->m_hWnd; // recupero handle finestra madre

HDC hDC = ::GetDC(hWnd); // recupero handle del contesto di dispositivo

::Rectangle(hDC,10,10,110,110); // disegno rettangolo di 100x100 unità

::ReleaseDC(hWnd,hDC); // rilascio contesto di dispositivo

Penso però che vi convenga utilizzare l'equivalente MFC:

CClientDC dc(this);

dc.Rectangle(10,10,110,110);

Come potete verificare i due costrutti per il vostro computer sono equivalenti, ma a voi la prima versione richiede circa il triplo dei caratteri da digitare !

Abbiamo precedentemente detto che in OnDraw possiamo anche mandare su stampante ciò che normalmente visualizziamo su schermo. Per vedere se attualmente stiamo disegnando a video o su stampante possiamo utilizzare la funzione CDC::IsPrinting() che ritorna un valore BOOL che è TRUE in caso di stampa.

CDC ha anche un'altra utile funzione per ricevere le caratteristiche del dispositivo di output:

int GetDeviceCaps( int nIndex ) const;

Questa funzione può essere utile ad esempio per avere la risoluzione corrente in pixel, la risoluzione in pollici, il numero di colori utilizzati, ma anche per testare se un dispositivo sopporta alcuni funzioni di disegno GDI (utile ad esempio nel caso di plotter che potrebbero non supportare le funzioni raster con le bitmap).

Ad esempio per avere la risoluzione orizzontale corrente in pixel potremmo scrivere il seguente codice:

CClientDC dc(this);

int hres=dc.GetDeviceCaps(HORZRES);

CDC possiede anche funzioni per settare il colore di sfondo ( SetBkColor ), per settare il colore del testo ( SetTextColor ), per ricevere le dimensioni del testo che si sta per disegnare ( GetTextExtent ) e altre decine che sono sempre utili.

Per avere l'elenco completo consultate l'help in linea sotto la voce CDC->ClassMembers.

Vi vorrei ricordo inoltre che, nel caso faceste degli esperimenti con le bitmap, tali oggetti non possono essere utilizzati direttamente, ma devono prima essere copiati in un DC di memoria; come fare lo vedremo più in la.

Come nota finale che vorrei ricordare è che le funzione GDI in Windows 95 utilizzano parametri a 16 bit, quindi è possibile passare sono valori compresi tra -32768 e -32767; valori che eccedono tali limiti vengono troncati.

 

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