www.pudn.com > DrawerMenu(完整版).rar > DrawerMenuCtl.cpp


// DrawerMenuCtl.cpp : Implementation of the CDrawerMenuCtrl ActiveX Control class. 
 
#include "stdafx.h" 
#include "DrawerMenu.h" 
#include "DrawerMenuCtl.h" 
#include "DrawerMenuPpg.h" 
 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
 
IMPLEMENT_DYNCREATE(CDrawerMenuCtrl, COleControl) 
 
 
///////////////////////////////////////////////////////////////////////////// 
// Message map 
 
BEGIN_MESSAGE_MAP(CDrawerMenuCtrl, COleControl) 
	//{{AFX_MSG_MAP(CDrawerMenuCtrl) 
	ON_WM_LBUTTONDOWN() 
	ON_WM_LBUTTONDBLCLK() 
	ON_WM_CREATE() 
	ON_WM_MOUSEMOVE() 
	ON_WM_LBUTTONUP() 
	//}}AFX_MSG_MAP 
	ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties) 
END_MESSAGE_MAP() 
 
 
///////////////////////////////////////////////////////////////////////////// 
// Dispatch map 
 
BEGIN_DISPATCH_MAP(CDrawerMenuCtrl, COleControl) 
	//{{AFX_DISPATCH_MAP(CDrawerMenuCtrl) 
	DISP_FUNCTION(CDrawerMenuCtrl, "SetSubCurSel", SetSubCurSel, VT_I4, VTS_I4 VTS_I4) 
	DISP_FUNCTION(CDrawerMenuCtrl, "AddSubItem", AddSubItem, VT_BOOL, VTS_I2 VTS_I2 VTS_I2 VTS_PI4) 
	DISP_FUNCTION(CDrawerMenuCtrl, "AddSuperItem", AddSuperItem, VT_BOOL, VTS_I2 VTS_PI4) 
	DISP_FUNCTION(CDrawerMenuCtrl, "SetSuperCurSel", SetSuperCurSel, VT_I4, VTS_I2) 
	DISP_FUNCTION(CDrawerMenuCtrl, "SetImageList", SetImageList, VT_I4, VTS_PI4) 
	DISP_STOCKFUNC_REFRESH() 
	DISP_STOCKPROP_BACKCOLOR() 
	//}}AFX_DISPATCH_MAP 
	DISP_FUNCTION_ID(CDrawerMenuCtrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE) 
END_DISPATCH_MAP() 
 
 
///////////////////////////////////////////////////////////////////////////// 
// Event map 
 
BEGIN_EVENT_MAP(CDrawerMenuCtrl, COleControl) 
	//{{AFX_EVENT_MAP(CDrawerMenuCtrl) 
	EVENT_CUSTOM("SUBITEMSELECTED", FireSubItemSelected, VTS_I4  VTS_BSTR) 
	//}}AFX_EVENT_MAP 
END_EVENT_MAP() 
 
 
///////////////////////////////////////////////////////////////////////////// 
// Property pages 
 
// TODO: Add more property pages as needed.  Remember to increase the count! 
BEGIN_PROPPAGEIDS(CDrawerMenuCtrl, 1) 
	PROPPAGEID(CDrawerMenuPropPage::guid) 
END_PROPPAGEIDS(CDrawerMenuCtrl) 
 
 
///////////////////////////////////////////////////////////////////////////// 
// Initialize class factory and guid 
 
IMPLEMENT_OLECREATE_EX(CDrawerMenuCtrl, "DRAWERMENU.DrawerMenuCtrl.1", 
	0xf4292780, 0xe478, 0x4c95, 0x97, 0x9f, 0x9e, 0x79, 0x48, 0xcb, 0xa, 0xd4) 
 
 
///////////////////////////////////////////////////////////////////////////// 
// Type library ID and version 
 
IMPLEMENT_OLETYPELIB(CDrawerMenuCtrl, _tlid, _wVerMajor, _wVerMinor) 
 
 
///////////////////////////////////////////////////////////////////////////// 
// Interface IDs 
 
const IID BASED_CODE IID_DDrawerMenu = 
		{ 0x132731d6, 0xd7cd, 0x46e8, { 0xa6, 0x67, 0x77, 0x3d, 0x98, 0xcd, 0xbe, 0x78 } }; 
const IID BASED_CODE IID_DDrawerMenuEvents = 
		{ 0x78cbacd2, 0xe277, 0x4bbd, { 0xab, 0xfc, 0xd, 0xcf, 0xec, 0x42, 0x96, 0x8d } }; 
 
 
///////////////////////////////////////////////////////////////////////////// 
// Control type information 
 
static const DWORD BASED_CODE _dwDrawerMenuOleMisc = 
	OLEMISC_ACTIVATEWHENVISIBLE | 
	OLEMISC_SETCLIENTSITEFIRST | 
	OLEMISC_INSIDEOUT | 
	OLEMISC_CANTLINKINSIDE | 
	OLEMISC_RECOMPOSEONRESIZE; 
 
IMPLEMENT_OLECTLTYPE(CDrawerMenuCtrl, IDS_DRAWERMENU, _dwDrawerMenuOleMisc) 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CDrawerMenuCtrl::CDrawerMenuCtrlFactory::UpdateRegistry - 
// Adds or removes system registry entries for CDrawerMenuCtrl 
 
BOOL CDrawerMenuCtrl::CDrawerMenuCtrlFactory::UpdateRegistry(BOOL bRegister) 
{ 
	// TODO: Verify that your control follows apartment-model threading rules. 
	// Refer to MFC TechNote 64 for more information. 
	// If your control does not conform to the apartment-model rules, then 
	// you must modify the code below, changing the 6th parameter from 
	// afxRegApartmentThreading to 0. 
 
	if (bRegister) 
		return AfxOleRegisterControlClass( 
			AfxGetInstanceHandle(), 
			m_clsid, 
			m_lpszProgID, 
			IDS_DRAWERMENU, 
			IDB_DRAWERMENU, 
			afxRegApartmentThreading, 
			_dwDrawerMenuOleMisc, 
			_tlid, 
			_wVerMajor, 
			_wVerMinor); 
	else 
		return AfxOleUnregisterClass(m_clsid, m_lpszProgID); 
} 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CDrawerMenuCtrl::CDrawerMenuCtrl - Constructor 
 
CDrawerMenuCtrl::CDrawerMenuCtrl() 
{ 
	InitializeIIDs(&IID_DDrawerMenu, &IID_DDrawerMenuEvents); 
 
	// TODO: Initialize your control's instance data here. 
	m_nSpaceH = 20; 
	m_nSuperH = 25; 
	m_nSubH = 40; 
	m_nCurSel = -1; 
	m_pImageList = NULL; 
 
	m_bEnter = FALSE; 
	m_nMode = MODE_NONE; 
	m_nWhich = WHICH_NONE; 
	m_nIndex = -1; 
} 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CDrawerMenuCtrl::~CDrawerMenuCtrl - Destructor 
 
CDrawerMenuCtrl::~CDrawerMenuCtrl() 
{ 
	// TODO: Cleanup your control's instance data here. 
	int index = m_superItems.GetSize(); 
	while(index) { delete (m_superItems[--index]); } 
	m_superItems.RemoveAll(); 
 
	if(m_pImageList != NULL) delete m_pImageList; 
} 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CDrawerMenuCtrl::OnDraw - Drawing function 
 
void CDrawerMenuCtrl::OnDraw( 
			CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid) 
{ 
	// TODO: Replace the following code with your own drawing code. 
	//pdc->FillRect(rcBounds, & CBrush(TranslateColor(GetBackColor())); 
	pdc->FillRect(rcBounds, & CBrush(RGB(170, 227, 255))); 
 
	DrawSuperItems(pdc, rcBounds); 
	DrawSubItems(pdc, rcBounds); 
} 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CDrawerMenuCtrl::DoPropExchange - Persistence support 
 
void CDrawerMenuCtrl::DoPropExchange(CPropExchange* pPX) 
{ 
	ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor)); 
	COleControl::DoPropExchange(pPX); 
 
	// TODO: Call PX_ functions for each persistent custom property. 
 
} 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CDrawerMenuCtrl::OnResetState - Reset control to default state 
 
void CDrawerMenuCtrl::OnResetState() 
{ 
	COleControl::OnResetState();  // Resets defaults found in DoPropExchange 
 
	// TODO: Reset any other control state here. 
} 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CDrawerMenuCtrl::AboutBox - Display an "About" box to the user 
 
void CDrawerMenuCtrl::AboutBox() 
{ 
	CDialog dlgAbout(IDD_ABOUTBOX_DRAWERMENU); 
	dlgAbout.DoModal(); 
} 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CDrawerMenuCtrl message handlers 
 
long CDrawerMenuCtrl::SetSuperCurSel(short nCurSel)  
{ 
	// TODO: Add your dispatch handler code here 
	long nOldSel = m_nCurSel; 
	m_nCurSel = (int)nCurSel; 
	return nOldSel; 
} 
 
long CDrawerMenuCtrl::SetSubCurSel(long nSuperIndex, long nCurSel)  
{ 
	// TODO: Add your dispatch handler code here 
	CSuperItem * psi = m_superItems[nSuperIndex]; 
	long nOldSel = psi->m_nCurSel; 
	psi->m_nCurSel = (int)nCurSel; 
	return nOldSel; 
} 
 
BOOL CDrawerMenuCtrl::AddSubItem(short nSuperIndex, short nItemID, short nImageIndex, long FAR* pText)  
{ 
	// TODO: Add your dispatch handler code here 
	CSuperItem * psi = m_superItems[nSuperIndex]; 
	return psi->AddSubItem(nItemID, nImageIndex, * (CString *)pText); 
} 
 
BOOL CDrawerMenuCtrl::AddSuperItem(short nItemID, long FAR* pText)  
{ 
	// TODO: Add your dispatch handler code here 
	CSuperItem * psi = NULL; 
	try 
	{ 
		psi = new CSuperItem(nItemID, * (CString *)pText); 
		m_superItems.Add(psi); 
	} 
	catch(CMemoryException * e) 
	{ 
		AfxMessageBox(_T("CDrawCtrl : Out of memory !")); 
		if(psi != NULL) 
		{ 
			delete psi; 
			psi = NULL; 
		} 
		e->Delete(); 
		return FALSE; 
	} 
	return TRUE; 
} 
 
void CDrawerMenuCtrl::DrawSuperItems(CDC *pDC, const CRect &rcBounds) 
{ 
	CFont * pFont; 
	CBrush brush(RGB(0, 128, 192)); 
 
	if(m_nCurSel < 0 || m_superItems.GetSize() == 0) 
		return; 
 
	///////////////////////上半部分 
 
	pFont = pDC->SelectObject(& m_fontSong); 
	COLORREF color = pDC->SetTextColor(RGB(0, 0, 0)); 
	int mode = pDC->SetBkMode(TRANSPARENT); 
 
	CRect rect(0, 0, rcBounds.right, m_nSuperH * (m_nCurSel + 1)); 
	pDC->FillRect(& rect, & brush); 
	pDC->MoveTo(0, rect.bottom); 
	pDC->LineTo(rect.right, rect.bottom); 
 
	CSuperItem * psi = NULL; 
	CSize size = pDC->GetTextExtent(CString(_T("宋体"))); 
	int x = 0; 
	int dy = (m_nSuperH - size.cy) / 2; 
	int y = dy; 
	for(int i=0; i<=m_nCurSel; i++) 
	{ 
		psi = m_superItems[i]; 
		size = pDC->GetTextExtent(psi->m_strText); 
		x = (rcBounds.right - size.cx) / 2; 
		pDC->TextOut(x, y, psi->m_strText); 
		y += m_nSuperH; 
	} 
 
	///////////////////////下半部分 
 
	int count = m_superItems.GetSize(); 
	rect.bottom = rcBounds.bottom; 
	rect.top = rect.bottom - (count - m_nCurSel - 1) * m_nSuperH; 
	pDC->FillRect(& rect, & brush); 
	pDC->MoveTo(0, rect.bottom); 
	pDC->LineTo(rect.right, rect.bottom); 
 
	size = pDC->GetTextExtent(CString(_T("宋体"))); 
	y = rcBounds.bottom - m_nSuperH + dy; 
	for(i=count-1; i>m_nCurSel; i--) 
	{ 
		psi = m_superItems[i]; 
		size = pDC->GetTextExtent(psi->m_strText); 
		x = (rcBounds.right - size.cx) / 2; 
		pDC->TextOut(x, y, psi->m_strText); 
		y -= m_nSuperH; 
	} 
 
	pDC->SelectObject(pFont); 
	pDC->SetTextColor(color); 
	pDC->SetBkMode(mode); 
} 
 
void CDrawerMenuCtrl::DrawSubItems(CDC *pDC, const CRect &rcBounds) 
{ 
	CFont * pFont; 
	CBrush brushSub(RGB(142, 219, 255)); 
	CBrush brushSel(RGB(221, 221, 221)); 
 
	if(m_nCurSel < 0 || m_superItems.GetSize() == 0) 
		return; 
 
	CSuperItem * psi = m_superItems[m_nCurSel]; 
	CSubArray & sa = psi->m_subItems; 
	int count = sa.GetSize(); 
	int sel = psi->m_nCurSel; 
 
	if(count == 0)// || m_pImageList == NULL) 
		return; 
 
	pFont = pDC->SelectObject(& m_fontSong); 
	COLORREF color = pDC->SetTextColor(RGB(0, 0, 0)); 
	int mode = pDC->SetBkMode(TRANSPARENT); 
 
	CRect rect(0, (m_nCurSel + 1) * m_nSuperH + m_nSpaceH,  
		rcBounds.right, 0); 
	rect.bottom = rect.top + count * m_nSubH; 
	pDC->FillRect(& rect, & brushSub); 
	pDC->MoveTo(0, rect.top); 
	pDC->LineTo(rect.right, rect.top); 
 
	if(sel >= 0) 
	{ 
		CRect rcSel(0, rect.top + sel * m_nSubH, rcBounds.right, 0); 
		rcSel.bottom = rcSel.top + m_nSubH; 
		pDC->FillRect(& rcSel, & brushSel); 
	} 
 
	int iw = 0, ih = 0; 
	POINT point; 
	if(m_pImageList != NULL) 
	{ 
		IMAGEINFO ii; 
		m_pImageList->GetImageInfo(0, & ii); 
		iw = ii.rcImage.right - ii.rcImage.left; 
		ih = ii.rcImage.bottom - ii.rcImage.top; 
		point.x = 10; 
		point.y =(m_nSubH - ih) / 2 + rect.top; 
	} 
 
	CSize size = pDC->GetTextExtent(CString(_T("宋体"))); 
	int x = 0; 
	if(m_pImageList != NULL) 
		x = iw + point.x + 5; 
	int dy = (m_nSubH - size.cy) / 2; 
	int y = rect.top; 
	for(int i=0; iDraw(pDC, sa[i]->m_nImageIndex, 
				point, ILD_TRANSPARENT); 
			point.y += m_nSubH; 
		} 
		else 
		{ 
			size = pDC->GetTextExtent(sa[i]->m_strText); 
			x = (rcBounds.right - size.cx) / 2; 
		} 
		pDC->TextOut(x, y + dy, sa[i]->m_strText); 
 
		y += m_nSubH; 
		pDC->MoveTo(0, y); 
		pDC->LineTo(rcBounds.right, y); 
	} 
 
	pDC->SelectObject(pFont); 
	pDC->SetTextColor(color); 
	pDC->SetBkMode(mode); 
} 
 
long CDrawerMenuCtrl::SetImageList(long FAR* pImageList)  
{ 
	// TODO: Add your dispatch handler code here 
	long pOldIL = (long)m_pImageList; 
	m_pImageList = (CImageList *)pImageList; 
	return pOldIL; 
} 
 
int CDrawerMenuCtrl::SuperItemHitTest(CPoint &point) 
{ 
	CRect rect; 
	GetClientRect(& rect); 
	int index = point.y / m_nSuperH; 
	if(index > m_nCurSel) 
	{ 
		int count = m_superItems.GetSize(); 
		count -= m_nCurSel + 1; 
		int top = rect.bottom - count * m_nSuperH; 
		if(point.y >= top) 
		{ 
			index = (point.y - top) / m_nSuperH; 
			index += m_nCurSel + 1; 
		} 
		else 
			index = -1; 
	} 
	return index; 
} 
 
int CDrawerMenuCtrl::SubItemHitTest(CPoint &point) 
{ 
	CRect rect; 
	GetClientRect(& rect); 
 
	int count = m_superItems[m_nCurSel]->m_subItems.GetSize(); 
	int top = (m_nCurSel + 1) * m_nSuperH + m_nSpaceH; 
	int btm = top + count * m_nSubH; 
	if(point.y >= top && point.y < btm) 
		return (point.y - top) / m_nSubH; 
	else 
		return -1; 
} 
 
void CDrawerMenuCtrl::OnLButtonDown(UINT nFlags, CPoint point)  
{ 
	// TODO: Add your message handler code here and/or call default 
	int index = SuperItemHitTest(point); 
	if(index >= 0) 
	{ 
		m_nMode = MODE_DOWN; 
		m_nWhich = WHICH_SUPER; 
		m_nIndex = index; 
		DrawSuperDown(index); 
	} 
	else 
	{ 
		index = SubItemHitTest(point); 
		if(index >= 0) 
		{ 
			m_nMode = MODE_DOWN; 
			m_nWhich = WHICH_SUB; 
			m_nIndex = index; 
			DrawSubDown(index); 
		} 
		else 
		{ 
			m_nMode = MODE_DOWN; 
			m_nWhich = WHICH_NONE; 
			m_nIndex = -1; 
		} 
	} 
 
	COleControl::OnLButtonDown(nFlags, point); 
} 
 
void CDrawerMenuCtrl::OnLButtonDblClk(UINT nFlags, CPoint point)  
{ 
	// TODO: Add your message handler code here and/or call default 
	OnLButtonDown(nFlags, point); 
	COleControl::OnLButtonDblClk(nFlags, point); 
} 
 
 
int CDrawerMenuCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)  
{ 
	if (COleControl::OnCreate(lpCreateStruct) == -1) 
		return -1; 
	 
	// TODO: Add your specialized creation code here 
	m_fontSong.CreatePointFont(90, _T("宋体")); 
 
	return 0; 
} 
 
void CDrawerMenuCtrl::OnMouseMove(UINT nFlags, CPoint point)  
{ 
	// TODO: Add your message handler code here and/or call default 
	if(m_bEnter == FALSE) 
	{ 
		m_bEnter = TRUE; 
		OnMouseEnter(nFlags, point); 
	} 
	else 
	{ 
		CRect rect; 
		GetClientRect(& rect); 
 
		if(rect.PtInRect(point)) 
		{ 
			if(nFlags & MK_LBUTTON == MK_LBUTTON) 
			{ 
				if(m_nMode == MODE_NONE)	//不可能是MODE_NONE 
				{ 
				} 
				else if(m_nMode == MODE_DOWN) 
				{ 
					int index = SuperItemHitTest(point); 
					if(index >= 0 && m_nWhich == WHICH_SUPER) 
					{ 
						if(index == m_nIndex) 
						{ 
							DrawSuperDown(m_nIndex); 
							return; 
						} 
					} 
					index = SubItemHitTest(point); 
					if(index >= 0 && m_nWhich == WHICH_SUB) 
					{ 
						if(m_nIndex == m_superItems[m_nCurSel]->m_nCurSel) 
						{ 
							DrawSubDown(m_nIndex); 
							return; 
						} 
						if(index == m_nIndex) 
						{ 
							DrawSubDown(m_nIndex); 
							return; 
						} 
					} 
					if(m_nWhich == WHICH_NONE) 
					{ 
					} 
					else if(m_nWhich == WHICH_SUPER) 
					{ 
							DrawSuperSelected(m_nIndex); 
					} 
					else 
					{ 
						DrawSubSelected(m_nIndex); 
					} 
				} 
				else		//不可能是MODE_MOVE 
				{ 
				} 
			} 
			else 
			{ 
				if(m_nMode == MODE_NONE)		//不可能是MODE_NONE 
				{ 
					 
				} 
				else if(m_nMode == MODE_DOWN)		//不可能是MODE_DOWN 
				{ 
				} 
				else 
				{ 
					int index = SuperItemHitTest(point); 
					if(index >= 0) 
					{ 
						if(m_nWhich == WHICH_NONE) 
						{ 
							DrawSuperSelected(index); 
							m_nWhich = WHICH_SUPER; 
							m_nIndex = index; 
						} 
						else if(m_nWhich == WHICH_SUPER) 
						{ 
							if(index == m_nIndex) 
							{ 
							} 
							else 
							{ 
								DrawSuperNormal(m_nIndex); 
								DrawSuperSelected(index); 
								m_nMode = MODE_MOVE; 
								m_nWhich = WHICH_SUPER; 
								m_nIndex = index;						 
							} 
						} 
						else 
						{ 
							DrawSuperSelected(index); 
							DrawSubNormal(m_nIndex); 
							m_nWhich = WHICH_SUPER; 
							m_nIndex = index; 
						} 
						return; 
					} 
					index = SubItemHitTest(point); 
					if(index >= 0) 
					{ 
						if(m_nWhich == WHICH_NONE) 
						{ 
							DrawSubSelected(index); 
							m_nWhich = WHICH_SUB; 
							m_nIndex = index; 
						} 
						else if(m_nWhich == WHICH_SUPER) 
						{ 
							DrawSuperNormal(m_nIndex); 
							DrawSubSelected(index); 
							m_nWhich = WHICH_SUB; 
							m_nIndex = index; 
						} 
						else 
						{ 
							if(index == m_nIndex) 
							{ 
							} 
							else 
							{ 
								if(m_nIndex == m_superItems[m_nCurSel]->m_nCurSel) 
									DrawSubDown(m_nIndex); 
								else 
									DrawSubNormal(m_nIndex); 
								DrawSubSelected(index); 
								m_nWhich = WHICH_SUB; 
								m_nIndex = index; 
							} 
						} 
						return; 
					} 
					if(m_nWhich == WHICH_SUPER) 
					{ 
						DrawSuperNormal(m_nIndex); 
					} 
					else if(m_nWhich == WHICH_SUB) 
					{ 
						if(m_nIndex == m_superItems[m_nCurSel]->m_nCurSel) 
						{ 
							DrawSubDown(m_nIndex); 
						} 
						else 
						{ 
							DrawSubNormal(m_nIndex); 
						} 
					} 
					else 
					{ 
					} 
					m_nWhich = WHICH_NONE; 
					m_nIndex = -1;	 
				} 
			} 
		} 
		else		//收到此消息时不在客户区 
		{ 
			if(nFlags & MK_LBUTTON == MK_LBUTTON) 
			{ 
				if(m_nMode == MODE_NONE)		//不可能是MODE_NONE 
				{ 
				} 
				else if(m_nMode == MODE_DOWN) 
				{ 
					if(m_nWhich == WHICH_NONE) 
					{ 
						OnMouseLeave(nFlags, point); 
						m_bEnter = FALSE; 
					} 
					else if(m_nWhich == WHICH_SUPER) 
					{ 
						DrawSuperSelected(m_nIndex); 
					} 
					else 
					{ 
						DrawSubSelected(m_nIndex); 
					} 
				} 
				else	//不可能是MODE_MOVE 
				{ 
				} 
			} 
			else 
			{ 
				OnMouseLeave(nFlags, point); 
				m_bEnter = FALSE; 
			} 
		} 
	} 
	COleControl::OnMouseMove(nFlags, point); 
} 
 
void CDrawerMenuCtrl::OnMouseEnter(UINT nFlags, CPoint point) 
{ 
	::SetCapture(m_hWnd); 
	if(nFlags & MK_LBUTTON == MK_LBUTTON) 
	{ 
		m_nMode = MODE_NONE; 
		m_nWhich = WHICH_NONE; 
		m_nIndex = -1; 
	} 
	else 
	{ 
		m_nMode = MODE_MOVE; 
		int index = SuperItemHitTest(point); 
		if(index >= 0) 
		{ 
			m_nWhich = WHICH_SUPER; 
			m_nIndex = index; 
			DrawSuperSelected(index); 
			return; 
		} 
		index = SuperItemHitTest(point); 
		if(index >= 0) 
		{ 
			m_nWhich = WHICH_SUB; 
			m_nIndex = index; 
			DrawSubSelected(index); 
		} 
		else 
		{ 
			m_nWhich = WHICH_NONE; 
			m_nIndex = -1; 
		} 
	} 
} 
 
void CDrawerMenuCtrl::OnMouseLeave(UINT nFlags, CPoint point) 
{ 
	if(::GetCapture() == m_hWnd) 
		::ReleaseCapture(); 
	m_nMode = MODE_NONE; 
	m_nWhich = WHICH_NONE; 
	m_nIndex = -1; 
	InvalidateControl(); 
} 
 
void CDrawerMenuCtrl::DrawOneSub(int index, COLORREF crBack, COLORREF crUp, COLORREF crBtm) 
{ 
	CSuperItem * psuper = m_superItems[m_nCurSel]; 
	CSubArray & sa = psuper->m_subItems; 
	CSubItem * psub = sa[index]; 
 
////////////////////////画彩色的矩形 
	int count = sa.GetSize(); 
	int top = (m_nCurSel + 1) * m_nSuperH + m_nSpaceH + index * m_nSubH; 
 
	CRect rect; 
	GetClientRect(& rect); 
 
	rect.top = top; 
	rect.bottom = top + m_nSubH; 
 
	CClientDC dc(this); 
	dc.FillRect(& rect, & CBrush(crBack)); 
 
	CPen pen1, pen2, * pPen; 
	pen1.CreatePen(PS_SOLID, 1, crUp); 
	pen2.CreatePen(PS_SOLID, 1, crBtm); 
	pPen = dc.SelectObject(& pen1); 
	dc.MoveTo(rect.left, rect.top); 
	dc.LineTo(rect.right, rect.top); 
	dc.SelectObject(& pen2); 
	dc.MoveTo(rect.left, rect.bottom); 
	dc.LineTo(rect.right, rect.bottom); 
 
///////////////////////////画图标 
	int iw = 0, ih = 0; 
	POINT point; 
	if(m_pImageList != NULL) 
	{ 
		IMAGEINFO ii; 
		m_pImageList->GetImageInfo(0, & ii); 
		iw = ii.rcImage.right - ii.rcImage.left; 
		ih = ii.rcImage.bottom - ii.rcImage.top; 
		point.x = 10; 
		point.y =(m_nSubH - ih) / 2 + rect.top; 
	} 
	m_pImageList->Draw(& dc, psub->m_nImageIndex,  
		point, ILD_TRANSPARENT); 
 
///////////////////////////画文本 
	int mode = dc.SetBkMode(TRANSPARENT); 
	CFont * pFont = dc.SelectObject(& m_fontSong); 
	CSize size = dc.GetTextExtent(psub->m_strText); 
	COLORREF color = dc.SetTextColor(RGB(0, 0, 0)); 
 
	int y = rect.top + (m_nSubH - size.cy) / 2; 
	int x = point.x + iw + 5; 
	dc.TextOut(x, y, psub->m_strText); 
 
	dc.SetTextColor(color); 
	dc.SelectObject(pFont); 
	dc.SetBkMode(mode); 
} 
 
void CDrawerMenuCtrl::DrawOneSuper(int index, COLORREF crText, COLORREF crRect) 
{ 
	CRect rect1, rect2; 
	GetClientRect(& rect1); 
	rect2 = rect1; 
 
	if(index <= m_nCurSel) 
	{ 
		rect2.top = index * m_nSuperH; 
	} 
	else 
	{ 
		int count = m_superItems.GetSize(); 
		rect2.top = rect1.bottom - (count - index) * m_nSuperH; 
	} 
	rect2.bottom = rect2.top + m_nSuperH; 
 
	rect2.DeflateRect(1, 1, 1, 1); 
 
	CClientDC dc(this); 
	dc.FrameRect(& rect2, & CBrush(crRect)); 
 
	CFont * pFont = dc.SelectObject(& m_fontSong); 
	COLORREF color = dc.SetTextColor(crText); 
	int mode = dc.SetBkMode(TRANSPARENT); 
 
	CSuperItem * psi = m_superItems[index]; 
	CSize size = dc.GetTextExtent(CString(_T("宋体"))); 
	int y = rect2.top + (m_nSuperH - size.cy) / 2 - 1; 
	size = dc.GetTextExtent(psi->m_strText); 
	int x = rect1.left + (rect1.Width() - size.cx) / 2; 
	dc.TextOut(x, y, psi->m_strText); 
 
	dc.SelectObject(pFont); 
	dc.SetTextColor(color); 
	dc.SetBkMode(mode); 
} 
 
void CDrawerMenuCtrl::DrawSuperDown(int index) 
{ 
	DrawOneSuper(index, RGB(255, 255, 255), RGB(255, 255, 255)); 
} 
 
void CDrawerMenuCtrl::DrawSuperNormal(int index) 
{ 
	DrawOneSuper(index, RGB(0, 0, 0), RGB(0, 128, 192)); 
} 
 
void CDrawerMenuCtrl::DrawSuperSelected(int index) 
{ 
	DrawOneSuper(index, RGB(255, 255, 255), RGB(0, 128, 192)); 
} 
 
void CDrawerMenuCtrl::DrawSubDown(int index) 
{ 
	DrawOneSub(index, RGB(221, 221, 221), RGB(0, 0, 0), RGB(0, 0, 0)); 
} 
 
void CDrawerMenuCtrl::DrawSubSelected(int index) 
{ 
	DrawOneSub(index, RGB(252, 205, 135), RGB(255, 255, 255), RGB(128, 128, 128)); 
} 
 
void CDrawerMenuCtrl::DrawSubNormal(int index) 
{ 
	DrawOneSub(index, RGB(124, 219, 255), RGB(0, 0, 0), RGB(0, 0, 0)); 
} 
 
void CDrawerMenuCtrl::OnLButtonUp(UINT nFlags, CPoint point)  
{ 
	// TODO: Add your message handler code here and/or call default 
	CRect rect; 
	GetClientRect(& rect); 
 
	if(rect.PtInRect(point)) 
	{ 
		int index = SuperItemHitTest(point); 
		if(index >= 0) 
		{ 
			if(m_nMode == MODE_NONE)		//不可能是MODE_NONE 
			{ 
			} 
			else if(m_nMode == MODE_DOWN) 
			{ 
				if(m_nWhich == WHICH_NONE) 
				{ 
					m_nMode = MODE_MOVE; 
					m_nWhich = WHICH_SUPER; 
					m_nIndex = index; 
					DrawSuperSelected(index); 
				} 
				else if(m_nWhich == WHICH_SUPER) 
				{ 
					if(index == m_nIndex) 
					{ 
						CSuperItem * psi = m_superItems[index]; 
						CSubArray & sa = psi->m_subItems; 
						int nCurSel = psi->m_nCurSel; 
						if(index != m_nCurSel) 
						{ 
							if(nCurSel >= 0) 
							{ 
								FireSubItemSelected(sa[nCurSel]->m_nItemID,  
									(LPCTSTR)(sa[nCurSel]->m_strText)); 
							} 
							SetSuperCurSel(index); 
							//InvalidateControl(); 
							Refresh(); 
							DrawSuperSelected(index); 
							m_nMode = MODE_MOVE; 
							m_nIndex = index; 
						} 
						else	//此时index == m_nCurSel 
						{ 
							int last = m_superItems.GetSize() - 1; 
							if(index != last) 
							{ 
								CSuperItem * psup = m_superItems[last]; 
								CSubArray & sarr = psup->m_subItems; 
								nCurSel = psup->m_nCurSel; 
								if(nCurSel >= 0) 
								{ 
									FireSubItemSelected(sarr[nCurSel]->m_nItemID,  
										(LPCTSTR)(sarr[nCurSel]->m_strText)); 
								} 
								SetSuperCurSel(last); 
								//InvalidateControl(); 
								Refresh(); 
							} 
							DrawSuperSelected(index); 
							m_nMode = MODE_MOVE; 
							m_nIndex = index; 
						} 
					} 
					else 
					{ 
						DrawSuperNormal(m_nIndex); 
						DrawSuperSelected(index); 
						m_nMode = MODE_MOVE; 
						m_nIndex = index; 
					} 
				} 
				else	//说明上次在sub上Down 
				{ 
					if(m_nIndex == m_superItems[m_nCurSel]->m_nCurSel) 
					{ 
						DrawSubDown(m_nIndex); 
					} 
					else 
					{ 
						DrawSubNormal(m_nIndex); 
					} 
					DrawSuperSelected(index); 
					m_nMode = MODE_MOVE; 
					m_nWhich = WHICH_SUPER; 
					m_nIndex = index; 
				} 
			} 
			else		//不可能是MODE_MOVE 
			{ 
			} 
			return; 
		} 
		index = SubItemHitTest(point); 
		if(index >= 0) 
		{ 
			if(m_nMode == MODE_NONE)	//不可能是MODE_NONE 
			{ 
			} 
			else if(m_nMode == MODE_DOWN) 
			{ 
				if(m_nWhich == WHICH_NONE) 
				{ 
					m_nMode = MODE_MOVE; 
					m_nWhich = WHICH_SUB; 
					m_nIndex = index; 
					DrawSuperSelected(index); 
				} 
				else if(m_nWhich == WHICH_SUPER) 
				{ 
					if(m_nIndex == m_nCurSel) 
					{ 
						DrawSuperNormal(m_nIndex); 
					} 
					else 
					{ 
						DrawSuperNormal(m_nIndex); 
					} 
					DrawSubSelected(index); 
					m_nMode = MODE_MOVE; 
					m_nWhich = WHICH_SUB; 
					m_nIndex = index; 
				} 
				else	//说明上次在sub上Down 
				{ 
					if(index == m_nIndex) 
					{ 
						CSuperItem * psi = m_superItems[m_nCurSel]; 
						CSubArray & sa = psi->m_subItems; 
						int nCurSel = psi->m_nCurSel; 
						if(index != nCurSel) 
						{ 
							if(nCurSel >= 0) 
							{ 
								DrawSubNormal(nCurSel); 
							} 
							SetSubCurSel(m_nCurSel, index); 
							DrawSubSelected(index); 
							m_nMode = MODE_MOVE; 
							FireSubItemSelected(sa[index]->m_nItemID,  
								(LPCTSTR)(sa[index]->m_strText)); 
						} 
						else 
						{ 
							DrawSubSelected(index); 
							m_nMode = MODE_MOVE; 
						} 
					} 
					else 
					{ 
						if(m_nIndex == m_superItems[m_nCurSel]->m_nCurSel) 
							DrawSubDown(m_nIndex); 
						else 
							DrawSubNormal(m_nIndex); 
						DrawSubSelected(index); 
						m_nMode = MODE_MOVE; 
						m_nIndex = index; 
					} 
				} 
			} 
			return; 
		} 
		//此时在Space区域Up 
		InvalidateControl(); 
		m_nMode = MODE_MOVE; 
		m_nWhich = WHICH_NONE; 
		m_nIndex = -1; 
	} 
	else 
	{ 
		OnMouseLeave(nFlags, point); 
		m_bEnter = FALSE; 
	} 
 
	COleControl::OnLButtonUp(nFlags, point); 
}