QQ分类按钮

花了一个礼拜时间,总算把这个代码啃完了,用的虚函数还是不太了解 

使用方法:

void CQQList::SetImageLists(CImageList *pImagelist)     设置关联的图像列表控件

void CQQList::AddButton(LPCSTR BtnTitle, UINT8 uID)    添加一个分类按钮,参数 分类名称,ID

void CQQList::AddButtonItems(UINT uID, CString &name, int nImageIndex)   为分类按钮uID添加一个项目,指定名称和图标

CQQList::m_pItemDlbFun                                                         设置回调函数,响应项目双击事件

 

ListButton.h          QQList的分类按钮,内含一些具体项目

class CListButton :
	public CButton
{
public:
	CListButton(void);
	~CListButton(void);
public:
	UINT m_Index;             //分类按钮的ID
	BOOL m_Toped;             //分类按钮的位置

	CStringList m_Entities;   //具体项目的名称
	CStringList m_Image;      //具体项目的图标
private:
	const UINT GetHeight()const;
	const UINT GetWidth()const;
public:
	virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
};

ListButton.cpp

#include "ListButton.h"

CListButton::CListButton(void)
: m_Index(0)
, m_Toped(FALSE)
{
}

CListButton::~CListButton(void)
{
}

const UINT CListButton::GetHeight()const
{
	CRect rect;
	GetClientRect(rect);
	return rect.Height();
}

const UINT CListButton::GetWidth()const
{
	CRect rect;
	GetClientRect(rect);
	return rect.Width();
}

void CListButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
	CRect rect;
	GetClientRect(rect);

	CDC dc;
	dc.Attach(lpDrawItemStruct->hDC);
	dc.SetBkMode(TRANSPARENT);

	CBrush m_Brush(RGB(100,140,200));
	dc.SelectObject(&m_Brush);
	dc.DrawEdge(rect,BDR_RAISEDINNER|BDR_RAISEDOUTER
		,BF_BOTTOMLEFT|BF_TOPRIGHT);
	dc.Draw3dRect(rect,RGB(51,51,51),RGB(0,0,0));

	CRect rc(rect);
	rc.DeflateRect(2,2,2,2);
	dc.FillRect(rc,&m_Brush);

	CString str;
	GetWindowText(str);
	dc.SetTextColor(RGB(255,255,255));
	dc.DrawText(str,CRect(0,0,rect.right,rect.bottom),
		DT_CENTER|DT_VCENTER|DT_SINGLELINE);
}


QQList.h

typedef void(ItemDlbFun)(const CListCtrl *pListCtrl,int nItemIndex);

class CQQList :
	public CListCtrl
{
public:
	CQQList(void);
	~CQQList(void);
public:
	void SetImageLists(CImageList *pImageList);    //设置项目关联的ImageList
	void AddButton(LPCSTR Btext, UINT8 nID);       //向List增加一个分类按钮
	void AddButtonItems(UINT nIndex,CString &strItem,int mImageIdex);  //向分类按钮增加一个项目

	ItemDlbFun *m_pItemDlbFun;                     //外部的回调函数
public:
	virtual void PreSubclassWindow(void);
	BOOL PreTranslateMessage(MSG * pMsg);          //截获双击事件,调用回调函数
	virtual BOOL OnCmdMsg(UINT nID, int nCode, void * pExtra, AFX_CMDHANDLERINFO * pHandlerInfo);
private:
	CListCtrl m_ClientList;
	CPtrArray m_pButton;
	UINT m_ButtonHeight;
	UINT m_LeftMargin;
private:
	UINT GetTopBtnsHeightSum(void);
	UINT GetBtmBtnsHeightSum(void);
	UINT GetFirstBtmIndex(void);
	CRect GetNewButtonsRect(void);
	CRect GetListClientRect();
	void MoveDown(UINT bIndex);
	void MoveUp(UINT bIndex);
	UINT CommandToIndex(UINT nID);
	void ShowButtonItems(UINT nIndex);
	void OnButtonDown(UINT bIndex, UINT nID);
};


QQList.cpp

#include "QQList.h"
#include "ListButton.h"

CQQList::CQQList(void)
: m_ButtonHeight(25)
, m_LeftMargin(0)
, m_pItemDlbFun(NULL)
{
}

CQQList::~CQQList(void)
{
	int m = m_pButton.GetSize();
	for( int i=0;i<m_pButton.GetSize();i++ )
	{
		((CListButton *)m_pButton[i])->DestroyWindow();
		delete((CListButton *)m_pButton[i]);
	}
}

/************************************************************
	虚函数
************************************************************/

void CQQList::PreSubclassWindow(void)
{
	m_ClientList.Create(LVS_ICON,CRect(0,0,0,0),this,101);
	m_ClientList.ShowWindow(SW_SHOW);
	m_ClientList.SetExtendedStyle(LVS_EX_FLATSB);
	m_ClientList.SetBkColor(RGB(255,255,255));
	m_ClientList.SetTextBkColor(RGB(255,255,255));
	m_ClientList.SetTextColor(RGB(0,0,255));
	m_ClientList.Arrange(LVA_ALIGNLEFT);

	CListCtrl::PreSubclassWindow();
}

BOOL CQQList::PreTranslateMessage(MSG * pMsg)
{
	if((pMsg->hwnd==m_ClientList.m_hWnd)&&(pMsg->message==WM_LBUTTONDBLCLK))
	{
		int index;
		index = m_ClientList.GetSelectionMark();
		if (m_pItemDlbFun != NULL)
			m_pItemDlbFun(&m_ClientList,index);
	}

	return CListCtrl::PreTranslateMessage(pMsg);
}

UINT CQQList::CommandToIndex(UINT nID)
{
	for(int i = 0;i< m_pButton.GetSize();i++)
	{
		if(((CListButton*)m_pButton[i])->GetDlgCtrlID()==nID)
		{
			return ((CListButton*)m_pButton[i])->m_Index;
		}
	}
	return -1;
}

BOOL CQQList::OnCmdMsg(UINT nID, int nCode, void * pExtra, AFX_CMDHANDLERINFO * pHandlerInfo)
{
	int index =  CommandToIndex(nID);
	if(index != -1)
	{
		OnButtonDown(index,nID);
	}
	m_ClientList.OnCmdMsg(nID,nCode,pExtra,pHandlerInfo);
	return CListCtrl::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}

/************************************************************
	区域计算
************************************************************/

CRect CQQList::GetNewButtonsRect(void)
{
	const int EXIST_BTN_NUM = m_pButton.GetSize();
	int       sumheight = 0;
	int       i = 0;
	while( i<EXIST_BTN_NUM )
	{
		sumheight += ((CListButton*)m_pButton[i])->GetHeight();
		i++;
	}

	CRect TotalRect;
	GetClientRect(TotalRect);
	return CRect(0,sumheight,TotalRect.Width(),sumheight+m_ButtonHeight);
}

UINT CQQList::GetTopBtnsHeightSum(void)
{
	UINT result = 0;

	for(int i = 0; i< m_pButton.GetSize();i++)
	{
		CListButton* aBtn = (CListButton*)m_pButton[i];
		if(aBtn->m_Toped)
		{
			result += aBtn->GetHeight();
		}
	}
	return result;
}

UINT CQQList::GetBtmBtnsHeightSum(void)
{
	UINT result = 0;

	for(int i = 0; i< m_pButton.GetSize();i++)
	{
		CListButton* aBtn = (CListButton*)m_pButton[i];
		if (aBtn->m_Toped==FALSE)
		{
			result += aBtn->GetHeight();
		}
	}
	return result;
}

CRect CQQList::GetListClientRect()
{
	CRect TotalRect;
	GetClientRect(TotalRect);

	int TopHeight = GetTopBtnsHeightSum();
	int BtmHeight = GetBtmBtnsHeightSum();

	CRect ClientRect(0,TopHeight,TotalRect.Width(),TotalRect.Height()-BtmHeight);
	return ClientRect;
}

/************************************************************
	
************************************************************/

UINT CQQList::GetFirstBtmIndex(void)
{
	for(int i = 0; i<m_pButton.GetSize();i++)
	{
		if (((CListButton*)m_pButton[i])->m_Toped==FALSE)
			return i;
	}
	return -1;
}

void CQQList::MoveDown(UINT bIndex)
{
	UINT BtmOffset = m_pButton.GetSize()-1-bIndex;
	CListButton* target       = (CListButton*)m_pButton[bIndex];

	CRect wholeRect;
	GetClientRect(wholeRect);
	CRect rect(
		0,
		wholeRect.bottom - (target->GetHeight())*(BtmOffset+1),
		target->GetWidth(),
		wholeRect.bottom - (target->GetHeight())*(BtmOffset)
	);				

	target->MoveWindow(rect);
	target->m_Toped = FALSE;
}

void CQQList::MoveUp(UINT bIndex)
{
	CListButton* target       = (CListButton*)m_pButton[bIndex];

	CRect wholeRect;
	GetClientRect(wholeRect);
	CRect rect(
		0,
		wholeRect.top + (target->GetHeight())*(bIndex),
		target->GetWidth(),
		wholeRect.top + (target->GetHeight())*(bIndex+1)
	);				

	target->MoveWindow(rect);
	target->m_Toped = TRUE;
}

//显示第nIndex个按钮内的内容
void CQQList::ShowButtonItems(UINT nIndex)
{
	m_ClientList.DeleteAllItems();
	CRect showrect = GetListClientRect();
	const UINT LEFT_MARGIN = showrect.Width()/2-20;

	CListButton* temp = (CListButton*)m_pButton[nIndex];
	if(temp->m_Entities.GetCount()>0)
	{
		int m = 0;

		POSITION pos = temp->m_Entities.GetHeadPosition();
		POSITION index = temp->m_Image.GetHeadPosition();
		while( pos != NULL && index != NULL )
		{
			CString itemName = temp->m_Entities.GetNext(pos);
			int     itemId   = atoi(temp->m_Image.GetNext(index));
			m_ClientList.InsertItem(m,itemName,itemId);
			m_ClientList.SetItemPosition(m,CPoint(LEFT_MARGIN,m*(48+5)));
			m++;
		};
	}
}

void CQQList::OnButtonDown(UINT btnIdx, UINT nID)
{
	if(m_pButton.GetSize()<2)
	{
		return;
	}

	CListButton* aBtn       = (CListButton*)m_pButton[btnIdx];
	if(aBtn->m_Toped)
	{
		int targetBtnIdx = m_pButton.GetSize()-1;
		while( targetBtnIdx>btnIdx )
		{
			MoveDown(targetBtnIdx--);
		}
	}
	else
	{
		int targetBtnIdx = GetFirstBtmIndex();
		while( targetBtnIdx<=btnIdx )
		{
			MoveUp(targetBtnIdx++);
		}
	}

	CRect rectclt = GetListClientRect();
	m_ClientList.MoveWindow(rectclt);
	ShowButtonItems(btnIdx);
}

/**************************************************
	用户接口
**************************************************/
void CQQList::SetImageLists(CImageList *pImagelist)
{
	if(pImagelist)
		m_ClientList.SetImageList(pImagelist,LVSIL_NORMAL);
}

void CQQList::AddButton(LPCSTR BtnTitle, UINT8 uID)
{
	CListButton *pBtn = new CListButton;
	pBtn->Create(BtnTitle,WS_CHILD|BS_OWNERDRAW,GetNewButtonsRect(),this,uID);
	pBtn->m_Index = m_pButton.GetSize();
	pBtn->ShowWindow(SW_SHOW);

	m_pButton.Add(pBtn);
}

void CQQList::AddButtonItems(UINT nIndex, CString &name, int nImageIdex)
{
	CListButton* temp = (CListButton*)m_pButton[nIndex];

	temp->m_Entities.AddTail(name);

	CString strIndex;
	strIndex.Format("%d",nImageIdex);
	temp->m_Image.AddTail(strIndex);
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值