//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ //=============================================================================// #include "cbase.h" #include "tier0/dbg.h" #include #include "drawhelper.h" // #define COLOR_BACKGROUND RGB( 120, 120, 150 ) //----------------------------------------------------------------------------- // Purpose: // Input : *widget - //----------------------------------------------------------------------------- CDrawHelper::CDrawHelper( mxWindow *widget ) { Init( widget, 0, 0, 0, 0, COLOR_BACKGROUND ); } //----------------------------------------------------------------------------- // Purpose: // Input : *widget - //----------------------------------------------------------------------------- CDrawHelper::CDrawHelper( mxWindow *widget, COLORREF bgColor ) { Init( widget, 0, 0, 0, 0, bgColor ); } //----------------------------------------------------------------------------- // Purpose: // Input : *widget - // bounds - //----------------------------------------------------------------------------- CDrawHelper::CDrawHelper( mxWindow *widget, RECT& bounds ) { Init( widget, bounds.left, bounds.top, bounds.right - bounds.left, bounds.bottom - bounds.top, COLOR_BACKGROUND ); } //----------------------------------------------------------------------------- // Purpose: // Input : *widget - // x - // y - // w - // h - //----------------------------------------------------------------------------- CDrawHelper::CDrawHelper( mxWindow *widget, int x, int y, int w, int h, COLORREF bgColor ) { Init( widget, x, y, w, h, bgColor ); } //----------------------------------------------------------------------------- // Purpose: // Input : *widget - // bounds - // bgColor - //----------------------------------------------------------------------------- CDrawHelper::CDrawHelper( mxWindow *widget, RECT& bounds, COLORREF bgColor ) { Init( widget, bounds.left, bounds.top, bounds.right - bounds.left, bounds.bottom - bounds.top, bgColor ); } //----------------------------------------------------------------------------- // Purpose: // Input : *widget - // x - // y - // w - // h - //----------------------------------------------------------------------------- void CDrawHelper::Init( mxWindow *widget, int x, int y, int w, int h, COLORREF bgColor ) { m_x = x; m_y = y; m_w = w ? w : widget->w2(); m_h = h ? h : widget->h2(); m_hWnd = (HWND)widget->getHandle(); Assert( m_hWnd ); m_dcReal = GetDC( m_hWnd ); m_rcClient.left = m_x; m_rcClient.top = m_y; m_rcClient.right = m_x + m_w; m_rcClient.bottom = m_y + m_h; m_dcMemory = CreateCompatibleDC( m_dcReal ); m_bmMemory = CreateCompatibleBitmap( m_dcReal, m_w, m_h ); m_bmOld = (HBITMAP)SelectObject( m_dcMemory, m_bmMemory ); m_clrOld = SetBkColor( m_dcMemory, bgColor ); HBRUSH br = CreateSolidBrush( bgColor ); RECT rcFill = m_rcClient; OffsetRect( &rcFill, -m_rcClient.left, -m_rcClient.top ); FillRect( m_dcMemory, &rcFill, br ); DeleteObject( br ); m_ClipRegion = (HRGN)0; } //----------------------------------------------------------------------------- // Purpose: Finish up //----------------------------------------------------------------------------- CDrawHelper::~CDrawHelper( void ) { SelectClipRgn( m_dcMemory, NULL ); while ( m_ClipRects.Size() > 0 ) { StopClipping(); } BitBlt( m_dcReal, m_x, m_y, m_w, m_h, m_dcMemory, 0, 0, SRCCOPY ); SetBkColor( m_dcMemory, m_clrOld ); SelectObject( m_dcMemory, m_bmOld ); DeleteObject( m_bmMemory ); DeleteObject( m_dcMemory ); ReleaseDC( m_hWnd, m_dcReal ); ValidateRect( m_hWnd, &m_rcClient ); } //----------------------------------------------------------------------------- // Purpose: // Output : int //----------------------------------------------------------------------------- int CDrawHelper::GetWidth( void ) { return m_w; } //----------------------------------------------------------------------------- // Purpose: // Output : int //----------------------------------------------------------------------------- int CDrawHelper::GetHeight( void ) { return m_h; } //----------------------------------------------------------------------------- // Purpose: // Input : rc - //----------------------------------------------------------------------------- void CDrawHelper::GetClientRect( RECT& rc ) { rc.left = rc.top = 0; rc.right = m_w; rc.bottom = m_h; } //----------------------------------------------------------------------------- // Purpose: // Output : HDC //----------------------------------------------------------------------------- HDC CDrawHelper::GrabDC( void ) { return m_dcMemory; } //----------------------------------------------------------------------------- // Purpose: // Input : *font - // pointsize - // weight - // maxwidth - // rcText - // *fmt - // ... - //----------------------------------------------------------------------------- void CDrawHelper::CalcTextRect( const char *font, int pointsize, int weight, int maxwidth, RECT& rcText, const char *fmt, ... ) { va_list args; static char output[1024]; va_start( args, fmt ); vprintf( fmt, args ); vsprintf( output, fmt, args ); HFONT fnt = CreateFont( -pointsize, 0, 0, 0, weight, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH, font ); HFONT oldFont = (HFONT)SelectObject( m_dcMemory, fnt ); DrawText( m_dcMemory, output, -1, &rcText, DT_LEFT | DT_NOPREFIX | DT_VCENTER | DT_WORDBREAK | DT_CALCRECT ); SelectObject( m_dcMemory, oldFont ); DeleteObject( fnt ); } //----------------------------------------------------------------------------- // Purpose: // Input : *font - // pointsize - // weight - // *fmt - // ... - // Output : int //----------------------------------------------------------------------------- int CDrawHelper::CalcTextWidth( const char *font, int pointsize, int weight, const char *fmt, ... ) { va_list args; static char output[1024]; va_start( args, fmt ); vprintf( fmt, args ); vsprintf( output, fmt, args ); HFONT fnt = CreateFont( -pointsize, 0, 0, 0, weight, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH, font ); HDC screen = GetDC( NULL ); HFONT oldFont = (HFONT)SelectObject( screen, fnt ); RECT rcText; rcText.left = rcText.top = 0; rcText.bottom = pointsize + 5; rcText.right = rcText.left + 2048; DrawText( screen, output, -1, &rcText, DT_LEFT | DT_NOPREFIX | DT_VCENTER | DT_SINGLELINE | DT_CALCRECT ); SelectObject( screen, oldFont ); DeleteObject( fnt ); ReleaseDC( NULL, screen ); return rcText.right; } //----------------------------------------------------------------------------- // Purpose: // Input : *font - // pointsize - // weight - // *fmt - // ... - // Output : int //----------------------------------------------------------------------------- int CDrawHelper::CalcTextWidthW( const char *font, int pointsize, int weight, const wchar_t *fmt, ... ) { va_list args; static wchar_t output[1024]; va_start( args, fmt ); vwprintf( fmt, args ); vswprintf( output, fmt, args ); HFONT fnt = CreateFont( -pointsize, 0, 0, 0, weight, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH, font ); HFONT oldFont = (HFONT)SelectObject( m_dcMemory, fnt ); RECT rcText; rcText.left = rcText.top = 0; rcText.bottom = pointsize + 5; rcText.right = rcText.left + 2048; DrawTextW( m_dcMemory, output, -1, &rcText, DT_LEFT | DT_NOPREFIX | DT_VCENTER | DT_SINGLELINE | DT_CALCRECT ); SelectObject( m_dcMemory, oldFont ); DeleteObject( fnt ); return rcText.right; } //----------------------------------------------------------------------------- // Purpose: // Input : fnt - // *fmt - // ... - // Output : int //----------------------------------------------------------------------------- int CDrawHelper::CalcTextWidth( HFONT fnt, const char *fmt, ... ) { va_list args; static char output[1024]; va_start( args, fmt ); vprintf( fmt, args ); vsprintf( output, fmt, args ); HDC screen = GetDC( NULL ); HFONT oldFont = (HFONT)SelectObject( screen, fnt ); RECT rcText; rcText.left = rcText.top = 0; rcText.bottom = 1000; rcText.right = rcText.left + 2048; DrawText( screen, output, -1, &rcText, DT_LEFT | DT_NOPREFIX | DT_VCENTER | DT_SINGLELINE | DT_CALCRECT ); SelectObject( screen, oldFont ); ReleaseDC( NULL, screen ); return rcText.right; } int CDrawHelper::CalcTextWidthW( HFONT fnt, const wchar_t *fmt, ... ) { va_list args; static wchar_t output[1024]; va_start( args, fmt ); vwprintf( fmt, args ); vswprintf( output, fmt, args ); HFONT oldFont = (HFONT)SelectObject( m_dcMemory, fnt ); RECT rcText; rcText.left = rcText.top = 0; rcText.bottom = 1000; rcText.right = rcText.left + 2048; DrawTextW( m_dcMemory, output, -1, &rcText, DT_LEFT | DT_NOPREFIX | DT_VCENTER | DT_SINGLELINE | DT_CALCRECT ); SelectObject( m_dcMemory, oldFont ); return rcText.right; } //----------------------------------------------------------------------------- // Purpose: // Input : *font - // pointsize - // weight - // clr - // rcText - // *fmt - // ... - //----------------------------------------------------------------------------- void CDrawHelper::DrawColoredText( const char *font, int pointsize, int weight, COLORREF clr, RECT& rcText, const char *fmt, ... ) { va_list args; static char output[1024]; va_start( args, fmt ); vsprintf( output, fmt, args ); va_end( args ); DrawColoredTextCharset( font, pointsize, weight, ANSI_CHARSET, clr, rcText, output ); } //----------------------------------------------------------------------------- // Purpose: // Input : *font - // pointsize - // weight - // clr - // rcText - // *fmt - // ... - //----------------------------------------------------------------------------- void CDrawHelper::DrawColoredTextW( const char *font, int pointsize, int weight, COLORREF clr, RECT& rcText, const wchar_t *fmt, ... ) { va_list args; static wchar_t output[1024]; va_start( args, fmt ); vswprintf( output, fmt, args ); va_end( args ); DrawColoredTextCharsetW( font, pointsize, weight, ANSI_CHARSET, clr, rcText, output ); } //----------------------------------------------------------------------------- // Purpose: // Input : font - // clr - // rcText - // *fmt - // ... - //----------------------------------------------------------------------------- void CDrawHelper::DrawColoredText( HFONT font, COLORREF clr, RECT& rcText, const char *fmt, ... ) { va_list args; static char output[1024]; va_start( args, fmt ); vsprintf( output, fmt, args ); va_end( args ); HFONT oldFont = (HFONT)SelectObject( m_dcMemory, font ); COLORREF oldColor = SetTextColor( m_dcMemory, clr ); int oldMode = SetBkMode( m_dcMemory, TRANSPARENT ); RECT rcTextOffset = rcText; OffsetSubRect( rcTextOffset ); DrawText( m_dcMemory, output, -1, &rcTextOffset, DT_LEFT | DT_NOPREFIX | DT_VCENTER | DT_SINGLELINE | DT_WORD_ELLIPSIS ); SetBkMode( m_dcMemory, oldMode ); SetTextColor( m_dcMemory, oldColor ); SelectObject( m_dcMemory, oldFont ); } //----------------------------------------------------------------------------- // Purpose: // Input : font - // clr - // rcText - // *fmt - // ... - //----------------------------------------------------------------------------- void CDrawHelper::DrawColoredTextW( HFONT font, COLORREF clr, RECT& rcText, const wchar_t *fmt, ... ) { va_list args; static wchar_t output[1024]; va_start( args, fmt ); vswprintf( output, fmt, args ); va_end( args ); HFONT oldFont = (HFONT)SelectObject( m_dcMemory, font ); COLORREF oldColor = SetTextColor( m_dcMemory, clr ); int oldMode = SetBkMode( m_dcMemory, TRANSPARENT ); RECT rcTextOffset = rcText; OffsetSubRect( rcTextOffset ); DrawTextW( m_dcMemory, output, -1, &rcTextOffset, DT_LEFT | DT_NOPREFIX | DT_VCENTER | DT_SINGLELINE | DT_WORD_ELLIPSIS ); SetBkMode( m_dcMemory, oldMode ); SetTextColor( m_dcMemory, oldColor ); SelectObject( m_dcMemory, oldFont ); } //----------------------------------------------------------------------------- // Purpose: // Input : *font - // pointsize - // weight - // clr - // rcText - // *fmt - // ... - //----------------------------------------------------------------------------- void CDrawHelper::DrawColoredTextCharset( const char *font, int pointsize, int weight, DWORD charset, COLORREF clr, RECT& rcText, const char *fmt, ... ) { va_list args; static char output[1024]; va_start( args, fmt ); vsprintf( output, fmt, args ); va_end( args ); HFONT fnt = CreateFont( -pointsize, 0, 0, 0, weight, FALSE, FALSE, FALSE, charset, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH, font ); HFONT oldFont = (HFONT)SelectObject( m_dcMemory, fnt ); COLORREF oldColor = SetTextColor( m_dcMemory, clr ); int oldMode = SetBkMode( m_dcMemory, TRANSPARENT ); RECT rcTextOffset = rcText; OffsetSubRect( rcTextOffset ); DrawText( m_dcMemory, output, -1, &rcTextOffset, DT_LEFT | DT_NOPREFIX | DT_VCENTER | DT_SINGLELINE | DT_WORD_ELLIPSIS ); SetBkMode( m_dcMemory, oldMode ); SetTextColor( m_dcMemory, oldColor ); SelectObject( m_dcMemory, oldFont ); DeleteObject( fnt ); } void CDrawHelper::DrawColoredTextCharsetW( const char *font, int pointsize, int weight, DWORD charset, COLORREF clr, RECT& rcText, const wchar_t *fmt, ... ) { va_list args; static wchar_t output[1024]; va_start( args, fmt ); vswprintf( output, fmt, args ); va_end( args ); HFONT fnt = CreateFont( -pointsize, 0, 0, 0, weight, FALSE, FALSE, FALSE, charset, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH, font ); HFONT oldFont = (HFONT)SelectObject( m_dcMemory, fnt ); COLORREF oldColor = SetTextColor( m_dcMemory, clr ); int oldMode = SetBkMode( m_dcMemory, TRANSPARENT ); RECT rcTextOffset = rcText; OffsetSubRect( rcTextOffset ); DrawTextW( m_dcMemory, output, -1, &rcTextOffset, DT_LEFT | DT_NOPREFIX | DT_VCENTER | DT_SINGLELINE | DT_WORD_ELLIPSIS ); SetBkMode( m_dcMemory, oldMode ); SetTextColor( m_dcMemory, oldColor ); SelectObject( m_dcMemory, oldFont ); DeleteObject( fnt ); } //----------------------------------------------------------------------------- // Purpose: // Input : *font - // pointsize - // weight - // clr - // rcText - // *fmt - // ... - //----------------------------------------------------------------------------- void CDrawHelper::DrawColoredTextMultiline( const char *font, int pointsize, int weight, COLORREF clr, RECT& rcText, const char *fmt, ... ) { va_list args; static char output[1024]; va_start( args, fmt ); vprintf( fmt, args ); vsprintf( output, fmt, args ); HFONT fnt = CreateFont( -pointsize, 0, 0, 0, weight, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH, font ); HFONT oldFont = (HFONT)SelectObject( m_dcMemory, fnt ); COLORREF oldColor = SetTextColor( m_dcMemory, clr ); int oldMode = SetBkMode( m_dcMemory, TRANSPARENT ); RECT rcTextOffset = rcText; OffsetSubRect( rcTextOffset ); DrawText( m_dcMemory, output, -1, &rcTextOffset, DT_LEFT | DT_NOPREFIX | DT_VCENTER | DT_WORDBREAK | DT_WORD_ELLIPSIS ); SetBkMode( m_dcMemory, oldMode ); SetTextColor( m_dcMemory, oldColor ); SelectObject( m_dcMemory, oldFont ); DeleteObject( fnt ); } //----------------------------------------------------------------------------- // Purpose: // Input : r - // g - // b - // style - // width - // x1 - // y1 - // x2 - // y2 - //----------------------------------------------------------------------------- void CDrawHelper::DrawColoredLine( COLORREF clr, int style, int width, int x1, int y1, int x2, int y2 ) { HPEN pen = CreatePen( style, width, clr ); HPEN oldPen = (HPEN)SelectObject( m_dcMemory, pen ); MoveToEx( m_dcMemory, x1-m_x, y1-m_y, NULL ); LineTo( m_dcMemory, x2-m_x, y2-m_y ); SelectObject( m_dcMemory, oldPen ); DeleteObject( pen ); }; //----------------------------------------------------------------------------- // Purpose: // Input : clr - // style - // width - // count - // *pts - //----------------------------------------------------------------------------- void CDrawHelper::DrawColoredPolyLine( COLORREF clr, int style, int width, CUtlVector< POINT >& points ) { int c = points.Count(); if ( c < 2 ) return; HPEN pen = CreatePen( style, width, clr ); HPEN oldPen = (HPEN)SelectObject( m_dcMemory, pen ); POINT *temp = (POINT *)_alloca( c * sizeof( POINT ) ); Assert( temp ); int i; for ( i = 0; i < c; i++ ) { POINT *pt = &points[ i ]; temp[ i ].x = pt->x - m_x; temp[ i ].y = pt->y - m_y; } Polyline( m_dcMemory, temp, c ); SelectObject( m_dcMemory, oldPen ); DeleteObject( pen ); } //----------------------------------------------------------------------------- // Purpose: // Input : r - // g - // b - // style - // width - // x1 - // y1 - // x2 - // y2 - //----------------------------------------------------------------------------- POINTL CDrawHelper::DrawColoredRamp( COLORREF clr, int style, int width, int x1, int y1, int x2, int y2, float rate, float sustain ) { HPEN pen = CreatePen( style, width, clr ); HPEN oldPen = (HPEN)SelectObject( m_dcMemory, pen ); MoveToEx( m_dcMemory, x1-m_x, y1-m_y, NULL ); int dx = x2 - x1; int dy = y2 - y1; POINTL p; p.x = 0L; p.y = 0L; for (float i = 0.1f; i <= 1.09f; i += 0.1f) { float j = 3.0f * i * i - 2.0f * i * i * i; p.x = x1+(int)(dx*i*(1.0f-rate))-m_x; p.y = y1+(int)(dy*sustain*j)-m_y; LineTo( m_dcMemory, p.x, p.y ); } SelectObject( m_dcMemory, oldPen ); DeleteObject( pen ); return p; }; //----------------------------------------------------------------------------- // Purpose: Draw a filled rect // Input : clr - // x1 - // y1 - // x2 - // y2 - //----------------------------------------------------------------------------- void CDrawHelper::DrawFilledRect( COLORREF clr, RECT& rc ) { RECT rcCopy = rc; HBRUSH br = CreateSolidBrush( clr ); OffsetSubRect( rcCopy ); FillRect( m_dcMemory, &rcCopy, br ); DeleteObject( br ); } //----------------------------------------------------------------------------- // Purpose: Draw a filled rect // Input : clr - // x1 - // y1 - // x2 - // y2 - //----------------------------------------------------------------------------- void CDrawHelper::DrawFilledRect( COLORREF clr, int x1, int y1, int x2, int y2 ) { HBRUSH br = CreateSolidBrush( clr ); RECT rc; rc.left = x1; rc.right = x2; rc.top = y1; rc.bottom = y2; OffsetSubRect( rc ); FillRect( m_dcMemory, &rc, br ); DeleteObject( br ); } //----------------------------------------------------------------------------- // Purpose: // Input : clr - // style - // width - // rc - //----------------------------------------------------------------------------- void CDrawHelper::DrawOutlinedRect( COLORREF clr, int style, int width, RECT& rc ) { DrawOutlinedRect( clr, style, width, rc.left, rc.top, rc.right, rc.bottom ); } //----------------------------------------------------------------------------- // Purpose: Draw an outlined rect // Input : clr - // style - // width - // x1 - // y1 - // x2 - // y2 - //----------------------------------------------------------------------------- void CDrawHelper::DrawOutlinedRect( COLORREF clr, int style, int width, int x1, int y1, int x2, int y2 ) { HPEN oldpen, pen; HBRUSH oldbrush, brush; pen = CreatePen( PS_SOLID, width, clr ); oldpen = (HPEN)SelectObject( m_dcMemory, pen ); brush = (HBRUSH)GetStockObject( NULL_BRUSH ); oldbrush = (HBRUSH)SelectObject( m_dcMemory, brush ); RECT rc; rc.left = x1; rc.right = x2; rc.top = y1; rc.bottom = y2; OffsetSubRect( rc); Rectangle( m_dcMemory, rc.left, rc.top, rc.right, rc.bottom ); SelectObject( m_dcMemory, oldbrush ); DeleteObject( brush ); SelectObject( m_dcMemory, oldpen ); DeleteObject( pen ); } //----------------------------------------------------------------------------- // Purpose: // Input : x1 - // y1 - // x2 - // y2 - // clr - // thickness - //----------------------------------------------------------------------------- void CDrawHelper::DrawLine( int x1, int y1, int x2, int y2, COLORREF clr, int thickness ) { HPEN oldpen, pen; HBRUSH oldbrush, brush; pen = CreatePen( PS_SOLID, thickness, clr ); oldpen = (HPEN)SelectObject( m_dcMemory, pen ); brush = (HBRUSH)GetStockObject( NULL_BRUSH ); oldbrush = (HBRUSH)SelectObject( m_dcMemory, brush ); // Offset x1 -= m_x; x2 -= m_x; y1 -= m_y; y2 -= m_y; MoveToEx( m_dcMemory, x1, y1, NULL ); LineTo( m_dcMemory, x2, y2 ); SelectObject( m_dcMemory, oldbrush ); DeleteObject( brush ); SelectObject( m_dcMemory, oldpen ); DeleteObject( pen ); } //----------------------------------------------------------------------------- // Purpose: // Input : rc - // fillr - // fillg - // fillb - //----------------------------------------------------------------------------- void CDrawHelper::DrawTriangleMarker( RECT& rc, COLORREF fill, bool inverted /*= false*/ ) { POINT region[3]; int cPoints = 3; if ( !inverted ) { region[ 0 ].x = rc.left - m_x; region[ 0 ].y = rc.top - m_y; region[ 1 ].x = rc.right - m_x; region[ 1 ].y = rc.top - m_y; region[ 2 ].x = ( ( rc.left + rc.right ) / 2 ) - m_x; region[ 2 ].y = rc.bottom - m_y; } else { region[ 0 ].x = rc.left - m_x; region[ 0 ].y = rc.bottom - m_y; region[ 1 ].x = rc.right - m_x; region[ 1 ].y = rc.bottom - m_y; region[ 2 ].x = ( ( rc.left + rc.right ) / 2 ) - m_x; region[ 2 ].y = rc.top - m_y; } HRGN rgn = CreatePolygonRgn( region, cPoints, ALTERNATE ); int oldPF = SetPolyFillMode( m_dcMemory, ALTERNATE ); HBRUSH brFace = CreateSolidBrush( fill ); FillRgn( m_dcMemory, rgn, brFace ); DeleteObject( brFace ); SetPolyFillMode( m_dcMemory, oldPF ); DeleteObject( rgn ); } void CDrawHelper::StartClipping( RECT& clipRect ) { RECT fixed = clipRect; OffsetSubRect( fixed ); m_ClipRects.AddToTail( fixed ); ClipToRects(); } void CDrawHelper::StopClipping( void ) { Assert( m_ClipRects.Size() > 0 ); if ( m_ClipRects.Size() <= 0 ) return; m_ClipRects.Remove( m_ClipRects.Size() - 1 ); ClipToRects(); } void CDrawHelper::ClipToRects( void ) { SelectClipRgn( m_dcMemory, NULL ); if ( m_ClipRegion ) { DeleteObject( m_ClipRegion ); m_ClipRegion = HRGN( 0 ); } if ( m_ClipRects.Size() > 0 ) { RECT rc = m_ClipRects[ 0 ]; m_ClipRegion = CreateRectRgn( rc.left, rc.top, rc.right, rc.bottom ); for ( int i = 1; i < m_ClipRects.Size(); i++ ) { RECT add = m_ClipRects[ i ]; HRGN addIn = CreateRectRgn( add.left, add.top, add.right, add.bottom ); HRGN result = CreateRectRgn( 0, 0, 100, 100 ); CombineRgn( result, m_ClipRegion, addIn, RGN_AND ); DeleteObject( m_ClipRegion ); DeleteObject( addIn ); m_ClipRegion = result; } } SelectClipRgn( m_dcMemory, m_ClipRegion ); } //----------------------------------------------------------------------------- // Purpose: // Input : rc - //----------------------------------------------------------------------------- void CDrawHelper::OffsetSubRect( RECT& rc ) { OffsetRect( &rc, -m_x, -m_y ); } //----------------------------------------------------------------------------- // Purpose: // Input : br - // rc - //----------------------------------------------------------------------------- void CDrawHelper::DrawFilledRect( HBRUSH br, RECT& rc ) { RECT rcFill = rc; OffsetSubRect( rcFill ); FillRect( m_dcMemory, &rcFill, br ); } void CDrawHelper::DrawCircle( COLORREF clr, int x, int y, int radius, bool filled /*= true*/ ) { RECT rc; rc.left = x - radius / 2; rc.right = rc.left + radius; rc.top = y - radius / 2; rc.bottom = y + radius; OffsetSubRect( rc ); HPEN pen = CreatePen( PS_SOLID, 1, clr ); HBRUSH br = CreateSolidBrush( clr ); HPEN oldPen = (HPEN)SelectObject( m_dcMemory, pen ); HBRUSH oldBr = (HBRUSH)SelectObject( m_dcMemory, br ); if ( filled ) { Ellipse( m_dcMemory, rc.left, rc.top, rc.right, rc.bottom ); } else { Arc( m_dcMemory, rc.left, rc.top, rc.right, rc.bottom, rc.left, rc.top, rc.left, rc.top ); } SelectObject( m_dcMemory, oldPen ); SelectObject( m_dcMemory, oldBr ); DeleteObject( pen ); DeleteObject( br ); } //----------------------------------------------------------------------------- // Purpose: // Input : rc - // clr1 - // clr2 - // vertical - //----------------------------------------------------------------------------- void CDrawHelper::DrawGradientFilledRect( RECT& rc, COLORREF clr1, COLORREF clr2, bool vertical ) { RECT rcDraw = rc; OffsetRect( &rcDraw, -m_x, -m_y ); TRIVERTEX vert[2] ; GRADIENT_RECT gradient_rect; vert[0].x = rcDraw.left; vert[0].y = rcDraw.top; vert[0].Red = GetRValue( clr1 ) << 8; vert[0].Green = GetGValue( clr1 ) << 8; vert[0].Blue = GetBValue( clr1 ) << 8; vert[0].Alpha = 0x0000; vert[1].x = rcDraw.right; vert[1].y = rcDraw.bottom; vert[1].Red = GetRValue( clr2 ) << 8; vert[1].Green = GetGValue( clr2 ) << 8; vert[1].Blue = GetBValue( clr2 ) << 8; vert[1].Alpha = 0x0000; gradient_rect.UpperLeft = 0; gradient_rect.LowerRight = 1; GradientFill( m_dcMemory, vert, 2, &gradient_rect, 1, vertical ? GRADIENT_FILL_RECT_V : GRADIENT_FILL_RECT_H ); }