/*
CComBox控件属性必须为:
Owner Drawer : Variable
Has Strings : False;
Type: Drop List;
Sort:False
四个条件缺一不可
参考网站:
https://blog.csdn.net/wyansai/article/details/51002535?utm_source=blogxgwz0
https://blog.csdn.net/wyansai/article/details/50971959
*/
#include "stdafx.h"
#include "PngComboBox.h"
#include "resource.h"
IMPLEMENT_DYNAMIC(CPngComboBox, CComboBox)
BEGIN_MESSAGE_MAP(CPngComboBox, CComboBox)
ON_WM_PAINT()
ON_WM_MOUSEMOVE()
ON_WM_ERASEBKGND()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
ON_CONTROL_REFLECT(CBN_SELCHANGE, OnCbnSelchange)
END_MESSAGE_MAP()
//
//
CPngComboBox::CPngComboBox()
{
m_bOver = FALSE;
m_bArtFont = FALSE;
m_pBrsh = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
m_bgPen.CreatePen(PS_SOLID, 1, RGB(160, 31, 208));
m_font.CreateFont(15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _T("宋体"));
m_bDown = FALSE;
m_selItem = 666666666;
m_preSelItem = 666666666;
m_bFous = FALSE;
m_endIcon = NULL;
m_crFrame = DEF_FRAME_COLOR;
m_crBgTitle = DEF_BG_COLOR;
m_crBgSelected = DEF_SELECT_COLOR;
m_crBgNoSelected = DEF_BG_COLOR;
m_crArtFont = DEF_FRAME_COLOR;
m_norImg = NULL;
m_clickImg = NULL;
}
CPngComboBox::~CPngComboBox()
{
if(m_bgPen.m_hObject != NULL)
{
m_bgPen.DeleteObject();
}
if(m_pBrsh->m_hObject != NULL)
{
m_pBrsh->DeleteObject();
}
if(m_font.m_hObject != NULL)
{
m_font.DeleteObject();
}
for(auto *e : m_vecItemList)
{
if(e != NULL)
{
delete e;
}
}
}
void CPngComboBox::AddNewString(CString leftText, UINT icon, COLORREF leftColor)
{
ItemList *pItem = new ItemList;
pItem->clrLeft = leftColor;
pItem->hIcon = icon ? AfxGetApp()->LoadIcon(icon) : NULL;
pItem->strUrl = leftText;
pItem->iItem = AddString(leftText);
m_vecItemList.push_back(pItem);
}
void CPngComboBox::SetEndIcon(UINT endIcon)
{
m_endIcon = endIcon;
}
void CPngComboBox::SetRightButton(UINT norImg, UINT clickImg)
{
m_norImg = ImageFromResource(AfxGetInstanceHandle(), norImg, _T("PNG"));
m_clickImg = ImageFromResource(AfxGetInstanceHandle(), clickImg, _T("PNG"));
if(!m_norImg || !m_clickImg)
{
m_norImg = m_clickImg = NULL;
}
}
Image *CPngComboBox::ImageFromResource(HINSTANCE hInstance, UINT uImgID, LPCTSTR lpType)
{
HRSRC hResInfo = ::FindResource(hInstance, MAKEINTRESOURCE(uImgID), lpType);
if(hResInfo == NULL)
{
return NULL; //fail
}
DWORD dwSize;
dwSize = SizeofResource(hInstance, hResInfo); //get resource size(bytes)
HGLOBAL hResData;
hResData = ::LoadResource(hInstance, hResInfo);
if(hResData == NULL)
{
return NULL; //fail
}
HGLOBAL hMem;
hMem = ::GlobalAlloc(GMEM_MOVEABLE, dwSize);
if(hMem == NULL)
{
::FreeResource(hResData);
return NULL;
}
LPVOID lpResData, lpMem;
lpResData = ::LockResource(hResData);
lpMem = ::GlobalLock(hMem);
::CopyMemory(lpMem, lpResData, dwSize); //copy memory
::GlobalUnlock(hMem);
::FreeResource(hResData); //free memory
IStream *pStream;
HRESULT hr;
hr = ::CreateStreamOnHGlobal(hMem, TRUE, &pStream);//create stream object
Image *pImage = NULL;
if(SUCCEEDED(hr))
{
pImage = Image::FromStream(pStream);//get GDI+ pointer
pStream->Release();
}
::GlobalFree(hMem);
return pImage;
}
void CPngComboBox::SetComboColor(COLORREF crFrame, COLORREF crBgTitle, COLORREF crBgSelected, COLORREF crBgNoSelected)
{
m_crFrame = crFrame;
m_crBgTitle = crBgTitle;
m_crBgSelected = crBgSelected;
m_crBgNoSelected = crBgNoSelected;
}
void CPngComboBox::SetFontType(int fontSize, CString fontType, BOOL bArtFont, COLORREF crArtFont)
{
m_font.Detach();
LOGFONT lf;
memset(&lf, 0, sizeof(LOGFONT));
lf.lfHeight = fontSize;
_tcsncpy_s(lf.lfFaceName, LF_FACESIZE, fontType, fontType.GetLength());
VERIFY(m_font.CreateFontIndirect(&lf));
m_bArtFont = bArtFont;
m_crArtFont = crArtFont;
}
void CPngComboBox::OnNcPaint(CDC *pDC)
{
//绘制客户区
CDC dMemDC;
dMemDC.CreateCompatibleDC(pDC);
dMemDC.SetMapMode(pDC->GetMapMode());
//画动作
CBitmap mNewBmp;
CRect rc;
GetClientRect(&rc);
mNewBmp.CreateCompatibleBitmap(pDC, rc.right - rc.left, rc.bottom - rc.top);
CBitmap *pOldBmp = dMemDC.SelectObject(&mNewBmp);
CPen *pOldPen = dMemDC.SelectObject(&m_bgPen);
CBrush bgBs(m_crBgNoSelected);
CBrush *pOldBrsh = dMemDC.SelectObject(&bgBs);
dMemDC.Rectangle(&rc);
dMemDC.SelectObject(pOldPen);
dMemDC.SelectObject(&pOldBrsh);
if((GetCurSel() > 4) || (GetCurSel() < 0))
{
return;
}
PItemList pItem = m_vecItemList[GetCurSel()];
CPen m_penLeft;
CPen m_penRight;
CRect rcLeft, rcMid, rcRight;
rcLeft = rcMid = rcRight = rc;
dMemDC.SetBkMode(TRANSPARENT);
//画第一段图标
if(pItem->hIcon != NULL)
{
rcLeft.left = 5;
rcLeft.right = rcLeft.left + 16;
rcLeft.top += 4;
::DrawIconEx(dMemDC.m_hDC, rcLeft.left, rcLeft.top, pItem->hIcon, 16, 16, NULL, NULL, DI_NORMAL);
}
else
{
rcLeft.right = 0;
}
//画第二段文本
rcMid.left = rcLeft.right + 5;
CFont *pOldFont = dMemDC.SelectObject(&m_font);
DrawTextString(&dMemDC, pItem->strUrl, pItem->clrLeft, m_crArtFont, &rcMid);
dMemDC.SelectObject(pOldFont);
CRect rcEnd(rc);
rcEnd.left = rc.right - 22;
if(m_norImg == NULL)
{
if(m_bDown)
{
dMemDC.DrawFrameControl(&rcEnd, DFC_SCROLL, DFCS_SCROLLDOWN | DFCS_FLAT | DFCS_MONO | DFCS_PUSHED);
}
else
{
dMemDC.DrawFrameControl(&rcEnd, DFC_SCROLL, DFCS_SCROLLDOWN | DFCS_FLAT | DFCS_MONO);
}
}
else
{
Graphics graphics(dMemDC.m_hDC);
if(m_bDown)
{
graphics.DrawImage(m_norImg, rcEnd.left, rcEnd.top + 1, 20, 22);
}
else
{
graphics.DrawImage(m_clickImg, rcEnd.left, rcEnd.top + 1, 20, 22);
}
graphics.ReleaseHDC(dMemDC.m_hDC);
}
pDC->BitBlt(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, &dMemDC,
rc.left, rc.top, SRCCOPY);
//恢复
dMemDC.SelectObject(pOldBmp);
pOldBmp->DeleteObject();
dMemDC.DeleteDC();
}
void CPngComboBox::OnPaint()
{
CPaintDC dc(this); // device context for painting
OnNcPaint(&dc);
}
void CPngComboBox::DrawContent(UINT iState, CRect rcClient, CDC *pDC, int itemID)
{
PItemList pItem = m_vecItemList[itemID];
CPen m_penLeft;
CPen m_penRight;
CRect rcLeft, rcMid;
rcLeft = rcMid = rcClient;
pDC->SetBkMode(TRANSPARENT);
if(iState & ODS_SELECTED)
{
//及时更新选择区域
UpdateRect();
}
if(itemID == m_selItem)
{
CPen bgPen;
bgPen.CreatePen(PS_SOLID, 1, RGB(141, 178, 227));
CPen *pOldPen = pDC->SelectObject(&bgPen);
CBrush bgBs(m_crBgSelected);
CBrush *pOldBrush = pDC->SelectObject(&bgBs);
pDC->RoundRect(&rcClient, CPoint(5, 5));
pDC->SelectObject(pOldBrush);
pDC->SelectObject(pOldPen);
bgPen.DeleteObject();
}
else
{
CBrush bgBs(m_crBgNoSelected);
pDC->FillRect(&rcClient, &bgBs);
}
//画第一段图标
if(pItem->hIcon != NULL)
{
rcLeft.left = 5;
rcLeft.right = rcLeft.left + 16;
rcLeft.top += 4;
::DrawIconEx(pDC->m_hDC, rcLeft.left, rcLeft.top, pItem->hIcon, 16, 16, NULL, N
评论0