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

📄 toolbarex.cs

📁 c#编写的仿OUTLOOK工具条的Winform菜单
💻 CS
📖 第 1 页 / 共 3 页
字号:
				{
					if (point != lastMousePosition)
					{
						int index = HitTest(point);
						if ((IsValid(index)) && (index != trackHotItem))
							TrackDropDownNext(index);
						lastMousePosition = point;
					}
				}
				else if (message.Msg == (int)Msg.WM_LBUTTONDOWN)
				{
					if (HitTest(point) == trackHotItem)
					{
						TrackDropDownNext(-1);
						return true;
					}
				}
			}
	
			return false;
		
		}

		void SetState(State state, int index)
		{
			if (this.state != state)
			{
				if (state == State.None)
					index = -1;
					
				SetHotItem(index);
				
				if (state == State.HotTracking)
				{
					trackEscapePressed = false;
					trackHotItem = index;
				}
			}
			
			this.lastState = this.state;
			this.state = state;
		}
		
		void IChevron.Show(Control control, Point point)
		{
			ToolBarItemCollection chevronItems = new ToolBarItemCollection();
			Size size = ClientSize;
			int currentCount = 0;
			bool addItem = true;
			ToolBarItem lastItem;
			bool hasComboBox = false;

			for (int i = 0; i < items.Count; i++)
			{
				bool IsSeparator = false;
				RECT rect = new RECT();
				WindowsAPI.SendMessage(Handle, (int)ToolBarMessages.TB_GETITEMRECT, i, ref rect);
				if (rect.right > size.Width)
				{
					ToolBarItem item = items[i];
					if ( item.ComboBox != null )
						hasComboBox = true;
					IsSeparator = (item.Style == ToolBarItemStyle.Separator);
					if ( item.Visible ) 
						if ( (!IsSeparator ) || (chevronItems.Count != 0) )
						{
							// don't add it if previous item was a separator
							currentCount = chevronItems.Count;
							if ( currentCount > 0 ) 
							{
								lastItem = chevronItems[currentCount-1];
								if ( lastItem.Style == ToolBarItemStyle.Separator && IsSeparator )
								{
									addItem = false;
								}
							}

							if ( addItem )
								chevronItems.Add(item);
							addItem = true;
						}
				}
			}

			// Don't show a separator as the last item of the context menu
			int itemsCount = chevronItems.Count;
			if ( itemsCount > 0 )
			{
				lastItem = chevronItems[itemsCount-1];
				if ( lastItem.Style == ToolBarItemStyle.Separator )
					chevronItems.RemoveAt(itemsCount-1);
			}
			
			chevronMenu.Items = chevronItems;
			chevronMenu.Style = VisualStyle.IDE;
			chevronMenu.TrackPopup(control.PointToScreen(point));

			// Need to reparent the combobox to this toolbar in case
			// there was a combobox that was displayed by the popup menu
			if ( hasComboBox )
			{
				// Run the logic for combobox visibility before reposition it
				ToolbarSizeChanged();      

				for (int i = 0; i < items.Count; i++)
				{
					ToolBarItem item = items[i];
					if ( item.Style == ToolBarItemStyle.ComboBox )
					{
						WindowsAPI.SetParent(item.ComboBox.Handle, Handle);
						ComboBoxBase cbb = (ComboBoxBase)item.ComboBox;
						cbb.ToolBarUse = true;
						UpdateItem(i);
						cbb.Invalidate();
					}
				}
			}		
		}

		internal void ToolbarSizeChanged()
		{
			if ( BarType == BarType.MenuBar )
				return;
			
			// Make sure that comboboxes are either visible
			// or invisible depending wheater they are showing
			// all of the client area or they are partially hidden
			Size size = ClientSize;
			for (int i = 0; i < items.Count; i++)
			{
				ToolBarItem item = items[i];
				if ( item.Style == ToolBarItemStyle.ComboBox )
				{
					RECT rect = new RECT();
					WindowsAPI.SendMessage(Handle, (int)ToolBarMessages.TB_GETITEMRECT, i, ref rect);
					if (rect.right > size.Width)
						item.ComboBox.Visible = false;
					else
						item.ComboBox.Visible = true;
				}
			}
		}

		protected override void WndProc(ref Message message)
		{
			base.WndProc(ref message);
			int index = -1;
			ToolBarItem item = null;

			switch (message.Msg)
			{
				case (int)ReflectedMessages.OCM_COMMAND:
					index = (int) message.WParam & 0xFFFF;
					item = items[index];
					item.RaiseClick();
					base.WndProc(ref message);
					ResetMouseEventArgs();
					break;

				case (int)Msg.WM_MENUCHAR:
					MenuChar(ref message);
					break;

				case (int)Msg.WM_ERASEBKGND:
					break;
				
				case (int)Msg.WM_NOTIFY:
				case (int)ReflectedMessages.OCM_NOTIFY:
					NMHDR nm = (NMHDR) message.GetLParam(typeof(NMHDR));
					switch (nm.code)
					{
						case (int)ToolBarNotifications.TTN_NEEDTEXTA:
							NotifyNeedTextA(ref message);
							break;
		
						case (int)ToolBarNotifications.TTN_NEEDTEXTW:
							NotifyNeedTextW(ref message);
							break;				
		
						case (int)ToolBarNotifications.TBN_QUERYINSERT:
							message.Result = (IntPtr) 1;
							break;
		
						case (int)ToolBarNotifications.TBN_DROPDOWN:
							NMTOOLBAR nmt = (NMTOOLBAR) message.GetLParam(typeof(NMTOOLBAR));
							index = nmt.iItem;
							item = items[index];
							item.Dropped = true;
							item.RaiseDropDown();
							break;
							
						case (int)NotificationMessages.NM_CUSTOMDRAW:
							NotifyCustomDraw(ref message);
							break;

						case (int)ToolBarNotifications.TBN_HOTITEMCHANGE:
							break;
					}
					break;
			}
		}

		void MenuChar(ref Message message)
		{
			
			ToolBarItem item = items[trackHotItem];
			Menu menu = item.ToolBarItemMenu.FindMenuItem(MenuItem.FindHandle, message.LParam);
			if (item.ToolBarItemMenu.Handle == message.LParam) menu = item.ToolBarItemMenu;

			if (menu != null)
			{
				char key = char.ToUpper((char) ((int) message.WParam & 0x0000FFFF));
				int index = 0;
				foreach (MenuItem menuItem in menu.MenuItems)
				{
					if ((menuItem != null) && (menuItem.OwnerDraw) && (menuItem.Mnemonic == key))
					{
						message.Result = (IntPtr) (((int)MenuCharReturnValues.MNC_EXECUTE << 16) | index);
						return;
					}
					
					if (menuItem.Visible) index++;
				}
			}
		}


		void NotifyNeedTextA(ref Message m)
		{
			TOOLTIPTEXTA ttt = (TOOLTIPTEXTA) m.GetLParam(typeof(TOOLTIPTEXTA));
			ToolBarItem item = (ToolBarItem) items[ttt.hdr.idFrom];
			string toolTip = item.ToolTip;
			if ( toolTip != null && toolTip != string.Empty )
			{
				ttt.szText = toolTip;
				ttt.hinst = IntPtr.Zero;
				if ( RightToLeft == RightToLeft.Yes ) ttt.uFlags |= (int)ToolTipFlags.TTF_RTLREADING;
				Marshal.StructureToPtr(ttt, m.LParam, true);
				m.Result = (IntPtr) 1;
			}
		}
	
		void NotifyNeedTextW(ref Message m)
		{
			if (Marshal.SystemDefaultCharSize != 2) return;
	
			// This code is a duplicate of NotifyNeedTextA
			TOOLTIPTEXT ttt = (TOOLTIPTEXT) m.GetLParam(typeof(TOOLTIPTEXT));
			ToolBarItem item = (ToolBarItem) items[ttt.hdr.idFrom];
			string toolTip = item.ToolTip;
			if ( toolTip != null && toolTip != string.Empty )
			{
				ttt.szText = toolTip;
				ttt.hinst = IntPtr.Zero;
				if (RightToLeft == RightToLeft.Yes) ttt.uFlags |= (int)ToolTipFlags.TTF_RTLREADING;
				Marshal.StructureToPtr(ttt, m.LParam, true);
				m.Result = (IntPtr) 1;
			}
		}

		void NotifyCustomDraw(ref Message m)
		{
			m.Result = (IntPtr) CustomDrawReturnFlags.CDRF_DODEFAULT;
			NMTBCUSTOMDRAW tbcd = (NMTBCUSTOMDRAW)m.GetLParam(typeof(NMTBCUSTOMDRAW));

			switch (tbcd.nmcd.dwDrawStage)
			{
				case (int)CustomDrawDrawStateFlags.CDDS_PREPAINT:
					// Tell toolbar control that we want to do the painting ourselves
					m.Result = (IntPtr) CustomDrawReturnFlags.CDRF_NOTIFYITEMDRAW;
					break;
	
				case (int)CustomDrawDrawStateFlags.CDDS_ITEMPREPAINT:
					// Do custom painting
					NotifyCustomDrawToolBar(ref m);
					break;
			}
		}

		void NotifyCustomDrawToolBar(ref Message m)
		{
			m.Result = (IntPtr) CustomDrawReturnFlags.CDRF_DODEFAULT;
			
			// See if use wants the VSNet look or let XP dictate
			// the toolbar look
			if ( IsCommonCtrl6() )
			{
                // Let the operating system do the drawing
				return;
			}
					
			NMTBCUSTOMDRAW tbcd = (NMTBCUSTOMDRAW) m.GetLParam(typeof(NMTBCUSTOMDRAW));
			RECT rc = tbcd.nmcd.rc;
			Rectangle rectangle = new Rectangle(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top);

			Graphics g = Graphics.FromHdc(tbcd.nmcd.hdc);
			int index = tbcd.nmcd.dwItemSpec;
			ToolBarItem item = items[index];

			if ( item.Style == ToolBarItemStyle.ComboBox )
			{
				// ComboBoxes paint themselves
				// the combox new size, after changing the combobox font,
				// does not get updated until later in the drawing logic
				// pick up the right size here and update the combobox position
				UpdateComboBoxPosition(index);
				m.Result = (IntPtr) CustomDrawReturnFlags.CDRF_SKIPDEFAULT;
				return;
			}

			bool hot = (bool)((tbcd.nmcd.uItemState & (int)CustomDrawItemStateFlags.CDIS_HOT) != 0);
			bool selected = (bool)((tbcd.nmcd.uItemState & (int)CustomDrawItemStateFlags.CDIS_SELECTED) != 0);
			bool disabled = (bool)((tbcd.nmcd.uItemState & (int)CustomDrawItemStateFlags.CDIS_DISABLED) != 0);
			string tempString = item.Text;
			bool hasText = (tempString != string.Empty && tempString != null);
	
			if (item.Checked) 
			{
				if ( hot )
					g.FillRectangle(new SolidBrush(ColorUtil.VSNetPressedColor), rectangle);
				else
					g.FillRectangle(new SolidBrush(ColorUtil.VSNetCheckedColor), rectangle);
				g.DrawRectangle(new Pen(new SolidBrush(ColorUtil.VSNetBorderColor), 1), 
					rectangle.Left, rectangle.Top, rectangle.Width-1, rectangle.Height-1);
				
			}
			else if (selected) 
			{
				if ( item.Style == ToolBarItemStyle.DropDownButton ) 
				{
					// Draw background
					g.FillRectangle(new SolidBrush(ColorUtil.VSNetSelectionColor), rectangle);
					g.FillRectangle(new SolidBrush(ColorUtil.VSNetPressedColor), rectangle.Left, rectangle.Top, 
						rectangle.Width-DROWPDOWN_ARROW_WIDTH+1, rectangle.Height);
					g.DrawRectangle(new Pen(new SolidBrush(ColorUtil.VSNetBorderColor), 1), 
						rectangle.Left, rectangle.Top, rectangle.Width-1, rectangle.Height-1);
				}
				else 
				{
					if ( barType == BarType.MenuBar)
					{
						g.FillRectangle(new SolidBrush(ColorUtil.VSNetControlColor), rectangle);
						if ( ColorUtil.UsingCustomColor )
						{
							// Use same color for both sides to make it look flat
							g.DrawRectangle(new Pen(ColorUtil.VSNetBorderColor), 
								rectangle.Left, rectangle.Top, rectangle.Width-1, rectangle.Height-1);
						}
						else 
						{
							ControlPaint.DrawBorder3D(g, rectangle.Left, rectangle.Top, rectangle.Width-1, 
								rectangle.Height-1, Border3DStyle.Flat, Border3DSide.Top | Border3DSide.Left | Border3DSide.Right);
						}
					}
					else 
					{
						g.FillRectangle(new SolidBrush(ColorUtil.VSNetPressedColor), rectangle);
						g.DrawRectangle(new Pen(new SolidBrush(ColorUtil.VSNetBorderColor), 1), 
							rectangle.Left, rectangle.Top, rectangle.Width-1, rectangle.Height-1);
					}
				}
				
				
			}
			else if ( item.Style == ToolBarItemStyle.DropDownButton && item.Dropped )
			{
				g.FillRectangle(new SolidBrush(ColorUtil.VSNetControlColor), rectangle);
				g.DrawRectangle(new Pen(new SolidBrush(SystemColors.ControlDark), 1), 
					rectangle.Left, rectangle.Top, rectangle.Width-1, rectangle.Height-1);
			}
			else if (hot)
			{
				g.FillRectangle(new SolidBrush(ColorUtil.VSNetSelectionColor), rectangle);
				g.DrawRectangle(new Pen(new SolidBrush(ColorUtil.VSNetBorderColor), 1), 
					rectangle.Left, rectangle.Top, rectangle.Width-1, rectangle.Height-1);
			}
			else 
			{
				if ( item.Style == ToolBarItemStyle.DropDownButton )
				{
					
					IntPtr hreBar = WindowsAPI.GetParent(Handle);
					IntPtr hMainWindow = IntPtr.Zero;
					bool mainHasFocus = false;
					if ( hreBar != IntPtr.Zero )
					{
						hMainWindow = WindowsAPI.GetParent(hreBar);
						if ( hMainWindow != IntPtr.Zero ) 
							mainHasFocus = ( hMainWindow == WindowsAPI.GetFocus());
					}

					if ( hMainWindow != IntPtr.Zero &&  mainHasFocus)
					{
						Point pos = Control.MousePosition;
						Point clientPoint = PointToClient(pos);
						if ( rectangle.Contains(clientPoint))
						{
							g.FillRectangle(new SolidBrush(ColorUtil.VSNetSelectionColor), rectangle);
							g.DrawRectangle(new Pen(new SolidBrush(ColorUtil.VSNetBorderColor), 1), 
								rectangle.Left, rectangle.Top, rectangle.Width-1, rectangle.Height-1);

							rc.right -= DROWPDOWN_ARROW_WIDTH;
							g.DrawLine(new Pen(new SolidBrush(ColorUtil.VSNetBorderColor), 1), 
								rc.right+1, rc.top, rc.right+1, rc.top + (rc.bottom-rc.top));
							rc.right += DROWPDOWN_ARROW_WIDTH;
						}
					}
				}
			}

			if ( item.Style == ToolBarItemStyle.DropDownButton ) 
			{
				DrawArrowGlyph(g, rectangle);

				// Draw line that separates the arrow from the button
				rc.right -= DROWPDOWN_ARROW_WIDTH;
				if ( hot && !item.Dropped )
					g.DrawLine(new Pen(new SolidBrush(ColorUtil.VSNetBorderColor), 1), 
						rc.right+1, rc.top, rc.right+1, rc.top + (rc.bottom-rc.top));
				item.Dropped = false;

			}
			
			Image image = item.Image;
			if (image != null)
			{
				Size size = image.Size;
				Point point = new Point(rc.left + ((rc.right - rc.left - size.Width) / 2), 
					rc.top + ((rc.bottom - rc.top - size.Height) / 2));
				if ( hasText ) point.X = rc.left + MARGIN;

⌨️ 快捷键说明

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