📄 superprogressctrl.cpp
字号:
if(((m_nPosition+m_nStep) >= m_nMin) &&
((m_nPosition+m_nStep) <= m_nMax))
m_nPosition += m_nStep;
else if((m_nPosition+m_nStep) < m_nMin)
m_nPosition = m_nMin;
else
m_nPosition = m_nMax;
// Invalidate the window if necessary
if(m_nPosition != oldpos)
::InvalidateRgn(m_hWnd, m_hRegion, FALSE);
return oldpos;
}
int CSuperProgressCtrl::SetFillStyle(int nStyle)
{
int oldstyle = m_nFillStyle;
// Make sure the new style is valid
ASSERT((nStyle >= 1) && (nStyle <= 4));
// Set the new fill style
m_nFillStyle = nStyle;
// Invalidate the window if necessary
if(m_nFillStyle != oldstyle)
::InvalidateRgn(m_hWnd, m_hRegion, FALSE);
// Return the old style
return oldstyle;
}
int CSuperProgressCtrl::GetFillStyle() const
{
// Return the current fill style
return m_nFillStyle;
}
void CSuperProgressCtrl::SetColours(COLORREF Colour1, COLORREF Colour2)
{
// Invalidate the window if necessary
if((Colour1 != m_Colour1) || (Colour2 != m_Colour2))
::InvalidateRgn(m_hWnd, m_hRegion, FALSE);
// Set the new colours
m_Colour1 = Colour1;
m_Colour2 = Colour2;
}
void CSuperProgressCtrl::GetColours(COLORREF* Colour1,
COLORREF* Colour2) const
{
// Return the old colours
if(Colour1) *Colour1 = m_Colour1;
if(Colour2) *Colour2 = m_Colour2;
}
COLORREF CSuperProgressCtrl::SetBackColour(COLORREF Colour)
{
COLORREF oldval = m_Background;
// Set the background colour
m_Background = Colour;
return oldval;
}
COLORREF CSuperProgressCtrl::GetBackColour() const
{
return m_Background;
}
BOOL CSuperProgressCtrl::MessageLoop() const
{
// Local variables
MSG msg;
LONG lIdle;
// Process all the messages in the message queue
while(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
if(!AfxGetApp()->PumpMessage())
{
PostQuitMessage(0);
return FALSE; // Signal WM_QUIT received
}
}
// let MFC do its idle processing
lIdle = 0;
while(AfxGetApp()->OnIdle(lIdle++));
// Signal to continue processing
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////////
// Emboss - Creates a 3D embossed effect
// Taken directly from an article by Zafir Anjum entitled
// "Emboss text and other shape on your bitmap"
///////////////////////////////////////////////////////////////////////////////////
// Returns - A new bitmap containing the resulting effect
// hBitmap - Bitmap that contains the basic text & shapes
// hbmBackGnd - Contains the color image
// hPal - Handle of palette associated with hbmBackGnd
// bRaised - True if raised effect is desired. False for sunken effect
// xDest - x coordinate - used to offset hBitmap
// yDest - y coordinate - used to offset hBitmap
// clrHightlight - Color used for the highlight edge
// clrShadow - Color used for the shadow
//
// Note - 1. Neither of the bitmap handles passed in should be selected
// in a device context.
// 2. The pixel at 0,0 in hBitmap is considered the background color
//
static
HBITMAP Emboss( HBITMAP hBitmap, HBITMAP hbmBackGnd,
HPALETTE hPal, BOOL bRaised, int xDest, int yDest,
COLORREF clrHighlight, COLORREF clrShadow )
{
const DWORD PSDPxax = 0x00B8074A;
BITMAP bmInfo ;
HBITMAP hbmOld, hbmShadow, hbmHighlight, hbmResult, hbmOldMem ;
HBRUSH hbrPat ;
HDC hDC, hColorDC, hMonoDC, hMemDC ;
if( !bRaised )
{
// Swap the highlight and shadow color
COLORREF clrTemp = clrShadow;
clrShadow = clrHighlight;
clrHighlight = clrTemp;
}
// We create two monochrome bitmaps. One of them will contain the
// highlighted edge and the other will contain the shadow. These
// bitmaps are then used to paint the highlight and shadow on the
// background image.
hbmResult = NULL ;
hDC = GetDC( NULL ) ;
// Create a compatible DCs
hMemDC = ::CreateCompatibleDC( hDC );
hMonoDC = CreateCompatibleDC( hDC );
hColorDC = CreateCompatibleDC( hDC );
if( hMemDC == NULL || hMonoDC == NULL || hColorDC == NULL )
{
if( hMemDC ) DeleteDC( hMemDC );
if( hMonoDC ) DeleteDC( hMonoDC );
if( hColorDC ) DeleteDC( hColorDC );
return NULL;
}
// Select the background image into memory DC so that we can draw it
hbmOldMem = (HBITMAP)::SelectObject( hMemDC, hbmBackGnd );
// Get dimensions of the background image
BITMAP bm;
::GetObject( hbmBackGnd, sizeof( bm ), &bm );
// Create the monochrome and compatible color bitmaps
GetObject( hBitmap, sizeof( BITMAP ), (LPSTR) &bmInfo ) ;
hbmShadow =
CreateBitmap( bmInfo.bmWidth, bmInfo.bmHeight, 1, 1, NULL ) ;
hbmHighlight =
CreateBitmap( bmInfo.bmWidth, bmInfo.bmHeight, 1, 1, NULL ) ;
hbmResult =
CreateCompatibleBitmap( hDC, bm.bmWidth, bm.bmHeight ) ;
hbmOld = (HBITMAP)SelectObject( hColorDC, hBitmap ) ;
// Set background color of bitmap for mono conversion
// We assume that the pixel in the top left corner has the background color
SetBkColor( hColorDC, GetPixel( hColorDC, 0, 0 ) ) ;
// Create the highlight bitmap.
hbmHighlight = (HBITMAP)SelectObject( hMonoDC, (HGDIOBJ) hbmHighlight ) ;
PatBlt( hMonoDC, 0, 0, bmInfo.bmWidth, bmInfo.bmHeight, WHITENESS ) ;
BitBlt( hMonoDC, 0, 0, bmInfo.bmWidth - 1, bmInfo.bmHeight - 1,
hColorDC, 1, 1, SRCCOPY ) ;
BitBlt( hMonoDC, 0, 0, bmInfo.bmWidth, bmInfo.bmHeight,
hColorDC, 0, 0, MERGEPAINT ) ;
hbmHighlight = (HBITMAP)SelectObject( hMonoDC, (HGDIOBJ) hbmHighlight ) ;
// create the shadow bitmap
hbmShadow = (HBITMAP)SelectObject( hMonoDC, (HGDIOBJ) hbmShadow ) ;
PatBlt( hMonoDC, 0, 0, bmInfo.bmWidth, bmInfo.bmHeight, WHITENESS ) ;
BitBlt( hMonoDC, 1, 1, bmInfo.bmWidth-1, bmInfo.bmHeight-1,
hColorDC, 0, 0, SRCCOPY ) ;
BitBlt( hMonoDC, 0, 0, bmInfo.bmWidth, bmInfo.bmHeight,
hColorDC, 0, 0, MERGEPAINT ) ;
hbmShadow = (HBITMAP)SelectObject( hMonoDC, (HGDIOBJ) hbmShadow ) ;
// Now let's start working on the final image
SelectObject( hColorDC, hbmResult ) ;
// Select and realize the palette if one is supplied
if( hPal && GetDeviceCaps(hDC, RASTERCAPS) & RC_PALETTE )
{
::SelectPalette( hColorDC, hPal, FALSE );
::RealizePalette(hColorDC);
}
// Draw the background image
BitBlt(hColorDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0,SRCCOPY);
// Restore the old bitmap in the hMemDC
::SelectObject( hMemDC, hbmOldMem );
// Set the background and foreground color for the raster operations
SetBkColor( hColorDC, RGB(255,255,255) ) ;
SetTextColor( hColorDC, RGB(0,0,0) ) ;
// blt the highlight edge
hbrPat = CreateSolidBrush( clrHighlight ) ;
hbrPat = (HBRUSH)SelectObject( hColorDC, hbrPat ) ;
hbmHighlight = (HBITMAP)SelectObject( hMonoDC, (HGDIOBJ) hbmHighlight ) ;
BitBlt( hColorDC, xDest, yDest, bmInfo.bmWidth, bmInfo.bmHeight,
hMonoDC, 0, 0, PSDPxax ) ;
DeleteObject( SelectObject( hColorDC, hbrPat ) ) ;
hbmHighlight = (HBITMAP)SelectObject( hMonoDC, (HGDIOBJ) hbmHighlight ) ;
// blt the shadow edge
hbrPat = CreateSolidBrush( clrShadow ) ;
hbrPat = (HBRUSH)SelectObject( hColorDC, hbrPat ) ;
hbmShadow = (HBITMAP)SelectObject( hMonoDC, (HGDIOBJ) hbmShadow ) ;
BitBlt( hColorDC, xDest, yDest, bmInfo.bmWidth, bmInfo.bmHeight,
hMonoDC, 0, 0, PSDPxax ) ;
DeleteObject( SelectObject( hColorDC, hbrPat ) ) ;
hbmShadow = (HBITMAP)SelectObject( hMonoDC, (HGDIOBJ) hbmShadow ) ;
// select old bitmap into color DC
SelectObject( hColorDC, hbmOld ) ;
DeleteObject( (HGDIOBJ) hbmShadow ) ;
DeleteObject( (HGDIOBJ) hbmHighlight ) ;
ReleaseDC( NULL, hDC ) ;
return ( hbmResult ) ;
}
void CSuperProgressCtrl::OnPaint()
{
// Note: It is very easy to fill in the shape of the bitmap,
// a result of the SetWindowRgn() call in the Create()
// function. The only clipping we have to perform is
// with a call to SelectClipRgn()
// Local Variables
CPaintDC dc(this); // device context for painting
CDC memDC; // memory device context (eliminate flicker)
HBITMAP hbmBack; // bitmap for emboss background
HBITMAP hbmEmboss; // bitmap for the embossing
HBITMAP hOldBitmap; // Save the device context state...
CRect rect; // client/region area rectangle
int nRange; // The range of the progress control
BYTE rs, gs, bs; // Starting red, green and blue values
BYTE re, ge, be; // Ending red, green and blue values
float red, green, blue; // Current colour components
float rstep, gstep, bstep; // Colour step values
int xPos, yPos; // Counters for drawing gradients quickly
// Get the client area
GetClientRect(rect);
// Create the memory device contexts
memDC.CreateCompatibleDC(&dc);
// Create and select a bitmap to use for the device context
hbmBack = CreateCompatibleBitmap(dc.GetSafeHdc(), rect.Width(), rect.Height());
if(!hbmBack)
return;
hOldBitmap = (HBITMAP)SelectObject(memDC.GetSafeHdc(), hbmBack);
// Colour in the bitmap background
memDC.FillSolidRect(rect, m_Background);
SelectClipRgn(memDC.GetSafeHdc(), m_hRegion);
// Fill the area
nRange = m_nMax - m_nMin + 1;
if((m_nFillStyle == SP_FILL_HORZGRAD) ||
(m_nFillStyle == SP_FILL_VERTGRAD))
{
// Get the starting and ending colour components
rs = GetRValue(m_Colour1); re = GetRValue(m_Colour2);
gs = GetGValue(m_Colour1); ge = GetGValue(m_Colour2);
bs = GetBValue(m_Colour1); be = GetBValue(m_Colour2);
}
switch(m_nFillStyle)
{
case SP_FILL_VERT:
// Fill in the rectangle
memDC.FillSolidRect(rect.left, rect.top-1,
rect.Width(), ((m_nPosition-m_nMin)*(rect.Height()+2)/nRange)+1,
m_Colour1);
break;
case SP_FILL_HORZ:
// Fill in the rectangle
memDC.FillSolidRect(rect.left-1, rect.top,
((m_nPosition-m_nMin)*(rect.Width()+2)/nRange)+1, rect.Height(),
m_Colour1);
break;
case SP_FILL_VERTGRAD:
// Get the initial colour values
red = (float)rs;
green = (float)gs;
blue = (float)bs;
// Get the colour step values
rstep = (float)(re - rs) / rect.Height();
gstep = (float)(ge - gs) / rect.Height();
bstep = (float)(be - bs) / rect.Height();
yPos = rect.top-1;
while(yPos+1 <= ((m_nPosition-m_nMin)*(rect.Height()+2))/nRange)
{
// Fill in the current rectangle
memDC.FillSolidRect(rect.left, yPos, rect.Width(), 1,
RGB((int)red, (int)green, (int)blue));
// Get the next colour to use
red += rstep; green += gstep; blue += bstep;
// Get the next rectangle
yPos++;
}
break;
case SP_FILL_HORZGRAD:
// Get the initial colour values
red = (float)rs;
green = (float)gs;
blue = (float)bs;
// Get the colour step values
rstep = (float)(re - rs) / rect.Width();
gstep = (float)(ge - gs) / rect.Width();
bstep = (float)(be - bs) / rect.Width();
xPos = rect.left-1;
while(xPos+1 <= ((m_nPosition-m_nMin)*(rect.Width()+2))/nRange)
{
// Fill in the current rectangle
memDC.FillSolidRect(xPos, rect.top, 1, rect.Height(),
RGB((int)red, (int)green, (int)blue));
// Get the next colour to use
red += rstep; green += gstep; blue += bstep;
// Get the next rectangle
xPos++;
}
break;
}
// Emboss the bitmap on the device context
SelectObject(memDC.GetSafeHdc(), hOldBitmap);
hbmEmboss = Emboss(m_hbmArea, hbmBack, NULL, FALSE, 0, 0,
GetSysColor(COLOR_3DHILIGHT),
GetSysColor(COLOR_3DSHADOW));
SelectObject(memDC.GetSafeHdc(), hbmEmboss);
// Copy to the screen
dc.BitBlt(0, 0, rect.Width(), rect.Height(), &memDC, 0, 0, SRCCOPY);
// Cleanup
SelectObject(memDC.GetSafeHdc(), hOldBitmap);
DeleteObject(hbmBack);
DeleteObject(hbmEmboss);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -