?? unibutton.cpp
字號:
// UniButton.cpp : implementation file
//
#include "stdafx.h"
#include "UniButton.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CUniButton
CUniButton::CUniButton()
{
m_nColor = GetSysColor(COLOR_BTNFACE); // 取得系統顏色 -- 正常
m_sColor = m_nColor; // -- 被選擇時顏色
m_hColor = m_nColor; // -- 鼠標在按鈕上時顏色
m_dColor = m_nColor; // -- 被禁用時顏色
m_nBorder = 4;
m_pNormal = NULL;
m_hRgn = 0;
m_bHover = false;
m_bTracking = FALSE;
bSunken =false;
m_bCapture =false;
}
CUniButton::~CUniButton()
{
delete m_pNormal;
DeleteObject(m_hRgn);
}
BEGIN_MESSAGE_MAP(CUniButton, CButton)
//{{AFX_MSG_MAP(CUniButton)
ON_WM_ERASEBKGND()
ON_WM_MOUSEMOVE()
ON_WM_CREATE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
BOOL CUniButton::Create(LPCTSTR lpszCaption, DWORD dwStyle, const CPoint point, const HRGN hRgn, CWnd* pParentWnd, UINT nID, UINT nBorder, COLORREF nColor, COLORREF sColor, COLORREF hColor, COLORREF dColor)
{
m_nBorder = nBorder;
m_nColor = nColor;
m_sColor = sColor;
m_hColor = hColor;
m_dColor = dColor;
DeleteObject(m_hRgn);
m_hRgn = CreateRectRgn(0, 0, 31, 31);
CRect box(0, 0, 0, 0);
if (m_hRgn != 0)
CombineRgn(m_hRgn, hRgn, 0, RGN_COPY);
// make sure that region bounding rect is located in (0, 0)
GetRgnBox(m_hRgn, &box);
OffsetRgn(m_hRgn, -box.left, -box.top);
GetRgnBox(m_hRgn, &box);
// update position of region center for caption output
m_CenterPoint = CPoint(box.left + box.Width() /2 , box.top + box.Height() /2);
box.OffsetRect(point);
return CButton::Create(lpszCaption, dwStyle, box, pParentWnd, nID);
}
// 修改為自繪屬性
void CUniButton::PreSubclassWindow()
{
// change window style to allow owner draw
ModifyStyle(0, BS_OWNERDRAW | BS_PUSHBUTTON);
m_Font.CreateFont(
18, // nHeight
0, // nWidth
0, // nEscapement
0, // nOrientation
FW_BOLD, // nWeight
FALSE, // bItalic
FALSE, // bUnderline
0, // cStrikeOut
ANSI_CHARSET, // nCharSet
OUT_DEFAULT_PRECIS, // nOutPrecision
CLIP_DEFAULT_PRECIS, // nClipPrecision
DEFAULT_QUALITY, // nQuality
DEFAULT_PITCH | FF_SWISS, // nPitchAndFamily
_T("新宋體")); // lpszFacename
CButton::PreSubclassWindow();
}
int CUniButton::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CButton::OnCreate(lpCreateStruct) == -1)
return -1;
SetWindowRgn(m_hRgn, true);
return 0;
}
// 鼠標移動
void CUniButton::OnMouseMove(UINT nFlags, CPoint point)
{
if (HitTest(point))
{
if (!m_bCapture)
{
SetCapture();
m_bCapture = true;
}
if (!m_bHover)
{
m_bHover = true;
InvalidateRect(NULL);
}
}
else
{
if (m_bCapture)
{
ReleaseCapture();
m_bCapture = false;
}
m_bHover = false;
InvalidateRect(NULL);
}
CButton::OnMouseMove(nFlags, point);
}
// 不擦除背景
BOOL CUniButton::OnEraseBkgnd(CDC* pDC)
{
// do not erase background
return 1;
}
//////////////////////// DRAWING ROUTINES ////////////////////////////
// 繪制函數
void CUniButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
// prepare DC
CDC* pDC = CDC::FromHandle(lpDrawItemStruct -> hDC);
CRect rect1;
GetClientRect(rect1);
CRect* pRect;
pRect=&rect1;
CDC * pMemDC;
pMemDC = new CDC;
pMemDC -> CreateCompatibleDC(pDC);
UINT state = lpDrawItemStruct->itemState;
COLORREF color;
if (m_bHover)
color = m_hColor;
else
color = m_nColor;
if (state & ODS_FOCUS)
{
bSunken=false;
color = m_sColor;
}
if (state & ODS_SELECTED)
{
bSunken=true;
}
delete m_pNormal;
m_pNormal = new CBitmap;
m_pNormal -> CreateCompatibleBitmap(pDC, pRect -> Width(), pRect -> Height());
pMemDC -> SelectObject(m_pNormal);
// prepare region
HRGN hRgn = CreateRectRgn(0, 0, 0, 0);
GetWindowRgn(hRgn);
// fill rect a with transparent color and fill rgn
HBRUSH hBrush = CreateSolidBrush(color);
pMemDC -> FillSolidRect(pRect, RGB(0, 0, 0));
FillRgn(pMemDC -> GetSafeHdc(), hRgn, hBrush);
DeleteObject(hBrush);
FrameRgn3D(pMemDC -> GetSafeHdc(), hRgn, bSunken);
GetWindowRgn(hRgn);
// paint using region for clipping
::SelectClipRgn(pDC -> GetSafeHdc(), hRgn);
pDC -> BitBlt(0, 0, pRect -> Width(), pRect -> Height(), pMemDC, 0, 0, SRCCOPY);
::SelectClipRgn(pDC -> GetSafeHdc(), NULL);
DeleteObject(hRgn);
CString m_btntext;
GetWindowText(m_btntext);
if (m_btntext!="")
{
if (bSunken)
rect1.OffsetRect(-m_nBorder,-m_nBorder);
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(RGB(0,0,0));
pDC->SelectObject(&m_Font);
pDC->DrawText(m_btntext,&rect1,DT_VCENTER | DT_CENTER | DT_SINGLELINE);
}
delete pMemDC;
}
// 3D效果
void CUniButton::FrameRgn3D(HDC hDC, const HRGN hRgn, BOOL bSunken)
{
// 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
if (!bSunken) {
ltOuter = GetSysColor(COLOR_3DLIGHT);
ltInner = GetSysColor(COLOR_3DHILIGHT);
rbOuter = GetSysColor(COLOR_3DDKSHADOW);
rbInner = GetSysColor(COLOR_3DSHADOW);
}
else {
rbInner = GetSysColor(COLOR_3DLIGHT);
rbOuter = GetSysColor(COLOR_3DHILIGHT);
ltInner = GetSysColor(COLOR_3DDKSHADOW);
ltOuter = GetSysColor(COLOR_3DSHADOW);
}
CombineRgn(hBaseRgn, hRgn, 0, RGN_COPY);
OffsetRgn(hBaseRgn, 4, 4);
CombineRgn(hBaseRgn, hRgn, hBaseRgn, RGN_DIFF);
hBrush = CreateSolidBrush(ltInner);
FillRgn(hDC, hBaseRgn, hBrush);
DeleteObject(hBrush);
CombineRgn(hBaseRgn, hRgn, 0, RGN_COPY);
OffsetRgn(hBaseRgn, -4, -4);
CombineRgn(hBaseRgn, hRgn, hBaseRgn, RGN_DIFF);
hBrush = CreateSolidBrush(rbInner);
FillRgn(hDC, hBaseRgn, hBrush);
DeleteObject(hBrush);
CombineRgn(hBaseRgn, hRgn, 0, RGN_COPY);
OffsetRgn(hBaseRgn, 2, 2);
CombineRgn(hBaseRgn, hRgn, hBaseRgn, RGN_DIFF);
hBrush = CreateSolidBrush(ltOuter);
FillRgn(hDC, hBaseRgn, hBrush);
DeleteObject(hBrush);
CombineRgn(hBaseRgn, hRgn, 0, RGN_COPY);
OffsetRgn(hBaseRgn, -2, -2);
CombineRgn(hBaseRgn, hRgn, hBaseRgn, RGN_DIFF);
hBrush = CreateSolidBrush(rbOuter);
FillRgn(hDC, hBaseRgn, hBrush);
DeleteObject(hBrush);
// clean up regions
DeleteObject(hBaseRgn);
}
BOOL CUniButton::HitTest(CPoint point)
{
BOOL result = false;
// Obtain handle to window region.
HRGN hRgn = CreateRectRgn(0, 0, 0, 0);
GetWindowRgn(hRgn);
CRect rgnRect;
GetRgnBox(hRgn, &rgnRect);
// First check if point is in region bounding rect.
// Then check if point is in the region in adition to being in the bouding rect.
result = PtInRect(&rgnRect, point) && PtInRegion(hRgn, point.x, point.y);
// Clean up and exit.
DeleteObject(hRgn);
return result;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -