/**=============================================================================
CLASSE OFFSCREEN v1.4.5 - agosto 2014 ( corretto get_rect( RectF *r ) mancante )
=============================================================================**/
#include "offscreen.h"
static const char kErrOffscreenNonCreato[]
= "classe OFFSCREEN: impossibile impostare la grafica offscreen";
static const char kErrNienteDC[]
= "classe OFFSCREEN: impossibile creare il device context";
static const char kErrNienteCostruttoreDiCopia[]
= "classe OFFSCREEN: costruttore di copia non implementato!";
OFFSCREEN::OFFSCREEN( HWND hwnd ) {
HDC dcOrig;
RECT rAux;
dcOrig = NULL;
dc = NULL;
bmp = NULL;
dc_sfondo = NULL;
bmp_sfondo = NULL;
p_sfondo = NULL;
if( hwnd == NULL ) goto errore_e_uscita;
finestra = hwnd;
dcOrig = GetDC( finestra );
if( dcOrig == NULL ) goto errore_e_uscita;
dc = CreateCompatibleDC( dcOrig );
if( dc == NULL ) goto errore_e_uscita;
GetClientRect( finestra, &rAux );
w = rAux.right;
h = rAux.bottom;
bmp = CreateCompatibleBitmap( dcOrig, w, h );
if( bmp == NULL ) goto errore_e_uscita;
set_sfondo( RGB(0xFF,0xFF,0xFF) );
SelectObject( dc, bmp );
cancella();
return;
errore_e_uscita:
if( dcOrig != NULL ) ReleaseDC( finestra, dcOrig );
if( dc != NULL ) DeleteDC( dc );
if( bmp != NULL ) DeleteObject( bmp );
throw kErrOffscreenNonCreato;
}
OFFSCREEN::OFFSCREEN(const OFFSCREEN& orig) {
throw kErrNienteCostruttoreDiCopia;
}
OFFSCREEN::~OFFSCREEN() {
if( dc != NULL ) {
SelectObject( dc, (HBITMAP) NULL );
SelectObject( dc, (HBRUSH) NULL );
DeleteDC( dc );
}
if( bmp != NULL ) DeleteObject( bmp );
if( dc_sfondo != NULL ) {
SelectObject( dc_sfondo, (HBITMAP) NULL );
DeleteDC( dc_sfondo );
}
if( p_sfondo != NULL ) DeleteObject( bmp );
}
void OFFSCREEN::set_sfondo( COLORREF c_sfondo ) {
HBRUSH p;
p = CreateSolidBrush( c_sfondo );
if( p != NULL ) {
if( p_sfondo != NULL )
DeleteObject( p_sfondo );
p_sfondo = p;
bmp_sfondo = NULL;
}
}
void OFFSCREEN::set_sfondo( HBITMAP b_sfondo ) {
HDC dcTemp = NULL;
if( b_sfondo == NULL ) return;
dcTemp = CreateCompatibleDC( dc );
if( dcTemp == NULL ) throw kErrNienteDC;
if( dc_sfondo != NULL ) DeleteDC( dc_sfondo );
dc_sfondo = dcTemp;
bmp_sfondo = b_sfondo;
SelectObject( dc_sfondo, bmp_sfondo );
}
void OFFSCREEN::cancella( const RECT *r ) {
// se non c'e' un'immagine di sfondo, usiamo il colore compatto
if( bmp_sfondo == NULL || dc_sfondo == NULL ) {
RECT rAux;
if( r == NULL )
SetRect( &rAux, 0, 0, w, h );
else rAux = *r;
FillRect( dc, &rAux, p_sfondo );
}
else { // altrimenti copiamo dall'immagine di sfondo
if( r == NULL ) {
BitBlt( dc, 0, 0, w, h, dc_sfondo, 0, 0, SRCCOPY );
}
else {
BitBlt(
dc,
r->left, r->top, r->right-r->left, r->bottom-r->top,
dc_sfondo, r->left, r->top, SRCCOPY
);
}
}
}
void OFFSCREEN::cancella( HRGN r ) {
// se non c'e' un'immagine di sfondo, usiamo il colore compatto
if( bmp_sfondo == NULL || dc_sfondo == NULL ) {
FillRgn( dc, r, p_sfondo );
}
else { // altrimenti copiamo dall'immagine di sfondo
RECT rAux;
SelectClipRgn( dc, r );
GetClipBox( dc, &rAux );
BitBlt(
dc,
rAux.left, rAux.top, rAux.right-rAux.left, rAux.bottom-rAux.top,
dc_sfondo, rAux.left, rAux.top, SRCCOPY
);
SelectClipRgn( dc, NULL );
}
}
#if kOffscreenUsaGdiPlus == TRUE
void OFFSCREEN::cancella( const Rect *r ) {
static RECT rAux;
SetRect(
&rAux, (LONG)r->X, (LONG)r->Y,
(LONG)r->GetRight(), (LONG)r->GetBottom()
);
cancella( &rAux );
}
void OFFSCREEN::cancella( const RectF *r ) {
static RECT rAux;
SetRect(
&rAux, (LONG)r->X, (LONG)r->Y,
(LONG)r->GetRight(), (LONG)r->GetBottom()
);
cancella( &rAux );
}
#endif // kOffscreenUsaGdiPlus
void OFFSCREEN::invalida( const RECT *r ) {
RECT rAux;
if( r == NULL )
SetRect( &rAux, 0, 0, w, h );
else rAux = *r;
InvalidateRect( finestra, &rAux, FALSE );
}
void OFFSCREEN::invalida( HRGN r ) {
InvalidateRgn( finestra, r, FALSE );
}
#if kOffscreenUsaGdiPlus == TRUE
void OFFSCREEN::invalida( const Rect *r ) {
static RECT rAux;
SetRect(
&rAux, (LONG)r->X, (LONG)r->Y,
(LONG)r->GetRight(), (LONG)r->GetBottom()
);
invalida( &rAux );
}
void OFFSCREEN::invalida( const RectF *r ) {
static RECT rAux;
SetRect(
&rAux, (LONG)r->X, (LONG)r->Y,
(LONG)r->GetRight(), (LONG)r->GetBottom()
);
invalida( &rAux );
}
#endif // kOffscreenUsaGdiPlus
void OFFSCREEN::aggiorna( void ) {
UpdateWindow( finestra );
}
void OFFSCREEN::mostra( void ) {
PAINTSTRUCT ps;
HDC hdc;
hdc = BeginPaint( finestra, &ps );
BitBlt(
hdc,
ps.rcPaint.left, ps.rcPaint.top,
ps.rcPaint.right, ps.rcPaint.bottom,
dc,
ps.rcPaint.left, ps.rcPaint.top,
SRCCOPY
);
EndPaint( finestra, &ps );
}
void OFFSCREEN::mostra( LPDRAWITEMSTRUCT ds ) {
BitBlt(
ds->hDC, 0, 0, w, h,
dc, 0, 0, SRCCOPY
);
}
RECT *OFFSCREEN::get_RECT( RECT *r ) {
SetRect( r, 0, 0, w, h );
return r;
}
#if kOffscreenUsaGdiPlus == TRUE
Rect *OFFSCREEN::get_Rect( Rect *r ) {
r->X = 0; r->Y = 0; r->Width = w; r->Height = h;
return r;
}
RectF *OFFSCREEN::get_Rect( RectF *r ) {
r->X = 0; r->Y = 0; r->Width = w; r->Height = h;
return r;
}
#endif // kOffscreenUsaGdiPlus