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

📄 cmdbar.h

📁 WTL开发的一个写字板程序 ,很有借鉴意义
💻 H
📖 第 1 页 / 共 5 页
字号:
		return 0;
	}

	LRESULT OnHookSysChar(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
	{
		bHandled = FALSE;
#ifdef _CMDBAR_EXTRA_TRACE
		ATLTRACE2(atlTraceUI, 0, "CmdBar - Hook WM_SYSCHAR (0x%2.2X)\n", wParam);
#endif

		if(!m_bMenuActive && m_hWndHook != m_hWnd && wParam != VK_SPACE)
			bHandled = TRUE;
		return 0;
	}

	LRESULT OnHookKeyDown(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
	{
#ifdef _CMDBAR_EXTRA_TRACE
		ATLTRACE2(atlTraceUI, 0, "CmdBar - Hook WM_KEYDOWN (0x%2.2X)\n", wParam);
#endif
		bHandled = FALSE;

		if(wParam == VK_ESCAPE)
		{
			if(m_bMenuActive && !m_bContextMenu)
			{
				int nHot = GetHotItem();
				if(nHot == -1)
					nHot = m_nPopBtn;
				if(nHot == -1)
					nHot = 0;
				SetHotItem(nHot);
				bHandled = TRUE;
				TakeFocus();
				m_bEscapePressed = true; // To keep focus
			}
			else if(::GetFocus() == m_hWnd && m_wndParent.IsWindow())
			{
				SetHotItem(-1);
				GiveFocusBack();
				bHandled = TRUE;
			}
		}
		else if(wParam == VK_RETURN || wParam == VK_UP || wParam == VK_DOWN)
		{
			if(!m_bMenuActive && ::GetFocus() == m_hWnd && m_wndParent.IsWindow())
			{
				int nHot = GetHotItem();
				if(nHot != -1)
				{
					if(wParam != VK_RETURN)
						PostMessage(WM_KEYDOWN, VK_DOWN, 0L);
				}
				else
				{
					ATLTRACE2(atlTraceUI, 0, "CmdBar - Can't find hot button\n");
				}
			}
			if(wParam == VK_RETURN && m_bMenuActive)
			{
				PostMessage(TB_SETHOTITEM, (WPARAM)-1, 0L);
				m_nNextPopBtn = -1;
				GiveFocusBack();
			}
		}
		else if(wParam == VK_LEFT || wParam == VK_RIGHT)
		{
			if(m_bMenuActive && !(wParam == VK_RIGHT && m_bPopupItem))
			{
				bool bAction = false;
				int nCount = ::GetMenuItemCount(m_hMenu);

				if(wParam == VK_LEFT && s_pCurrentBar->m_stackMenuWnd.GetSize() == 1)
				{
					bAction = true;
					m_nNextPopBtn = m_nPopBtn - 1;
					if(m_nNextPopBtn < 0)
						m_nNextPopBtn = nCount - 1;
				}
				else if(wParam == VK_RIGHT)
				{
					bAction = true;
					m_nNextPopBtn = m_nPopBtn + 1;
					if(m_nNextPopBtn >= nCount)
						m_nNextPopBtn = 0;
				}
				HWND hWndMenu = m_stackMenuWnd.GetCurrent();
				ATLASSERT(hWndMenu != NULL);

				// Close the popup menu
				if(bAction)
				{
					::PostMessage(hWndMenu, WM_KEYDOWN, VK_ESCAPE, 0L);
					if(wParam == VK_RIGHT)
					{
						int cItem = m_stackMenuWnd.GetSize() - 1;
						while(cItem >= 0)
						{
							hWndMenu = m_stackMenuWnd[cItem];
							if(hWndMenu)
							{
								::PostMessage(hWndMenu, WM_KEYDOWN, VK_ESCAPE, 0L);
							}
							cItem--;
						}
					}
					bHandled = TRUE;
				}
			}
		}
		return 0;
	}

	LRESULT OnHookNextMenu(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
#ifdef _CMDBAR_EXTRA_TRACE
		ATLTRACE2(atlTraceUI, 0, "CmdBar - Hook WM_NEXTMENU\n");
#endif
		bHandled = FALSE;
		return 1;
	}

 	LRESULT OnHookChar(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
	{
#ifdef _CMDBAR_EXTRA_TRACE
		ATLTRACE2(atlTraceUI, 0, "CmdBar - Hook WM_CHAR (0x%2.2X)\n", wParam);
#endif
		bHandled = (wParam == VK_ESCAPE);
		if(wParam != VK_ESCAPE && wParam != VK_RETURN && m_bMenuActive)
		{
			SetHotItem(-1);
			GiveFocusBack();
		}
		return 0;
	}

// Implementation - ownerdraw overrideables and helpers
	void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
	{
		_MenuItemData* pmd = (_MenuItemData*)lpDrawItemStruct->itemData;
		CDCHandle dc = lpDrawItemStruct->hDC;
		const RECT& rcItem = lpDrawItemStruct->rcItem;

		if(pmd->fType & MFT_SEPARATOR)
		{
			// draw separator
			RECT rc = rcItem;
			rc.top += (rc.bottom - rc.top) / 2;	// vertical center
			dc.DrawEdge(&rc, EDGE_ETCHED, BF_TOP);	// draw separator line
		}
		else		// not a separator
		{
			//== Begin, Ramon Smits 22 april 2000
			if(lpDrawItemStruct->itemID == SIDEBAR_ID)
			{
				DrawSideBar(dc, rcItem, pmd->lpstrText);
				return;
			}
			//== End

			BOOL bDisabled = lpDrawItemStruct->itemState & ODS_GRAYED;
			BOOL bSelected = lpDrawItemStruct->itemState & ODS_SELECTED;
			BOOL bChecked = lpDrawItemStruct->itemState & ODS_CHECKED;
			BOOL bHasImage = FALSE;

			if(LOWORD(lpDrawItemStruct->itemID) == (WORD)-1)
				bSelected = FALSE;
			RECT rcButn = { rcItem.left, rcItem.top, rcItem.left + m_szButton.cx, rcItem.top + m_szButton.cy };			// button rect
			::OffsetRect(&rcButn, 0, ((rcItem.bottom - rcItem.top) - (rcButn.bottom - rcButn.top)) / 2);	// center vertically

			int iButton = pmd->iButton;
			if(iButton >= 0)
			{
				bHasImage = TRUE;

				// calc drawing point
				SIZE sz = { rcButn.right - rcButn.left - m_szBitmap.cx, rcButn.bottom - rcButn.top - m_szBitmap.cy };
				sz.cx /= 2;
				sz.cy /= 2;
				POINT point = { rcButn.left + sz.cx, rcButn.top + sz.cy };

				// draw disabled or normal
				if(!bDisabled)
				{
					// normal - fill background depending on state
					if(!bChecked || bSelected)
						dc.FillRect(&rcButn, (HBRUSH)LongToPtr((bChecked && !bSelected) ? (COLOR_3DLIGHT + 1) : (COLOR_MENU + 1)));
					else
					{
						COLORREF crTxt = dc.SetTextColor(::GetSysColor(COLOR_BTNFACE));
						COLORREF crBk = dc.SetBkColor(::GetSysColor(COLOR_BTNHILIGHT));
						CBrush hbr(CDCHandle::GetHalftoneBrush());
						dc.SetBrushOrg(rcButn.left, rcButn.top);
						dc.FillRect(&rcButn, hbr);
						
						dc.SetTextColor(crTxt);
						dc.SetBkColor(crBk);
					}

					// draw pushed-in or popped-out edge
					if(bSelected || bChecked)
					{
						RECT rc2 = rcButn;
						dc.DrawEdge(&rc2, bChecked ? BDR_SUNKENOUTER : BDR_RAISEDINNER, BF_RECT);
					}
					// draw the image
					::ImageList_Draw(m_hImageList, iButton, dc, point.x, point.y, ILD_TRANSPARENT);
				}
				else
				{
					DrawBitmapDisabled(dc, iButton, point);
				}
			}
			else
			{
				// no image - look for custom checked/unchecked bitmaps
				CMenuItemInfo info;
				info.fMask = MIIM_CHECKMARKS;
				::GetMenuItemInfo((HMENU)lpDrawItemStruct->hwndItem, lpDrawItemStruct->itemID, MF_BYCOMMAND, &info);
				if(bChecked || info.hbmpUnchecked)
					bHasImage = Draw3DCheckmark(dc, rcButn, bSelected, bChecked ? info.hbmpChecked : info.hbmpUnchecked);
			}

			// draw item text
			int cxButn = m_szButton.cx;
			COLORREF colorBG = ::GetSysColor(bSelected ? COLOR_HIGHLIGHT : COLOR_MENU);
			if(bSelected || lpDrawItemStruct->itemAction == ODA_SELECT)
			{
				RECT rcBG = rcItem;
				if(bHasImage)
					rcBG.left += cxButn + s_kcxGap;
				dc.FillRect(&rcBG, (HBRUSH)LongToPtr(bSelected ? (COLOR_HIGHLIGHT + 1) : (COLOR_MENU + 1)));
				// == Begin, Ramon Smits 22-04-2000
		//		if(bSelected)
		//			dc.Draw3dRect(&rcBG, GetSysColor(COLOR_3DDKSHADOW), GetSysColor(COLOR_3DHILIGHT));
				// == End
			}else{
			}

			// calc text rectangle and colors
			RECT rcText = rcItem;
			rcText.left += cxButn + s_kcxGap + s_kcxTextMargin;
			rcText.right -= cxButn;
			dc.SetBkMode(TRANSPARENT);
			COLORREF colorText = ::GetSysColor(bDisabled ?  COLOR_GRAYTEXT : (bSelected ? COLOR_HIGHLIGHTTEXT : COLOR_MENUTEXT));
			COLORREF colorAccellerator = ::GetSysColor(bDisabled ?  COLOR_GRAYTEXT : (bSelected ? COLOR_HIGHLIGHTTEXT : COLOR_HIGHLIGHT)); //RS
			// font already selected by Windows
			if(bDisabled && (!bSelected || colorText == colorBG))
			{
				// disabled - draw shadow text shifted down and right 1 pixel (unles selected)
				RECT rcDisabled = rcText;
				::OffsetRect(&rcDisabled, 1, 1);
				DrawMenuText(dc, rcDisabled, pmd->lpstrText, GetSysColor(COLOR_3DHILIGHT));
			}
			// == Begin (altered), Ramon Smits 22-04-2000
			DrawMenuText(dc, rcText, pmd->lpstrText, colorText, colorAccellerator);
			// == End, Original Begin
			// DrawMenuText(dc, rcText, pmd->lpstrText, colorText); // finally!
			// == End
		}
	}

	void DrawMenuText(CDCHandle& dc, RECT& rc, LPCTSTR lpstrText, COLORREF color)
	{
		int nTab = -1;
		for(int i = 0; i < lstrlen(lpstrText); i++)
		{
			if(lpstrText[i] == '\t')
			{
				nTab = i;
				break;
			}
		}
		dc.SetTextColor(color);
		dc.DrawText(lpstrText, nTab, &rc, DT_SINGLELINE | DT_LEFT | DT_VCENTER);
		dc.SetTextColor( GetSysColor(COLOR_HIGHLIGHT) );
		if(nTab != -1)
			dc.DrawText(&lpstrText[nTab + 1], -1, &rc, DT_SINGLELINE | DT_RIGHT | DT_VCENTER);
		dc.SetTextColor(color);
	}
	
	// == Begin, Ramon Smits 22-04-2000
	// This version takes 2 colors, one for the text and one for the shortcut. This way
	// both can have a different color.
	void DrawMenuText(CDCHandle& dc, RECT& rc, LPCTSTR lpstrText, COLORREF colorText, COLORREF colorAccellerator)
	{
		int nTab = -1;
		for(int i = 0; i < lstrlen(lpstrText); i++)
		{
			if(lpstrText[i] == '\t')
			{
				nTab = i;
				break;
			}
		}
		dc.SetTextColor(colorText);
		dc.DrawText(lpstrText, nTab, &rc, DT_SINGLELINE | DT_LEFT | DT_VCENTER);
		dc.SetTextColor( colorAccellerator );
		if(nTab != -1)
			dc.DrawText(&lpstrText[nTab + 1], -1, &rc, DT_SINGLELINE | DT_RIGHT | DT_VCENTER);
		dc.SetTextColor(colorText);
	}
	// == End

	// == Begin, Ramon Smits 22-04-2000
	// This renders a gradient bar from top to botten in the width that is specified in the 
	// item structure.
	void DrawSideBar (CDCHandle& dc, const RECT& grrect, LPCTSTR lpstrSidebarText)
	{
		RECT rct;
		dc.GetClipBox(&rct);
		int iWidth = grrect.right - grrect.left;
//		int iHeight = grrect.top - grrect.bottom;
		int iSideBarHeight = rct.bottom-rct.top;
//		int iSideBarWidth = rct.right-rct.left;

		COLORREF right	= GetSysColor(COLOR_ACTIVECAPTION);
		COLORREF left	= GetSysColor(27); // COLOR_GRADIENTACTIVECAPTION

		COLOR16 r = (COLOR16) ((left & 0x000000FF)<<8);
		COLOR16 g = (COLOR16) (left & 0x0000FF00);
		COLOR16 b = (COLOR16) ((left & 0x00FF0000)>>8);

		TRIVERTEX        vert[2] ;
		GRADIENT_RECT    gRect;
		vert [0] .x      = 0;
		vert [0] .y      = 0;
		vert [0] .Red    = r;
		vert [0] .Green  = g;
		vert [0] .Blue   = b;
		vert [0] .Alpha  = 0x0000;

		r = (COLOR16) ((right & 0x000000FF)<<8);
		g = (COLOR16) (right & 0x0000FF00);
		b = (COLOR16) ((right & 0x00FF0000)>>8);

		vert [1] .x      = iWidth;
		vert [1] .y      = iSideBarHeight;
		vert [1] .Red    = r;
		vert [1] .Green  = g;
		vert [1] .Blue   = b;
		vert [1] .Alpha  = 0x0000;

		gRect.UpperLeft  = 0;
		gRect.LowerRight = 1;
		
		GradientFill(dc.m_hDC,vert,2,&gRect,1,GRADIENT_FILL_RECT_V);

		HFONT hFont;

		hFont = CreateFont(iWidth, 0, 900,900,0,FALSE,FALSE,FALSE,0,
			OUT_DEFAULT_PRECIS,CLIP_MASK, PROOF_QUALITY, FF_DONTCARE, _T(SIDEBAR_FONT));

		if (lpstrSidebarText)
		{
			dc.SetBkMode(TRANSPARENT);
			HFONT fontold = dc.SelectFont( hFont );

			RECT dims;

			dims.left = dims.top = 1;
			dims.right = iWidth;
			dims.bottom = iSideBarHeight;

			dc.SetTextColor( 0x0 );
			dc.DrawText(lpstrSidebarText, strlen(lpstrSidebarText),
				&dims,
				DT_SINGLELINE|DT_BOTTOM);

			dims.top -= 1;
			dims.left -= 1;
			dims.right -= 1;
			dims.bottom -= 1;

			dc.SetTextColor( GetSysColor(COLOR_CAPTIONTEXT) );
			dc.DrawText(lpstrSidebarText, strlen(lpstrSidebarText),
				&dims,
				DT_SINGLELINE|DT_BOTTOM);

			dc.SelectFont( fontold );
		}
	}
	// == End

	void DrawBitmapDisabled(CDCHandle& dc, int nImage, POINT point)
	{
		// create memory DC
		CDC dcMem;
		dcMem.CreateCompatibleDC(dc);
		// create mono or color bitmap
		CBitmap bmp;
		bmp.CreateCompatibleBitmap(dc, m_szBitmap.cx, m_szBitmap.cy);
		ATLASSERT(bmp.m_hBitmap != NULL);
		// draw image into memory DC--fill BG white first
		HBITMAP hBmpOld = dcMem.SelectBitmap(bmp);
		dcMem.PatBlt(0, 0, m_szBitmap.cx, m_szBitmap.cy, WHITENESS);
		// If white is the text color, we can't use the normal painting since
		// it would blend with the WHITENESS, but the mask is OK
		UINT uDrawStyle = (::GetSysColor(COLOR_BTNTEXT) == RGB(255, 255, 255)) ? ILD_MASK : ILD_NORMAL;
		::ImageList_Draw(m_hImageList, nImage, dcMem, 0, 0, uDrawStyle);
		dc.DitherBlt(point.x, point.y, m_szBitmap.cx, m_szBitmap.cy, dcMem, NULL, 0, 0);
		dcMem.SelectBitmap(hBmpOld);		// restore
	}

	BOOL Draw3DCheckmark(CDCHandle& dc, const RECT& rc, BOOL bSelected, HBITMAP hBmpCheck)
	{
		// get checkmark bitmap if none, use Windows standard
		CBitmapHandle bmp = hBmpCheck;
		if(hBmpCheck == NULL)
		{
			bmp.LoadOEMBitmap(OBM_CHECK);
			ATLASSERT(bmp.m_hBitmap != NULL);
		}
		// center bitmap in caller's rectangle
		SIZE size = { 0, 0 };
		bmp.GetSize(size);
		RECT rcDest = rc;
		POINT p = { 0, 0 };
		SIZE szDelta = { (rc.right - rc.left - size.cx) / 2, (rc.bottom - rc.top - size.cy) / 2 };
		if(rc.right - rc.left > size.cx)
		{
			rcDest.left = rc.left + szDelta.cx;
			rcDest.top = rc.top + szDelta.cy;
			rcDest.right = rcDest.left + size.cx;
			rcDest.bottom = rcDest.top + size.cy;
		}
		else
		{
			p.x -= szDelta.cx;
			p.y -= szDelta.cy;
		}
		// select checkmark into memory DC
		CDC dcMem;
		dcMem.CreateCompatibleDC(dc);
		HBITMAP hBmpOld = dcMem.SelectBitmap(bmp);

⌨️ 快捷键说明

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