📄 bcgpdrawmanager.cpp
字号:
}
int x21 = x11 + nOffset;
int x22 = x21 + (x12 - x11);
POINT points [4];
points [0].x = x11;
points [0].y = 0;
points [1].x = x12;
points [1].y = 0;
points [2].x = x22;
points [2].y = rect.Height ();
points [3].x = x21;
points [3].y = rect.Height ();
CBrush* pOldBrush = dcMem.SelectObject (&br);
dcMem.Polygon (points, 4);
dcMem.SelectObject (pOldBrush);
}
dcMem.SelectObject (pOldPen);
//--------------------------------
// Copy bitmap back to the screen:
//--------------------------------
m_dc.BitBlt (rect.left, rect.top, rect.Width (), rect.Height (), &dcMem, 0, 0, SRCCOPY);
dcMem.SelectObject (pOldBmp);
}
//************************************************************************************
BOOL CBCGPDrawManager::DrawGradientRing (CRect rect,
COLORREF colorStart, COLORREF colorFinish,
COLORREF colorBorder,
int nAngle /* 0 - 360 */,
int nWidth,
COLORREF clrFace /* = -1 */)
{
int cx = rect.Width ();
int cy = rect.Height ();
if (cx <= 4 || cy <= 4)
{
//--------------------
// Rectangle too small
//--------------------
return FALSE;
}
int xOrig = rect.left;
int yOrig = rect.top;
//--------------------------------------------
// Copy screen content into the memory bitmap:
//--------------------------------------------
CDC dcMem;
if (!dcMem.CreateCompatibleDC (&m_dc))
{
ASSERT (FALSE);
return FALSE;
}
CBitmap bmpMem;
if (!bmpMem.CreateCompatibleBitmap (&m_dc, cx, cy))
{
ASSERT (FALSE);
return FALSE;
}
CBitmap* pOldBmp = dcMem.SelectObject(&bmpMem);
ASSERT (pOldBmp != NULL);
LPBITMAPINFO lpbi;
// Fill in the BITMAPINFOHEADER
lpbi = (LPBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEADER) ];
lpbi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
lpbi->bmiHeader.biWidth = cx;
lpbi->bmiHeader.biHeight = cy;
lpbi->bmiHeader.biPlanes = 1;
lpbi->bmiHeader.biBitCount = 32;
lpbi->bmiHeader.biCompression = BI_RGB;
lpbi->bmiHeader.biSizeImage = cx * cy;
lpbi->bmiHeader.biXPelsPerMeter = 0;
lpbi->bmiHeader.biYPelsPerMeter = 0;
lpbi->bmiHeader.biClrUsed = 0;
lpbi->bmiHeader.biClrImportant = 0;
COLORREF* pBits = NULL;
HBITMAP hmbpDib = CreateDIBSection (
dcMem.m_hDC, lpbi, DIB_RGB_COLORS, (void **)&pBits,
NULL, NULL);
if (hmbpDib == NULL || pBits == NULL)
{
delete lpbi;
ASSERT (FALSE);
return FALSE;
}
dcMem.SelectObject (hmbpDib);
dcMem.BitBlt (0, 0, cx, cy, &m_dc, rect.left, rect.top, SRCCOPY);
rect.OffsetRect (-xOrig, -yOrig);
const int xCenter = (rect.left + rect.right) / 2;
const int yCenter = (rect.top + rect.bottom) / 2;
const int nSteps = 360;
const double fDelta = 2. * PI / nSteps;
const double fStart = PI * nAngle / 180;
const double fFinish = fStart + 2. * PI;
double rDelta = (double) (.5 + GetRValue (colorFinish) - GetRValue (colorStart)) / nSteps * 2;
double gDelta = (double) (.5 + GetGValue (colorFinish) - GetGValue (colorStart)) / nSteps * 2;
double bDelta = (double) (.5 + GetBValue (colorFinish) - GetBValue (colorStart)) / nSteps * 2;
for (int nLevel = 0; nLevel < nWidth; nLevel++)
{
int i = 0;
const int nRadius = min (rect.Width (), rect.Height ()) / 2;
const int nRectDelta = rect.Width () - rect.Height ();
if (clrFace != (COLORREF) -1 && nLevel == 0)
{
//---------------
// Fill interior:
//---------------
CBrush brFill (clrFace);
CBrush* pOldBrush = dcMem.SelectObject (&brFill);
CPen* pOldPen = (CPen*) dcMem.SelectStockObject (NULL_PEN);
if (nRectDelta == 0) // Circle
{
dcMem.Ellipse (rect);
}
else if (nRectDelta > 0) // Horizontal
{
dcMem.Ellipse (rect.left, rect.top, rect.left + rect.Height (), rect.bottom);
dcMem.Ellipse (rect.right - rect.Height (), rect.top, rect.right, rect.bottom);
dcMem.Rectangle (rect.left + rect.Height () / 2, rect.top, rect.right - rect.Height () / 2, rect.bottom);
}
else // Vertical
{
dcMem.Ellipse (rect.left, rect.top, rect.right, rect.top + rect.Width ());
dcMem.Ellipse (rect.left, rect.bottom - rect.Width (), rect.right, rect.bottom);
dcMem.Rectangle (rect.left, rect.top + rect.Width () / 2, rect.right, rect.bottom - rect.Width () / 2);
}
dcMem.SelectObject (pOldBrush);
dcMem.SelectObject (pOldPen);
}
int xPrev = -1;
int yPrev = -1;
for (double fAngle = fStart; fAngle < fFinish + fDelta; fAngle += fDelta, i ++)
{
const int nStep = fAngle <= (fFinish + fStart) / 2 ? i : nSteps - i;
const BYTE bR = (BYTE) max (0, min (255, (.5 + rDelta * nStep + GetRValue (colorStart))));
const BYTE bG = (BYTE) max (0, min (255, (.5 + gDelta * nStep + GetGValue (colorStart))));
const BYTE bB = (BYTE) max (0, min (255, (.5 + bDelta * nStep + GetBValue (colorStart))));
COLORREF color = nLevel == 0 && colorBorder != -1 ?
colorBorder : RGB (bR, bG, bB);
int x = xCenter + (int) (cos (fAngle) * nRadius);
int y = yCenter + (int) (sin (fAngle) * nRadius);
if (nRectDelta > 0)
{
if (x > xCenter)
{
x += (int) (.5 * nRectDelta);
}
else
{
x -= (int) (.5 * nRectDelta);
}
if (xPrev != -1 && (xPrev > xCenter) != (x > xCenter))
{
for (int x1 = min (x, xPrev); x1 < max (x, xPrev); x1++)
{
SetPixel (pBits, cx, cy, x1, y, color);
}
}
}
else if (nRectDelta < 0)
{
if (y > yCenter)
{
y -= (int) (.5 * nRectDelta);
}
else
{
y += (int) (.5 * nRectDelta);
}
if (yPrev != -1 && (yPrev > yCenter) != (y > yCenter))
{
for (int y1 = min (y, yPrev); y1 < max (y, yPrev); y1++)
{
SetPixel (pBits, cx, cy, x, y1, color);
}
}
}
SetPixel (pBits, cx, cy, x, y, color);
xPrev = x;
yPrev = y;
}
rect.DeflateRect (1, 1);
}
//--------------------------------
// Copy bitmap back to the screen:
//--------------------------------
m_dc.BitBlt (xOrig, yOrig, cx, cy, &dcMem, 0, 0, SRCCOPY);
dcMem.SelectObject (pOldBmp);
DeleteObject (hmbpDib);
delete lpbi;
return TRUE;
}
//*************************************************************************************
BOOL CBCGPDrawManager::DrawShadow (CRect rect, int nDepth,
int iMinBrightness, int iMaxBrightness,
CBitmap* pBmpSaveBottom,
CBitmap* pBmpSaveRight,
COLORREF clrBase)
// ==================================================================
//
// FUNCTION : DrawShadows ()
//
// * Description : Draws the shadow for a rectangular screen element
//
// * Authors: [Stas Levin ]
// [Timo Hummel], Modified: [8/11/99 5:06:59 PM]
//
// * Function parameters :
// [rect] - The CRect of the rectangular region to draw the
// shadow around (altough the CDC needs to be big enough
// to hold the shadow)
// ==================================================================
{
ASSERT (nDepth >= 0);
if (nDepth == 0 || rect.IsRectEmpty ())
{
return TRUE;
}
int cx = rect.Width ();
int cy = rect.Height ();
if (pBmpSaveRight != NULL && pBmpSaveRight->GetSafeHandle () != NULL &&
pBmpSaveBottom != NULL && pBmpSaveBottom->GetSafeHandle () != NULL)
{
//---------------------------------------------------
// Shadows are already implemented, put them directly
// to the DC:
//---------------------------------------------------
m_dc.DrawState (CPoint (rect.right, rect.top),
CSize (nDepth, cy + nDepth),
pBmpSaveRight, DSS_NORMAL);
m_dc.DrawState (CPoint (rect.left, rect.bottom),
CSize (cx + nDepth, nDepth),
pBmpSaveBottom, DSS_NORMAL);
return TRUE;
}
ASSERT (pBmpSaveRight == NULL || pBmpSaveRight->GetSafeHandle () == NULL);
ASSERT (pBmpSaveBottom == NULL || pBmpSaveBottom->GetSafeHandle () == NULL);
//--------------------------------------------
// Copy screen content into the memory bitmap:
//--------------------------------------------
CDC dcMem;
if (!dcMem.CreateCompatibleDC (&m_dc))
{
ASSERT (FALSE);
return FALSE;
}
//--------------------------------------------
// Gets the whole menu and changes the shadow.
//--------------------------------------------
CBitmap bmpMem;
if (!bmpMem.CreateCompatibleBitmap (&m_dc, cx + nDepth, cy + nDepth))
{
ASSERT (FALSE);
return FALSE;
}
CBitmap* pOldBmp = dcMem.SelectObject(&bmpMem);
ASSERT (pOldBmp != NULL);
BITMAPINFO bi;
// Fill in the BITMAPINFOHEADER
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biWidth = cx + nDepth;
bi.bmiHeader.biHeight = cy + nDepth;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 32;
bi.bmiHeader.biCompression = BI_RGB;
bi.bmiHeader.biSizeImage = (cx + nDepth) * (cy + nDepth);
bi.bmiHeader.biXPelsPerMeter = 0;
bi.bmiHeader.biYPelsPerMeter = 0;
bi.bmiHeader.biClrUsed = 0;
bi.bmiHeader.biClrImportant = 0;
COLORREF* pBits = NULL;
HBITMAP hmbpDib = CreateDIBSection (
dcMem.m_hDC, &bi, DIB_RGB_COLORS, (void **)&pBits,
NULL, NULL);
if (hmbpDib == NULL || pBits == NULL)
{
ASSERT (FALSE);
return FALSE;
}
dcMem.SelectObject (hmbpDib);
dcMem.BitBlt (0, 0, cx + nDepth, cy + nDepth, &m_dc, rect.left, rect.top, SRCCOPY);
//----------------------------------------------------------------------------
// Process shadowing:
// For having a very nice shadow effect, its actually hard work. Currently,
// I'm using a more or less "hardcoded" way to set the shadows (by using a
// hardcoded algorythm):
//
// This algorythm works as follows:
//
// It always draws a few lines, from left to bottom, from bottom to right,
// from right to up, and from up to left). It does this for the specified
// shadow width and the color settings.
//-----------------------------------------------------------------------------
// For speeding up things, iShadowOffset is the
// value which is needed to multiply for each shadow step
int iShadowOffset = (iMaxBrightness - iMinBrightness) / nDepth;
// Loop for drawing the shadow
// Actually, this was simpler to implement than I thought
for (int c = 0; c < nDepth; c++)
{
// Draw the shadow from left to bottom
for (int y = cy; y < cy + (nDepth - c); y++)
{
SetAlphaPixel (pBits, rect, c + nDepth, y,
iMaxBrightness - ((nDepth - c) * (iShadowOffset)), nDepth, clrBase);
}
// Draw the shadow from left to right
for (int x = nDepth + (nDepth - c); x < cx + c; x++)
{
SetAlphaPixel(pBits, rect,x, cy + c,
iMaxBrightness - ((c) * (iShadowOffset)),nDepth, clrBase);
}
// Draw the shadow from top to bottom
for (int y1 = nDepth + (nDepth - c); y1 < cy + c + 1; y1++)
{
SetAlphaPixel(pBits, rect, cx+c, y1,
iMaxBrightness - ((c) * (iShadowOffset)),
nDepth, clrBase);
}
// Draw the shadow from top to left
for (int x1 = cx; x1 < cx + (nDepth - c); x1++)
{
SetAlphaPixel (pBits, rect, x1, c + nDepth,
iMaxBrightness - ((nDepth - c) * (iShadowOffset)),
nDepth, clrBase);
}
}
//-----------------------------------------
// Copy shadowed bitmap back to the screen:
//-----------------------------------------
m_dc.BitBlt (rect.left, rect.top, cx + nDepth, cy + nDepth,
&dcMem, 0, 0, SRCCOPY);
//------------------------------------
// Save shadows in the memory bitmaps:
//------------------------------------
if (pBmpSaveRight != NULL)
{
pBmpSaveRight->CreateCompatibleBitmap (&m_dc, nDepth + 1, cy + nDepth);
dcMem.SelectObject (pBmpSaveRight);
dcMem.BitBlt (0, 0, nDepth, cy + nDepth,
&m_dc, rect.right, rect.top, SRCCOPY);
}
if (pBmpSaveBottom != NULL)
{
pBmpSaveBottom->CreateCompatibleBitmap (&m_dc, cx + nDepth, nDepth + 1);
dcMem.SelectObject (pBmpSaveBottom);
dcMem.BitBlt (0, 0, cx + nDepth, nDepth,
&m_dc, rect.left, rect.bottom, SRCCOPY);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -