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

📄 cbmpmenu.cpp

📁 桌面台球3D 开发环境VC 库DIRECTX8.1以上
💻 CPP
📖 第 1 页 / 共 3 页
字号:

		//draw background
		CBrush brush;
		CBitmap bmp;
		WORD      Bits[8] = { 0x0055, 0x00aa, 0x0055, 0x00aa,
							 0x0055, 0x00aa, 0x0055, 0x00aa };
		bmp.CreateBitmap( 8, 8, 1, 1, &Bits );
		//hatched background
		brush.CreatePatternBrush(&bmp);

		//if item is selected, then we draw plain background
		CBrush brush1(GetSysColor(COLOR_MENU));

		CBrush* oldBr = dc.SelectObject(bSelected ? &brush1 : &brush);

		//the text color is used by pattern brush
		dc.SetTextColor(GetSysColor(COLOR_3DHIGHLIGHT));
		dc.SetBkColor(GetSysColor(COLOR_MENU));

		if(!hbmCheck)
			dc.ExtFloodFill(rc.left+1, rc.top+1, GetSysColor(bSelected?COLOR_HIGHLIGHT:COLOR_MENU), FLOODFILLSURFACE);
		else
			dc.ExtFloodFill(rc.left+1, rc.top+1, GetSysColor(COLOR_MENU), FLOODFILLSURFACE);

		//cleanup
		dc.SelectObject(oldBr);
		brush.DeleteObject();
		brush1.DeleteObject();
		bmp.DeleteObject();
	}

	return TRUE;
}

int MenuToolBar::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	lpCreateStruct->style &= ~WS_VISIBLE;
	if (CToolBar::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	ModifyStyleEx(0, WS_EX_TOOLWINDOW);
	GetToolBarCtrl().SetExtendedStyle(TBSTYLE_EX_DRAWDDARROWS);

	NONCLIENTMETRICS nc;
	ZeroMemory(&nc, sizeof(nc));
	nc.cbSize = sizeof(nc);
	SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &nc, 0);
	m_oMenuFont.CreateFontIndirect(&nc.lfMenuFont);
	SetFont(&m_oMenuFont);

	return 0;
}

void MenuToolBar::OnLButtonDown(UINT nFlags, CPoint point) 
{
	//Calculate button index and post a user define message to ourselves..so that this function returns immediately
	int nBtnIndex = GetToolBarCtrl().HitTest(&point);

	TBBUTTON tbb;
	GetToolBarCtrl().GetButton(nBtnIndex, &tbb);

	//if this button is disabled or grayed down...then we simply return
	BOOL bRet = (((MENUITEMINFO*)(tbb.dwData))->fState & MF_GRAYED) || 
					(((MENUITEMINFO*)(tbb.dwData))->fState & MF_DISABLED);

	if(bRet)
		return;

	if(nBtnIndex >= 0)
	{
		if(m_nLastLBDownIndex != nBtnIndex)
		{
			//If already another popup menu was opened, then we need to close that window
			((CBmpMenu*)GetParent())->DestroySubMenus();

			PostMessage(WM_LBUTTONDOWNAFTER, nFlags, MAKELPARAM(point.x, point.y));

			m_nLastLBDownIndex = nBtnIndex;
		}
	}
}

void MenuToolBar::OnPostLbuttonMsg(UINT nFlags, LPARAM lp)
{
	//claculate the button index
	CPoint point(LOWORD(lp), HIWORD(lp));

	int nBtnIndex = GetToolBarCtrl().HitTest(&point);
	TBBUTTON tbb;
	GetToolBarCtrl().GetButton(nBtnIndex, &tbb);

	//if the click was on a button corresponding to popup item, then we need to open up popup menu 
	//and don't pass the message up windows hirarchy.
	if(tbb.dwData && ((MENUITEMINFO*)(tbb.dwData))->hSubMenu)
	{
		((CBmpMenu*)GetParent())->SendMessage(WM_POPUPSUBMENU, lp, (MENU_SELECTFIRSTITEM & nFlags)?MENU_SELECTFIRSTITEM:0);
		return;
	}

	//If this is a valid button and no submenu then send wm_command message to owner and close all menus
	((CBmpMenu*)GetParent())->m_pOwnerWnd->PostMessage(WM_COMMAND, MAKEWPARAM(tbb.idCommand, 0), 0);
	((CBmpMenu*)GetParent())->DestroyRootMenu();
}


void MenuToolBar::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	int nBtnIndex = GetToolBarCtrl().HitTest(&point);

	//skip mouse move message if this button is disabled or grayed or inactive
	TBBUTTON tbb;
	GetToolBarCtrl().GetButton(nBtnIndex, &tbb);

	//if this button is disabled or grayed down...then we simply return
	BOOL bRet = (((MENUITEMINFO*)(tbb.dwData))->fState & MF_GRAYED) || 
					(((MENUITEMINFO*)(tbb.dwData))->fState & MF_DISABLED);

	if(bRet)
		return;

	//skip WM_MOUSEMOVE message if the last mouse position is same as curent one.
	static CPoint pt(0,0);

	if(point != pt)
		pt = point;
	else
		return;

	if(nBtnIndex >= 0)
	{
		if(m_nLastHoverIndex != nBtnIndex)
		{
			m_nLastHoverIndex = nBtnIndex;
			m_oHoverPt = point;

			//Hovetrack only for submenu items
			TRACKMOUSEEVENT tme = {sizeof(tme), TME_HOVER, m_hWnd, 0};

			_TrackMouseEvent(&tme);
		}
	}
	CToolBar::OnMouseMove(nFlags, point);
}

LRESULT MenuToolBar::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
	// TODO: Add your specialized code here and/or call the base class
	//Garb WM_MOUSEHOVER message
	if(message == WM_MOUSEHOVER)
	{
		if(m_nLastHoverIndex >= 0)
		{
			TBBUTTON tbb;
			GetToolBarCtrl().GetButton(m_nLastHoverIndex, &tbb);

			if(tbb.dwData)
			{
				//pass on left mouse down event for submenu items
				if(((MENUITEMINFO*)(tbb.dwData))->hSubMenu)
				{
					SendMessage(WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(m_oHoverPt.x, m_oHoverPt.y));		
					SendMessage(WM_LBUTTONUP, MK_LBUTTON, MAKELPARAM(m_oHoverPt.x, m_oHoverPt.y));	
				}
				else //delete any submenus present for this menu
				{
					((CBmpMenu*)GetParent())->DestroySubMenus();
					m_nLastLBDownIndex = -1; //reset after destroying submenus
				}
			}
		}
	}

	if(message == WM_RESETDATA)
		m_nLastLBDownIndex = -1;

	return CToolBar::DefWindowProc(message, wParam, lParam);
}

//Grab Key down events
BOOL MenuToolBar::KeyboardFilter(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	//On escape key, we close all menu windows
	if(nChar==VK_ESCAPE)
	{
		((CBmpMenu*)GetParent())->DestroyRootMenu();
		return TRUE;
	}

	//On left arrow...we need to close the current submenu and go to parent
	if(nChar == VK_LEFT)
	{
		CWnd *pWnd = GetParent()->GetParent();

		if(pWnd && IsWindow(pWnd->m_hWnd) && pWnd->IsKindOf(RUNTIME_CLASS(CBmpMenu)))
		{
			((CBmpMenu*)pWnd)->DestroySubMenus();

			(CBmpMenu*)pWnd->SendMessage(WM_RESETDATA, 0, 0);
		}
		return TRUE;
	}

	if((nChar == VK_RIGHT) || (nChar == VK_RETURN))
	{	
		if(m_nSelectedItem != -1)
		{
			int ndx = CommandToIndex(m_nSelectedItem);

			if(ndx >= 0)
			{
				TBBUTTON tbb;
				GetToolBarCtrl().GetButton(ndx, &tbb);

				CRect rect;
				GetToolBarCtrl().GetItemRect(ndx, &rect);

				if(tbb.dwData)
				{
					//pass on left mouse down event for submenu items..also need to select the first submenu item
					if((((MENUITEMINFO*)(tbb.dwData))->hSubMenu) || (nChar == VK_RETURN))
					{
						m_nLastLBDownIndex = -1;
						SendMessage(WM_LBUTTONDOWN, MK_LBUTTON|MENU_SELECTFIRSTITEM, MAKELPARAM(rect.left+1, rect.top+1));		
						SendMessage(WM_LBUTTONUP, MK_LBUTTON|MENU_SELECTFIRSTITEM, MAKELPARAM(rect.left+1, rect.top+1));
					}
				}
			}
		}

		return TRUE;
	}

	//pass on for further processing
	OnChar(nChar, nRepCnt, nFlags);

	return FALSE;
}

void MenuToolBar::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	// TODO: Add your message handler code here and/or call default
	if(KeyboardFilter(nChar,nRepCnt,nFlags)) 
		return;

	CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
}

// User typed a char into menu. Look for item with & preceeding the char typed.
void MenuToolBar::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	// TODO: Add your message handler code here and/or call default
	//////////////////
	UINT iCurrentItem = (UINT)-1; // guaranteed higher than any command ID
	CUIntArray arItemsMatched;		// items that match the character typed

	UINT nItem = GetToolBarCtrl().GetButtonCount();
	
	for (UINT i=0; i< nItem; i++) 
	{
		// get menu info
		TBBUTTON tbb;
		GetToolBarCtrl().GetButton(i, &tbb);

		if(tbb.dwData)
		{
			if(((MENUITEMINFO*)(tbb.dwData))->dwTypeData)
			{
				CString text = ((MENUITEMINFO*)(tbb.dwData))->dwTypeData;
				int iAmpersand = text.Find('&');
				if (iAmpersand >=0 && toupper(nChar)==toupper(text[iAmpersand+1]))
					arItemsMatched.Add(i);
			}
			if ((UINT)SendMessage(TB_GETHOTITEM, 0, 0) == i)
				iCurrentItem = i; // note index of current item
		}
	}
	// arItemsMatched now contains indexes of items that match the char typed.
	UINT nFound = arItemsMatched.GetSize();
	if (nFound == 0)
	{
		//notify owner window and take corresponding action
		UINT lRet = (((CBmpMenu*)GetParent())->m_pOwnerWnd)->SendMessage(WM_MENUCHAR, MAKEWPARAM(nChar, MF_POPUP), 
													(LPARAM)((CBmpMenu*)GetParent())->m_hMenu);

		switch(HIWORD(lRet))
		{
		case MNC_CLOSE:
			((CBmpMenu*)GetParent())->DestroyRootMenu();
			break;

		case MNC_SELECT:
			//select the menu item
			break;

		case MNC_EXECUTE:
			(((CBmpMenu*)GetParent())->m_pOwnerWnd)->SendMessage(WM_COMMAND, LOWORD(lRet), 0);			
			break;
		}

		return;
	}

	else if (nFound==1)
	{
		CRect rect;
		GetToolBarCtrl().GetItemRect(arItemsMatched[0], &rect);
		SendMessage(TB_SETHOTITEM, arItemsMatched[0], 0);
		m_nLastLBDownIndex = -1;
		SendMessage(WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(rect.left+1, rect.top+1));		
		SendMessage(WM_LBUTTONUP, MK_LBUTTON, MAKELPARAM(rect.left+1, rect.top+1));
		return;
	}

	// more than one found--return 1st one past current selected item;
	UINT iSelect = 0;
	for (i=0; i < nFound; i++) {
		if (arItemsMatched[i] > iCurrentItem) {
			iSelect = i;
			break;
		}
	}

	SendMessage(TB_SETHOTITEM, iSelect, 0);
}

HBITMAP 
GetSysColorBitmap(HDC hDC, HBITMAP hSourceBitmap, BOOL bMono, BOOL bSelected)
{
	struct _COLORMAPTABLE{
		COLORREF	rgb;
		int			nSysColor;
	};

	_COLORMAPTABLE _ColorMap[]=
	{
		// mapping from color in DIB to system color
		{ RGB(0x00, 0x00, 0x00),  COLOR_BTNTEXT },       // black
		{ RGB(0x80, 0x80, 0x80),  COLOR_BTNSHADOW },     // dark gray
		{ RGB(0xC0, 0xC0, 0xC0),  COLOR_MENU },       // bright gray
		{ RGB(0xFF, 0xFF, 0xFF),  COLOR_BTNHIGHLIGHT }   // white
	};

	HBITMAP hOldSourceBitmap, hOldDestBitmap, hDestBitmap;
	HDC hMemSrc, hMemDest;
	int height, width;
	int i, j;
	BITMAP SrcBitmap;

	if(bSelected && !bMono)
		_ColorMap[2].nSysColor= COLOR_HIGHLIGHT;
	else
		_ColorMap[2].nSysColor= COLOR_MENU;

	// Step 1: Create a memory DC for the source and destination bitmaps
	//         compatible with the device used.

	hMemSrc = CreateCompatibleDC(hDC);
	hMemDest= CreateCompatibleDC(hDC);


	// Step 2: Get the height and width of the source bitmap.

	GetObject(hSourceBitmap, sizeof(BITMAP), (LPSTR)&SrcBitmap);
	width = SrcBitmap.bmWidth;
	height = SrcBitmap.bmHeight;


	// Step 3: Select the source bitmap into the source DC. Create a
	//         destination bitmap, and select it into the destination DC.

	hOldSourceBitmap = (HBITMAP)SelectObject(hMemSrc, hSourceBitmap);
	hDestBitmap = CreateBitmap(height, width, (bMono)?1:SrcBitmap.bmPlanes,
		(bMono)?1:SrcBitmap.bmBitsPixel, NULL);

	if (hDestBitmap)
	{
		hOldDestBitmap = (HBITMAP)SelectObject(hMemDest, hDestBitmap);

		// Step 4: Copy the pixels from the source to the destination.

		for (i = 0; i < width; ++i)
		{
			for (j = 0; j < height; ++j)
			{
				//Get the color of source bitmap
				COLORREF rgb = GetPixel(hMemSrc, i, j);
				
				SetPixel(hMemDest, i, j, rgb);

				if(!bMono)
				{
					//check if we need to change this color
					for(int k=0; k<sizeof(_ColorMap)/sizeof(_ColorMap[0]); k++)
					{
						if(rgb == _ColorMap[k].rgb)
						{
							SetPixel(hMemDest, i, j, GetSysColor(_ColorMap[k].nSysColor));
							break;
						}
					}
				}
			}
		}
	}


	// Step 5: Destroy the DCs.

	SelectObject(hMemSrc, hOldSourceBitmap);
	SelectObject(hMemDest, hOldDestBitmap);
	DeleteDC(hMemDest);
	DeleteDC(hMemSrc);


	// Step 6: Return the rotated bitmap.

	return(hDestBitmap);

}

⌨️ 快捷键说明

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