www.pudn.com > MDITab.rar > PopupMenu.cpp


// PopupMenu.cpp: implementation of the CPopupMenu class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "PopupMenu.h" 
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#define new DEBUG_NEW 
#endif 
 
#ifndef OBM_CHECK 
#define OBM_CHECK 32760 // from winuser.h 
#endif 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
CPopupMenu::CPopupMenu() 
{ 
	crMenuText    = GetSysColor(COLOR_MENUTEXT); 
	crMenuTextSel = GetSysColor(COLOR_HIGHLIGHTTEXT); 
	 
	cr3dFace    = GetSysColor(COLOR_3DFACE); 
	crMenu      = GetSysColor(COLOR_MENU); 
	crHighlight = GetSysColor(COLOR_HIGHLIGHT); 
	cr3dHilight = GetSysColor(COLOR_3DHILIGHT); 
	cr3dShadow  = GetSysColor(COLOR_3DSHADOW); 
	crGrayText  = GetSysColor(COLOR_GRAYTEXT); 
	 
	m_clrBtnFace    = GetSysColor(COLOR_BTNFACE); 
	m_clrBtnHilight = GetSysColor(COLOR_BTNHILIGHT); 
	m_clrBtnShadow  = GetSysColor(COLOR_BTNSHADOW); 
	 
	iSpawnItem = 0; 
	pSpawnItem = NULL; 
	 
	iImageItem = 0; 
	pImageItem = NULL; 
 
	szImage = CSize(20, 20); 
	 
	hMenuFont = NULL; 
	 
	NONCLIENTMETRICS ncm; 
	memset(&ncm, 0, sizeof(ncm)); 
	ncm.cbSize = sizeof(ncm); 
	 
	::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, static_cast(&ncm), 0); 
	 
	hGuiFont = ::CreateFontIndirect(&ncm.lfMenuFont); 
	 
	// David 08/04/98 - start - bold font handling 
	hMenuBoldFont = NULL; 
	CreateBoldFont(); 
	// David 08/04/98 - end - bold font handling 
} 
 
CPopupMenu::~CPopupMenu() 
{ 
	if (iSpawnItem > 0) 
	{ 
		for (int t = 0; t < iSpawnItem; t++) 
		{ 
			if (pSpawnItem[t])  
				delete pSpawnItem[t]; 
		} 
		 
		GlobalFree(static_cast(pSpawnItem)); 
	} 
	if (iImageItem > 0) 
	{ 
		GlobalFree(static_cast(pImageItem)); 
	} 
	if (hMenuFont)  
		::DeleteObject(static_cast(hMenuFont)); 
	if (hMenuBoldFont)  
		::DeleteObject(static_cast(hMenuBoldFont)); 
} 
 
void CPopupMenu::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
{ 
	//	CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC); 
	//	CRect rcItem(lpDrawItemStruct->rcItem); 
	//	pDC->FillSolidRect(rcItem, RGB(255,0,0)); 
	if (lpDrawItemStruct->CtlType == ODT_MENU) 
	{ 
		UINT state    = lpDrawItemStruct->itemState; 
		BOOL bEnab    = !(state & ODS_DISABLED); 
		BOOL bSelect  = (state & ODS_SELECTED) ? TRUE : FALSE; 
		BOOL bChecked = (state & ODS_CHECKED)  ? TRUE : FALSE; 
		// David 08/04/98 - start - bold font handling 
		BOOL bBold    = (state & ODS_DEFAULT) ? TRUE : FALSE; 
		// David 08/04/98 - end - bold font handling 
		 
		SpawnItem* pItem = reinterpret_cast(lpDrawItemStruct->itemData); 
		if (pItem) 
		{ 
			CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC); 
			CFont* pft; 
			// David 08/04/98 - start - bold font handling 
			if (!bBold) 
				pft = CFont::FromHandle(static_cast(hMenuFont) ? hMenuFont : hGuiFont); 
			else  
				pft = CFont::FromHandle(static_cast(hMenuBoldFont) ? hMenuBoldFont : hGuiFont); 
			// David 08/04/98 - end - bold font handling 
			CFont* of = pDC->SelectObject(pft); 
			 
			CRect rc(lpDrawItemStruct->rcItem); 
			CRect rcImage(rc), rcText(rc); 
			rcImage.right = rcImage.left + rc.Height(); 
			rcImage.bottom = rc.bottom; 
			 
			if (pItem->iCmd == -3) // is a separator 
			{ 
				CPen pnDk(PS_SOLID, 1, cr3dShadow); 
				CPen pnLt(PS_SOLID, 1, cr3dHilight); 
				CPen * opn = pDC->SelectObject(&pnDk); 
				pDC->MoveTo(rc.left + 2, rc.top + 2); 
				pDC->LineTo(rc.right - 2, rc.top + 2); 
				pDC->SelectObject(&pnLt); 
				pDC->MoveTo(rc.left + 2, rc.top + 3); 
				pDC->LineTo(rc.right - 2, rc.top + 3); 
				pDC->SelectObject(opn); 
			} 
			else if (pItem->iCmd == -4) // is a title item 
			{ 
				CString cs(pItem->cText), cs1; 
				CRect rcBdr(rcText); 
				 
				if (bSelect && bEnab) 
				{ 
					rcText.top ++; 
					rcText.left += 2; 
				} 
				pDC->FillSolidRect(rcText, crMenu); 
				pDC->DrawText(cs, rcText, DT_VCENTER | DT_CENTER | DT_SINGLELINE); 
				if (bSelect && bEnab) 
					pDC->Draw3dRect(rcBdr, cr3dShadow, cr3dHilight); 
			} 
			else 
			{ 
				rcText.left += rcImage.right + 1; 
				 
				int obk = pDC->SetBkMode(TRANSPARENT); 
				 
				COLORREF ocr; 
				if (bSelect) 
				{ 
					if (pItem->iImageIdx >= 0 || (state & ODS_CHECKED)) 
						pDC->FillSolidRect(rcText, crHighlight); 
					else 
						pDC->FillSolidRect(rc, crHighlight); 
					 
					ocr = pDC->SetTextColor(crMenuTextSel); 
				} 
				else 
				{ 
					if (pItem->iImageIdx >= 0 || (state & ODS_CHECKED)) 
						pDC->FillSolidRect(rcText, crMenu); 
					else 
						pDC->FillSolidRect(rc/*rcText*/, crMenu); 
					ocr = pDC->SetTextColor(crMenuText); 
				} 
				 
				if (pItem->iImageIdx >= 0) 
				{ 
					int ay = (rcImage.Height() - szImage.cy) / 2; 
					int ax = (rcImage.Width()  - szImage.cx) / 2; 
					 
					if (bSelect && bEnab) 
						pDC->Draw3dRect(rcImage, cr3dHilight, cr3dShadow); 
					else 
					{ 
						pDC->Draw3dRect(rcImage, crMenu, crMenu); 
					} 
					 
					 
					if (bEnab) 
					{ 
						ilList.Draw(pDC, pItem->iImageIdx, CPoint(rcImage.left + ax,  
							rcImage.top +ay), ILD_NORMAL); 
					} 
					else 
					{ 
						HICON hIcon = ilList.ExtractIcon(pItem->iImageIdx); 
						pDC->DrawState(CPoint(rcImage.left + ax, rcImage.top + ay), szImage,  
							static_cast(hIcon), DST_ICON | DSS_DISABLED,  
							static_cast(NULL)); 
					} 
				} 
				else 
				{ 
				/* 
				if (bChecked) 
				{ 
				int ay = (rcImage.Height() - szImage.cy) / 2; 
				int ax = (rcImage.Width()  - szImage.cx) / 2; 
				 
				  ilOther.Draw(pDC, 0, CPoint(rcImage.left + ax, rcImage.top + ay - 2), ILD_NORMAL); 
				 } 
				*/		 
					if (bChecked) 
					{ 
						CRect rcTemp = rcImage; 
						rcTemp.DeflateRect(2, 2); 
						DrawCheckmark(*pDC, rcTemp, bSelect); 
					} 
					 
					if (bSelect || lpDrawItemStruct->itemAction == ODA_SELECT)  
					{ 
						COLORREF colorBG = GetSysColor(bSelect ? COLOR_HIGHLIGHT : COLOR_MENU);  	 
						// selected or selection state changed: paint text background 
						CRect rcBG(lpDrawItemStruct->rcItem);	// the whole rectangle 
						rcBG.left += rcImage.Width();			// do not paint over it! 
						CBrush brush(colorBG); 
						CBrush* pOldBrush = pDC->SelectObject(&brush); 
						pDC->PatBlt(rcBG.left, rcBG.top, rcBG.Width(), rcBG.Height(), PATCOPY); 
						pDC->SelectObject(pOldBrush); 
					} 
					 
				} 
				 
				CString cs(pItem->cText), cs1; 
				CSize sz; 
				sz = pDC->GetTextExtent(cs); 
				int ay1 = (rcText.Height() - sz.cy) / 2; 
				rcText.top   += ay1; 
				rcText.left  += 2; 
				rcText.right -= 15; 
				 
				int tf = cs.Find('\t'); 
				if (tf >= 0) 
				{ 
					cs1 = cs.Right(cs.GetLength() - tf - 1); 
					cs = cs.Left(tf); 
					if (!bEnab) 
					{ 
						if (!bSelect) 
						{ 
							CRect rcText1(rcText); 
							rcText1.InflateRect(-1, - 1); 
							pDC->SetTextColor(cr3dHilight); 
							pDC->DrawText(cs, rcText1, DT_VCENTER | DT_LEFT); 
							pDC->DrawText(cs1, rcText1, DT_VCENTER | DT_RIGHT); 
							pDC->SetTextColor(crGrayText); 
							pDC->DrawText(cs, rcText, DT_VCENTER | DT_LEFT); 
							pDC->DrawText(cs1, rcText, DT_VCENTER | DT_RIGHT); 
						} 
						else 
						{ 
							pDC->SetTextColor(crMenu); 
							pDC->DrawText(cs, rcText, DT_VCENTER | DT_LEFT); 
							pDC->DrawText(cs1, rcText, DT_VCENTER | DT_RIGHT); 
						} 
					} 
					else 
					{ 
						pDC->DrawText(cs, rcText, DT_VCENTER | DT_LEFT); 
						pDC->DrawText(cs1, rcText, DT_VCENTER | DT_RIGHT); 
					} 
				} 
				else  
				{ 
					if (!bEnab) 
					{ 
						if (!bSelect) 
						{ 
							CRect rcText1(rcText); 
							rcText1.InflateRect(-1, - 1); 
							pDC->SetTextColor(cr3dHilight); 
							pDC->DrawText(cs, rcText1, DT_VCENTER | DT_LEFT | DT_EXPANDTABS); 
							pDC->SetTextColor(crGrayText); 
							pDC->DrawText(cs, rcText, DT_VCENTER | DT_LEFT | DT_EXPANDTABS); 
						} 
						else 
						{ 
							pDC->SetTextColor(crMenu); 
							pDC->DrawText(cs, rcText, DT_VCENTER | DT_LEFT | DT_EXPANDTABS); 
						} 
					} 
					else 
						pDC->DrawText(cs, rcText, DT_VCENTER | DT_LEFT | DT_EXPANDTABS); 
				} 
				pDC->SetTextColor(ocr); 
				pDC->SetBkMode(obk); 
			} 
			 
			pDC->SelectObject(of); 
		} 
	} 
} 
 
void CPopupMenu::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) 
{ 
	//	lpMeasureItemStruct->itemWidth = 200; 
	//	lpMeasureItemStruct->itemHeight = 25; 
	if (lpMeasureItemStruct->CtlType == ODT_MENU) 
	{ 
		SpawnItem* pItem = reinterpret_cast(lpMeasureItemStruct->itemData); 
		if (pItem) 
		{ 
			if (pItem->iCmd == -3) // is a separator 
			{ 
				lpMeasureItemStruct->itemWidth  = 10; 
				lpMeasureItemStruct->itemHeight = 6; 
			} 
			else 
			{ 
				CString cs(pItem->cText); 
				if (!cs.IsEmpty()) 
				{ 
					CClientDC dc(AfxGetMainWnd()); 
					CFont* pft = CFont::FromHandle(hMenuFont ? hMenuFont : hGuiFont); 
					CFont* of  = dc.SelectObject(pft); 
					CSize osz  = dc.GetOutputTabbedTextExtent(cs, 0, NULL); 
					if (pItem->iCmd == -4) 
					{ 
						CRect rci(0, 0, 0, 0); 
						dc.DrawText(cs, rci, DT_CALCRECT | DT_TOP | DT_VCENTER | DT_SINGLELINE); 
						lpMeasureItemStruct->itemHeight = rci.Height(); 
						lpMeasureItemStruct->itemWidth  = rci.Width(); 
					} 
					else 
					{ 
						lpMeasureItemStruct->itemHeight = szImage.cy + 5; 
						if (osz.cy > static_cast(lpMeasureItemStruct->itemHeight)) 
							lpMeasureItemStruct->itemHeight = static_cast(osz.cy); 
						lpMeasureItemStruct->itemWidth  = osz.cx + 2 + 15; 
						lpMeasureItemStruct->itemWidth += lpMeasureItemStruct->itemHeight > static_cast(szImage.cx)  
							? static_cast(lpMeasureItemStruct->itemHeight) : static_cast(szImage.cx); 
					} 
					dc.SelectObject(of); 
				} 
				else 
				{ 
					lpMeasureItemStruct->itemHeight = szImage.cy + 5; 
					lpMeasureItemStruct->itemWidth  = 100; 
				} 
			} 
		} 
	} 
} 
 
BOOL CPopupMenu::CreateBoldFont() 
{ 
	if (hMenuBoldFont)  
		::DeleteObject(static_cast(hMenuBoldFont)); 
	 
	LOGFONT lgFont; 
	memset(&lgFont, 0, sizeof(LOGFONT)); 
	::GetObject (hMenuFont ? hMenuFont : hGuiFont, sizeof(lgFont), &lgFont); 
	lgFont.lfWeight = FW_BOLD; 
	 
	hMenuBoldFont = CreateFontIndirect(&lgFont); 
	return !!hMenuBoldFont; 
} 
 
BOOL CPopupMenu::AddToolBarResource(UINT resId) 
{ 
	// David 08/04/98 - start - put CMenuSpawn in DLL 
	HINSTANCE hInst = AfxFindResourceHandle(MAKEINTRESOURCE(resId), RT_TOOLBAR); 
	if (!hInst) 
		return FALSE; 
	// David 08/04/98 - end - put CMenuSpawn in DLL 
	 
	HRSRC hRsrc = ::FindResource(/*AfxGetResourceHandle()*/hInst, MAKEINTRESOURCE(resId), RT_TOOLBAR); 
	if (hRsrc == NULL) 
		return FALSE; 
	 
	HGLOBAL hGlb = ::LoadResource(/*AfxGetResourceHandle()*/hInst, hRsrc); 
	if (hGlb == NULL) 
		return FALSE; 
	 
	 
	ToolBarData* pTBData = static_cast(::LockResource(hGlb)); 
	if (pTBData == NULL) 
		return FALSE; 
	 
	ASSERT(pTBData->wVersion == 1); 
	 
	CBitmap bmp; 
	bmp.LoadBitmap(resId); 
	int nBmpItems = ilList.Add(&bmp, RGB(192, 192, 192)); 
	bmp.DeleteObject(); 
	 
	WORD* pItem = reinterpret_cast(pTBData + 1); 
	 
	for (int i = 0; i < pTBData->wItemCount; i++, pItem++) 
	{ 
		if (*pItem != ID_SEPARATOR) 
			AddImageItem(nBmpItems++, static_cast(*pItem)); 
	} 
	// ** it seem that Windows doesn't free these resource (from Heitor Tome) 
    ::UnlockResource(hGlb); 
    ::FreeResource(hGlb); 
	// ** 
	return TRUE; 
} 
 
BOOL CPopupMenu::LoadToolBarResource(UINT resId) 
{ 
	// David 08/04/98 - start - put CMenuSpawn in DLL 
	HINSTANCE hInst = AfxFindResourceHandle(MAKEINTRESOURCE(resId), RT_TOOLBAR); 
	if (!hInst) 
		return FALSE; 
	// David 08/04/98 - end - put CMenuSpawn in DLL 
	 
	HRSRC hRsrc = ::FindResource(/*AfxGetResourceHandle()*/hInst, MAKEINTRESOURCE(resId), RT_TOOLBAR); 
	if (hRsrc == NULL) 
		return FALSE; 
	 
	HGLOBAL hGlb = ::LoadResource(/*AfxGetResourceHandle()*/hInst, hRsrc); 
	if (hGlb == NULL) 
		return FALSE; 
	 
	ToolBarData* pTBData = static_cast(::LockResource(hGlb)); 
	if (pTBData == NULL) 
		return FALSE; 
	 
	ASSERT(pTBData->wVersion == 1); 
	 
	szImage.cx = static_cast(pTBData->wWidth); 
	szImage.cy = static_cast(pTBData->wHeight); 
	 
	if (ilList.Create(szImage.cx, szImage.cy, ILC_COLOR4 | ILC_MASK, pTBData->wItemCount, 0) == FALSE) 
		return FALSE; 
	 
	ilList.SetBkColor(cr3dFace); 
	 
	CBitmap bmp; 
	bmp.LoadBitmap(resId); 
	ilList.Add(&bmp, RGB(192, 192, 192)); 
	bmp.DeleteObject(); 
	 
	WORD* pItem = reinterpret_cast(pTBData + 1); 
	int nBmpItems = 0; 
	for (int i = 0; i < pTBData->wItemCount; i++, pItem++) 
	{ 
		if (*pItem != ID_SEPARATOR) 
			AddImageItem(nBmpItems++, static_cast(*pItem)); 
	} 
	// ** it seem that Windows doesn't free these resource (from Heitor Tome) 
    ::UnlockResource(hGlb); 
    ::FreeResource(hGlb); 
	// ** 
	return TRUE; 
} 
 
void CPopupMenu::AddImageItem(const int idx, WORD cmd) 
{ 
	if (iImageItem == 0) 
		pImageItem = static_cast(GlobalAlloc(GPTR, sizeof(ImageItem))); 
	else 
		pImageItem = static_cast(GlobalReAlloc(static_cast(pImageItem),  
		sizeof(ImageItem) * (iImageItem + 1), GMEM_MOVEABLE | GMEM_ZEROINIT)); 
	 
	ASSERT(pImageItem); 
	pImageItem[iImageItem].iCmd      = static_cast(cmd); 
	pImageItem[iImageItem].iImageIdx = idx; 
	iImageItem ++; 
} 
 
void CPopupMenu::RemapMenu(CMenu* pMenu) 
{ 
	static int iRecurse = 0; 
	iRecurse ++; 
	 
	ASSERT(pMenu); 
	int nItem = pMenu->GetMenuItemCount(); 
	while ((--nItem) >= 0) 
	{ 
		UINT itemId = pMenu->GetMenuItemID(nItem); 
		if (itemId == static_cast(-1)) 
		{ 
			CMenu* pops = pMenu->GetSubMenu(nItem); 
			if (pops) 
				RemapMenu(pops); 
			if (iRecurse > 0) 
			{ 
				CString cs; 
				pMenu->GetMenuString(nItem, cs, MF_BYPOSITION); 
				if (cs != "") 
				{ 
					SpawnItem* sp = AddSpawnItem(cs, (iRecurse == 1) ? -4 : -2); 
					pMenu->ModifyMenu(nItem, MF_BYPOSITION | MF_OWNERDRAW,  
						static_cast(-1), reinterpret_cast(sp)); 
				} 
			} 
		} 
		else 
		{ 
			if (itemId != 0) 
			{ 
				UINT oldState = pMenu->GetMenuState(nItem, MF_BYPOSITION); 
				if (!(oldState & MF_OWNERDRAW) && !(oldState & MF_BITMAP)) 
				{ 
					ASSERT(oldState != (UINT) - 1); 
					CString cs; 
					pMenu->GetMenuString(nItem, cs, MF_BYPOSITION); 
					SpawnItem* sp = AddSpawnItem(cs, itemId); 
					pMenu->ModifyMenu(nItem, MF_BYPOSITION | MF_OWNERDRAW | oldState,  
						static_cast(itemId), reinterpret_cast(sp)); 
				} 
			} 
			else 
			{ 
				UINT oldState = pMenu->GetMenuState(nItem, MF_BYPOSITION); 
				if (!(oldState & MF_OWNERDRAW) && !(oldState & MF_BITMAP)) 
				{ 
					ASSERT(oldState != static_cast(-1)); 
					SpawnItem* sp = AddSpawnItem(_T("--"), -3); 
					pMenu->ModifyMenu(nItem, MF_BYPOSITION | MF_OWNERDRAW | oldState,  
						static_cast(itemId), reinterpret_cast(sp));	  
				} 
			} 
		} 
	} 
	iRecurse --; 
} 
 
CPopupMenu::SpawnItem * CPopupMenu::AddSpawnItem(const TCHAR* txt, const int cmd) 
{ 
	if (iSpawnItem == 0) 
		pSpawnItem = static_cast(GlobalAlloc(GPTR, sizeof(SpawnItem))); 
	else 
		pSpawnItem = static_cast(GlobalReAlloc(static_cast(pSpawnItem),  
		sizeof(SpawnItem) * (iSpawnItem + 1), GMEM_MOVEABLE | GMEM_ZEROINIT)); 
	 
	ASSERT(pSpawnItem); 
	 
	SpawnItem* p = new SpawnItem; 
	ASSERT(p); 
	pSpawnItem[iSpawnItem] = p; 
	lstrcpy(p->cText, txt); 
	p->iCmd = cmd; 
	 
	if (cmd >= 0) 
		p->iImageIdx = FindImageItem(cmd); 
	else p->iImageIdx = cmd; 
	 
	iSpawnItem++; 
	return p; 
} 
 
int CPopupMenu::FindImageItem(const int cmd) 
{ 
	for (int t = 0; t < iImageItem; t++) 
	{ 
		if (pImageItem[t].iCmd == cmd) 
			return pImageItem[t].iImageIdx; 
	} 
	return -1; 
} 
 
void CPopupMenu::EnableMenuItems(CMenu* pMenu, CWnd* pParent) 
{ 
	ASSERT(pMenu); 
	ASSERT(pParent); 
	 
	int nItem = pMenu->GetMenuItemCount(); 
	CCmdUI state; 
	state.m_pMenu     = pMenu; 
	state.m_nIndex    = nItem - 1; 
	state.m_nIndexMax = nItem; 
	 
	while ((--nItem) >= 0) 
	{ 
		UINT itemId = pMenu->GetMenuItemID(nItem); 
		if (itemId == static_cast(-1)) 
		{ 
			CMenu* pops = pMenu->GetSubMenu(nItem); 
			if (pops) 
				EnableMenuItems(pops, pParent); 
		} 
		else 
		{ 
			if (itemId != 0) 
			{ 
				state.m_nID = itemId; 
				pParent->OnCmdMsg(itemId, CN_UPDATE_COMMAND_UI, &state, NULL); 
				state.DoUpdate(pParent, TRUE); 
			} 
		} 
		state.m_nIndex = nItem - 1; 
	} 
} 
 
BOOL CPopupMenu::DrawCheckmark(CDC& dc, const CRect& rc, BOOL bSelected) 
{ 
	// Use Windows standard 
	HBITMAP hbmCheck = ::LoadBitmap(NULL, reinterpret_cast(OBM_CHECK)); 
	 
	// Center bitmap in distination rectangle 
	BITMAP bm; 
	::GetObject(hbmCheck, sizeof(bm), &bm); 
	int cx = bm.bmWidth; 
	int cy = bm.bmHeight; 
 
	CRect rcDest = rc; 
	CPoint ptSrc = -CPoint((rc.Width() - cx)/2, (rc.Height() - cy)/2); 
 
	// Select checkmark into memory DC 
	CDC memdc; 
	memdc.CreateCompatibleDC(&dc); 
	HBITMAP hOldBM = reinterpret_cast(::SelectObject(memdc, hbmCheck)); 
 
	// Set background color based on selected state 
	COLORREF colorOld = dc.SetBkColor(GetSysColor(bSelected ? COLOR_MENU : COLOR_3DLIGHT)); 
	dc.BitBlt(rcDest.left, rcDest.top, rcDest.Width(), rcDest.Height(), 
		&memdc, ptSrc.x, ptSrc.y, SRCCOPY); 
	dc.SetBkColor(colorOld); 
 
	::SelectObject(memdc, hOldBM); // restore 
 
	// draw pushed-in hilight. 
	dc.DrawEdge(&rcDest, BDR_SUNKENOUTER, BF_RECT); 
 
	return TRUE; 
}