#pragma once
#include "afxwin.h"
#include
#include
#pragma comment(lib, "gdiplus.lib")
using namespace Gdiplus;
class CButtonIT : public CButton
{
public:
CButtonIT();
virtual ~CButtonIT();
DECLARE_MESSAGE_MAP()
public:
enum ButtonType
{
PUSHBUTTON, // 普通按钮
CHECKBOX, // 复选框
RADIOBUTTON, // 单选按钮
};
// 按钮状态,即鼠标与按钮的位置
enum ButtonState
{
MOUSE_OUT = 0, // 鼠标在按钮外面
MOUSE_IN, // 鼠标在按钮里面
MOUSE_DOWN, // 按钮按下
MOUSE_FOCUS, // 按钮获得焦点
MOUSE_DISABLE // 按钮禁用
};
// 图像和文字位置
enum ButtonImgTextPosion
{
IT_CENTER, // 图像和文字重叠居中
IT_OUT_LEFT, // 文字在图像外面,及左边
IT_OUT_TOP, // 文字在图像外面,及右边
IT_OUT_RIGHT, // 文字在图像外面,及上面
IT_OUT_BOTTOM, // 文字在图像外面,及下面
IT_IN_LEFT, // 文字在图像里面,及左边
IT_IN_TOP, // 文字在图像里面,及右边
IT_IN_RIGHT, // 文字在图像里面,及上面
IT_IN_BOTTOM // 文字在图像里面,及下面
};
protected:
virtual void PreSubclassWindow();
public:
void FreeImagesResources();
void SetFrameColors(const Color& crOut = Color(0, 255, 255, 255)
, const Color& crIn = Color(0, 255, 255, 255)
, const Color& crDown = Color(0, 255, 255, 255)
, const Color& crFocus = Color(0, 255, 255, 255)
, const Color& crDisable = Color(0, 255, 255, 255));
void SetBackgroundColors(const Color& crOut = Color(0, 220, 220, 247)
, const Color& crIn = Color(0, 240, 240, 240)
, const Color& crDown = Color(0, 240, 240, 240)
, const Color& crFocus = Color(0, 240, 240, 240)
, const Color& crDisable = Color(0, 240, 240, 240));
void SetFontFamilys(LPCTSTR lpszOut = _T("宋体")
, LPCTSTR lpszIn = _T("宋体")
, LPCTSTR lpszDown = _T("宋体")
, LPCTSTR lpszFocus = _T("宋体")
, LPCTSTR lpszDisable = _T("宋体"));
void SetFontSizes(const float& sizeOut = 16
, const float& sizeIn = 16
, const float& sizeDown = 16
, const float& sizeFocus = 16
, const float& sizeDisable = 16);
void SetFontStyles(const FontStyle& fsOut = FontStyleRegular
, const FontStyle& fsIn = FontStyleRegular
, const FontStyle& fsDown = FontStyleRegular
, const FontStyle& fsFocus = FontStyleRegular
, const FontStyle& fsDisable = FontStyleRegular);
void SetTextColors(const Color& crOut = Color(255, 0, 0, 0)
, const Color& crIn = Color(255, 0, 0, 0)
, const Color& crDown = Color(255, 0, 0, 0)
, const Color& crFocus = Color(255, 0, 0, 200)
, const Color& crDisable = Color(255, 0, 0, 0));
void InitToolTip();
void SetTooltipText(LPCTSTR lpszText, BOOL isActivate = TRUE);
void ActivateTooltip(BOOL isEnable = TRUE);
void EnableBalloonTooltip(BOOL isEnable);
virtual BOOL PreTranslateMessage(MSG* pMsg);
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
Status LoadImages(UINT nImageOut, UINT nImageIn = NULL, UINT nImageDown = NULL, UINT nImageFocus = NULL, UINT nImageDisable = NULL);
Status LoadImages(LPCTSTR lpImageOut, LPCTSTR lpImageIn = NULL, LPCTSTR lpImageDown = NULL, LPCTSTR lpImageFocus = NULL, LPCTSTR lpImageDisable = NULL);
inline void SetImgTextPosition(ButtonImgTextPosion btPos);
inline void SetWindowText(LPCTSTR lpszString);
inline void SetBmpTextDistance(BYTE distance);
void SetHitOffset(byte offset);
inline byte GetIndex();
void GetImageTextRect(LPRECT lpRectItem, LPRECT lpRectImage, LPRECT lpRectText);
virtual void DrawImage(Graphics& graphics, LPRECT lpRectImage);
virtual void DrawText(Graphics& graphics, LPRECT lpRectText);
virtual void DrawRoundRectange(Graphics& graphics, LPRECT lpRect, Color& color);
virtual void FillRoundRectangle(Graphics& graphics, LPRECT lpRect, Color& color);
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
LRESULT OnMouseLeave(WPARAM wParam, LPARAM lParam);
afx_msg void OnKillFocus(CWnd* pNewWnd);
private:
ULONG_PTR m_gdiplusToken;
Gdiplus::GdiplusStartupInput m_gdiplusStartupInput;
const static BYTE BTN_STATES = 5;
//const double EPSINON; // 最小精度
const int ROUND_RADIUS; // 圆角半径
byte m_type; // 按钮类型,为ButtonType中的值之一
byte m_state; // 按钮状态,为ButtonState中的值之一,但不表示是否拥有焦点,用m_isFocus表示
byte m_itPosition; // 图像和文字位置,为ButtonImgTextPosion中的值之一
byte m_hitOffset; // 单击时,图像文字偏移量
BYTE m_itDistance;
bool m_isFocus; // 表示是否获得焦点
CRect m_frameRect; // 边框区域
CRect m_drawRect; // 绘画背景按钮文字区域
CRect m_imgRect; // 图像区域
CRect m_textRect; // 文字区域
//
CDC m_bgDC;
CBitmap m_bgBmp;
Image* m_pImgs[BTN_STATES];
Color m_frameColors[BTN_STATES]; // button background color
Color m_bgColors[BTN_STATES]; // button background color
CString m_text; // button caption
CString m_fontNames[BTN_STATES];
float m_fontSizes[BTN_STATES];
FontStyle m_fontStyles[BTN_STATES];
Color m_fontColors[BTN_STATES];
CToolTipCtrl m_tooltip;
DWORD m_dwTooltipStyle; // Style of tooltip control
BOOL m_isTracking;
};
inline byte CButtonIT::GetIndex()
{
byte index;
if (m_isFocus && m_state == MOUSE_OUT)
{
index = MOUSE_FOCUS;
}
else
{
index = m_state;
}
if (m_pImgs[index] == NULL)
{
index = 0;
}
return index;
}
inline void CButtonIT::SetImgTextPosition(ButtonImgTextPosion btPos)
{
m_itPosition = btPos;
GetImageTextRect(m_drawRect, m_imgRect, m_textRect);
}
inline void CButtonIT::SetWindowText(LPCTSTR lpszString)
{
m_text = lpszString;
GetImageTextRect(m_drawRect, m_imgRect, m_textRect);
}
inline void CButtonIT::SetBmpTextDistance(BYTE distance)
{
m_itDistance = distance;
GetImageTextRect(m_drawRect, m_imgRect, m_textRect);
}
///
#include "StdAfx.h"
#include "ButtonIT.h"
#include
CButtonIT::CButtonIT(void)
: ROUND_RADIUS(5)
, m_type(PUSHBUTTON)
, m_state(MOUSE_OUT)
, m_itPosition(IT_OUT_BOTTOM)
, m_hitOffset(2)
, m_isFocus(false)
, m_frameRect(CRect(0,0,0,0))
, m_drawRect(CRect(0,0,0,0))
, m_imgRect(CRect(0,0,0,0))
, m_textRect(CRect(0,0,0,0))
, m_dwTooltipStyle(0)
, m_itDistance(2)
, m_isTracking(FALSE)
{
// 初始化GDI+
Gdiplus::GdiplusStartup(&m_gdiplusToken, &m_gdiplusStartupInput, NULL);
for (int i(0); i < BTN_STATES; ++i)
{
m_pImgs[i] = NULL;
}
SetFontFamilys();
SetFontSizes();
SetFontStyles();
SetTextColors();
SetFrameColors();
SetBackgroundColors();
}
CButtonIT::~CButtonIT(void)
{
// 清理所有GDI+资源
Gdiplus::GdiplusShutdown(m_gdiplusToken);
FreeImagesResources();
if (m_tooltip.m_hWnd)
{
m_tooltip.DestroyWindow();
}
}
BEGIN_MESSAGE_MAP(CButtonIT, CButton)
ON_WM_ERASEBKGND()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
ON_WM_KILLFOCUS()
END_MESSAGE_MAP()
void CButtonIT::FreeImagesResources()
{
for (int i(0); i < BTN_STATES; ++i)
{
if (m_pImgs[i])
{
delete m_pImgs[i];
m_pImgs[i] = NULL;
}
}
}
void CButtonIT::PreSubclassWindow()
{
m_type = GetButtonStyle(); // get specific BS_ styles
if ((m_type & BS_AUTOCHECKBOX) == BS_AUTOCHECKBOX)
{
m_type = CHECKBOX;
}
else if ((m_type & BS_AUTORADIOBUTTON) == BS_AUTORADIOBUTTON)
{
m_type = RADIOBUTTON;
}
else
{
m_type = PUSHBUTTON;
}
if (!IsWindowEnabled())
{
m_state = MOUSE_DISABLE;
}
GetWindowText(m_text);
InitToolTip();
ModifyStyle(NULL, BS_OWNERDRAW);
//设置按钮的有效区域
GetClientRect(&m_drawRect);
m_frameRect = m_drawRect;
m_drawRect.DeflateRect(1,1,1,1);
GetImageTextRect(m_drawRect, m_imgRect, m_textRect);
//有效区域为一个角半径为5的圆角矩形
CRgn rgn;
rgn.CreateRoundRectRgn(m_frameRect.left, m_frameRect.top, m_frameRect.right, m_frameRect.bottom, ROUND_RADIUS, ROUND_RADIUS);
SetWindowRgn(rgn, TRUE);
rgn.DeleteObject();
CButton::PreSubclassWindow();
}
void CButtonIT::SetFontFamilys(LPCTSTR lpszOut
, LPCTSTR lpszIn
, LPCTSTR lpszDown
, LPCTSTR lpszFocus
, LPCTSTR lpszDisable)
{
m_fontNames[MOUSE_OUT] = lpszOut;
m_fontNames[MOUSE_IN] = lpszIn;
m_fontNames[MOUSE_DOWN] = lpszDown;
m_fontNames[MOUSE_FOCUS] = lpszFocus;
m_fontNames[MOUSE_DISABLE] = lpszDisable;
}
void CButtonIT::SetFontSizes(const float& sizeOut
, const float& sizeIn
, const float& sizeDown
, const float& sizeFocus
, const float& sizeDisable)
{
m_fontSizes[MOUSE_OUT] = sizeOut;
m_fontSizes[MOUSE_IN] = sizeIn;
m_fontSizes[MOUSE_DOWN] = sizeDown;
m_fontSizes[MOUSE_FOCUS] = sizeFocus;
m_fontSizes[MOUSE_DISABLE] = sizeDisable;
}
void CButtonIT::SetFontStyles(const FontStyle& fsOut
, const FontStyle& fsIn
, const FontStyle& fsDown
, const FontStyle& fsFocus
, const FontStyle& fsDisable)
{
m_fontStyles[MOUSE_OUT] = fsOut;
m_fontStyles[MOUSE_IN] = fsIn;
m_fontStyles[MOUSE_DOWN] = fsDown;
m_fontStyles[MOUSE_FOCUS] = fsFocus;
m_fontStyles[MOUSE_DISABLE] = fsDisable;
}
void CButtonIT::SetTextColors(const Color& crOut /* = Color */
, const Color& crIn /* = Color */
, const Color& crDown /* = Color */
, const Color& crFocus /* = Color */
, const Color& crDisable /* = Color */)
{
m_fontColors[MOUSE_OUT] = crOut;
m_fontColors[MOUSE_IN] = crIn;
m_fontColors[MOUSE_DOWN] = crDown;
m_fontColors[MOUSE_FOCUS] = crFocus;
m_fontColors[MOUSE_DISABLE] = crDisable;
}
void CButtonIT::SetFrameColors(const Color& crOut /* = Color */
, const Color& crIn /* = Color */
, const Color& crDown /* = Color */
, const Color& crFocus /* = Color */
, const Color& crDisable /* = Color */)
{
m_frameColors[MOUSE_OUT] = crOut;
m_frameColors[MOUSE_IN] = crIn;
m_frameColors[MOUSE_DOWN] = crDown;
m_frameColors[MOUSE_FOCUS] = crFocus;
m_frameColors[MOUSE_DISABLE] = crDisable;
}
void CButtonIT::SetBackgroundColors(const Color& crOut /* = Color */
, const Color& crIn /* = Color */
, const Color& crDown /* = Color */
, const Color& crFocus /* = Color */
, const Color& crDisable /* = Color */)
{
m_bgColors[MOUSE_OUT] = crOut;
m_bgColors[MOUSE_IN] = crIn;
m_bgColors[MOUSE_DOWN] = crDown;
m_bgColors[MOUSE_FOCUS] = crFocus;
m_bgColors[MOUSE_DISABLE] = crDisable;
}
void CButtonIT::InitToolTip()
{
if (m_tooltip.m_hWnd == NULL)
{
m_tooltip.Create(this, m_dwTooltipStyle);
m_tooltip.Activate(FALSE);
m_tooltip.SendMessage(TTM_SETMAXTIPWIDTH, 0, 400);
}
}
void CButtonIT::SetTooltipText(LPCTSTR lpszText, BOOL isActivate)
{
if (lpszText)
{
InitToolTip();
if (m_tooltip.GetToolCount() == 0)
{
CRect rectBtn;
GetClientRect(rectBtn);
m_tooltip.AddTool(this, lpszText, rectBtn, 1);
}
m_tooltip.UpdateTipText(lpszText, this, 1);
m_tooltip.Activate(isActivate);
}
}
void CButtonIT::ActivateTooltip(BOOL isActivate)
{
if (m_tooltip.GetToolCount() > 0)
{
m_tooltip.Activate(isActivate);
}
}
// 必须调用SetTooltipText,重新设置文字
void CButtonIT::EnableBalloonTooltip(BOOL isEnable)
{
if (m_tooltip.m_hWnd)
{
m_tooltip.DestroyWindow();
}
if (isEnable)
{
m_dwTooltipStyle |= TTS_BALLOON;
}
else
{
m_dwTooltipStyle = NULL;
}
InitToolTip();
}
BOOL CButtonIT::PreTranslateMessage(MSG* pMsg)
{
m_tooltip.RelayEvent(pMsg);
return CButton::PreTranslateMessage(pMsg);
}
BOOL CButtonIT::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}
Status CButtonIT::LoadImages(UINT nImageOut, UINT nImageIn /* = NULL */, UINT nImageDown /* = NULL */, UINT nImageFocus /* = NULL */, UINT nImageDisable /* = NULL */)
{
return LoadImages(MAKEINTRESOURCE(nImageOut)
, MAKEINTRESOURCE(nImageIn)
, MAKEINTRESOURCE(nImageDown)
, MAKEINTRESOURCE(nImageFocus)
, MAKEINTRESOURCE(nImageDisable));
}
Status CButtonIT::LoadImages(LPCTSTR lpImageOut, LPCTSTR lpImageIn /* = NULL */, LPCTSTR lpImageDown /* = NULL */, LPCTSTR lpImageFocus /* = NULL */, LPCTSTR lpImageDisable /* = NULL */)
{
Status status = GenericError;
try
{
if (lpImageOut)
{
Image* pImage(NULL);
pImage = new Image(lpImageOut);
status = pImage->GetLastStatus();
if(status != Ok)
{
m_pImgs[MOUSE_OUT] = NULL;
throw false;
}
else
{
m_pImgs[MOUSE_OUT] = pImage;
}
}
else
{
m_pImgs[MOUSE_OUT] = NULL;
throw false;
}
if (lpImageIn == NULL)
{
lpImageIn = lpImageOut;
}
if (lpImageDown == NULL)
{
lpImageDown = lpImageOut;
}
if (lpImageFocus == NULL)
{
lpImageFocus = lpImageOut;
}
if (lpImageDisable == NULL)
{
lpImageDisable = lpImageOut;
}
if (lpImageIn)
{
Image* pImage(NULL);
pImage = new Image(lpImageIn);
status = pImage->GetLastStatus();
if(status != Ok)
{
m_pImgs[MOUSE_IN] = NULL;
throw false;
}
else
{
m_pImgs[MOUSE_IN] = pImage;
}
}
if (lpImageDown)
{
Image* pImage(NULL);
pImage = new Image(lpImageDown);
status = pImage->GetLastStatus();
if(status != Ok)
{
m_pImgs[MOUSE_DOWN] = NULL;
throw false;
}
else
{
m_pImgs[MOUSE_DOWN] = pImage;
}
}
if (lpImageFocus)
{
Image* pImage(NULL);
pImage = new Image(lpImageFocus);
status = pImage->GetLastStatus();
if(status != Ok)
{
m_pImgs[MOUSE_FOCUS] = NULL;
throw false;
}
else
{
m_pImgs[MOUSE_FOCUS] = pImage;
}
}
if (lpImageDisable)
{
Image* pImage(NULL);
pImage = new Image(lpImageDisable);
status = pImage->GetLastStatus();
if(status != Ok)
{
m_pImgs[MOUSE_DISABLE] = NULL;
throw false;
}
else
{
m_pImgs[MOUSE_DISABLE] = pImage;
}
}
}
catch (...)
{
}
GetImageTextRect( m_drawRect, m_imgRect, m_textRect);
return status;
}
void CButtonIT::GetImageTextRect(LPRECT lpRectItem, LPRECT lpRectImage, LPRECT lpRectText)
{
// 按钮高宽
UINT width(lpRectItem->right - lpRectItem->left);
UINT height(lpRectItem->bottom - lpRectItem->top);
CClientDC dc(this);
Gdiplus::Graphics graphics(dc);
FontFamily fontFamily(m_fontNames[0]);
Gdiplus::Font font(&fontFamily, m_fontSizes[0], m_fontStyles[0], UnitPixel);
RectF outrect;
graphics.MeasureString(m_text, m_text.GetLength(), &font, RectF(0,0,0,0), &outrect);
UINT textWidth = static_cast
(outrect.Width);
UINT textHeight = static_cast
(outrect.Height);
if (textWidth > width)
{
textWidth = width;
}
if (textHeight > height)
{
textHeight = height;
}
lpRectImage->left = 0;
lpRectImage->top = 0;
lpRectImage->right = 0;
lpRectImage->bottom = 0;
lpRectText->left = 0;
lpRectText->top = 0;
lpRectText->right = 0;
lpRectText->bottom = 0;
if (m_pImgs[0] == NULL)
{
lpRectText->left = lpRectItem->left;
lpRectText->top = lpRectItem->top;
lpRectText->right = lpRectItem->right;
lpRectText->bottom = lpRectItem->bottom;
// 文字居中
lpRectText->left += (width - textWidth) / 2;
lpRectText->top += (height - textHeight) / 2;
lpRectText->right = lpRectText->left + textWidth;
lpRectText->bottom = lpRectText->top + textWidth;
}
else
{
lpRectImage->left = lpRectItem->left;
lpRectImage->top = lpRectItem->top;
lpRectImage->right = lpRectItem->right;
lpRectImage->bottom = lpRectItem->bottom;
UINT imgWidth = m_pImgs[0]->GetWidth();
UINT imgHeight = m_pImgs[0]->GetHeight();
if (imgWidth > width)
{
imgWidth = width;
}
if (imgHeight > height)
{
imgHeight = height;
}
// 计算位置是否已经完成
bool isFinished(true);
if (!m_text.IsEmpty())
{
switch (m_itPosition)
{
case IT_OUT_LEFT:
{
// 图像文字水平排列宽度
UINT btWidth = textWidth + imgWidth + m_itDistance;
// 图像 + 文字 + 间隔 宽度 <= 按钮宽度
if (btWidth <= width)
{
// | text Bmp |
lpRectText->left = (width - btWidth) / 2;
lpRectText->top += (height - textHeight) / 2; // 高居中
lpRectText->right = lpRectText->left + textWidth;
lpRectText->bottom = lpRectText->top + textHeight;
lpRectImage->left = lpRectText->right + m_itDistance;
lpRectImage->top += (height - imgHeight) / 2; // 高居中
lpRectImage->right = lpRectImage->left + imgWidth;
lpRectImage->bottom = lpRectImage->top + imgHeight;
}
// 两边对齐,中间交叉
else
{
lpRectText->left = 1;
lpRectText->top += (height - textHeight) / 2; // 高居中
lpRectText->right = lpRectText->left + textWidth;
lpRectText->bottom = lpRectText->top + textHeight;
lpRectImage->right = width - 1;
lpRectImage->top += (height - imgHeight) / 2; // 高居中
lpRectImage->left = lpRectImage->right - imgWidth;
lpRectImage->bottom = lpRectImage->top + imgHeight;
}
}
break;
case IT_OUT_TOP:
{
// 图像文字垂直排列宽度
UINT btHeight = textHeight + imgHeight + m_itDistance;
// 图像 + 文字 + 间隔 宽度 <= 按钮宽度
if (btHeight <= height)
{
// | text |
// | Bmp |
lpRectText->left += (width - textWidth) / 2; // 左 居中
lpRectText->top = (height - btHeight) / 2;
lpRectText->right = lpRectText->left + textWidth;
lpRectText->bottom = lpRectText->top + textHeight;
lpRectImage->left += (width - imgWidth) / 2; // 左 居中
lpRectImage->top = lpRectText->bottom + m_itDistance;
lpRectImage->right = lpRectImage->left + imgWidth;
lpRectImage->bottom = lpRectImage->top + imgHeight;
}
// 两边对齐,中间交叉
else
{
lpRectText->left += (width - textWidth) / 2; // 左 居中
lpRectText->top = 1;
lpRectText->right = lpRectText->left + textWidth;
lpRectText->bottom = lpRectText->top + textHeight;
lpRectImage->left += (width - imgWidth) / 2; // 左 居中
lpRectImage->bottom = height - 1;
lpRectImage->top = lpRectImage->bottom - imgHeight;
lpRectImage->right = lpRectImage->left + imgWidth;
}
}
break;
case IT_OUT_RIGHT:
{
// 图像文字水平排列宽度
UINT btWidth = textWidth + imgWidth + m_itDistance;
// 图像 + 文字 + 间隔 宽度 <= 按钮宽度
if (btWidth <= width)
{
// | Bmp text |
lpRectImage->left = (width - btWidth) / 2;
lpRectImage->top += (height - imgHeight) / 2; // 高居中
lpRectImage->right = lpRectImage->left + imgWidth;
lpRectImage->bottom = lpRectImage->top + imgHeight;
lpRectText->left = lpRectImage->right + m_itDistance;
lpRectText->top += (height - textHeight) / 2; // 高居中
lpRectText->right = lpRectText->left + textWidth;
lpRectText->bottom = lpRectText->top + textHeight;
}
// 两边对齐,中间交叉
else
{
lpRectImage->left = 1;
lpRectImage->top += (height - imgHeight) / 2; // 高居中
lpRectImage->right = lpRectImage->left + imgWidth;
lpRectImage->bottom = lpRectImage->top + imgHeight;
lpRectText->right = width - 1;
lpRectText->top += (height - textHeight) / 2; // 高居中
lpRectText->left = lpRectText->right - textWidth;
lpRectText->bottom = lpRectText->top + textHeight;
}
}
break;
case IT_OUT_BOTTOM:
{
// 图像文字垂直排列宽度
UINT btHeight = textHeight + imgHeight + m_itDistance;
// 图像 + 文字 + 间隔 宽度 <= 按钮宽度
if (btHeight <= height)
{
// | Bmp |
// | text |
lpRectImage->left += (width - imgWidth) / 2; // 左 居中
lpRectImage->top = (height - btHeight) / 2;
lpRectImage->right = lpRectImage->left + imgWidth;
lpRectImage->bottom = lpRectImage->top + imgHeight;
lpRectText->left += (width - textWidth) / 2; // 左 居中
lpRectText->top = lpRectImage->bottom + m_itDistance;
lpRectText->right = lpRectText->left + textWidth;
lpRectText->bottom = lpRectText->top + textHeight;
}
// 两边对齐,中间交叉
else
{
lpRectImage->left += (width - imgWidth) / 2; // 左 居中
lpRectImage->top = 1;
lpRectImage->right = lpRectImage->left + imgWidth;
lpRectImage->bottom = lpRectImage->top + imgHeight;
lpRectText->left += (width - textWidth) / 2; // 左 居中
lpRectText->bottom = height - 1;
lpRectText->right = lpRectText->left + textWidth;
lpRectText->top = lpRectText->bottom - textHeight;
}
}
break;
default:
isFinished = false;
break;
}
}
else
{
isFinished = false;
}
if (isFinished == false)
{
// 图像居中
lpRectImage->left += (width - imgWidth) / 2;
lpRectImage->top += (height - imgHeight) / 2;
lpRectImage->right = lpRectImage->left + imgWidth;
lpRectImage->bottom = lpRectImage->top + imgHeight;
switch (m_itPosition)
{
case IT_IN_LEFT:
{
lpRectText->left = lpRectImage->left + m_itDistance;
lpRectText->top += (height - textHeight) / 2; // 高居中
lpRectText->right = lpRectText->left + textWidth;
lpRectText->bottom = lpRectText->top + textHeight;
}
break;
case IT_IN_TOP:
{
lpRectText->left += (width - textWidth) / 2; // 左 居中
lpRectText->top = lpRectImage->top + m_itDistance;
lpRectText->right = lpRectText->left + textWidth;
lpRectText->bottom = lpRectText->top + textHeight;
}
break;
case IT_IN_RIGHT:
{
lpRectText->right = lpRectImage->right - m_itDistance;
lpRectText->top += (height - textHeight) / 2; // 高居中
lpRectText->left = lpRectText->right - textWidth;
lpRectText->bottom = lpRectText->top + textHeight;
}
break;
case IT_IN_BOTTOM:
{
lpRectText->left += (width - textWidth) / 2; // 左 居中
lpRectText->bottom = lpRectImage->bottom - m_itDistance;
lpRectText->right = lpRectText->left + textWidth;
lpRectText->top = lpRectText->bottom - textHeight;
}
break;
default:
{
// 文字居中
lpRectText->left += (width - textWidth) / 2;
lpRectText->top += (height - textHeight) / 2;
lpRectText->right = lpRectText->left + textWidth;
lpRectText->bottom = lpRectText->top + textHeight;
}
break;
}
}
}
}
void CButtonIT::DrawImage(Graphics& graphics, LPRECT lpRectImage)
{
byte index(GetIndex());
int offset(0);
if (m_state == MOUSE_DOWN)
{
offset = m_hitOffset;
}
// CClientDC dc(this);
// Graphics g(dc.m_hDC);
if (m_state == MOUSE_OUT || m_state == MOUSE_DISABLE)
{
graphics.DrawImage(m_pImgs[index], m_imgRect.left + offset, m_imgRect.top + offset, m_pImgs[index]->GetWidth(), m_pImgs[index]->GetHeight());
}
else if (m_state == MOUSE_IN || m_state == MOUSE_DOWN)
{
ColorMatrix HotMat = { 1.05f, 0.00f, 0.00f, 0.00f, 0.00f,
0.00f, 1.05f, 0.00f, 0.00f, 0.00f,
0.00f, 0.00f, 1.05f, 0.00f, 0.00f,
0.00f, 0.00f, 0.00f, 1.00f, 0.00f,
0.05f, 0.05f, 0.05f, 0.00f, 1.00f };
ImageAttributes ia;
ia.SetColorMatrix(&HotMat);
float width = (float)m_pImgs[index]->GetWidth();
float height = (float)m_pImgs[index]->GetHeight();
RectF rectF(static_cast (m_imgRect.left + offset), static_cast (m_imgRect.top + offset), width, height);
graphics.DrawImage(m_pImgs[index], rectF, 0, 0, width, height, UnitPixel, &ia);
}
}
void CButtonIT::DrawText(Graphics& graphics, LPRECT lpRectText)
{
byte index(GetIndex());
FontFamily fontFamily(m_fontNames[index]);
Gdiplus::Font font(&fontFamily, m_fontSizes[index], m_fontStyles[index], UnitPixel);
SolidBrush solidBrush(m_fontColors[index]);
int offset(0);
if (m_state == MOUSE_DOWN)
{
offset = m_hitOffset;
}
PointF pointF(static_cast
(m_textRect.left + offset), static_cast
(m_textRect.top + offset));
graphics.SetTextRenderingHint(TextRenderingHintAntiAlias);
graphics.DrawString(m_text, -1, &font, pointF, &solidBrush);
}
void CButtonIT::DrawRoundRectange(Graphics& graphics, LPRECT lpRect, Color& color)
{
// 设置画图时的滤波模式为消除锯齿现象
graphics.SetSmoothingMode(SmoothingModeAntiAlias);
GraphicsPath graphicspath;
graphicspath.AddArc(lpRect->right - ROUND_RADIUS - 1, lpRect->top, ROUND_RADIUS, ROUND_RADIUS, 270, 90);
graphicspath.AddArc(lpRect->right - ROUND_RADIUS - 1, lpRect->bottom - ROUND_RADIUS - 1, ROUND_RADIUS, ROUND_RADIUS, 0, 90);
graphicspath.AddArc(lpRect->left, lpRect->bottom - ROUND_RADIUS - 1, ROUND_RADIUS, ROUND_RADIUS, 90, 90);
graphicspath.AddArc(lpRect->left, lpRect->top, ROUND_RADIUS, ROUND_RADIUS, 180, 90);
graphicspath.AddLine(lpRect->left + ROUND_RADIUS, lpRect->top, lpRect->right - ROUND_RADIUS/2, lpRect->top);
// 创建一个红色的画笔
Pen pen(color);
graphics.DrawPath(&pen, &graphicspath);
}
void CButtonIT::FillRoundRectangle(Graphics& graphics, LPRECT lpRect, Color& color)
{
// 用路径渐变画笔填充
GraphicsPath graphicspath;
//graphicspath.AddArc(lpRect->right - ROUND_RADIUS - 1, lpRect->top, ROUND_RADIUS, ROUND_RADIUS, 270, 90);
graphicspath.AddArc(lpRect->right - ROUND_RADIUS - 1, lpRect->bottom - ROUND_RADIUS - 1, ROUND_RADIUS, ROUND_RADIUS, 0, 90);
graphicspath.AddArc(lpRect->left, lpRect->bottom - ROUND_RADIUS - 1, ROUND_RADIUS, ROUND_RADIUS, 90, 90);
graphicspath.AddArc(lpRect->left, lpRect->top, ROUND_RADIUS, ROUND_RADIUS, 180, 90);
graphicspath.AddLine(lpRect->left + ROUND_RADIUS, lpRect->top, lpRect->right - ROUND_RADIUS/2, lpRect->top);
// Use the path to construct a brush.
PathGradientBrush pthGrBrush(&graphicspath);
// Set the color at the center of the path to blue.
pthGrBrush.SetCenterColor(color);
// Set the color along the entire boundary of the path to aqua.
Color colors[] = {color};
int count = 1;
pthGrBrush.SetSurroundColors(colors, &count);
// Fill the path with the path gradient brush.
graphics.FillPath(&pthGrBrush, &graphicspath);
}
void CButtonIT::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
CClientDC parentDC(GetParent());
CRect rcClient;
CRect rcWindow;
GetClientRect(rcClient);
GetWindowRect(rcWindow);
GetParent()->ScreenToClient(rcWindow);
// 得到透明背景memdc
if (m_bgDC.m_hDC == NULL)
{
m_bgDC.CreateCompatibleDC(&parentDC);
m_bgBmp.CreateCompatibleBitmap(&parentDC, rcClient.Width(), rcClient.Height());
m_bgDC.SelectObject(&m_bgBmp);
m_bgDC.BitBlt(0, 0, rcClient.Width(), rcClient.Height(), &parentDC, rcWindow.left, rcWindow.top, SRCCOPY);
}
// 是否禁用或有焦点
if (lpDrawItemStruct->itemState & ODS_DISABLED)
{
m_state = MOUSE_DISABLE;
}
else
{
if (m_type == CHECKBOX)
{
// checked
if ((lpDrawItemStruct->itemState & ODS_SELECTED) || (m_state == MOUSE_FOCUS))
{
m_isFocus = true;
}
}
}
pDC->SetBkMode(TRANSPARENT);
LONG width = m_frameRect.Width();
LONG height = m_frameRect.Height();
CDC memDC;
memDC.CreateCompatibleDC(pDC);
memDC.SetBkMode(TRANSPARENT);
CBitmap bmp;
bmp.CreateCompatibleBitmap(pDC, width, height);
memDC.SelectObject(&bmp);
memDC.BitBlt(0,0, width, height, &m_bgDC, 0, 0, SRCCOPY);
Gdiplus::Graphics graphics(memDC);
byte index(GetIndex());
FillRoundRectangle(graphics, m_frameRect, m_bgColors[index]);
// Draw the image
if (m_pImgs[0])
{
DrawImage(graphics, m_imgRect);
}
if (!m_text.IsEmpty())
{
DrawText(graphics, m_textRect);
}
DrawRoundRectange(graphics, m_frameRect, m_frameColors[index]);
CRect rect(m_frameRect);
rect.DeflateRect(1, 1, 1, 1);
DrawRoundRectange(graphics, rect, Color(47, 255, 255, 255));
pDC->BitBlt(0, 0, width, height, &memDC, 0, 0, SRCCOPY);
bmp.DeleteObject();
}
void CButtonIT::OnMouseMove(UINT nFlags, CPoint point)
{
if (m_state != MOUSE_IN)
{
m_state = MOUSE_IN;
Invalidate(FALSE);
}
CButton::OnMouseMove(nFlags, point);
if (!m_isTracking)
{
TRACKMOUSEEVENT tm;
tm.cbSize = sizeof(TRACKMOUSEEVENT);
// 注册 消息
tm.dwFlags = TME_HOVER|TME_LEAVE;
tm.dwHoverTime = HOVER_DEFAULT;
tm.hwndTrack = m_hWnd;
m_isTracking = _TrackMouseEvent(&tm);
}
}
void CButtonIT::OnLButtonDown(UINT nFlags, CPoint point)
{
if (m_state != MOUSE_DOWN)
{
m_state = MOUSE_DOWN;
Invalidate(FALSE);
}
CButton::OnLButtonDown(nFlags, point);
}
void CButtonIT::OnLButtonUp(UINT nFlags, CPoint point)
{
if (m_state != MOUSE_IN || !m_isFocus)
{
m_state = MOUSE_IN;
m_isFocus = true;
Invalidate(FALSE);
}
CButton::OnLButtonUp(nFlags, point);
}
LRESULT CButtonIT::OnMouseLeave(WPARAM wParam, LPARAM lParam)
{
if (m_state != MOUSE_OUT)
{
m_state = MOUSE_OUT;
Invalidate(FALSE);
}
m_isTracking = FALSE;
return S_OK;
}
void CButtonIT::OnKillFocus(CWnd* pNewWnd)
{
CButton::OnKillFocus(pNewWnd);
if (m_isFocus)
{
m_isFocus = false;
Invalidate(FALSE);
}
}