📄 buttonex.cpp
字号:
CPoint pt = CPoint( m_ptCentre.x - Extent.cx/2, m_ptCentre.y - Extent.cy/2 );
if (state & ODS_SELECTED)
pt.Offset(2,2);
pDC->SetBkMode(TRANSPARENT);
if (state & ODS_DISABLED)
{
pDC->DrawState(pt, Extent, strText, DSS_DISABLED, TRUE, 0, HBRUSH(NULL) );
}
else if( m_3DText )
{// changed this code to give the text a 3d-look
pDC->DrawState(pt, Extent, strText, DSS_DISABLED, TRUE, 0, HBRUSH(NULL) );
pDC->DrawState(pt, Extent, strText, DSS_NORMAL, TRUE, 0, HBRUSH(NULL) );
}
else
{
pDC->DrawState(pt, Extent, strText, DSS_NORMAL, TRUE, 0, HBRUSH(NULL) );
}
}
void CBtnEx::DrawFaceIMG(CDC * pDC, UINT state, CRect & rect, int & nRadius )
{
// draw the bmp
UINT nStyle = GetStyle();
IMAGEINFO imgInfo;
int imgCount = m_faceIMG.GetImageCount();
int imgID;
m_faceIMG.GetImageInfo( 0, &imgInfo );
CRect rcIMG(imgInfo.rcImage);
CPoint pt = CPoint( m_ptCentre.x - rcIMG.Width()/2,
m_ptCentre.y - rcIMG.Height()/2 );
if (state & ODS_DISABLED)
{
imgID = 2;
if( imgCount < 3 )
{
imgID = 0;
}
}
else if (state & ODS_SELECTED)
{
imgID = 1;
if( imgCount < 2 )
{
pt.Offset(2,2);
imgID = 0;
}
}
else if( m_bHover )
{
imgID = 3;
if( imgCount < 4 )
{
imgID = 0;
}
}
else
{
imgID = 0;
}
m_faceIMG.Draw( pDC, imgID, pt, ILD_TRANSPARENT );
}
void CBtnEx::DrawBorderOther(CDC * pDC, UINT state, CRect & rect, int & nRadius )
{
}
void CBtnEx::DrawBorderRound(CDC * pDC, UINT state, CRect & rect, int & nRadius )
{
UINT nStyle = GetStyle();
pDC->SelectStockObject(NULL_BRUSH);
// Draw the focus circle around the button for non-stretched buttons
if( (state & ODS_FOCUS)
&& m_bDrawDashedFocusCircle
&& !m_bStretch)
{
DrawCircle(pDC, m_ptCentre, nRadius--, RGB(0,0,0));
}
// Draw the raised/sunken edges of the button (unless flat)
if (nStyle & BS_FLAT)
{
if(m_bStretch)
{// for stretched buttons: draw left and right arcs and connect the with lines
CPen* oldpen;
CRect LeftBound(0,0,nRadius*2,nRadius*2);
CRect RightBound(m_ptRight.x-nRadius,0,m_ptRight.x+nRadius,nRadius*2);
oldpen = pDC->SelectObject(new CPen(PS_SOLID, 1, m_clr3dDKShadow));
pDC->Arc(LeftBound, CPoint(m_ptLeft.x,0), CPoint(m_ptLeft.x,nRadius*2));
pDC->Arc(RightBound, CPoint(m_ptRight.x,nRadius*2), CPoint(m_ptRight.x,0));
pDC->MoveTo(m_ptLeft.x,0); pDC->LineTo(m_ptRight.x,0);
pDC->MoveTo(m_ptLeft.x,nRadius*2-1); pDC->LineTo(m_ptRight.x,nRadius*2-1);
if( m_nBorder > 1 )
{
nRadius--;
LeftBound.DeflateRect(1,1);
RightBound.DeflateRect(1,1);
delete pDC->SelectObject(new CPen(PS_SOLID, 1, m_clr3dHighLight));
pDC->Arc(LeftBound, CPoint(m_ptLeft.x,1), CPoint(m_ptLeft.x,nRadius*2));
pDC->Arc(RightBound, CPoint(m_ptRight.x,nRadius*2), CPoint(m_ptRight.x,0));
pDC->MoveTo(m_ptLeft.x,1); pDC->LineTo(m_ptRight.x,1);
pDC->MoveTo(m_ptLeft.x,nRadius*2); pDC->LineTo(m_ptRight.x,nRadius*2);
}
delete pDC->SelectObject(oldpen);
}
else
{// for non-stretched buttons: draw two circles
DrawCircle(pDC, m_ptCentre, nRadius--, m_clr3dDKShadow);
if( m_nBorder > 1 )
{
DrawCircle(pDC, m_ptCentre, nRadius--, m_clr3dHighLight);
}
}
}
else
{
if ((state & ODS_SELECTED))
{// draw the circular segments for stretched AND non-stretched buttons
DrawCircleLeft(pDC, m_ptLeft, nRadius,
m_clr3dDKShadow,
m_clr3dHighLight);
DrawCircleRight(pDC, m_ptRight, nRadius,
m_clr3dDKShadow,
m_clr3dHighLight);
if( m_nBorder > 1 )
{
DrawCircleLeft(pDC, m_ptLeft, nRadius-1,
m_clr3dShadow,
m_clr3dLight);
DrawCircleRight(pDC, m_ptRight, nRadius-1,
m_clr3dShadow,
m_clr3dLight);
}
if (m_bStretch)
{// draw connecting lines for stretched buttons only
CPen* oldpen;
oldpen = pDC->SelectObject(new CPen(PS_SOLID, 1, m_clr3dDKShadow));
pDC->MoveTo(m_ptLeft.x, 1); pDC->LineTo(m_ptRight.x, 1);
delete pDC->SelectObject(new CPen(PS_SOLID, 1, m_clr3dHighLight));
pDC->MoveTo(m_ptLeft.x, m_ptLeft.y + nRadius); pDC->LineTo(m_ptRight.x, m_ptLeft.y + nRadius);
if( m_nBorder > 1 )
{
delete pDC->SelectObject(new CPen(PS_SOLID, 1, m_clr3dShadow));
pDC->MoveTo(m_ptLeft.x, 2); pDC->LineTo(m_ptRight.x, 2);
delete pDC->SelectObject(new CPen(PS_SOLID, 1, m_clr3dLight));
pDC->MoveTo(m_ptLeft.x, m_ptLeft.y + nRadius-1); pDC->LineTo(m_ptRight.x, m_ptLeft.y + nRadius-1);
}
delete pDC->SelectObject(oldpen);
}
}
else
{// draw the circular segments for stretched AND non-stretched buttons
DrawCircleLeft(pDC, m_ptLeft, nRadius,
m_clr3dHighLight,
m_clr3dDKShadow);
DrawCircleRight(pDC, m_ptRight, nRadius,
m_clr3dHighLight,
m_clr3dDKShadow);
if( m_nBorder > 1 )
{
DrawCircleLeft(pDC, m_ptLeft, nRadius - 1,
m_clr3dLight,
m_clr3dShadow);
DrawCircleRight(pDC, m_ptRight, nRadius - 1,
m_clr3dLight,
m_clr3dShadow);
}
if (m_bStretch)
{// draw connecting lines for stretched buttons only
CPen* oldpen;
oldpen = pDC->SelectObject(new CPen(PS_SOLID, 1, pDC->GetPixel(m_ptLeft.x, 1)));
pDC->MoveTo(m_ptLeft.x, 1); pDC->LineTo(m_ptRight.x, 1);
delete pDC->SelectObject(new CPen(PS_SOLID, 1, pDC->GetPixel(m_ptLeft.x, m_ptLeft.y + nRadius - 1)));
pDC->MoveTo(m_ptLeft.x, m_ptLeft.y + nRadius - 1); pDC->LineTo(m_ptRight.x, m_ptLeft.y + nRadius - 1);
if( m_nBorder > 1 )
{
delete pDC->SelectObject(new CPen(PS_SOLID, 1, pDC->GetPixel(m_ptLeft.x, 2)));
pDC->MoveTo(m_ptLeft.x, 2); pDC->LineTo(m_ptRight.x, 2);
delete pDC->SelectObject(new CPen(PS_SOLID, 1, pDC->GetPixel(m_ptLeft.x, m_ptLeft.y + nRadius)));
pDC->MoveTo(m_ptLeft.x, m_ptLeft.y + nRadius); pDC->LineTo(m_ptRight.x, m_ptLeft.y + nRadius);
}
delete pDC->SelectObject(oldpen);
}
}
}
// Draw the focus circle on the inside of the button if it is non-stretched
if ((state & ODS_FOCUS) && m_bDrawDashedFocusCircle && !m_bStretch)
DrawCircle(pDC, m_ptCentre, nRadius-2, RGB(0,0,0), TRUE);
}
void CBtnEx::DrawBorderRect(CDC * pDC, UINT state, CRect & rect, int & nRadius )
{
pDC->SelectStockObject(NULL_BRUSH);
if ((state & ODS_SELECTED))
{
pDC->Draw3dRect( rect, m_clr3dShadow, m_clr3dHighLight );
if( m_nBorder > 1 )
{
rect.DeflateRect(1,1);
pDC->Draw3dRect( rect, m_clr3dDKShadow, m_clr3dLight );
}
}
else
{
pDC->Draw3dRect( rect, m_clr3dHighLight, m_clr3dDKShadow );
if( m_nBorder > 1 )
{
rect.DeflateRect(1,1);
pDC->Draw3dRect( rect, m_clr3dLight, m_clr3dShadow );
}
}
}
BOOL CBtnEx::OnEraseBkgnd(CDC* pDC)
{
if( m_bgTransparent )
return TRUE;
pDC->SelectClipRgn(&m_rgn);
BOOL re = CButton::OnEraseBkgnd(pDC);
pDC->SelectClipRgn(NULL);
return re;
}
/////////////////////////////////////////////////////////////////////////////
// CBtnRgn
CBtnRgn::CBtnRgn()
{
m_bmp3DBorder = TRUE;
m_pattern = patternOther;
}
CBtnRgn::~CBtnRgn()
{
}
BEGIN_MESSAGE_MAP(CBtnRgn, CBtnEx)
//{{AFX_MSG_MAP(CBtnRgn)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CBtnRgn message handlers
BOOL CBtnRgn::Create(LPCTSTR lpszCaption, DWORD dwStyle,
const CPoint point, CRgn & rgn,
CWnd* pParentWnd, UINT nID)
{
// store region in member variable
m_rgn.DeleteObject();
m_rgn.CreateRectRgn( 0, 0, 0, 0 );
m_rgn.CopyRgn( &rgn );
// make sure that region bounding rect is located in (0, 0)
CRect box(0, 0, 0, 0);
m_rgn.GetRgnBox( box );
m_rgn.OffsetRgn( -box.left, -box.top );
m_rgn.GetRgnBox( box );
// update position of region center for caption output
m_ptCentre = box.CenterPoint();
//设置窗口位置
box.OffsetRect(point);
return CButton::Create(lpszCaption, dwStyle, box, pParentWnd, nID);
}
BOOL CBtnRgn::Create(LPCTSTR lpszCaption, DWORD dwStyle,
const CPoint point, CRgn & rgn,
CWnd* pParentWnd, UINT nID,
UINT nBorder,
COLORREF nColor, COLORREF sColor,
COLORREF hColor, COLORREF dColor)
{
m_nBorder = nBorder;
m_clrFaceN = nColor;
m_clrFaceS = sColor;
m_clrFaceH = hColor;
m_clrFaceD = dColor;
return Create(lpszCaption, dwStyle, point, rgn, pParentWnd, nID );
}
//////////////////////// DRAWING ROUTINES ////////////////////////////
void CBtnRgn::DrawBorderOther(CDC * pDC, UINT state, CRect & rect, int & nRadius )
{
if( m_faceIMG.GetSafeHandle() != NULL && !m_bmp3DBorder )
{//当使用BMP,没有指定使用自绘边框
return;
}
int mBorder = (m_enableFlat) ? MBORDER_FLAT : MBORDER_RISING;
if( state & ODS_SELECTED )
mBorder = MBORDER_SUNKEN;
else if( m_bHover )
mBorder = MBORDER_RISING;
FrameRgn3D( *pDC, m_rgn, mBorder );
}
void CBtnRgn::FrameRgn3D(HDC hDC, const HRGN hRgn, int mBorder)
{
// we need two differenr regions to keep base region and border region
HBRUSH hBrush;
HRGN hBaseRgn = CreateRectRgn(0, 0, 0, 0);
COLORREF ltOuter, ltInner, rbOuter, rbInner; // colors of inner and outer shadow for top-left and right-bottom corners
// decide on color scheme
switch( mBorder )
{
case MBORDER_RISING:
ltOuter = m_clr3dLight;
ltInner = m_clr3dHighLight;
rbOuter = m_clr3dDKShadow;
rbInner = m_clr3dShadow;
break;
case MBORDER_SUNKEN:
rbInner = m_clr3dLight;
rbOuter = m_clr3dHighLight;
ltInner = m_clr3dDKShadow;
ltOuter = m_clr3dShadow;
break;
case MBORDER_FLAT:
default:
return;
}
// offset highlight and shadow regions
// substract them from the base region
switch (m_nBorder)
{
case 2:
CombineRgn(hBaseRgn, hRgn, 0, RGN_COPY);
OffsetRgn(hBaseRgn, 2, 2);
CombineRgn(hBaseRgn, hRgn, hBaseRgn, RGN_DIFF);
hBrush = CreateSolidBrush(ltInner);
FillRgn(hDC, hBaseRgn, hBrush);
DeleteObject(hBrush);
CombineRgn(hBaseRgn, hRgn, 0, RGN_COPY);
OffsetRgn(hBaseRgn, -2, -2);
CombineRgn(hBaseRgn, hRgn, hBaseRgn, RGN_DIFF);
hBrush = CreateSolidBrush(rbInner);
FillRgn(hDC, hBaseRgn, hBrush);
DeleteObject(hBrush);
CombineRgn(hBaseRgn, hRgn, 0, RGN_COPY);
OffsetRgn(hBaseRgn, 1, 1);
CombineRgn(hBaseRgn, hRgn, hBaseRgn, RGN_DIFF);
hBrush = CreateSolidBrush(ltOuter);
FillRgn(hDC, hBaseRgn, hBrush);
DeleteObject(hBrush);
CombineRgn(hBaseRgn, hRgn, 0, RGN_COPY);
OffsetRgn(hBaseRgn, -1, -1);
CombineRgn(hBaseRgn, hRgn, hBaseRgn, RGN_DIFF);
hBrush = CreateSolidBrush(rbOuter);
FillRgn(hDC, hBaseRgn, hBrush);
DeleteObject(hBrush);
break;
default:
CombineRgn(hBaseRgn, hRgn, 0, RGN_COPY);
OffsetRgn(hBaseRgn, 1, 1);
CombineRgn(hBaseRgn, hRgn, hBaseRgn, RGN_DIFF);
hBrush = CreateSolidBrush(ltInner);
FillRgn(hDC, hBaseRgn, hBrush);
DeleteObject(hBrush);
CombineRgn(hBaseRgn, hRgn, 0, RGN_COPY);
OffsetRgn(hBaseRgn, -1, -1);
CombineRgn(hBaseRgn, hRgn, hBaseRgn, RGN_DIFF);
hBrush = CreateSolidBrush(rbOuter);
FillRgn(hDC, hBaseRgn, hBrush);
DeleteObject(hBrush);
break;
}
// clean up regions
DeleteObject(hBaseRgn);
}
void CBtnRgn::RgnPixelWork(CDC * pDC, CRgn * pRgn)
{
// get size of data composing region
int size = pRgn -> GetRegionData(NULL, 0);
HANDLE hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, size);
RGNDATA * pData = (RGNDATA *)GlobalLock(hData);
// retrieve region data
int res = pRgn -> GetRegionData(pData, size);
RECT * pRect = (RECT *) pData -> Buffer;
// now we know how region is represented and we are able to manipulate it as we like
for (DWORD i = 0; i < pData -> rdh.nCount; i++) {
RECT rect = *(pRect + i);
for (int x = rect.left; x < rect.right; x++)
for (int y = rect.top; y < rect.bottom; y++) {
// use SetPixel(x, y, color) to do pixel work
}
}
// free region data
GlobalUnlock(hData);
GlobalFree(hData);
}
void CBtnRgn::CopyBitmap(CBitmap * bmpD, CBitmap * bmpS, long xOff, long yOff)
{
bmpD->DeleteObject();
BITMAP bmp;
CDC dcS, dcD;
CBitmap * pS, *pD;
bmpS->GetBitmap( &bmp );
bmpD->CreateBitmapIndirect( &bmp );
dcS.CreateCompatibleDC( NULL );
dcD.CreateCompatibleDC( NULL );
pS = dcS.SelectObject( bmpS );
pD = dcD.SelectObject( bmpD );
//清空目标位图
dcD.FillSolidRect( 0, 0, bmp.bmWidth, bmp.bmHeight, RGB( 0, 0, 0 ) );
//拷贝位图
dcD.BitBlt( xOff, yOff, bmp.bmWidth, bmp.bmHeight, &dcS, 0, 0, SRCCOPY );
dcS.SelectObject( pS );
dcD.SelectObject( pD );
/*复制BMP的另一种方法
BITMAP bmp;
bmpS->GetBitmap( &bmp );
long bmpSize = long(bmp.bmWidthBytes)*long(bmp.bmHeight);
bmp.bmBits = LPVOID( new char[bmpSize] );
bmpS->GetBitmapBits( bmpSize, bmp.bmBits );
bmpD->CreateBitmapIndirect( &bmp );
delete (char*)bmp.bmBits;
*/
}
BOOL CBtnRgn::SetBMP( CBitmap * pN, CBitmap * pS, CBitmap * pH,
CBitmap * pD, COLORREF clrMask, BOOL transparent )
{
m_faceIMG.DeleteImageList();
if( pN == NULL )
{
return TRUE;
}
if( pH == NULL )
{
pH = pN;
}
if( pD == NULL )
{
pD = pN;
}
CBitmap bmpSelected;
if( pS == NULL )
{//将pN平移后放入pS中
CopyBitmap( &bmpSelected, pN, m_nBorder, m_nBorder );
}
else
{
CopyBitmap( &bmpSelected, pS );
}
if( !transparent )
{
CBitmap bmp;
BITMAP sBMP;
pN->GetBitmap( &sBMP );
m_faceIMG.Create( sBMP.bmWidth, sBMP.bmHeight, ILC_COLOR24|ILC_MASK, 0, 1 );
m_faceIMG.Add( pN, clrMask );
m_faceIMG.Add( &bmpSelected, clrMask );
m_faceIMG.Add( pD, clrMask );
m_faceIMG.Add( pH, clrMask );
}
CImg2Rgn img2Rgn;
img2Rgn.m_bmpMaskClr = clrMask;
img2Rgn.SetBMP( pN );
return img2Rgn.GetRgn( m_rgn );
}
BOOL CBtnRgn::SetFaceIMG( CBitmap * pBMP, int cx, COLORREF mask)
{
if( !CBtnEx::SetFaceIMG( pBMP, cx, mask ) )
{
return FALSE;
}
//构造透明区域的位图
CBitmap bmpRgn;
{
BITMAP sBMP;
CDC dcS, dcD;
CBitmap * pS, *pD;
pBMP->GetBitmap( &sBMP );
sBMP.bmWidth = cx;
bmpRgn.CreateBitmapIndirect( &sBMP );
dcS.CreateCompatibleDC( NULL );
dcD.CreateCompatibleDC( NULL );
pS = dcS.SelectObject( pBMP );
pD = dcD.SelectObject( &bmpRgn );
//清空目标位图
dcD.FillSolidRect( 0, 0, sBMP.bmWidth, sBMP.bmHeight, RGB( 0, 0, 0 ) );
//拷贝位图
dcD.BitBlt( 0, 0, sBMP.bmWidth, sBMP.bmHeight, &dcS, 0, 0, SRCCOPY );
dcS.SelectObject( pS );
dcD.SelectObject( pD );
}
CImg2Rgn img2Rgn;
img2Rgn.m_bmpMaskClr = mask;
img2Rgn.SetBMP( &bmpRgn );
return img2Rgn.GetRgn( m_rgn );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -