| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816 |
- #include "stdafx.h"
- #include "SPColorManager.h"
- #include "SPDrawHelpers.h"
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #define new DEBUG_NEW
- #endif
- HHOOK CSPMouseMonitor::m_hHookMouse = 0;
- CWnd * CSPMouseMonitor::m_pWndMonitor = 0;
- //////////////////////////////////////////////////////////////////////////
- // CSPMouseMonitor
- //////////////////////////////////////////////////////////////////////////
- void CSPMouseMonitor::SetupHook( CWnd * pWndMonitor )
- {
- if ( pWndMonitor && m_hHookMouse == 0 )
- {
- m_hHookMouse = SetWindowsHookEx( WH_MOUSE,MouseProc,0,GetCurrentThreadId() );
- }
- if ( !pWndMonitor && m_hHookMouse )
- {
- UnhookWindowsHookEx( m_hHookMouse );
- m_hHookMouse = 0;
- }
- m_pWndMonitor = pWndMonitor;
- }
- LRESULT CALLBACK CSPMouseMonitor::MouseProc( int nCode , WPARAM wParam , LPARAM lParam )
- {
- if ( nCode != HC_ACTION || !m_pWndMonitor )
- {
- return CallNextHookEx( m_hHookMouse,nCode,wParam,lParam );
- }
- CSPWindowRect rc ( m_pWndMonitor );
- if ( !rc.PtInRect( ( ( PMOUSEHOOKSTRUCT ) lParam )->pt ) )
- {
- switch ( wParam )
- {
- case WM_LBUTTONDOWN:
- case WM_NCLBUTTONDOWN:
- case WM_RBUTTONDOWN:
- case WM_NCRBUTTONDOWN:
- case WM_MBUTTONDOWN:
- case WM_NCMBUTTONDOWN:
- case WM_LBUTTONUP:
- case WM_NCLBUTTONUP:
- m_pWndMonitor->GetOwner()->SetFocus();
- return TRUE;
- }
- }
- return CallNextHookEx( m_hHookMouse,nCode,wParam,lParam );
- }
- //===========================================================================
- // CSPClientCursorPos class
- //===========================================================================
- CSPTransparentBitmap::CSPTransparentBitmap( HBITMAP hBitmap ) : m_hBitmap( hBitmap )
- {
- }
- // Not foolproof, but works 99% of the time :). Assumes the top
- // left pixel is the transparent color.
- COLORREF CSPTransparentBitmap::GetTransparentColor() const
- {
- CBitmap * pBitmap = CBitmap::FromHandle( m_hBitmap );
- if ( pBitmap != NULL )
- {
- CSPCompatibleDC dc ( NULL,pBitmap );
- return dc.GetPixel( 0,0 );
- }
- return ( COLORREF ) - 1;
- }
- HICON CSPTransparentBitmap::ConvertToIcon() const
- {
- if ( m_hBitmap == NULL )
- {
- return NULL;
- }
- COLORREF crTransparent = GetTransparentColor();
- BITMAP bmp;
- if ( !::GetObject( m_hBitmap,sizeof( BITMAP ),&bmp ) )
- {
- return NULL;
- }
- if ( bmp.bmHeight == 0 || bmp.bmWidth == 0 )
- {
- return NULL;
- }
- CImageList il;
- il.Create( bmp.bmWidth,bmp.bmHeight,ILC_COLOR24 | ILC_MASK,0,1 );
- il.Add( CBitmap::FromHandle( m_hBitmap ),crTransparent );
- ASSERT( il.GetImageCount() == 1 );
- return il.ExtractIcon( 0 );
- }
- //===========================================================================
- // CSPClientCursorPos class
- //===========================================================================
- CSPClientCursorPos::CSPClientCursorPos( CWnd * pWnd )
- {
- GetCursorPos( this );
- pWnd->ScreenToClient( this );
- }
- //===========================================================================
- // CSPEmptyRect class
- //===========================================================================
- CSPEmptyRect::CSPEmptyRect()
- {
- SetRectEmpty();
- }
- //===========================================================================
- // CSPWindowRect class
- //===========================================================================
- CSPWindowRect::CSPWindowRect( HWND hWnd )
- {
- if ( ::IsWindow( hWnd ) )
- {
- ::GetWindowRect( hWnd,this );
- }
- else
- {
- SetRectEmpty();
- }
- }
- CSPWindowRect::CSPWindowRect( const CWnd * pWnd )
- {
- if ( ::IsWindow( pWnd->GetSafeHwnd() ) )
- {
- ::GetWindowRect( pWnd->GetSafeHwnd(),this );
- }
- else
- {
- SetRectEmpty();
- }
- }
- //===========================================================================
- // CSPClientRect class
- //===========================================================================
- CSPClientRect::CSPClientRect( HWND hWnd )
- {
- if ( ::IsWindow( hWnd ) )
- {
- ::GetClientRect( hWnd,this );
- }
- else
- {
- SetRectEmpty();
- }
- }
- CSPClientRect::CSPClientRect( const CWnd * pWnd )
- {
- if ( ::IsWindow( pWnd->GetSafeHwnd() ) )
- {
- ::GetClientRect( pWnd->GetSafeHwnd(),this );
- }
- else
- {
- SetRectEmpty();
- }
- }
- //===========================================================================
- // CSPBufferDC class
- //===========================================================================
- CSPBufferDC::CSPBufferDC( HDC hDestDC , const CRect rcPaint ) : m_hDestDC( hDestDC )
- {
- m_rect = rcPaint;
- Attach( ::CreateCompatibleDC( m_hDestDC ) );
- m_bitmap.Attach( ::CreateCompatibleBitmap( m_hDestDC,m_rect.right,m_rect.bottom ) );
- m_hOldBitmap = ::SelectObject( m_hDC,m_bitmap );
- }
- CSPBufferDC::~CSPBufferDC()
- {
- ::BitBlt( m_hDestDC,m_rect.left,m_rect.top,m_rect.Width(),m_rect.Height(),m_hDC,m_rect.left,m_rect.top,SRCCOPY );
- ::SelectObject( m_hDC,m_hOldBitmap );
- }
- CDC * CSPBufferDC::GetDestDC()
- {
- return CDC::FromHandle( m_hDestDC );
- }
- //===========================================================================
- // CSPFontDC class
- //===========================================================================
- CSPFontDC::CSPFontDC( CDC * pDC , CFont * pFont ) : m_hDC( pDC->GetSafeHdc() )
- {
- m_hOldFont = SelectObject( m_hDC,pFont->GetSafeHandle() );
- }
- CSPFontDC::~CSPFontDC()
- {
- ::SelectObject( m_hDC,m_hOldFont );
- }
- void CSPFontDC::SetFont( CFont * pFont )
- {
- ::SelectObject( m_hDC,m_hOldFont );
- m_hOldFont = SelectObject( m_hDC,pFont->GetSafeHandle() );
- }
- //===========================================================================
- // CSPPenDC class
- //===========================================================================
- CSPPenDC::CSPPenDC( HDC hDC , COLORREF crColor ) : m_hDC( hDC )
- {
- VERIFY( m_pen.CreatePen( PS_SOLID,1,crColor ) );
- m_hOldPen = ( HPEN ) ::SelectObject( m_hDC,m_pen );
- }
- CSPPenDC::~CSPPenDC()
- {
- ::SelectObject( m_hDC,m_hOldPen );
- }
- void CSPPenDC::Color( COLORREF crColor )
- {
- ::SelectObject( m_hDC,m_hOldPen );
- VERIFY( m_pen.DeleteObject() );
- VERIFY( m_pen.CreatePen( PS_SOLID,1,crColor ) );
- m_hOldPen = ( HPEN ) ::SelectObject( m_hDC,m_pen );
- }
- COLORREF CSPPenDC::Color()
- {
- LOGPEN logPen;
- m_pen.GetLogPen( &logPen );
- return logPen.lopnColor;
- }
- //===========================================================================
- // CSPBrushDC class
- //===========================================================================
- CSPBrushDC::CSPBrushDC( HDC hDC , COLORREF crColor ) : m_hDC( hDC )
- {
- VERIFY( m_brush.CreateSolidBrush( crColor ) );
- m_hOldBrush = ( HBRUSH ) ::SelectObject( m_hDC,m_brush );
- }
- CSPBrushDC::~CSPBrushDC()
- {
- ::SelectObject( m_hDC,m_hOldBrush );
- }
- void CSPBrushDC::Color( COLORREF crColor )
- {
- ::SelectObject( m_hDC,m_hOldBrush );
- VERIFY( m_brush.DeleteObject() );
- VERIFY( m_brush.CreateSolidBrush( crColor ) );
- m_hOldBrush = ( HBRUSH ) ::SelectObject( m_hDC,m_brush );
- }
- //===========================================================================
- // CSPCompatibleDC class
- //===========================================================================
- CSPCompatibleDC::CSPCompatibleDC( CDC * pDC , CBitmap * pBitmap )
- {
- CreateCompatibleDC( pDC );
- m_pBmp = SelectObject( pBitmap );
- }
- CSPCompatibleDC::~CSPCompatibleDC()
- {
- SelectObject( m_pBmp );
- DeleteDC();
- }
- //===========================================================================
- // CSPSplitterTracker class
- //===========================================================================
- CSPSplitterTracker::CSPSplitterTracker( BOOL bSolid /*= FALSE*/ )
- {
- m_bSolid = bSolid;
- m_rcBoundRect.SetRectEmpty();
- }
- void CSPSplitterTracker::OnInvertTracker( CRect rect )
- {
- ASSERT( !rect.IsRectEmpty() );
- if ( m_bSolid )
- {
- m_pDC->InvertRect( rect );
- }
- else
- {
- CBrush *pDitherBrush = CDC::GetHalftoneBrush();
- CBrush *pBrush = ( CBrush * ) m_pDC->SelectObject( pDitherBrush );
- m_pDC->PatBlt( rect.left,rect.top,rect.Width(),rect.Height(),PATINVERT );
- m_pDC->SelectObject( pBrush );
- }
- }
- BOOL CSPSplitterTracker::Track( CWnd * pTrackWnd , CRect rcAvail , CRect & rectTracker , CPoint point , BOOL bHoriz )
- {
- pTrackWnd->SetCapture();
- m_pDC = 0;
- CWnd * pWnd = CWnd::GetDesktopWindow();
- if ( pWnd->LockWindowUpdate() )
- {
- m_pDC = pWnd->GetDCEx( NULL,DCX_WINDOW | DCX_CACHE | DCX_LOCKWINDOWUPDATE );
- }
- else
- {
- m_pDC = pWnd->GetDCEx( NULL,DCX_WINDOW | DCX_CACHE );
- }
- ASSERT( m_pDC != NULL );
- CPoint ptOffset = bHoriz ? CPoint( rectTracker.left - point.x,0 ) : CPoint( 0,rectTracker.top - point.y );
- OnInvertTracker( rectTracker );
- if ( !m_rcBoundRect.IsRectEmpty() )
- {
- OnInvertTracker( m_rcBoundRect );
- }
- BOOL bAccept = FALSE;
- while ( CWnd::GetCapture() == pTrackWnd )
- {
- MSG msg;
- if ( !GetMessage( &msg,NULL,0,0 ) )
- break;
- if ( msg.message == WM_MOUSEMOVE )
- {
- point = CPoint( msg.lParam );
- pTrackWnd->ClientToScreen( &point );
- point += ptOffset;
- point.x = max( min( point.x,rcAvail.right ),rcAvail.left );
- point.y = max( min( point.y,rcAvail.bottom ),rcAvail.top );
- if ( bHoriz )
- {
- if ( rectTracker.left != point.x )
- {
- OnInvertTracker( rectTracker );
- rectTracker.OffsetRect( point.x - rectTracker.left,0 );
- OnInvertTracker( rectTracker );
- }
- }
- else
- {
- if ( rectTracker.top != point.y )
- {
- OnInvertTracker( rectTracker );
- rectTracker.OffsetRect( 0,point.y - rectTracker.top );
- OnInvertTracker( rectTracker );
- }
- }
- }
- else if ( msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE )
- break;
- else if ( msg.message == WM_LBUTTONUP )
- {
- bAccept = TRUE;
- break;
- }
- else
- ::DispatchMessage( &msg );
- }
- if ( !m_rcBoundRect.IsRectEmpty() )
- {
- OnInvertTracker( m_rcBoundRect );
- }
- OnInvertTracker( rectTracker );
- if ( CWnd::GetCapture() == pTrackWnd )
- {
- ReleaseCapture();
- }
- pWnd = CWnd::GetDesktopWindow();
- pWnd->UnlockWindowUpdate();
- if ( m_pDC != NULL )
- {
- pWnd->ReleaseDC( m_pDC );
- m_pDC = NULL;
- }
- return bAccept;
- }
- //===========================================================================
- // CSPDrawHelpers class
- //===========================================================================
- CSPDrawHelpers CSPDrawHelpers::m_instance; // singleton
- CSPDrawHelpers::CSPDrawHelpers() : m_hMsImgDll( NULL )
- {
- m_pfnFastGradientFill = 0;
- m_hMsImgDll = ::LoadLibrary( _T( "msimg32.dll" ) );
- if ( m_hMsImgDll )
- {
- m_pfnFastGradientFill = ( PFNGRADIENTFILL ) GetProcAddress( m_hMsImgDll,"GradientFill" );
- }
- }
- CSPDrawHelpers::~CSPDrawHelpers()
- {
- if ( m_hMsImgDll != NULL )
- {
- ::FreeLibrary( m_hMsImgDll );
- }
- }
- BOOL CSPDrawHelpers::GradientFill( HDC hdc , PTRIVERTEX pVertex , ULONG dwNumVertex , PVOID pMesh , ULONG dwNumMesh , ULONG dwMode )
- {
- if ( m_pfnFastGradientFill )
- {
- return ( *m_pfnFastGradientFill ) ( hdc,pVertex,dwNumVertex,pMesh,dwNumMesh,dwMode );
- }
- return FALSE;
- }
- void CSPDrawHelpers::GradientFillSlow( CDC * pDC , LPRECT lpRect , COLORREF crFrom , COLORREF crTo , BOOL bHorz )
- {
- int cx = max( 1,lpRect->right - lpRect->left );
- int cy = max( 1,lpRect->bottom - lpRect->top );
- CRect rc;
- pDC->GetClipBox( &rc );
- if ( rc.IsRectEmpty() )
- {
- rc = *lpRect;
- }
- else
- {
- rc.IntersectRect( rc,lpRect );
- }
- if ( bHorz )
- {
- for ( int nX = rc.left; nX < rc.right; nX++ )
- {
- pDC->FillSolidRect( nX,rc.top,1,rc.Height(),BlendColors( crFrom,crTo,( float ) ( 1.0 - ( ( nX - lpRect->left ) / ( float ) cx ) ) ) );
- }
- }
- else
- {
- for ( int nY = rc.top; nY < rc.bottom; nY++ )
- {
- pDC->FillSolidRect( rc.left,nY,rc.Width(),1,BlendColors( crFrom,crTo,( float ) ( 1.0 - ( ( nY - lpRect->top ) ) / ( float ) cy ) ) );
- }
- }
- }
- void CSPDrawHelpers::GradientFillFast( CDC * pDC , LPRECT lpRect , COLORREF crFrom , COLORREF crTo , BOOL bHorz )
- {
- TRIVERTEX vert[2];
- vert[0].x = lpRect->left;
- vert[0].y = lpRect->top;
- vert[0].Red = ( COLOR16 ) ( GetRValue( crFrom ) << 8 );
- vert[0].Green = ( COLOR16 ) ( GetGValue( crFrom ) << 8 );
- vert[0].Blue = ( COLOR16 ) ( GetBValue( crFrom ) << 8 );
- vert[0].Alpha = 0x0000;
- vert[1].x = lpRect->right;
- vert[1].y = lpRect->bottom;
- vert[1].Red = ( COLOR16 ) ( GetRValue( crTo ) << 8 );
- vert[1].Green = ( COLOR16 ) ( GetGValue( crTo ) << 8 );
- vert[1].Blue = ( COLOR16 ) ( GetBValue( crTo ) << 8 );
- vert[1].Alpha = 0x0000;
- GRADIENT_RECT gRect ={0, 1};
- GradientFill( *pDC,vert,2,&gRect,1,bHorz ? GRADIENT_FILL_RECT_H : GRADIENT_FILL_RECT_V );
- }
- void CSPDrawHelpers::GradientFill( CDC * pDC , LPRECT lpRect , COLORREF crFrom , COLORREF crTo , BOOL bHorz )
- {
- if ( !lpRect )
- {
- return;
- }
- if ( ::IsRectEmpty( lpRect ) )
- {
- return;
- }
- if ( IsLowResolution( pDC->GetSafeHdc() ) )
- {
- pDC->FillSolidRect( lpRect,crFrom );
- }
- else if ( crFrom == crTo )
- {
- pDC->FillSolidRect( lpRect,crFrom );
- }
- else if ( m_pfnFastGradientFill != NULL )
- {
- GradientFillFast( pDC,lpRect,crFrom,crTo,bHorz );
- }
- else
- {
- GradientFillSlow( pDC,lpRect,crFrom,crTo,bHorz );
- }
- }
- void CSPDrawHelpers::GradientFill( CDC * pDC , LPRECT lpRect , CSPPaintManagerColorGradient & grc , BOOL bHorz )
- {
- GradientFill( pDC,lpRect,grc.clrLight,grc.clrDark,bHorz );
- }
- void CSPDrawHelpers::ExcludeCorners( CDC * pDC , CRect rc )
- {
- pDC->ExcludeClipRect( rc.left,rc.top,rc.left + 1,rc.top + 1 );
- pDC->ExcludeClipRect( rc.right - 1,rc.top,rc.right,rc.top + 1 );
- pDC->ExcludeClipRect( rc.left,rc.bottom - 1,rc.left + 1,rc.bottom + 1 );
- pDC->ExcludeClipRect( rc.right - 1,rc.bottom - 1,rc.right,rc.bottom + 1 );
- }
- void CSPDrawHelpers::BlurPoints( CDC * pDC , LPPOINT pts , int nCount )
- {
- for ( int i = 0; i < nCount; i += 2 )
- {
- CPoint ptBlur = pts[i];
- CPoint ptDirection ( pts[i].x + pts[i + 1].x,pts[i].y + pts[i + 1].y );
- COLORREF clrBlur = pDC->GetPixel( ptDirection );
- COLORREF clrDirection = pDC->GetPixel( ptBlur );
- pDC->SetPixel( ptBlur,RGB( ( GetRValue( clrBlur ) + GetRValue( clrDirection ) ) / 2,( GetGValue( clrBlur ) + GetGValue( clrDirection ) ) / 2,( GetBValue( clrBlur ) + GetBValue( clrDirection ) ) / 2 ) );
- }
- }
- COLORREF CSPDrawHelpers::BlendColors( COLORREF crA , COLORREF crB , float fAmountA )
- {
- BYTE btR = ( BYTE ) min( 255,( int ) ( GetRValue( crA ) * fAmountA + GetRValue( crB ) * ( 1.0f - fAmountA ) ) );
- BYTE btG = ( BYTE ) min( 255,( int ) ( GetGValue( crA ) * fAmountA + GetGValue( crB ) * ( 1.0f - fAmountA ) ) );
- BYTE btB = ( BYTE ) min( 255,( int ) ( GetBValue( crA ) * fAmountA + GetBValue( crB ) * ( 1.0f - fAmountA ) ) );
- return RGB( btR,btG,btB );
- }
- static int CALLBACK SPEnumFontFamExProc( ENUMLOGFONTEX * pelf , NEWTEXTMETRICEX* /*lpntm*/ , int /*FontType*/ , LPVOID pThis )
- {
- CString strFontName = *( CString * ) pThis;
- CString strFaceName = pelf->elfLogFont.lfFaceName;
- if ( strFaceName.CompareNoCase( strFontName ) == 0 )
- {
- return 0;
- }
- return 1;
- }
- BOOL CSPDrawHelpers::FontExists( CString & strFaceName )
- {
- // Enumerate all styles and charsets of all fonts:
- LOGFONT lfEnum;
- ::ZeroMemory( &lfEnum,sizeof( LOGFONT ) );
- lfEnum.lfFaceName[0] = 0;
- lfEnum.lfCharSet = DEFAULT_CHARSET;
- CWindowDC dc ( NULL );
- return ::EnumFontFamiliesEx( dc.m_hDC,&lfEnum,( FONTENUMPROC ) SPEnumFontFamExProc,( LPARAM ) & strFaceName,0 ) == 0;
- }
- CString CSPDrawHelpers::GetDefaultFontName()
- {
- LOGFONT lfFont;
- ::GetObject( ::GetStockObject( DEFAULT_GUI_FONT ),sizeof( LOGFONT ),&lfFont );
- return CString( lfFont.lfFaceName );
- }
- CString CSPDrawHelpers::GetVerticalFontName( BOOL bUseOfficeFont )
- {
- LOGFONT lfFont;
- ::GetObject( ::GetStockObject( DEFAULT_GUI_FONT ),sizeof( LOGFONT ),&lfFont );
- bool bUseSystemFont = lfFont.lfCharSet > SYMBOL_CHARSET;
- if ( bUseSystemFont )
- {
- OSVERSIONINFO osvi;
- osvi.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
- VERIFY( GetVersionEx( &osvi ) );
- if ( !( ( osvi.dwPlatformId == VER_PLATFORM_WIN32_NT ) && ( osvi.dwMajorVersion > 4 ) ) )
- bUseSystemFont = FALSE;
- }
- CString strOfficeFont = _T( "Tahoma" );
- CString strVerticalFaceName = _T( "Arial" );
- if ( bUseSystemFont || !FontExists( strVerticalFaceName ) )
- {
- strVerticalFaceName = lfFont.lfFaceName;
- }
- else if ( bUseOfficeFont && !bUseSystemFont && FontExists( strOfficeFont ) )
- {
- strVerticalFaceName = strOfficeFont;
- }
- return strVerticalFaceName;
- }
- void CSPDrawHelpers::Triangle( CDC * pDC , CPoint pt0 , CPoint pt1 , CPoint pt2 , COLORREF clr )
- {
- CSPPenDC pen ( *pDC,clr );
- CSPBrushDC brush ( *pDC,clr );
- Triangle( pDC,pt0,pt1,pt2 );
- }
- BOOL CSPDrawHelpers::IsLowResolution( HDC hDC/* = 0*/ )
- {
- if ( hDC )
- {
- int nColors = ::GetDeviceCaps( hDC,BITSPIXEL );
- return ( nColors > 0 && nColors <= 8 );
- }
- hDC = ::GetDC( ::GetDesktopWindow() );
- if ( hDC )
- {
- int nColors = ::GetDeviceCaps( hDC,BITSPIXEL );
- ::ReleaseDC( ::GetDesktopWindow(),hDC );
- return ( nColors > 0 && nColors <= 8 );
- }
- return FALSE;
- }
- SPCurrentSystemTheme CSPDrawHelpers::GetCurrentSystemTheme()
- {
- return SPColorManager()->GetCurrentSystemTheme();
- }
- //=============================================================================
- // Multi-Monitor API
- //=============================================================================
- class CSPMultiMonitor
- {
- protected:
- DECLARE_HANDLE( HMONITOR );
- protected:
- typedef struct tagMONITORINFO
- {
- DWORD cbSize;
- RECT rcMonitor;
- RECT rcWork;
- DWORD dwFlags;
- } MONITORINFO, * LPMONITORINFO;
- protected:
- CSPMultiMonitor();
- protected:
- BOOL InitMultipleMonitorStubs();
- CRect GetWorkArea( HMONITOR hMonitor )
- {
- if ( hMonitor && m_pfnGetMonitorInfo )
- {
- ASSERT( sizeof( MONITORINFO ) == 40 );
- MONITORINFO info;
- info.cbSize = sizeof( MONITORINFO );
- if ( m_pfnGetMonitorInfo( hMonitor,( MONITORINFO * ) &info ) )
- return info.rcWork;
- }
- RECT rcWork;
- ::SystemParametersInfo( SPI_GETWORKAREA,NULL,&rcWork,0 );
- return rcWork;
- }
- public:
- CRect GetWorkArea( HWND hWnd )
- {
- return GetWorkArea( InitMultipleMonitorStubs() ? m_pfnMonitorFromWindow( hWnd,0 ) : 0 );
- }
- CRect GetWorkArea( POINT ptScreenCoords )
- {
- return GetWorkArea( InitMultipleMonitorStubs() ? m_pfnMonitorFromPoint( ptScreenCoords,0 ) : 0 );
- }
- CRect GetWorkArea( LPCRECT lprcScreenCoords )
- {
- return GetWorkArea( InitMultipleMonitorStubs() ? m_pfnMonitorFromRect( lprcScreenCoords,0 ) : 0 );
- }
- protected:
- int ( WINAPI* m_pfnGetSystemMetrics )( int );
- HMONITOR ( WINAPI* m_pfnMonitorFromWindow )( HWND , DWORD );
- HMONITOR ( WINAPI* m_pfnMonitorFromRect )( LPCRECT , DWORD );
- HMONITOR ( WINAPI* m_pfnMonitorFromPoint )( POINT , DWORD );
- BOOL ( WINAPI* m_pfnGetMonitorInfo )( HMONITOR , LPMONITORINFO );
- BOOL m_fMultiMonInitDone;
- public:
- static CSPMultiMonitor s_monInstance;
- };
- CSPMultiMonitor CSPMultiMonitor::s_monInstance;
- CSPMultiMonitor::CSPMultiMonitor()
- {
- m_fMultiMonInitDone = FALSE;
- }
- BOOL CSPMultiMonitor::InitMultipleMonitorStubs()
- {
- if ( m_fMultiMonInitDone )
- {
- return m_pfnGetMonitorInfo != NULL;
- }
- #ifdef UNICODE
- OSVERSIONINFO osvi ={0};
- osvi.dwOSVersionInfoSize = sizeof( osvi );
- GetVersionEx( &osvi );
- BOOL fMultimonPlatformNT = ( VER_PLATFORM_WIN32_NT == osvi.dwPlatformId );
- #endif
- HMODULE hUser32 = GetModuleHandle( TEXT( "USER32" ) );
- if ( hUser32 && ( *( FARPROC * ) &m_pfnGetSystemMetrics = GetProcAddress( hUser32,"GetSystemMetrics" ) ) != NULL && ( *( FARPROC * ) &m_pfnMonitorFromWindow = GetProcAddress( hUser32,"MonitorFromWindow" ) ) != NULL && ( *( FARPROC * ) &m_pfnMonitorFromRect = GetProcAddress( hUser32,"MonitorFromRect" ) ) != NULL && ( *( FARPROC * ) &m_pfnMonitorFromPoint = GetProcAddress( hUser32,"MonitorFromPoint" ) ) != NULL &&
- #ifdef UNICODE
- ( *( FARPROC * ) &m_pfnGetMonitorInfo = fMultimonPlatformNT ? GetProcAddress( hUser32,"GetMonitorInfoW" ) : GetProcAddress( hUser32,"GetMonitorInfoA" ) ) != NULL
- #else
- ( *( FARPROC * ) &m_pfnGetMonitorInfo = GetProcAddress( hUser32,"GetMonitorInfoA" ) ) != NULL
- #endif
- )
- {
- m_fMultiMonInitDone = TRUE;
- return TRUE;
- }
- else
- {
- m_pfnGetSystemMetrics = NULL;
- m_pfnMonitorFromWindow = NULL;
- m_pfnMonitorFromRect = NULL;
- m_pfnMonitorFromPoint = NULL;
- m_pfnGetMonitorInfo = NULL;
- m_fMultiMonInitDone = TRUE;
- return FALSE;
- }
- }
- CRect CSPDrawHelpers::GetWorkArea( const CRect & rect )
- {
- return CSPMultiMonitor::s_monInstance.GetWorkArea( rect );
- }
- CRect CSPDrawHelpers::GetWorkArea( const CWnd * pWnd )
- {
- ASSERT_VALID( pWnd );
- return CSPMultiMonitor::s_monInstance.GetWorkArea( pWnd->GetSafeHwnd() );
- }
- CRect CSPDrawHelpers::GetWorkArea()
- {
- POINT point;
- ::GetCursorPos( &point );
- return CSPMultiMonitor::s_monInstance.GetWorkArea( point );
- }
|