⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 coollistctrl.cpp

📁 自绘CCombBox组件,具有combo组件的所有功能
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// CoolListCtrl.cpp : implementation file
//

#include "stdafx.h"
//#include "TestCoolList.h"
#include "CoolListCtrl.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

//#define WM_FURL_MSG WM_USER + 1231//控件收拢消息

#define ONEPAGE_NUM 8//展开后,下拉列表一页中条目数 

enum{FOCUS_UPBTN=0,FOCUS_DOWNBTN,FOCUS_SLIDER};

enum{
	AREA_LIST_SLIDER_0,AREA_LIST_SLIDER_1,AREA_LIST_SLIDER_2,AREA_LIST_SLIDER_3,
	AREA_LIST_SLIDER_4,AREA_LIST_SLIDER_5,AREA_LIST_SLIDER_6,AREA_LIST_SLIDER_7,
	AREA_LIST_SLIDER_UP,AREA_LIST_SLIDER_DOWN,AREA_LIST_SLIDER	
	};

/////////////////////////////////////////////////////////////////////////////
// CCoolListCtrl
void CCoolListCtrl:: DrawSemiTransparentRect(CDC *pDstDC, CRect rtTran, COLORREF clrSrc)
{
	int nSavedDC = pDstDC->SaveDC();//保存原始DC

	int nWidth   = rtTran.Width();//半透明区域的宽度
	int nHeight  = rtTran.Height();//半透明区域的高度

	//拷屏 , 新建一个DC来拷贝目标区域
	CDC  bmpDC;
	bmpDC.CreateCompatibleDC(pDstDC);
	CBitmap  bmp ;

	bmp.CreateCompatibleBitmap(pDstDC , nWidth , nHeight);
	CBitmap* pOldBmp = (CBitmap*)bmpDC.SelectObject(&bmp);
	bmpDC.BitBlt(0 , 0 , nWidth , nHeight , pDstDC , rtTran.left , rtTran.top , SRCCOPY);

	//获取bmpDC中的图形数据到BYTE数组
	HDC hDIBDC = CreateCompatibleDC(NULL);

	BITMAPINFO hdr; 
	ZeroMemory(&hdr , sizeof(BITMAPINFO));

	hdr.bmiHeader.biSize         =  sizeof(BITMAPINFOHEADER);
	hdr.bmiHeader.biWidth      =  nWidth;
	hdr.bmiHeader.biHeight     =  nHeight;
	hdr.bmiHeader.biPlanes     =  1;
	hdr.bmiHeader.biBitCount =  32;
//这里统一用32位图形 ,原因是32位图形结构相对固定 , 每个
//像素用4个字节表示 。每行末尾不需要添加额外的字节。
//而24位图形 , 每行末尾需要添加额外的字节 , 以保证每行的
//字节数是4的整数倍
//如果想缩减开销和字节数 , 可以采用24位的图形 ,不过就会多
//出一些判断添加额外自己的代码 。

	BYTE * pbtPixels = NULL ; 
	HBITMAP hDIBitmap  =  CreateDIBSection(hDIBDC,(BITMAPINFO *)&hdr,DIB_RGB_COLORS,(void **)&pbtPixels,NULL,0);
	HBITMAP hOldBmp = (HBITMAP)SelectObject(hDIBDC, hDIBitmap);
	BitBlt(hDIBDC,0,0,nWidth,nHeight,bmpDC.m_hDC,0,0,SRCCOPY);
	SelectObject(hDIBDC, hOldBmp);

      
	//对BYTE数组进行Alpha混和
	int nPixelSize = 4 ;//每个像素点用4个字节来存储

	BYTE btSR = GetRValue(clrSrc);
	BYTE btSG = GetGValue(clrSrc);
	BYTE btSB = GetBValue(clrSrc);

	for(int i = 0 ; i < nHeight ; i ++)
	{
		for(int j = 0 ;  j < nWidth ; j ++)
		{
   
			BYTE btB = pbtPixels[i *  nWidth * nPixelSize   + j * nPixelSize  ] ;
			BYTE btG = pbtPixels[i *  nWidth * nPixelSize   + j * nPixelSize + 1 ] ;
			BYTE btR = pbtPixels[i *  nWidth * nPixelSize   + j * nPixelSize + 2 ] ;

			btB = (btSB + btB ) >> 1 ; //btB = btSB * 0.5 + (1-0.5) * btB;
			btG = (btSG + btG ) >> 1 ; //btG = btSG * 0.5 + (1-0.5) * btG;
			btR = (btSR + btR ) >> 1 ; //btR = btSR * 0.5 + (1-0.5) * btR;
   

			pbtPixels[i *  nWidth * nPixelSize   + j * nPixelSize  ]     = btB ;  
			pbtPixels[i *  nWidth * nPixelSize   + j * nPixelSize + 1 ] = btG ; 
			pbtPixels[i *  nWidth * nPixelSize   + j * nPixelSize + 2 ] = btR ;

		}
	}

	//绘制最终半透明图形到目标区域
	SetDIBitsToDevice(pDstDC->GetSafeHdc(),rtTran.left,rtTran.top,nWidth,nHeight,
		0,0,0,nHeight,(void*)pbtPixels,(BITMAPINFO*)&hdr,DIB_RGB_COLORS);
	//析构和清空
	bmpDC.SelectObject(pOldBmp);
	bmp.DeleteObject();
	delete [] pbtPixels ;
	bmpDC.DeleteDC();
	DeleteObject(hDIBDC);
	DeleteObject(hDIBitmap);
	pDstDC->RestoreDC(nSavedDC);//恢复初始DC
	pbtPixels=NULL;

	
}

CCoolListCtrl::CCoolListCtrl():m_bOnceFlag(false),
m_bIsMouseDownFlag(false)
{

	m_iCurFocusBtn = -1;

	m_fSliderPercent = 0.0;

	m_iItemTotal = 0;

	m_iCurTextID = 0;

	m_iHead = 0;
	m_iTail= 14;
	
	m_pBackDC = NULL;

	m_TextColor = RGB(255,255,255);
	m_SeledTxtColor = RGB(0,255,0);
	m_TransColor = RGB(255,255,255);
	m_SeledTransColor = RGB(0,0,255);
	m_BorderColor = RGB(192,192,192);

}

CCoolListCtrl::~CCoolListCtrl()
{



}


BEGIN_MESSAGE_MAP(CCoolListCtrl, CStatic)
	//{{AFX_MSG_MAP(CCoolListCtrl)
	ON_WM_PAINT()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONDOWN()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CCoolListCtrl message handlers
void CCoolListCtrl::Init(CDC *pBackDC,CRect *pRect,CRect *BkImageRect)
{

//	m_pRect = pRect;

	m_pBkImageRect = BkImageRect;

	m_pBackDC = pBackDC;


}

void CCoolListCtrl::InsertText(LPTSTR sText)
{

	m_pItemText.Add(sText);

}

void CCoolListCtrl::InsertBmp(CBitmap *pBitmap)
{
	//只须获得位图指针即可调用位图
	m_pButtonBmp = pBitmap;

}

//获得指定区域的矩形
BOOL CCoolListCtrl::GetAppointedRect(UINT iFlag, CRect *pDestRect)
{
	//slideWid+=5;

	switch(iFlag)
	{
		case AREA_LIST_SLIDER_0://列表0条目区域的矩形,有滑竿

				pDestRect->left  = m_screenRect.left;			
				pDestRect->top  = m_screenRect.top;
				pDestRect->right  = m_screenRect.right - slideWid;
				pDestRect->bottom  = m_screenRect.top+slideWid;				
			
				break;
		case AREA_LIST_SLIDER_1://列表1条目区域的矩形,有滑竿

				pDestRect->left  = m_screenRect.left;			
				pDestRect->top  = m_screenRect.top + slideWid;
				pDestRect->right  = m_screenRect.right - slideWid;
				pDestRect->bottom  = m_screenRect.top + slideWid*2;			
			
				break;
		case AREA_LIST_SLIDER_2://列表2条目区域的矩形,有滑竿

				pDestRect->left  = m_screenRect.left;			
				pDestRect->top  = m_screenRect.top + slideWid*2;
				pDestRect->right  = m_screenRect.right - slideWid;
				pDestRect->bottom  = m_screenRect.top + slideWid*3;			
			
				break;
		case AREA_LIST_SLIDER_3://列表3条目区域的矩形,有滑竿

				pDestRect->left  = m_screenRect.left;			
				pDestRect->top  = m_screenRect.top + slideWid*3;
				pDestRect->right  = m_screenRect.right - slideWid;
				pDestRect->bottom  = m_screenRect.top + slideWid*4;			
			
				break;
		case AREA_LIST_SLIDER_4://列表4条目区域的矩形,有滑竿

				pDestRect->left  = m_screenRect.left;			
				pDestRect->top  = m_screenRect.top + slideWid*4;
				pDestRect->right  = m_screenRect.right - slideWid;
				pDestRect->bottom  = m_screenRect.top + slideWid*5;			
			
				break;
		case AREA_LIST_SLIDER_5://列表5条目区域的矩形,有滑竿

				pDestRect->left  = m_screenRect.left;			
				pDestRect->top  = m_screenRect.top + slideWid*5;
				pDestRect->right  = m_screenRect.right - slideWid;
				pDestRect->bottom  = m_screenRect.top + slideWid*6;			
			
				break;
		case AREA_LIST_SLIDER_6://列表6条目区域的矩形,有滑竿

				pDestRect->left  = m_screenRect.left;			
				pDestRect->top  = m_screenRect.top + slideWid*6;
				pDestRect->right  = m_screenRect.right - slideWid;
				pDestRect->bottom  = m_screenRect.top + slideWid*7;			
			
				break;
		case AREA_LIST_SLIDER_7://列表7条目区域的矩形,有滑竿

				pDestRect->left  = m_screenRect.left;			
				pDestRect->top  = m_screenRect.top + slideWid*7;
				pDestRect->right  = m_screenRect.right - slideWid;
				pDestRect->bottom  = m_screenRect.top + slideWid*8;			
			
				break;

		case AREA_LIST_SLIDER_UP://滑竿的上按纽区域矩形
			
				pDestRect->left  = m_screenRect.right - slideWid;			
				pDestRect->top  = m_screenRect.top;
				pDestRect->right  = m_screenRect.right;
				pDestRect->bottom  = m_screenRect.top+slideWid;				
				
				break;

		case AREA_LIST_SLIDER_DOWN://滑竿的下按纽区域矩形
				
				pDestRect->left  = m_screenRect.right - slideWid;			
				pDestRect->top  = m_screenRect.bottom - slideWid;
				pDestRect->right  = m_screenRect.right;
				pDestRect->bottom  = m_screenRect.bottom;				
				
				break;
		case AREA_LIST_SLIDER://滑竿矩形区域
				pDestRect->left  = m_screenRect.right - slideWid;			
				pDestRect->top  = m_screenRect.top+slideWid;
				pDestRect->right  = m_screenRect.right;
				pDestRect->bottom  = m_screenRect.bottom-slideWid;					
				break;

		default:
				return false;
				break;


	}

	
	return true;

}

//判断给入的点在哪一个区域
INT CCoolListCtrl::GetCurSeledRect(CPoint point)
{

	CRect rect;

	int temp[11];

	temp[0]=AREA_LIST_SLIDER_0;
	temp[1]=AREA_LIST_SLIDER_1;
	temp[2]=AREA_LIST_SLIDER_2;
	temp[3]=AREA_LIST_SLIDER_3;
	temp[4]=AREA_LIST_SLIDER_4;
	temp[5]=AREA_LIST_SLIDER_5;
	temp[6]=AREA_LIST_SLIDER_6;
	temp[7]=AREA_LIST_SLIDER_7;
	temp[8]=AREA_LIST_SLIDER_UP;
	temp[9]=AREA_LIST_SLIDER_DOWN;
	temp[10]=AREA_LIST_SLIDER;

	for(int i = 0;i<=10;i++)
	{
		if(GetAppointedRect(temp[i],&rect))
		{
			if(rect.PtInRect(point))
				return temp[i];	
		}
	}

	
	
	return -1;
}

void CCoolListCtrl::OnceCode(CDC *pDC)
{
	GetClientRect(&m_screenRect);
	m_iItemTotal = m_pItemText.GetSize();//获得总的条目数

	//滑块对应的小矩形初始化
	CRect rect;
	GetAppointedRect(AREA_LIST_SLIDER,&rect);

	m_SliderRect.left = rect.left;
	m_SliderRect.top = rect.top;
	m_SliderRect.right = rect.right;
	m_SliderRect.bottom = rect.top+slideWid;

	//设置头尾标志
	m_iHead = 0;
	if(m_iItemTotal<ONEPAGE_NUM)
		m_iTail= m_iItemTotal -1;
	else
	m_iTail = ONEPAGE_NUM - 1;
	
	TempBmp.CreateCompatibleBitmap(pDC,m_screenRect.Width(),m_screenRect.Height());
	m_MemDC.CreateCompatibleDC(pDC);
	pOldBmp=m_MemDC.SelectObject(&TempBmp);

	font = new CFont;
	font->CreateFont(40, 0, 0, 0, FW_NORMAL, FALSE, FALSE,0,0,0,0,0,0, _T("Arial"));

	BITMAP bm;
	m_pButtonBmp->GetBitmap(&bm);
	slideWid = bm.bmWidth/6;



}


void CCoolListCtrl::DrawOneScreen(CDC *pDC)
{
	pOldTempBmp = m_MemDC.SelectObject(&TempBmp);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -