00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "StdAfx.h"
00023 #include "Shareaza.h"
00024 #include "Settings.h"
00025 #include "CoolInterface.h"
00026 #include "SkinWindow.h"
00027 #include "XML.h"
00028
00029 #ifdef _DEBUG
00030 #undef THIS_FILE
00031 static char THIS_FILE[]=__FILE__;
00032 #define new DEBUG_NEW
00033 #endif
00034
00035
00036 #define BORDER_WIDTH GetSystemMetrics( SM_CXSIZEFRAME )
00037 #define SIZEBOX_WIDTH GetSystemMetrics( SM_CXSIZE )
00038
00039
00041
00042
00043 CSkinWindow::CSkinWindow()
00044 {
00045 m_bPart = new BOOL[ SKINPART_COUNT ];
00046 m_rcPart = new CRect[ SKINPART_COUNT ];
00047 m_nPart = new int[ SKINPART_COUNT ];
00048 m_bAnchor = new BOOL[ SKINANCHOR_COUNT ];
00049 m_rcAnchor = new CRect[ SKINANCHOR_COUNT ];
00050
00051 ZeroMemory( m_bPart, sizeof(BOOL) * SKINPART_COUNT );
00052 ZeroMemory( m_nPart, sizeof(int) * SKINPART_COUNT );
00053 ZeroMemory( m_bAnchor, sizeof(BOOL) * SKINANCHOR_COUNT );
00054
00055 m_szMinSize.cx = m_szMinSize.cy = 0;
00056 m_rcMaximise.SetRect( -1, 0, -1, -1 );
00057 m_rcResize.SetRect( BORDER_WIDTH, BORDER_WIDTH, BORDER_WIDTH, BORDER_WIDTH );
00058
00059 m_hoSkin = NULL;
00060 m_bCaption = FALSE;
00061 m_bCaptionCaps = FALSE;
00062 m_crCaptionFill = CLR_NONE;
00063 m_crCaptionText = RGB( 255, 255, 255 );
00064 m_crCaptionInactive = RGB( 128, 128, 128 );
00065 m_crCaptionShadow = CLR_NONE;
00066 m_crCaptionOutline = CLR_NONE;
00067 m_nCaptionAlign = 0;
00068
00069 m_pRegionXML = NULL;
00070
00071 m_nHoverAnchor = 0;
00072 m_nDownAnchor = 0;
00073 m_nMirror = 0;
00074 }
00075
00076 CSkinWindow::~CSkinWindow()
00077 {
00078 if ( m_dcSkin.m_hDC != NULL )
00079 {
00080 if ( m_hoSkin != NULL ) m_dcSkin.SelectObject( CBitmap::FromHandle( m_hoSkin ) );
00081 m_dcSkin.DeleteDC();
00082 }
00083
00084 if ( m_bmSkin.m_hObject != NULL ) m_bmSkin.DeleteObject();
00085
00086 if ( m_pRegionXML ) delete m_pRegionXML;
00087
00088 for ( POSITION pos = m_pPartList.GetStartPosition() ; pos ; )
00089 {
00090 CRect* pRect;
00091 CString str;
00092 m_pPartList.GetNextAssoc( pos, str, (void*&)pRect );
00093 delete pRect;
00094 }
00095
00096 for ( POSITION pos = m_pAnchorList.GetStartPosition() ; pos ; )
00097 {
00098 CRect* pRect;
00099 CString str;
00100 m_pAnchorList.GetNextAssoc( pos, str, (void*&)pRect );
00101 delete pRect;
00102 }
00103
00104 delete [] m_bPart;
00105 delete [] m_rcPart;
00106 delete [] m_nPart;
00107 delete [] m_bAnchor;
00108 delete [] m_rcAnchor;
00109 }
00110
00112
00113
00114 BOOL CSkinWindow::Parse(CXMLElement* pBase, const CString& strPath)
00115 {
00116 static LPCTSTR pszPart[] =
00117 {
00118 _T("TopLeft"), _T("Top"), _T("TopRight"),
00119 _T("TopLeftIA"), _T("TopIA"), _T("TopRightIA"),
00120 _T("LeftTop"), _T("Left"), _T("LeftBottom"),
00121 _T("RightTop"), _T("Right"), _T("RightBottom"),
00122 _T("BottomLeft"), _T("Bottom"), _T("BottomRight"),
00123 _T("System"), _T("SystemHover"), _T("SystemDown"),
00124 _T("Minimise"), _T("MinimiseHover"), _T("MinimiseDown"),
00125 _T("Maximise"), _T("MaximiseHover"), _T("MaximiseDown"),
00126 _T("Close"), _T("CloseHover"), _T("CloseDown"),
00127 NULL
00128 };
00129
00130 static LPCTSTR pszAnchor[] =
00131 {
00132 _T("Icon"), _T("System"), _T("Minimise"), _T("Maximise"), _T("Close"),
00133 NULL
00134 };
00135
00136 if ( ! pBase->IsNamed( _T("windowSkin") ) ) return FALSE;
00137
00138 CString str;
00139 CRect rc;
00140
00141 for ( POSITION pos = pBase->GetElementIterator() ; pos ; )
00142 {
00143 CXMLElement* pGroup = pBase->GetNextElement( pos );
00144
00145 if ( pGroup->IsNamed( _T("target") ) )
00146 {
00147 CString strTarget = pGroup->GetAttributeValue( _T("window") );
00148
00149 if ( strTarget == _T("CMainTabBarCtrl") )
00150 strTarget = strTarget;
00151
00152 if ( strTarget.GetLength() )
00153 {
00154 m_sTargets += '|';
00155 m_sTargets += strTarget;
00156 m_sTargets += '|';
00157 }
00158 }
00159 else if ( pGroup->IsNamed( _T("parts") ) )
00160 {
00161 for ( POSITION posInner = pGroup->GetElementIterator() ; posInner ; )
00162 {
00163 CXMLElement* pXML = pGroup->GetNextElement( posInner );
00164 if ( ! pXML->IsNamed( _T("part") ) ) continue;
00165
00166 if ( ! ParseRect( pXML, &rc ) ) continue;
00167 if ( ! rc.Width() ) rc.right++;
00168 if ( ! rc.Height() ) rc.bottom++;
00169
00170 CString strMode = pXML->GetAttributeValue( _T("mode") );
00171 int nMode = SKINPARTMODE_TILE;
00172
00173 if ( strMode.CompareNoCase( _T("tile") ) == 0 )
00174 nMode = SKINPARTMODE_TILE;
00175 else if ( strMode.CompareNoCase( _T("stretch") ) == 0 )
00176 nMode = SKINPARTMODE_STRETCH;
00177
00178 CString strName = pXML->GetAttributeValue( _T("name") );
00179 if ( strName.IsEmpty() ) continue;
00180
00181 int nPart = 0;
00182 for ( ; pszPart[ nPart ] ; nPart++ )
00183 {
00184 if ( _tcsicmp( strName, pszPart[ nPart ] ) == 0 )
00185 {
00186 m_bPart[ nPart ] = TRUE;
00187 m_nPart[ nPart ] = nMode;
00188 m_rcPart[ nPart ] = rc;
00189 break;
00190 }
00191 }
00192
00193 if ( pszPart[ nPart ] == NULL )
00194 {
00195 CRect* pRect;
00196
00197 if ( m_pPartList.Lookup( strName, (void*&)pRect ) )
00198 {
00199 *pRect = rc;
00200 }
00201 else
00202 {
00203 pRect = new CRect( &rc );
00204 m_pPartList.SetAt( strName, pRect );
00205 }
00206 }
00207 }
00208 }
00209 else if ( pGroup->IsNamed( _T("anchors") ) )
00210 {
00211 for ( POSITION posInner = pGroup->GetElementIterator() ; posInner ; )
00212 {
00213 CXMLElement* pXML = pGroup->GetNextElement( posInner );
00214 if ( ! pXML->IsNamed( _T("anchor") ) ) continue;
00215
00216 if ( ! ParseRect( pXML, &rc ) ) continue;
00217
00218 CString strName = pXML->GetAttributeValue( _T("name") );
00219
00220 int nAnchor = 0;
00221 for ( ; pszAnchor[ nAnchor ] ; nAnchor++ )
00222 {
00223 if ( _tcsicmp( strName, pszAnchor[ nAnchor ] ) == 0 )
00224 {
00225 m_bAnchor[ nAnchor ] = TRUE;
00226 m_rcAnchor[ nAnchor ] = rc;
00227 break;
00228 }
00229 }
00230
00231 if ( pszAnchor[ nAnchor ] == NULL )
00232 {
00233 CRect* pRect;
00234 if ( m_pAnchorList.Lookup( strName, (void*&)pRect ) )
00235 {
00236 *pRect = rc;
00237 }
00238 else
00239 {
00240 pRect = new CRect( &rc );
00241 m_pAnchorList.SetAt( strName, pRect );
00242 }
00243 if ( strName == "Mirror" )
00244 {
00245 m_nMirror = 1;
00246 m_rcMirror = pRect;
00247 }
00248 if ( strName == "MirrorFull" )
00249 {
00250 m_nMirror = 2;
00251 m_rcMirror = pRect;
00252 }
00253 }
00254 }
00255 }
00256 else if ( pGroup->IsNamed( _T("region") ) )
00257 {
00258 if ( m_pRegionXML ) delete m_pRegionXML;
00259 m_pRegionXML = pGroup->Detach();
00260 }
00261 else if ( pGroup->IsNamed( _T("caption") ) )
00262 {
00263 m_bCaption = ParseRect( pGroup, &m_rcCaption );
00264
00265 CString strFont = pGroup->GetAttributeValue( _T("fontFace") );
00266
00267 if ( strFont.GetLength() )
00268 {
00269 CString strSize = pGroup->GetAttributeValue( _T("fontSize") );
00270 CString strBold = pGroup->GetAttributeValue( _T("fontWeight") );
00271
00272 if ( strBold.CompareNoCase( _T("bold") ) == 0 )
00273 strBold = _T("700");
00274 else if ( strBold.CompareNoCase( _T("normal") ) == 0 )
00275 strBold = _T("400");
00276
00277 int nFontSize = 13, nFontWeight = FW_BOLD;
00278 _stscanf( strSize, _T("%i"), &nFontSize );
00279 _stscanf( strBold, _T("%i"), &nFontWeight );
00280
00281 LOGFONT lf;
00282 ZeroMemory( &lf, sizeof(lf) );
00283 lf.lfHeight = nFontSize;
00284 lf.lfWeight = nFontWeight;
00285 lf.lfCharSet = DEFAULT_CHARSET;
00286 lf.lfQuality = DEFAULT_QUALITY;
00287 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
00288 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
00289 lf.lfPitchAndFamily = DEFAULT_PITCH|FF_DONTCARE;
00290 _tcscpy( lf.lfFaceName, strFont );
00291
00292 if ( _tcsistr( strSize, _T("pt") ) != NULL )
00293 {
00294 m_fnCaption.CreatePointFontIndirect( &lf );
00295 }
00296 else
00297 {
00298 lf.lfHeight = -lf.lfHeight;
00299 m_fnCaption.CreateFontIndirect( &lf );
00300 }
00301 }
00302
00303 str = pGroup->GetAttributeValue( _T("colour") );
00304 ParseColour( str, m_crCaptionText );
00305 str = pGroup->GetAttributeValue( _T("inactiveColour") );
00306 ParseColour( str, m_crCaptionInactive );
00307 str = pGroup->GetAttributeValue( _T("fill") );
00308 ParseColour( str, m_crCaptionFill );
00309 str = pGroup->GetAttributeValue( _T("fillColour") );
00310 ParseColour( str, m_crCaptionFill );
00311 str = pGroup->GetAttributeValue( _T("shadowColour") );
00312 ParseColour( str, m_crCaptionShadow );
00313 str = pGroup->GetAttributeValue( _T("outlineColour") );
00314 ParseColour( str, m_crCaptionOutline );
00315
00316 str = pGroup->GetAttributeValue( _T("caps") );
00317 m_bCaptionCaps = str.GetLength() > 0;
00318
00319 str = pGroup->GetAttributeValue( _T("align") );
00320 if ( str.CompareNoCase( _T("left") ) == 0 )
00321 m_nCaptionAlign = 0;
00322 else if ( str.CompareNoCase( _T("center") ) == 0 )
00323 m_nCaptionAlign = 1;
00324 else if ( str.CompareNoCase( _T("right") ) == 0 )
00325 m_nCaptionAlign = 2;
00326
00327 if ( m_bCaption && m_fnCaption.m_hObject == NULL )
00328 {
00329 NONCLIENTMETRICS pMetrics;
00330 pMetrics.cbSize = sizeof(pMetrics);
00331 SystemParametersInfo( SPI_GETNONCLIENTMETRICS, pMetrics.cbSize, &pMetrics, 0 );
00332 m_fnCaption.CreateFontIndirect( &pMetrics.lfCaptionFont );
00333 }
00334 }
00335 else if ( pGroup->IsNamed( _T("image") ) )
00336 {
00337 str = pGroup->GetAttributeValue( _T("language") );
00338
00339 if ( str.GetLength() > 0 )
00340 {
00341 if ( str.CompareNoCase( Settings.General.Language ) != 0 ) continue;
00342 m_sLanguage = str;
00343 }
00344
00345 CString strRes = pGroup->GetAttributeValue( _T("res") );
00346 CString strFile = pGroup->GetAttributeValue( _T("path") );
00347 HBITMAP hBitmap = NULL;
00348
00349 if ( strFile.GetLength() > 0 )
00350 {
00351 strFile = strPath + strFile;
00352 hBitmap = (HBITMAP)LoadImage( AfxGetInstanceHandle(), strFile,
00353 IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
00354 }
00355 else if ( strRes.GetLength() > 0 )
00356 {
00357 UINT nResID = 0;
00358 if ( _stscanf( strRes, _T("%lu"), &nResID ) != 1 ) return FALSE;
00359 if ( nResID == IDB_NAVBAR_IMAGE && theApp.m_bRTL )
00360 nResID = IDB_NAVBAR_IMAGE_RTL;
00361 else if ( nResID == IDB_NAVBAR_ALPHA && theApp.m_bRTL )
00362 nResID = IDB_NAVBAR_ALPHA_RTL;
00363 hBitmap = (HBITMAP)LoadImage( AfxGetInstanceHandle(),
00364 MAKEINTRESOURCE(nResID), IMAGE_BITMAP, 0, 0, 0 );
00365 }
00366
00367 if ( hBitmap == NULL ) return FALSE;
00368
00369 str = pGroup->GetAttributeValue( _T("type") );
00370 CharLower( str.GetBuffer() );
00371 str.ReleaseBuffer();
00372
00373 if ( str == _T("watermark") || str == _T("water") )
00374 {
00375 if ( m_bmWatermark.m_hObject != NULL ) m_bmWatermark.DeleteObject();
00376 m_bmWatermark.Attach( hBitmap );
00377 }
00378 else if ( str == _T("alpha") )
00379 {
00380 if ( m_bmAlpha.m_hObject != NULL ) m_bmAlpha.DeleteObject();
00381 m_bmAlpha.Attach( hBitmap );
00382 }
00383 else
00384 {
00385 if ( m_bmSkin.m_hObject != NULL ) m_bmSkin.DeleteObject();
00386 m_bmSkin.Attach( hBitmap );
00387 }
00388 }
00389 else if ( pGroup->IsNamed( _T("maximiseCrop") ) )
00390 {
00391 ParseRect( pGroup, &m_rcMaximise );
00392 m_rcMaximise.right -= m_rcMaximise.left;
00393 m_rcMaximise.bottom -= m_rcMaximise.top;
00394 }
00395 else if ( pGroup->IsNamed( _T("resizeBorder") ) )
00396 {
00397 ParseRect( pGroup, &m_rcResize );
00398 m_rcResize.right -= m_rcResize.left;
00399 m_rcResize.bottom -= m_rcResize.top;
00400 }
00401 else if ( pGroup->IsNamed( _T("minimumSize") ) )
00402 {
00403 CString str = pGroup->GetAttributeValue( _T("width") );
00404 _stscanf( str, _T("%i"), &m_szMinSize.cx );
00405 str = pGroup->GetAttributeValue( _T("height") );
00406 _stscanf( str, _T("%i"), &m_szMinSize.cy );
00407 }
00408 }
00409
00410 return ( m_bmSkin.m_hObject != NULL );
00411 }
00412
00414
00415
00416 BOOL CSkinWindow::ParseRect(CXMLElement* pXML, CRect* pRect)
00417 {
00418 CString strValue = pXML->GetAttributeValue( _T("rect") );
00419
00420 if ( strValue.GetLength() )
00421 {
00422 _stscanf( strValue, _T("%i,%i,%i,%i"), &pRect->left, &pRect->top,
00423 &pRect->right, &pRect->bottom );
00424 pRect->right += pRect->left;
00425 pRect->bottom += pRect->top;
00426 return TRUE;
00427 }
00428
00429 strValue = pXML->GetAttributeValue( _T("point") );
00430
00431 if ( strValue.GetLength() )
00432 {
00433 _stscanf( strValue, _T("%i,%i"), &pRect->left, &pRect->top );
00434 pRect->right = pRect->bottom = 0;
00435 return TRUE;
00436 }
00437
00438 return FALSE;
00439 }
00440
00441 BOOL CSkinWindow::ParseColour(const CString& str, COLORREF& cr)
00442 {
00443 if ( str.GetLength() != 6 ) return FALSE;
00444
00445 int nRed, nGreen, nBlue;
00446
00447 if ( _stscanf( str.Mid( 0, 2 ), _T("%x"), &nRed ) != 1 ) return FALSE;
00448 if ( _stscanf( str.Mid( 2, 2 ), _T("%x"), &nGreen ) != 1 ) return FALSE;
00449 if ( _stscanf( str.Mid( 4, 2 ), _T("%x"), &nBlue ) != 1 ) return FALSE;
00450
00451 cr = RGB( nRed, nGreen, nBlue );
00452
00453 return TRUE;
00454 }
00455
00457
00458
00459 void CSkinWindow::CalcWindowRect(RECT* pRect, BOOL bToClient, BOOL bZoomed)
00460 {
00461 CRect rcAdjust( 0, 0, 0, 0 );
00462
00463 if ( m_bPart[ SKINPART_TOP_LEFT ] )
00464 rcAdjust.top = max( rcAdjust.top, LONG(m_rcPart[ SKINPART_TOP_LEFT ].Height()) );
00465 if ( m_bPart[ SKINPART_TOP ] )
00466 rcAdjust.top = max( rcAdjust.top, LONG(m_rcPart[ SKINPART_TOP ].Height()) );
00467 if ( m_bPart[ SKINPART_TOP_RIGHT ] )
00468 rcAdjust.top = max( rcAdjust.top, LONG(m_rcPart[ SKINPART_TOP_RIGHT ].Height()) );
00469
00470 if ( m_bPart[ SKINPART_LEFT ] )
00471 rcAdjust.left = max( rcAdjust.left, LONG(m_rcPart[ SKINPART_LEFT ].Width()) );
00472
00473 if ( m_bPart[ SKINPART_RIGHT ] )
00474 rcAdjust.right = max( rcAdjust.right, LONG(m_rcPart[ SKINPART_RIGHT ].Width()) );
00475
00476 if ( m_bPart[ SKINPART_BOTTOM_LEFT ] )
00477 rcAdjust.bottom = max( rcAdjust.bottom, LONG(m_rcPart[ SKINPART_BOTTOM_LEFT ].Height()) );
00478 if ( m_bPart[ SKINPART_BOTTOM ] )
00479 rcAdjust.bottom = max( rcAdjust.bottom, LONG(m_rcPart[ SKINPART_BOTTOM ].Height()) );
00480 if ( m_bPart[ SKINPART_BOTTOM_RIGHT ] )
00481 rcAdjust.bottom = max( rcAdjust.bottom, LONG(m_rcPart[ SKINPART_BOTTOM_RIGHT ].Height()) );
00482
00483 if ( bToClient )
00484 {
00485 pRect->left += rcAdjust.left;
00486 pRect->top += rcAdjust.top;
00487 pRect->right -= rcAdjust.right;
00488 pRect->bottom -= rcAdjust.bottom;
00489 }
00490 else
00491 {
00492 pRect->left -= rcAdjust.left;
00493 pRect->top -= rcAdjust.top;
00494 pRect->right += rcAdjust.right;
00495 pRect->bottom += rcAdjust.bottom;
00496 }
00497 }
00498
00499 void CSkinWindow::OnNcCalcSize(CWnd* pWnd, BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp)
00500 {
00501 CalcWindowRect( &lpncsp->rgrc[0], TRUE, pWnd->IsZoomed() );
00502 }
00503
00504 void CSkinWindow::OnGetMinMaxInfo(MINMAXINFO* lpMMI)
00505 {
00506 CRect rcWork;
00507 if ( theApp.m_pfnGetMonitorInfoA != NULL )
00508 {
00509 MONITORINFO oMonitor;
00510 ZeroMemory( &oMonitor, sizeof(oMonitor) );
00511 oMonitor.cbSize = sizeof(oMonitor);
00512 theApp.m_pfnGetMonitorInfoA( theApp.m_pfnMonitorFromWindow( AfxGetMainWnd()->GetSafeHwnd(), MONITOR_DEFAULTTOPRIMARY ), &oMonitor );
00513
00514 rcWork = oMonitor.rcWork;
00515 }
00516 else
00517 {
00518 SystemParametersInfo( SPI_GETWORKAREA, 0, &rcWork, 0 );
00519 }
00520 rcWork.OffsetRect( -rcWork.left, -rcWork.top );
00521
00522 CRect rcAdjusted( &rcWork );
00523 CalcWindowRect( &rcAdjusted, FALSE, TRUE );
00524
00525 if ( m_rcMaximise.left < 0 )
00526 rcWork.left = rcAdjusted.left;
00527 else
00528 rcWork.left -= m_rcMaximise.left;
00529
00530 if ( m_rcMaximise.top < 0 )
00531 rcWork.top = rcAdjusted.top;
00532 else
00533 rcWork.top -= m_rcMaximise.top;
00534
00535 if ( m_rcMaximise.right < 0 )
00536 rcWork.right = rcAdjusted.right;
00537 else
00538 rcWork.right += m_rcMaximise.right;
00539
00540 if ( m_rcMaximise.bottom < 0 )
00541 rcWork.bottom = rcAdjusted.bottom;
00542 else
00543 rcWork.bottom += m_rcMaximise.bottom;
00544
00545 lpMMI->ptMaxPosition.x = rcWork.left;
00546 lpMMI->ptMaxPosition.y = rcWork.top;
00547 lpMMI->ptMaxSize.x = rcWork.right;
00548 lpMMI->ptMaxSize.y = rcWork.bottom;
00549
00550 lpMMI->ptMinTrackSize.x = max( lpMMI->ptMinTrackSize.x, m_szMinSize.cx );
00551 lpMMI->ptMinTrackSize.y = max( lpMMI->ptMinTrackSize.y, m_szMinSize.cy );
00552 }
00553
00554 UINT CSkinWindow::OnNcHitTest(CWnd* pWnd, CPoint point, BOOL bResizable)
00555 {
00556 CRect rc, rcAnchor;
00557 int nPointX;
00558
00559 pWnd->GetWindowRect( &rc );
00560 if ( theApp.m_bRTL )
00561 {
00562 nPointX = point.x;
00563 point.x = 2 * rc.left + rc.Width() - point.x;
00564 }
00565
00566 if ( m_bAnchor[ SKINANCHOR_SYSTEM ] )
00567 {
00568 ResolveAnchor( rc, rcAnchor, SKINANCHOR_SYSTEM );
00569 if ( rcAnchor.PtInRect( point ) ) return HTSYSMENU;
00570 }
00571
00572 if ( m_bAnchor[ SKINANCHOR_MINIMISE ] )
00573 {
00574 ResolveAnchor( rc, rcAnchor, SKINANCHOR_MINIMISE );
00575 if ( rcAnchor.PtInRect( point ) ) return HTREDUCE;
00576 }
00577
00578 if ( m_bAnchor[ SKINANCHOR_MAXIMISE ] )
00579 {
00580 ResolveAnchor( rc, rcAnchor, SKINANCHOR_MAXIMISE );
00581 if ( rcAnchor.PtInRect( point ) ) return HTZOOM;
00582 }
00583
00584 if ( m_bAnchor[ SKINANCHOR_CLOSE ] )
00585 {
00586 ResolveAnchor( rc, rcAnchor, SKINANCHOR_CLOSE );
00587 if ( rcAnchor.PtInRect( point ) ) return HTCLOSE;
00588 }
00589
00590 if ( theApp.m_bRTL ) point.x = nPointX;
00591 if ( bResizable && ! pWnd->IsZoomed() )
00592 {
00593 if ( point.x >= rc.right - SIZEBOX_WIDTH && point.y >= rc.bottom - SIZEBOX_WIDTH )
00594 return HTBOTTOMRIGHT;
00595
00596 if ( point.x < rc.left + m_rcResize.left )
00597 {
00598 if ( point.y < rc.top + m_rcResize.top ) return HTTOPLEFT;
00599 else if ( point.y >= rc.bottom - m_rcResize.bottom ) return HTBOTTOMLEFT;
00600 else return HTLEFT;
00601 }
00602 else if ( point.x >= rc.right - m_rcResize.right )
00603 {
00604 if ( point.y < rc.top + m_rcResize.top ) return HTTOPRIGHT;
00605 else if ( point.y >= rc.bottom - m_rcResize.bottom ) return HTBOTTOMRIGHT;
00606 else return HTRIGHT;
00607 }
00608 else if ( point.y < rc.top + m_rcResize.top )
00609 {
00610 if ( point.x < rc.left + m_rcResize.left ) return HTTOPLEFT;
00611 else if ( point.x >= rc.right - m_rcResize.right ) return HTTOPRIGHT;
00612 return HTTOP;
00613 }
00614 else if ( point.y >= rc.bottom - m_rcResize.bottom )
00615 {
00616 if ( point.x < rc.left + m_rcResize.left ) return HTBOTTOMLEFT;
00617 else if ( point.x >= rc.right - m_rcResize.right ) return HTBOTTOMRIGHT;
00618 return HTBOTTOM;
00619 }
00620 }
00621
00622 OnNcCalcSize( pWnd, FALSE, (NCCALCSIZE_PARAMS*)&rc );
00623
00624 if ( point.y < rc.top ) return HTCAPTION;
00625
00626 return rc.PtInRect( point ) ? HTCLIENT : HTBORDER;
00627 }
00628
00629 void CSkinWindow::OnNcPaint(CWnd* pWnd)
00630 {
00631 CWindowDC dc( pWnd );
00632 if ( theApp.m_bRTL ) theApp.m_pfnSetLayout( dc.m_hDC, LAYOUT_RTL );
00633 Paint( pWnd, dc, FALSE );
00634 }
00635
00636 BOOL CSkinWindow::OnNcActivate(CWnd* pWnd, BOOL bActive)
00637 {
00638 CWindowDC dc( pWnd );
00639 if ( theApp.m_bRTL ) theApp.m_pfnSetLayout( dc.m_hDC, LAYOUT_RTL );
00640 Paint( pWnd, dc, TRUE, bActive ? TS_TRUE : TS_FALSE );
00641 return FALSE;
00642 }
00643
00644 void CSkinWindow::OnSetText(CWnd* pWnd)
00645 {
00646 CWindowDC dc( pWnd );
00647 if ( theApp.m_bRTL ) theApp.m_pfnSetLayout( dc.m_hDC, LAYOUT_RTL );
00648 Paint( pWnd, dc, TRUE );
00649 }
00650
00651 void CSkinWindow::OnSize(CWnd* pWnd)
00652 {
00653 if ( pWnd->IsIconic() ) return;
00654
00655 if ( pWnd->IsZoomed() )
00656 {
00657 if ( theApp.m_pfnGetMonitorInfoA != NULL )
00658 {
00659 CRect rcWnd;
00660 SystemParametersInfo( SPI_GETWORKAREA, 0, rcWnd, 0 );
00661
00662 HMONITOR hMonitor = theApp.m_pfnMonitorFromWindow( pWnd->GetSafeHwnd(), MONITOR_DEFAULTTONEAREST );
00663 MONITORINFO mi;
00664 memset( &mi, 0, sizeof(MONITORINFO) );
00665 mi.cbSize = sizeof(MONITORINFO);
00666 VERIFY( GetMonitorInfo( hMonitor, &mi ) );
00667
00668 if ( mi.dwFlags & MONITORINFOF_PRIMARY )
00669 SetWindowPos( pWnd->m_hWnd, HWND_TOP, rcWnd.left, rcWnd.top, rcWnd.Width(),
00670 rcWnd.Height(), 0 );
00671 }
00672 pWnd->SetWindowRgn( NULL, TRUE );
00673 }
00674 else if ( m_pRegionXML )
00675 {
00676 SelectRegion( pWnd );
00677 }
00678 else if ( CoolInterface.IsNewWindows() )
00679 {
00680 CRect rcWnd;
00681
00682 pWnd->GetWindowRect( &rcWnd );
00683 rcWnd.OffsetRect( -rcWnd.left, -rcWnd.top );
00684 rcWnd.right++; rcWnd.bottom++;
00685
00686 HRGN hRgn = CreateRectRgnIndirect( &rcWnd );
00687 pWnd->SetWindowRgn( hRgn, TRUE );
00688 }
00689 }
00690
00691 BOOL CSkinWindow::OnEraseBkgnd(CWnd* pWnd, CDC* pDC)
00692 {
00693 if ( m_bmWatermark.m_hObject == NULL ) return FALSE;
00694
00695 if ( ! m_dcSkin.m_hDC ) m_dcSkin.CreateCompatibleDC( pDC );
00696 CBitmap* pOldImage = (CBitmap*)m_dcSkin.SelectObject( &m_bmWatermark );
00697
00698 BITMAP pWatermark;
00699 CRect rc;
00700
00701 pWnd->GetClientRect( &rc );
00702 m_bmWatermark.GetBitmap( &pWatermark );
00703
00704 for ( int nY = rc.top ; nY < rc.bottom ; nY += pWatermark.bmHeight )
00705 {
00706 for ( int nX = rc.left ; nX < rc.right ; nX += pWatermark.bmWidth )
00707 {
00708 pDC->BitBlt( nX, nY, pWatermark.bmWidth, pWatermark.bmHeight, &m_dcSkin, 0, 0, SRCCOPY );
00709 }
00710 }
00711
00712 m_dcSkin.SelectObject( pOldImage );
00713 return TRUE;
00714 }
00715
00716 void CSkinWindow::OnNcMouseMove(CWnd* pWnd, UINT nHitTest, CPoint point)
00717 {
00718 int nAnchor = 0;
00719 if ( nHitTest == HTSYSMENU ) nAnchor = SKINANCHOR_SYSTEM;
00720 else if ( nHitTest == HTREDUCE ) nAnchor = SKINANCHOR_MINIMISE;
00721 else if ( nHitTest == HTZOOM ) nAnchor = SKINANCHOR_MAXIMISE;
00722 else if ( nHitTest == HTCLOSE ) nAnchor = SKINANCHOR_CLOSE;
00723
00724 if ( m_nDownAnchor && m_nDownAnchor != nAnchor )
00725 {
00726 if ( ( GetAsyncKeyState( VK_LBUTTON ) & 0x8000 ) == 0 )
00727 m_nDownAnchor = 0;
00728 nAnchor = 0;
00729 }
00730
00731 if ( nAnchor != m_nHoverAnchor )
00732 {
00733 m_nHoverAnchor = nAnchor;
00734 CWindowDC dc( pWnd );
00735 if ( theApp.m_bRTL ) theApp.m_pfnSetLayout( dc.m_hDC, LAYOUT_RTL );
00736 Paint( pWnd, dc, TRUE );
00737 }
00738 }
00739
00740 BOOL CSkinWindow::OnNcLButtonDown(CWnd* pWnd, UINT nHitTest, CPoint point)
00741 {
00742 int nAnchor = 0;
00743 if ( nHitTest == HTSYSMENU ) nAnchor = SKINANCHOR_SYSTEM;
00744 else if ( nHitTest == HTREDUCE ) nAnchor = SKINANCHOR_MINIMISE;
00745 else if ( nHitTest == HTZOOM ) nAnchor = SKINANCHOR_MAXIMISE;
00746 else if ( nHitTest == HTCLOSE ) nAnchor = SKINANCHOR_CLOSE;
00747 else return FALSE;
00748
00749 m_nHoverAnchor = m_nDownAnchor = nAnchor;
00750
00751 if ( nAnchor == SKINANCHOR_SYSTEM )
00752 {
00753 CRect rcWindow, rcSystem;
00754
00755 pWnd->GetWindowRect( &rcWindow );
00756 ResolveAnchor( rcWindow, rcSystem, SKINANCHOR_SYSTEM );
00757 CMenu* pPopup = pWnd->GetSystemMenu( FALSE );
00758
00759 CWindowDC dc( pWnd );
00760 if ( theApp.m_bRTL ) theApp.m_pfnSetLayout( dc.m_hDC, LAYOUT_RTL );
00761 Paint( pWnd, dc, TRUE );
00762
00763 DWORD nTime = GetTickCount();
00764
00765 UINT nCmdID = pPopup->TrackPopupMenu( TPM_LEFTALIGN|TPM_TOPALIGN|TPM_RETURNCMD,
00766 theApp.m_bRTL ? rcWindow.right - rcSystem.left + rcWindow.left : rcSystem.left,
00767 rcSystem.bottom, pWnd, NULL );
00768
00769 m_nHoverAnchor = m_nDownAnchor = 0;
00770
00771 if ( nCmdID )
00772 {
00773 pWnd->PostMessage( WM_SYSCOMMAND, nCmdID, MAKELONG( rcSystem.left, rcSystem.bottom ) );
00774 }
00775 else if ( GetTickCount() - nTime < 300 )
00776 {
00777 GetCursorPos( &point );
00778 if ( OnNcHitTest( pWnd, point, FALSE ) == HTSYSMENU )
00779 {
00780 pWnd->PostMessage( WM_SYSCOMMAND, SC_CLOSE, MAKELONG( rcSystem.left, rcSystem.bottom ) );
00781 }
00782 }
00783 }
00784
00785 CWindowDC dc( pWnd );
00786 if ( theApp.m_bRTL ) theApp.m_pfnSetLayout( dc.m_hDC, LAYOUT_RTL );
00787 Paint( pWnd, dc, TRUE );
00788
00789 return TRUE;
00790 }
00791
00792 BOOL CSkinWindow::OnNcLButtonUp(CWnd* pWnd, UINT nHitTest, CPoint point)
00793 {
00794 if ( ! m_nDownAnchor ) return FALSE;
00795
00796 if ( m_nDownAnchor == m_nHoverAnchor )
00797 {
00798 switch ( m_nDownAnchor )
00799 {
00800 case SKINANCHOR_MINIMISE:
00801 pWnd->PostMessage( WM_SYSCOMMAND, SC_MINIMIZE );
00802 break;
00803 case SKINANCHOR_MAXIMISE:
00804 pWnd->PostMessage( WM_SYSCOMMAND, pWnd->IsZoomed() ? SC_RESTORE : SC_MAXIMIZE );
00805 break;
00806 case SKINANCHOR_CLOSE:
00807 pWnd->PostMessage( WM_SYSCOMMAND, SC_CLOSE );
00808 break;
00809 }
00810 }
00811
00812 m_nHoverAnchor = 0;
00813 m_nDownAnchor = 0;
00814
00815 CWindowDC dc( pWnd );
00816 if ( theApp.m_bRTL ) theApp.m_pfnSetLayout( dc.m_hDC, LAYOUT_RTL );
00817 Paint( pWnd, dc, TRUE );
00818
00819 return FALSE;
00820 }
00821
00822 BOOL CSkinWindow::OnNcLButtonDblClk(CWnd* pWnd, UINT nHitTest, CPoint point)
00823 {
00824 if ( nHitTest == HTSYSMENU )
00825 {
00826 pWnd->PostMessage( WM_SYSCOMMAND, SC_CLOSE );
00827 return TRUE;
00828 }
00829
00830 return FALSE;
00831 }
00832
00834
00835
00836 void CSkinWindow::Prepare(CDC* pDC)
00837 {
00838 if ( m_dcSkin.m_hDC == NULL )
00839 m_dcSkin.CreateCompatibleDC( pDC );
00840 if ( m_hoSkin == NULL )
00841 m_hoSkin = (HBITMAP)m_dcSkin.SelectObject( &m_bmSkin )->GetSafeHandle();
00842 if ( theApp.m_bRTL ) theApp.m_pfnSetLayout( m_dcSkin.m_hDC, LAYOUT_BITMAPORIENTATIONPRESERVED );
00843 }
00844
00845 void CSkinWindow::Paint(CWnd* pWnd, CDC& dc, BOOL bCaption, TRISTATE bActive)
00846 {
00847 HICON hIcon = NULL;
00848 CString strCaption;
00849 CRect rc, rcItem;
00850
00851 Prepare( &dc );
00852
00853 pWnd->GetWindowRect( &rc );
00854 rc.OffsetRect( -rc.left, -rc.top );
00855
00856 if ( bActive == TS_UNKNOWN )
00857 {
00858 if ( pWnd->IsKindOf( RUNTIME_CLASS(CMDIChildWnd) ) )
00859 {
00860 CMDIFrameWnd* pFrame = ((CMDIChildWnd*)pWnd)->GetMDIFrame();
00861 bActive = pFrame->MDIGetActive() == pWnd ? TS_TRUE : TS_FALSE;
00862 }
00863 else
00864 {
00865 bActive = CWnd::GetForegroundWindow() == pWnd ? TS_TRUE : TS_FALSE;
00866 }
00867 }
00868
00869 BOOL bZoomed = pWnd->IsZoomed();
00870
00871 if ( m_bCaption )
00872 {
00873 pWnd->GetWindowText( strCaption );
00874 if ( m_bCaptionCaps )
00875 {
00876 CharUpper( strCaption.GetBuffer() );
00877 strCaption.ReleaseBuffer();
00878 }
00879 }
00880
00881 if ( m_bAnchor[ SKINANCHOR_ICON ] )
00882 {
00883 hIcon = pWnd->GetIcon( FALSE );
00884 if ( hIcon == NULL ) hIcon = pWnd->GetIcon( TRUE );
00885 }
00886 int nCaptionHeight = 0;
00887
00888 if ( m_bPart[ SKINPART_TOP_LEFT ] ) nCaptionHeight = max( nCaptionHeight, m_rcPart[ SKINPART_TOP_LEFT ].Height() );
00889 if ( m_bPart[ SKINPART_TOP ] ) nCaptionHeight = max( nCaptionHeight, m_rcPart[ SKINPART_TOP ].Height() );
00890 if ( m_bPart[ SKINPART_TOP_RIGHT ] ) nCaptionHeight = max( nCaptionHeight, m_rcPart[ SKINPART_TOP_RIGHT ].Height() );
00891 CDC* pDC = CoolInterface.GetBuffer( dc, CSize( rc.Width(), nCaptionHeight ) );
00892
00893 for ( int nAnchor = SKINANCHOR_SYSTEM ; nAnchor <= SKINANCHOR_CLOSE ; nAnchor++ )
00894 {
00895 if ( m_bAnchor[ nAnchor ] )
00896 {
00897 int nPart = ( nAnchor - SKINANCHOR_SYSTEM ) * 3 + SKINPART_SYSTEM;
00898
00899 if ( m_nHoverAnchor == nAnchor )
00900 nPart += ( m_nDownAnchor == nAnchor ? 2 : 1 );
00901 else
00902 nPart += ( m_nDownAnchor == nAnchor ? 0 : 0 );
00903
00904 if ( m_bPart[ nPart ] )
00905 {
00906 ResolveAnchor( rc, rcItem, nAnchor );
00907
00908
00909
00910
00911
00912 if ( m_bPart[ SKINPART_TOP ] && theApp.m_bRTL && nAnchor == SKINANCHOR_CLOSE )
00913 pDC->StretchBlt( m_rcPart[ nPart ].Width() + rcItem.left - 1, rcItem.top,
00914 -m_rcPart[ nPart ].Width(), m_rcPart[ nPart ].Height(),
00915 &m_dcSkin, m_rcPart[ nPart ].left, m_rcPart[ nPart ].top,
00916 m_rcPart[ nPart ].Width(), m_rcPart[ nPart ].Height(), SRCCOPY );
00917 else
00918 pDC->BitBlt( rcItem.left, rcItem.top,
00919 m_rcPart[ nPart ].Width(), m_rcPart[ nPart ].Height(), &m_dcSkin,
00920 m_rcPart[ nPart ].left, m_rcPart[ nPart ].top, SRCCOPY );
00921 pDC->ExcludeClipRect( rcItem.left, rcItem.top,
00922 rcItem.left + m_rcPart[ nPart ].Width(),
00923 rcItem.top + m_rcPart[ nPart ].Height() );
00924 }
00925 }
00926 }
00927
00928 CRect rcLeft( &rc ), rcTop( &rc ), rcRight( &rc ), rcBottom( &rc );
00929 int nTotalWidth, nCaptionWidth, nSystemOffset;
00930 int nSystemWidth, nCaptionOffset, nRestOffset;
00931 nCaptionOffset = m_rcMirror.left;
00932 nCaptionWidth = m_rcMirror.top;
00933 nSystemOffset = m_rcMirror.right - m_rcMirror.left;
00934 nSystemWidth = m_rcMirror.bottom - m_rcMirror.top;
00935
00936 if ( bActive == TS_FALSE && m_bPart[ SKINPART_IA_TOP_LEFT ] )
00937 {
00938 pDC->BitBlt( 0, 0, m_rcPart[ SKINPART_IA_TOP_LEFT ].Width(),
00939 m_rcPart[ SKINPART_IA_TOP_LEFT ].Height(), &m_dcSkin,
00940 m_rcPart[ SKINPART_IA_TOP_LEFT ].left,
00941 m_rcPart[ SKINPART_IA_TOP_LEFT ].top, SRCCOPY );
00942
00943 nTotalWidth = m_rcPart[ SKINPART_IA_TOP_LEFT ].Width();
00944 nRestOffset = nTotalWidth - nSystemWidth - nSystemOffset - nCaptionWidth - nCaptionOffset;
00945
00946
00947 if ( theApp.m_bRTL && m_sTargets == "|CMainWnd|" && m_nMirror != 0 )
00948 {
00949 pDC->StretchBlt( nTotalWidth - nCaptionOffset, 0, -nCaptionWidth,
00950 m_rcPart[ SKINPART_IA_TOP_LEFT ].Height(), &m_dcSkin,
00951 m_rcPart[ SKINPART_IA_TOP_LEFT ].left + nRestOffset + nSystemWidth + nSystemOffset,
00952 m_rcPart[ SKINPART_IA_TOP_LEFT ].top, nCaptionWidth,
00953 m_rcPart[ SKINPART_IA_TOP_LEFT ].Height(), SRCCOPY );
00954 if ( m_nMirror == 2 )
00955 pDC->StretchBlt( nRestOffset + nSystemWidth, 0, -nSystemWidth,
00956 m_rcPart[ SKINPART_IA_TOP_LEFT ].Height(), &m_dcSkin,
00957 m_rcPart[ SKINPART_IA_TOP_LEFT ].left + nRestOffset,
00958 m_rcPart[ SKINPART_IA_TOP_LEFT ].top, nSystemWidth,
00959 m_rcPart[ SKINPART_IA_TOP_LEFT ].Height(), SRCCOPY );
00960 }
00961 rcLeft.top += m_rcPart[ SKINPART_IA_TOP_LEFT ].Height();
00962 rcTop.left += m_rcPart[ SKINPART_IA_TOP_LEFT ].Width();
00963 }
00964 else if ( m_bPart[ SKINPART_TOP_LEFT ] )
00965 {
00966 pDC->BitBlt( 0, 0, m_rcPart[ SKINPART_TOP_LEFT ].Width(),
00967 m_rcPart[ SKINPART_TOP_LEFT ].Height(), &m_dcSkin,
00968 m_rcPart[ SKINPART_TOP_LEFT ].left,
00969 m_rcPart[ SKINPART_TOP_LEFT ].top, SRCCOPY );
00970
00971
00972 if ( theApp.m_bRTL && m_sTargets == "|CMainWnd|" && m_nMirror != 0 )
00973 {
00974 nTotalWidth = m_rcPart[ SKINPART_TOP_LEFT ].Width();
00975 nRestOffset = nTotalWidth - nSystemWidth - nSystemOffset - nCaptionWidth - nCaptionOffset;
00976 pDC->StretchBlt( nTotalWidth - nCaptionOffset, 0, -nCaptionWidth,
00977 m_rcPart[ SKINPART_TOP_LEFT ].Height(), &m_dcSkin,
00978 m_rcPart[ SKINPART_TOP_LEFT ].left + nRestOffset + nSystemWidth + nSystemOffset,
00979 m_rcPart[ SKINPART_TOP_LEFT ].top, nCaptionWidth,
00980 m_rcPart[ SKINPART_TOP_LEFT ].Height(), SRCCOPY );
00981 if ( m_nMirror == 2 )
00982 pDC->StretchBlt( nRestOffset + nSystemWidth, 0, -nSystemWidth,
00983 m_rcPart[ SKINPART_TOP_LEFT ].Height(), &m_dcSkin,
00984 m_rcPart[ SKINPART_TOP_LEFT ].left + nRestOffset,
00985 m_rcPart[ SKINPART_TOP_LEFT ].top, nSystemWidth,
00986 m_rcPart[ SKINPART_TOP_LEFT ].Height(), SRCCOPY );
00987 }
00988 rcLeft.top += m_rcPart[ SKINPART_TOP_LEFT ].Height();
00989 rcTop.left += m_rcPart[ SKINPART_TOP_LEFT ].Width();
00990 }
00991
00992 if ( bActive == TS_FALSE && m_bPart[ SKINPART_IA_TOP_RIGHT ] )
00993 {
00994 pDC->BitBlt( rc.Width() - m_rcPart[ SKINPART_IA_TOP_RIGHT ].Width(), 0,
00995 m_rcPart[ SKINPART_IA_TOP_RIGHT ].Width(),
00996 m_rcPart[ SKINPART_IA_TOP_RIGHT ].Height(), &m_dcSkin,
00997 m_rcPart[ SKINPART_IA_TOP_RIGHT ].left,
00998 m_rcPart[ SKINPART_IA_TOP_RIGHT ].top, SRCCOPY );
00999 rcTop.right -= m_rcPart[ SKINPART_IA_TOP_RIGHT ].Width();
01000 rcRight.top += m_rcPart[ SKINPART_IA_TOP_RIGHT ].Height();
01001 }
01002 else if ( m_bPart[ SKINPART_TOP_RIGHT ] )
01003 {
01004 pDC->BitBlt( rc.Width() - m_rcPart[ SKINPART_TOP_RIGHT ].Width(), 0,
01005 m_rcPart[ SKINPART_TOP_RIGHT ].Width(),
01006 m_rcPart[ SKINPART_TOP_RIGHT ].Height(), &m_dcSkin,
01007 m_rcPart[ SKINPART_TOP_RIGHT ].left,
01008 m_rcPart[ SKINPART_TOP_RIGHT ].top, SRCCOPY );
01009 rcTop.right -= m_rcPart[ SKINPART_TOP_RIGHT ].Width();
01010 rcRight.top += m_rcPart[ SKINPART_TOP_RIGHT ].Height();
01011 }
01012
01013 if ( m_bPart[ SKINPART_BOTTOM_LEFT ] && ! bCaption )
01014 {
01015 dc.BitBlt( 0, rc.Height() - m_rcPart[ SKINPART_BOTTOM_LEFT ].Height(),
01016 m_rcPart[ SKINPART_BOTTOM_LEFT ].Width(),
01017 m_rcPart[ SKINPART_BOTTOM_LEFT ].Height(), &m_dcSkin,
01018 m_rcPart[ SKINPART_BOTTOM_LEFT ].left,
01019 m_rcPart[ SKINPART_BOTTOM_LEFT ].top, SRCCOPY );
01020 rcBottom.left += m_rcPart[ SKINPART_BOTTOM_LEFT ].Width();
01021 rcLeft.bottom -= m_rcPart[ SKINPART_BOTTOM_LEFT ].Height();
01022 }
01023
01024 if ( m_bPart[ SKINPART_BOTTOM_RIGHT ] && ! bCaption )
01025 {
01026 dc.BitBlt( rc.Width() - m_rcPart[ SKINPART_BOTTOM_RIGHT ].Width(),
01027 rc.Height() - m_rcPart[ SKINPART_BOTTOM_RIGHT ].Height(),
01028 m_rcPart[ SKINPART_BOTTOM_RIGHT ].Width(),
01029 m_rcPart[ SKINPART_BOTTOM_RIGHT ].Height(), &m_dcSkin,
01030 m_rcPart[ SKINPART_BOTTOM_RIGHT ].left,
01031 m_rcPart[ SKINPART_BOTTOM_RIGHT ].top, SRCCOPY );
01032 rcRight.bottom -= m_rcPart[ SKINPART_BOTTOM_RIGHT ].Height();
01033 rcBottom.right -= m_rcPart[ SKINPART_BOTTOM_RIGHT ].Width();
01034 }
01035
01036 if ( m_bPart[ SKINPART_LEFT_TOP ] && ! bCaption )
01037 {
01038 dc.BitBlt( 0, rcLeft.top, m_rcPart[ SKINPART_LEFT_TOP ].Width(),
01039 m_rcPart[ SKINPART_LEFT_TOP ].Height(), &m_dcSkin,
01040 m_rcPart[ SKINPART_LEFT_TOP ].left,
01041 m_rcPart[ SKINPART_LEFT_TOP ].top, SRCCOPY );
01042 rcLeft.top += m_rcPart[ SKINPART_LEFT_TOP ].Height();
01043 }
01044
01045 if ( m_bPart[ SKINPART_LEFT_BOTTOM ] && ! bCaption )
01046 {
01047 dc.BitBlt( 0, rcLeft.bottom - m_rcPart[ SKINPART_LEFT_BOTTOM ].Height(),
01048 m_rcPart[ SKINPART_LEFT_BOTTOM ].Width(),
01049 m_rcPart[ SKINPART_LEFT_BOTTOM ].Height(), &m_dcSkin,
01050 m_rcPart[ SKINPART_LEFT_BOTTOM ].left,
01051 m_rcPart[ SKINPART_LEFT_BOTTOM ].top, SRCCOPY );
01052 rcLeft.bottom -= m_rcPart[ SKINPART_LEFT_BOTTOM ].Height();
01053 }
01054
01055 if ( m_bPart[ SKINPART_RIGHT_TOP ] && ! bCaption )
01056 {
01057 dc.BitBlt( rcRight.right - m_rcPart[ SKINPART_RIGHT_TOP ].Width(),
01058 rcRight.top, m_rcPart[ SKINPART_RIGHT_TOP ].Width(),
01059 m_rcPart[ SKINPART_RIGHT_TOP ].Height(), &m_dcSkin,
01060 m_rcPart[ SKINPART_RIGHT_TOP ].left,
01061 m_rcPart[ SKINPART_RIGHT_TOP ].top, SRCCOPY );
01062 rcRight.top += m_rcPart[ SKINPART_RIGHT_TOP ].Height();
01063 }
01064
01065 if ( m_bPart[ SKINPART_RIGHT_BOTTOM ] && ! bCaption )
01066 {
01067 dc.BitBlt( rcRight.right - m_rcPart[ SKINPART_RIGHT_BOTTOM ].Width(),
01068 rcRight.bottom - m_rcPart[ SKINPART_RIGHT_BOTTOM ].Height(),
01069 m_rcPart[ SKINPART_RIGHT_BOTTOM ].Width(),
01070 m_rcPart[ SKINPART_RIGHT_BOTTOM ].Height(), &m_dcSkin,
01071 m_rcPart[ SKINPART_RIGHT_BOTTOM ].left,
01072 m_rcPart[ SKINPART_RIGHT_BOTTOM ].top, SRCCOPY );
01073 rcRight.bottom -= m_rcPart[ SKINPART_RIGHT_BOTTOM ].Height();
01074 }
01075
01076 if ( m_bPart[ SKINPART_LEFT ] && rcLeft.top < rcLeft.bottom && ! bCaption )
01077 {
01078 CRect* pRect = &m_rcPart[ SKINPART_LEFT ];
01079
01080 if ( m_nPart[ SKINPART_LEFT ] == SKINPARTMODE_STRETCH )
01081 {
01082 dc.SetStretchBltMode( STRETCH_DELETESCANS );
01083 dc.StretchBlt( 0, rcLeft.top, pRect->Width(), rcLeft.Height(),
01084 &m_dcSkin, pRect->left, pRect->top,
01085 pRect->Width(), pRect->Height(), SRCCOPY );
01086 }
01087 else
01088 {
01089 for ( int nY = rcLeft.top ; nY < rcLeft.bottom ; nY += pRect->Height() )
01090 {
01091 dc.BitBlt( 0, nY, pRect->Width(), min( pRect->Height(), int(rcLeft.bottom - nY) ),
01092 &m_dcSkin, pRect->left, pRect->top, SRCCOPY );
01093 }
01094 }
01095 }
01096
01097 if ( bActive == TS_FALSE && m_bPart[ SKINPART_IA_TOP ] && rcTop.left < rcTop.right )
01098 {
01099 CRect* pRect = &m_rcPart[ SKINPART_IA_TOP ];
01100
01101 if ( m_nPart[ SKINPART_IA_TOP ] == SKINPARTMODE_STRETCH )
01102 {
01103 pDC->SetStretchBltMode( STRETCH_DELETESCANS );
01104 pDC->StretchBlt( rcTop.left, 0, rcTop.Width(), pRect->Height(),
01105 &m_dcSkin, pRect->left, pRect->top,
01106 pRect->Width(), pRect->Height(), SRCCOPY );
01107 }
01108 else
01109 {
01110 for ( int nX = rcTop.left ; nX < rcTop.right ; nX += pRect->Width() )
01111 {
01112 pDC->BitBlt( nX, 0, min( pRect->Width(), int(rcTop.right - nX) ),
01113 pRect->Height(), &m_dcSkin, pRect->left, pRect->top, SRCCOPY );
01114 }
01115 }
01116 }
01117 else if ( m_bPart[ SKINPART_TOP ] && rcTop.left < rcTop.right )
01118 {
01119 CRect* pRect = &m_rcPart[ SKINPART_TOP ];
01120
01121 if ( m_nPart[ SKINPART_TOP ] == SKINPARTMODE_STRETCH )
01122 {
01123 pDC->SetStretchBltMode( STRETCH_DELETESCANS );
01124 pDC->StretchBlt( rcTop.left, 0, rcTop.Width(), pRect->Height(),
01125 &m_dcSkin, pRect->left, pRect->top,
01126 pRect->Width(), pRect->Height(), SRCCOPY );
01127 }
01128 else
01129 {
01130 for ( int nX = rcTop.left ; nX < rcTop.right ; nX += pRect->Width() )
01131 {
01132 pDC->BitBlt( nX, 0, min( pRect->Width(), int(rcTop.right - nX) ),
01133 pRect->Height(), &m_dcSkin, pRect->left, pRect->top, SRCCOPY );
01134 }
01135 }
01136 }
01137
01138 if ( m_bPart[ SKINPART_RIGHT ] && rcRight.top < rcRight.bottom && ! bCaption )
01139 {
01140 CRect* pRect = &m_rcPart[ SKINPART_RIGHT ];
01141
01142 if ( m_nPart[ SKINPART_RIGHT ] == SKINPARTMODE_STRETCH )
01143 {
01144 dc.SetStretchBltMode( STRETCH_DELETESCANS );
01145 dc.StretchBlt( rc.right - pRect->Width(), rcRight.top, pRect->Width(),
01146 rcRight.Height(), &m_dcSkin, pRect->left, pRect->top,
01147 pRect->Width(), pRect->Height(), SRCCOPY );
01148 }
01149 else
01150 {
01151 for ( int nY = rcRight.top ; nY < rcRight.bottom ; nY += pRect->Height() )
01152 {
01153 dc.BitBlt( rc.right - pRect->Width(), nY, pRect->Width(),
01154 min( pRect->Height(), int(rcRight.bottom - nY) ),
01155 &m_dcSkin, pRect->left, pRect->top, SRCCOPY );
01156 }
01157 }
01158 }
01159
01160 if ( m_bPart[ SKINPART_BOTTOM ] && rcTop.left < rcTop.right && ! bCaption )
01161 {
01162 CRect* pRect = &m_rcPart[ SKINPART_BOTTOM ];
01163
01164 if ( m_nPart[ SKINPART_TOP ] == SKINPARTMODE_STRETCH )
01165 {
01166 dc.SetStretchBltMode( STRETCH_DELETESCANS );
01167 dc.StretchBlt( rcBottom.left, rc.bottom - pRect->Height(),
01168 rcBottom.Width(), pRect->Height(),
01169 &m_dcSkin, pRect->left, pRect->top,
01170 pRect->Width(), pRect->Height(), SRCCOPY );
01171 }
01172 else
01173 {
01174 for ( int nX = rcBottom.left ; nX < rcBottom.right ; nX += pRect->Width() )
01175 {
01176 dc.BitBlt( nX, rc.bottom - pRect->Height(),
01177 min( pRect->Width(), int(rcBottom.right - nX) ), pRect->Height(),
01178 &m_dcSkin, pRect->left, pRect->top, SRCCOPY );
01179 }
01180 }
01181 }
01182
01183 if ( hIcon != NULL )
01184 {
01185 ResolveAnchor( rc, rcItem, SKINANCHOR_ICON );
01186 DrawIconEx( pDC->GetSafeHdc(), rcItem.left, rcItem.top, hIcon, 16, 16, 0, NULL, DI_NORMAL );
01187 }
01188
01189 if ( m_bCaption && strCaption.GetLength() )
01190 {
01191 CFont* pOldFont = (CFont*)pDC->SelectObject( &m_fnCaption );
01192 CSize sz = pDC->GetTextExtent( strCaption );
01193 CPoint ptCap;
01194
01195 rcItem.left = m_rcCaption.left + ( m_rcCaption.left >= 0 ? rc.left : rc.right );
01196 rcItem.right = m_rcCaption.Width() + ( m_rcCaption.Width() >= 0 ? rc.left : rc.right );
01197 rcItem.top = rc.top + m_rcCaption.top;
01198 rcItem.bottom = rc.top + m_rcCaption.bottom;
01199
01200 switch ( m_nCaptionAlign )
01201 {
01202 case 0:
01203 ptCap.x = rcItem.left + 1;
01204 break;
01205 case 1:
01206 ptCap.x = ( rcItem.left + rcItem.right ) / 2 - sz.cx / 2;
01207 ptCap.x = max( ptCap.x, rcItem.left + 1 );
01208 break;
01209 case 2:
01210 ptCap.x = rcItem.right - sz.cx - 1;
01211 ptCap.x = max( ptCap.x, rcItem.left + 1 );
01212 break;
01213 }
01214
01215 ptCap.y = ( rcItem.top + rcItem.bottom ) / 2 - sz.cy / 2;
01216
01217 pDC->SetBkMode( TRANSPARENT );
01218
01219 if ( m_crCaptionShadow != CLR_NONE )
01220 {
01221 pDC->SetTextColor( m_crCaptionShadow );
01222 pDC->ExtTextOut( ptCap.x + 1, ptCap.y + 1, ETO_CLIPPED, &rcItem, strCaption, NULL );
01223 }
01224 else if ( m_crCaptionOutline != CLR_NONE )
01225 {
01226 pDC->SetTextColor( m_crCaptionOutline );
01227 pDC->ExtTextOut( ptCap.x - 1, ptCap.y - 1, ETO_CLIPPED, &rcItem, strCaption, NULL );
01228 pDC->ExtTextOut( ptCap.x, ptCap.y - 1, ETO_CLIPPED, &rcItem, strCaption, NULL );
01229 pDC->ExtTextOut( ptCap.x + 1, ptCap.y - 1, ETO_CLIPPED, &rcItem, strCaption, NULL );
01230 pDC->ExtTextOut( ptCap.x - 1, ptCap.y, ETO_CLIPPED, &rcItem, strCaption, NULL );
01231 pDC->ExtTextOut( ptCap.x + 1, ptCap.y, ETO_CLIPPED, &rcItem, strCaption, NULL );
01232 pDC->ExtTextOut( ptCap.x - 1, ptCap.y + 1, ETO_CLIPPED, &rcItem, strCaption, NULL );
01233 pDC->ExtTextOut( ptCap.x, ptCap.y + 1, ETO_CLIPPED, &rcItem, strCaption, NULL );
01234 pDC->ExtTextOut( ptCap.x + 1, ptCap.y + 1, ETO_CLIPPED, &rcItem, strCaption, NULL );
01235 }
01236
01237 pDC->SetTextColor( bActive == TS_TRUE ? m_crCaptionText : m_crCaptionInactive );
01238 pDC->ExtTextOut( ptCap.x, ptCap.y, ETO_CLIPPED, &rcItem, strCaption, NULL );
01239 pDC->SelectObject( pOldFont );
01240 }
01241
01242 dc.BitBlt( 0, 0, rc.Width(), nCaptionHeight, pDC, 0, 0, SRCCOPY );
01243 pDC->SelectClipRgn( NULL );
01244
01245 dc.SetTextColor( 0 );
01246 }
01247
01249
01250
01251 BOOL CSkinWindow::GetPart(LPCTSTR pszName, CRect& rcPart)
01252 {
01253 CRect* pRect;
01254 if ( ! m_pPartList.Lookup( pszName, (void*&)pRect ) ) return FALSE;
01255 rcPart = *pRect;
01256 return TRUE;
01257 }
01258
01259 BOOL CSkinWindow::GetAnchor(LPCTSTR pszName, CRect& rcAnchor)
01260 {
01261 CRect* pRect;
01262 if ( ! m_pAnchorList.Lookup( pszName, (void*&)pRect ) ) return FALSE;
01263 rcAnchor = *pRect;
01264 return TRUE;
01265 }
01266
01267 BOOL CSkinWindow::GetAnchor(LPCTSTR pszName, const CRect& rcClient, CRect& rcAnchor)
01268 {
01269 CRect* pRect;
01270 if ( ! m_pAnchorList.Lookup( pszName, (void*&)pRect ) ) return FALSE;
01271 rcAnchor = *pRect;
01272 rcAnchor.OffsetRect( rcAnchor.left < 0 ? rcClient.right : rcClient.left, 0 );
01273 rcAnchor.OffsetRect( 0, rcAnchor.top < 0 ? rcClient.bottom : rcClient.top );
01274 return TRUE;
01275 }
01276
01277 BOOL CSkinWindow::PaintPartOnAnchor(CDC* pDC, const CRect& rcClient, LPCTSTR pszPart, LPCTSTR pszAnchor)
01278 {
01279 CRect rcPart, rcAnchor;
01280
01281 if ( ! GetPart( pszPart, rcPart ) ) return FALSE;
01282 if ( ! GetAnchor( pszAnchor, rcClient, rcAnchor ) ) return FALSE;
01283 if ( m_dcSkin.m_hDC == NULL ) Prepare( pDC );
01284
01285 pDC->BitBlt( rcAnchor.left, rcAnchor.top, rcPart.Width(), rcPart.Height(),
01286 &m_dcSkin, rcPart.left, rcPart.top, SRCCOPY );
01287 pDC->ExcludeClipRect( &rcAnchor );
01288
01289 return TRUE;
01290 }
01291
01292 void CSkinWindow::ResolveAnchor(const CRect& rcClient, CRect& rcAnchor, int nAnchor)
01293 {
01294 rcAnchor = m_rcAnchor[ nAnchor ];
01295 rcAnchor.OffsetRect( rcAnchor.left < 0 ? rcClient.right : rcClient.left, 0 );
01296 rcAnchor.OffsetRect( 0, rcAnchor.top < 0 ? rcClient.bottom : rcClient.top );
01297 }
01298
01300
01301
01302 void CSkinWindow::SelectRegion(CWnd* pWnd)
01303 {
01304 CRect rcWnd, rcPart;
01305 HRGN hRgn = NULL;
01306
01307 pWnd->GetWindowRect( &rcWnd );
01308 rcWnd.OffsetRect( -rcWnd.left, -rcWnd.top );
01309 rcWnd.right++; rcWnd.bottom++;
01310
01311 for ( POSITION pos = m_pRegionXML->GetElementIterator() ; pos ; )
01312 {
01313 CXMLElement* pXML = m_pRegionXML->GetNextElement( pos );
01314 if ( ! pXML->IsNamed( _T("shape") ) ) continue;
01315
01316 if ( ParseRect( pXML, &rcPart ) )
01317 {
01318 rcPart.right -= rcPart.left;
01319 rcPart.bottom -= rcPart.top;
01320 rcPart.left += rcPart.left >= 0 ? rcWnd.left : rcWnd.right + 1;
01321 rcPart.top += rcPart.top >= 0 ? rcWnd.top : rcWnd.bottom + 1;
01322 rcPart.right += rcPart.right >= 0 ? rcWnd.left : rcWnd.right + 1;
01323 rcPart.bottom += rcPart.bottom >= 0 ? rcWnd.top : rcWnd.bottom + 1;
01324 }
01325 else
01326 {
01327 rcPart.CopyRect( &rcWnd );
01328 }
01329
01330 CString strType = pXML->GetAttributeValue( _T("type") );
01331 HRGN hPart = NULL;
01332
01333 if ( strType.CompareNoCase( _T("rectangle") ) == 0 )
01334 {
01335 hPart = CreateRectRgnIndirect( &rcPart );
01336 }
01337 else if ( strType.CompareNoCase( _T("ellipse") ) == 0 )
01338 {
01339 hPart = CreateEllipticRgnIndirect( &rcPart );
01340 }
01341 else if ( strType.CompareNoCase( _T("roundRect") ) == 0 )
01342 {
01343 int nWidth, nHeight;
01344 _stscanf( pXML->GetAttributeValue( _T("size") ), _T("%i,%i"), &nWidth, &nHeight );
01345 hPart = CreateRoundRectRgn( rcPart.left, rcPart.top, rcPart.right, rcPart.bottom,
01346 nWidth, nHeight );
01347 }
01348 else
01349 {
01350 continue;
01351 }
01352
01353 if ( hPart == NULL )
01354 {
01355 if ( hRgn ) DeleteObject( hRgn );
01356 pWnd->SetWindowRgn( NULL, TRUE );
01357 return;
01358 }
01359
01360 if ( hRgn )
01361 {
01362 strType = pXML->GetAttributeValue( _T("combine") );
01363
01364 if ( strType.CompareNoCase( _T("and") ) == 0 )
01365 {
01366 CombineRgn( hRgn, hPart, hRgn, RGN_AND );
01367 }
01368 else if ( strType.CompareNoCase( _T("copy") ) == 0 )
01369 {
01370 CombineRgn( hRgn, hPart, hRgn, RGN_COPY );
01371 }
01372 else if ( strType.CompareNoCase( _T("diff") ) == 0 )
01373 {
01374 CombineRgn( hRgn, hRgn, hPart, RGN_DIFF );
01375 }
01376 else if ( strType.CompareNoCase( _T("or") ) == 0 )
01377 {
01378 CombineRgn( hRgn, hPart, hRgn, RGN_OR );
01379 }
01380 else if ( strType.CompareNoCase( _T("xor") ) == 0 )
01381 {
01382 CombineRgn( hRgn, hPart, hRgn, RGN_XOR );
01383 }
01384
01385 DeleteObject( hPart );
01386 }
01387 else
01388 {
01389 hRgn = hPart;
01390 }
01391 }
01392
01393 if ( hRgn ) pWnd->SetWindowRgn( hRgn, TRUE );
01394 }
01395
01396 CSize CSkinWindow::GetRegionSize()
01397 {
01398 if ( ! m_pRegionXML ) return CSize( 0, 0 );
01399
01400 CRect rcTotal( 0, 0, 0, 0 );
01401
01402 for ( POSITION pos = m_pRegionXML->GetElementIterator() ; pos ; )
01403 {
01404 CXMLElement* pXML = m_pRegionXML->GetNextElement( pos );
01405 CRect rcPart;
01406
01407 if ( pXML->IsNamed( _T("shape") ) && ParseRect( pXML, &rcPart ) )
01408 {
01409 rcTotal.UnionRect( &rcTotal, &rcPart );
01410 }
01411 }
01412
01413 return rcTotal.Size();
01414 }
01415
01417
01418
01419 BOOL CSkinWindow::PreBlend(CBitmap* pbmTarget, const CRect& rcTarget, const CRect& rcSource)
01420 {
01421 BITMAPINFO pTargeInfo, pImageInfo, pAlphaInfo;
01422
01423 ZeroMemory( &pTargeInfo, sizeof(pTargeInfo) );
01424 ZeroMemory( &pImageInfo, sizeof(pImageInfo) );
01425 ZeroMemory( &pAlphaInfo, sizeof(pAlphaInfo) );
01426
01427 pTargeInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
01428 pImageInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
01429 pAlphaInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
01430
01431 HDC hDC = ::GetDC( 0 );
01432 if ( theApp.m_bRTL ) theApp.m_pfnSetLayout( hDC, LAYOUT_BITMAPORIENTATIONPRESERVED );
01433
01434 if ( 0 == GetDIBits( hDC, m_bmSkin, 0, 0, NULL, &pImageInfo, DIB_RGB_COLORS ) ||
01435 0 == GetDIBits( hDC, *pbmTarget, 0, 0, NULL, &pTargeInfo, DIB_RGB_COLORS ) )
01436 {
01437 ::ReleaseDC( 0, hDC );
01438 return FALSE;
01439 }
01440
01441 BOOL bAlpha = ( 0 != GetDIBits( hDC, m_bmAlpha, 0, 0, NULL, &pAlphaInfo, DIB_RGB_COLORS ) );
01442 if ( ! bAlpha ) CopyMemory( &pAlphaInfo, &pImageInfo, sizeof(pAlphaInfo) );
01443
01444 int nTargePitch = ( ( pTargeInfo.bmiHeader.biWidth * 3 ) + 3 ) & ~3;
01445 int nImagePitch = ( ( pImageInfo.bmiHeader.biWidth * 3 ) + 3 ) & ~3;
01446 int nAlphaPitch = ( ( pAlphaInfo.bmiHeader.biWidth * 3 ) + 3 ) & ~3;
01447
01448 pTargeInfo.bmiHeader.biHeight = -abs( pTargeInfo.bmiHeader.biHeight );
01449 pTargeInfo.bmiHeader.biBitCount = 24;
01450 pTargeInfo.bmiHeader.biCompression = BI_RGB;
01451 pTargeInfo.bmiHeader.biSizeImage = -pTargeInfo.bmiHeader.biHeight * nTargePitch;
01452 pImageInfo.bmiHeader.biHeight = -abs( pImageInfo.bmiHeader.biHeight );
01453 pImageInfo.bmiHeader.biBitCount = 24;
01454 pImageInfo.bmiHeader.biCompression = BI_RGB;
01455 pImageInfo.bmiHeader.biSizeImage = -pImageInfo.bmiHeader.biHeight * nImagePitch;
01456 pAlphaInfo.bmiHeader.biHeight = -abs( pAlphaInfo.bmiHeader.biHeight );
01457 pAlphaInfo.bmiHeader.biBitCount = 24;
01458 pAlphaInfo.bmiHeader.biCompression = BI_RGB;
01459 pAlphaInfo.bmiHeader.biSizeImage = -pAlphaInfo.bmiHeader.biHeight * nAlphaPitch;
01460
01461 BYTE* pTargeData = new BYTE[ pTargeInfo.bmiHeader.biSizeImage ];
01462 BYTE* pImageData = new BYTE[ pImageInfo.bmiHeader.biSizeImage ];
01463 BYTE* pAlphaData = bAlpha ? new BYTE[ pAlphaInfo.bmiHeader.biSizeImage ] : NULL;
01464
01465 GetDIBits( hDC, *pbmTarget, 0, -pTargeInfo.bmiHeader.biHeight, pTargeData, &pTargeInfo, DIB_RGB_COLORS );
01466 GetDIBits( hDC, m_bmSkin, 0, -pImageInfo.bmiHeader.biHeight, pImageData, &pImageInfo, DIB_RGB_COLORS );
01467 if ( bAlpha ) GetDIBits( hDC, m_bmAlpha, 0, -pAlphaInfo.bmiHeader.biHeight, pAlphaData, &pAlphaInfo, DIB_RGB_COLORS );
01468
01469 int nSrcY = rcSource.top, nSrcLeft = rcSource.left * 3;
01470 int nDstY = rcTarget.top, nDstLeft = rcTarget.left * 3;
01471
01472 int nWidth = min( rcSource.Width(), rcTarget.Width() );
01473 nWidth = min( nWidth, int(pTargeInfo.bmiHeader.biWidth - rcTarget.left) );
01474 nWidth = min( nWidth, int(pImageInfo.bmiHeader.biWidth - rcSource.left) );
01475 nWidth = min( nWidth, int(pAlphaInfo.bmiHeader.biWidth - rcSource.left) );
01476
01477 for ( int nY = min( rcTarget.Height(), rcSource.Height() ) ; nY ; nY--, nSrcY++, nDstY++ )
01478 {
01479 BYTE* pTargePtr = pTargeData + nDstY * nTargePitch + nDstLeft;
01480 BYTE* pImagePtr = pImageData + nSrcY * nImagePitch + nSrcLeft;
01481 BYTE* pAlphaPtr = pAlphaData + nSrcY * nAlphaPitch + nSrcLeft;
01482
01483 if ( nDstY < 0 || nDstY >= -pTargeInfo.bmiHeader.biHeight )
01484 {
01485
01486 }
01487 else if ( nSrcY < 0 || nSrcY >= -pImageInfo.bmiHeader.biHeight )
01488 {
01489
01490 }
01491 else if ( bAlpha && nSrcY < -pAlphaInfo.bmiHeader.biHeight )
01492 {
01493 for ( int nX = nWidth ; nX ; nX-- )
01494 {
01495 register BYTE nAlpha = *pAlphaPtr; pAlphaPtr += 3;
01496 *pTargePtr = (BYTE)( ( (DWORD)(*pTargePtr) * ( 255 - nAlpha ) + (*pImagePtr) * nAlpha ) / 255 );
01497 pTargePtr++; pImagePtr++;
01498 *pTargePtr = (BYTE)( ( (DWORD)(*pTargePtr) * ( 255 - nAlpha ) + (*pImagePtr) * nAlpha ) / 255 );
01499 pTargePtr++; pImagePtr++;
01500 *pTargePtr = (BYTE)( ( (DWORD)(*pTargePtr) * ( 255 - nAlpha ) + (*pImagePtr) * nAlpha ) / 255 );
01501 pTargePtr++; pImagePtr++;
01502 }
01503 }
01504 else
01505 {
01506 CopyMemory( pTargePtr, pImagePtr, nWidth * 3 );
01507 }
01508 }
01509
01510 SetDIBits( hDC, *pbmTarget, 0, -pTargeInfo.bmiHeader.biHeight, pTargeData,
01511 &pTargeInfo, DIB_RGB_COLORS );
01512
01513 if ( bAlpha ) delete [] pAlphaData;
01514 delete [] pImageData;
01515 delete [] pTargeData;
01516
01517 ::ReleaseDC( 0, hDC );
01518
01519 return TRUE;
01520 }