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

📄 outlookbar.cs

📁 c#编写的仿OUTLOOK工具条的Winform菜单
💻 CS
📖 第 1 页 / 共 5 页
字号:
				if ( flatArrowButtons )
					if ( upArrowVisible && UpFlatArrowState != DrawState.Normal)
						DrawArrowButton(upArrowRect, ButtonState.Normal);
				else
					DrawArrowButton(upArrowRect, ButtonState.Normal);
			if ( downArrowDrawState == DrawState.Hot && ht == HitTestType.DownScroll
				|| flatArrowButtons )
				if ( flatArrowButtons )
					if ( downArrowVisible && DownFlatArrowState != DrawState.Normal )
						DrawArrowButton(downArrowRect, ButtonState.Normal);
				else
                    DrawArrowButton(downArrowRect, ButtonState.Normal);

			if ( ht == HitTestType.Header )
			{
				Cursor.Current = Cursors.Hand;
				HighlightHeader(index);
				highlightTimer.Start();
			}
			else if (ht == HitTestType.Item )
			{
				HighlightItem(index, false);
				highlightTimer.Start();
			}
			else if ( ht == HitTestType.UpScroll )
			{
				if ( flatArrowButtons 
					&& upArrowVisible )
				{
					if ( UpFlatArrowState != DrawState.Hot )
						DrawArrowButton(upArrowRect, ButtonState.Pushed);
				}
			}
			else if ( ht == HitTestType.DownScroll )
			{
				if ( flatArrowButtons
					&& downArrowVisible)
				{
					if ( DownFlatArrowState != DrawState.Hot )
						DrawArrowButton(downArrowRect, ButtonState.Pushed);
				}
			}
		}

		protected override void OnSizeChanged(EventArgs e)
		{
			base.OnSizeChanged(e);
			if ( HasChild() )
			{
				Rectangle rc = GetViewPortRect();
				OutlookBarBand newBand = bands[currentBandIndex];
				Control childControl = newBand.ChildControl;
				childControl.Bounds = rc;
			}

			// flag that we need to update the bitmap background
			// if there is one
			needBackgroundBitmapResize = true;
		}

		protected override void OnHandleCreated(EventArgs e)
		{
			base.OnHandleCreated(e);
			// Make text box a child of the outlookbar control
			WindowsAPI.SetParent(textBox.Handle, Handle);
		}

		protected override  void WndProc(ref Message m)
		{
			bool callBase = true;
			switch(m.Msg)
			{
				case ((int)Msg.WM_CONTEXTMENU):
				{
					Point pt = WindowsAPI.GetPointFromLPARAM((int)m.LParam);
					pt = PointToClient(pt);
					Rectangle viewPortRect = GetViewPortRect();
					
					// Save the point so that we can update our popup menu correctly
					lastClickedPoint = pt;
                    
					// If the user click on the child window don't
					// show a context menu
					if ( HasChild() && viewPortRect.Contains(pt)) 
					{
						callBase = false;
						break;
					}
				}
					break;
				default:
					break;
			}

			if ( callBase )
				base.WndProc(ref m);
		
		}
		#endregion

        #region Properties
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
		public OutlookBarBandCollection Bands
		{
			get { return bands; }
		}

		public BorderType BorderType 
		{
			set { borderType = value; }
			get { return borderType; }
		}

		public int AnimationSpeed  
		{
			set { animationSpeed = value; }
			get { return animationSpeed; }
		}

		public Color LeftTopColor  
		{
			set { leftTopColor = value; }
			get { return leftTopColor; }
		}

		public Color RightBottomColor  
		{
			set { rightBottomColor = value; }
			get { return rightBottomColor; }
		}

		public Bitmap BackgroundBitmap
		{
			set 
			{ 
				backgroundBitmap = value; 
				needBackgroundBitmapResize = true;
			}
			get { return backgroundBitmap; }
		}

		public bool FlatArrowButtons
		{
			set { flatArrowButtons = value; }
			get { return flatArrowButtons; }
		}

		internal DrawState UpFlatArrowState
		{
			set { upFlatArrowState = value; }
			get { return upFlatArrowState; }
		}

		internal DrawState DownFlatArrowState
		{
			set { downFlatArrowState = value; }
			get { return downFlatArrowState; }
		}
		#endregion

		#region Methods
		public HitTestType HitTest(Point point, out int index, bool doingDragging)
		{
			
			// If we don't have any bands just return
			index = 0;
			if ( bands.Count == 0 || currentBandIndex == -1 )	return HitTestType.Nothing;
					
			// Check if we hit the arrow buttons
			if (upArrowVisible && upArrowRect.Contains(point)) return HitTestType.UpScroll;
			if (downArrowVisible && downArrowRect.Contains(point)) return HitTestType.DownScroll;

			// Check to see if we hit a header
			for ( int i = 0; i < bands.Count; i++ )
			{
				Rectangle rc = GetHeaderRect(i);
				if ( rc.Contains(point) )
				{
					index = i;
					return HitTestType.Header;
				}
			}

			// Don't do any hit testing for items if
			// the current band has a child
			if ( HasChild() ) return HitTestType.Nothing;

			// Check to see if we hit an item
			int itemCount = bands[currentBandIndex].Items.Count;
			Rectangle viewPortRect = GetViewPortRect();
			Rectangle iconRect = Rectangle.Empty;
			Rectangle labelRect = Rectangle.Empty;
			for ( int i = firstItem; i < itemCount; i++ )
			{
				// Check if we hit the icon
				iconRect = GetIconRect(i);
				if ( iconRect.Contains(point) )
				{
					index = i;
					return HitTestType.Item;
				}
				else
					if ( iconRect.Bottom > viewPortRect.Bottom && !doingDragging) break;

				// Check to see if we hit the label
				labelRect = GetLabelRect(i);
				if ( labelRect.Contains(point) )
				{
					index = i;
					return HitTestType.Item;
				}
				else
					if ( labelRect.Bottom > viewPortRect.Bottom && !doingDragging) break;

				// If we are dragging, hit test for the drop line
				if ( doingDragging )
				{
					Rectangle dragRect = new Rectangle(viewPortRect.Left, iconRect.Top - Y_LARGEICON_SPACING,
						viewPortRect.Width, Y_LARGEICON_SPACING);
						
					if ( dragRect.Contains(point) )
					{
						index = i;
						return HitTestType.DropLine;
					}

					// if this is the last icon and the point is farther down the last item
					if ( (i == itemCount - 1) && point.Y > labelRect.Bottom )
					{
						index = itemCount - 1;
						return HitTestType.DropLineLastItem;
					}
				}
			}
			
			return HitTestType.Nothing;

		}

		public Rectangle GetItemRect(Graphics g, OutlookBarBand band, int index, Rectangle targetRect)
		{
			Rectangle rc = GetViewPortRect();
			if ( targetRect != Rectangle.Empty ) rc = targetRect;
			Size itemSize = new Size(0,0);
			int top = rc.Top;
			int y = 0;
			for ( int i = 0; i < index; i++ )
			{
				itemSize = GetItemSize(g, band, i, ItemSizeType.All);
				top += itemSize.Height;
				if ( band.IconView == IconView.Small )
					top += Y_SMALLICON_SPACING;
				else
					top += Y_LARGEICON_SPACING;
				if ( i == (firstItem - 1) )
				{
					// Subtract the hidden items height
					y = top - rc.Top;
				}
			}

			itemSize = GetItemSize(g, band, index, ItemSizeType.All);
			int margin = SMALL_TOP_MARGIN;
			if ( band.IconView == IconView.Large )
				margin = LARGE_TOP_MARGIN;

			// Work with Windows Rect is easier to change settings
			RECT rcItem = new RECT();
			rcItem.left = rc.Left;
			rcItem.top = top;
			rcItem.right = rc.Left + itemSize.Width;
			rcItem.bottom = top + itemSize.Height;

			// Adjust rectangle
			rcItem.top -= y;
			rcItem.bottom -= y;
			rcItem.top += margin;
			rcItem.bottom += margin;
			
			if ( band.IconView == IconView.Small )
			{
				rcItem.left  = rc.Left + LEFT_MARGIN;
				rcItem.right = rc.Right;
			}

			// Construct final rectangle
			Rectangle actualRect = new Rectangle(rcItem.left,  
				rcItem.top, rcItem.right - rcItem.left, rcItem.bottom - rcItem.top);
			       
			return actualRect;
		}
		public void ProcessOnMouseDown(MouseEventArgs e)
		{
			// To be used from the designer
			OnMouseDown(e);
		}

		public void OnContextMenu(object sender, EventArgs e)
		{
			OutlookBarBand band = bands[currentBandIndex];

			if (typeof(MenuItemEx).IsInstanceOfType(sender)) 
			{
				MenuItemEx item = (MenuItemEx)sender;
				if ( item.Text == "Large Icons")
				{
					band.IconView = IconView.Large;
					item.RadioCheck = true;
					contextMenu.MenuItems[1].RadioCheck = false;
				}
				else if ( item.Text == "Small Icons")
				{
					item.RadioCheck = true;
					band.IconView = IconView.Small;
					contextMenu.MenuItems[0].RadioCheck = false;
				}
				else if ( item.Text == "Rename Shortcut" )
				{
					RenameItem();
				}
				else if ( item.Text == "Rename Group" )
				{
					RenameHeader();
				}
			}
			Invalidate();
		}

		public int GetCurrentBand()
		{
			return currentBandIndex;
		}

		public void SetCurrentBand(int index)
		{
			// If in design mode and index equals -1 just don't do anything
			if ( DesignMode && index == -1 )
				return;

			// Make sure index is valid
			Debug.Assert(index >= 0 && index < bands.Count, "Invalid Band Index");
			// Don't do anything if requested to set it to the same one
			if ( currentBandIndex == index)
				return;
						
			// Hide current child control if any
			Control childControl;
			if ( currentBandIndex != -1 && bands.Count > 0)
			{
				OutlookBarBand oldBand = bands[currentBandIndex];
				childControl = oldBand.ChildControl;
				if ( childControl != null )
					childControl.Visible = false;
			}

			// Animate showing the new band
			if ( index != currentBandIndex )
			{
				AnimateScroll(currentBandIndex, index);
			}

			// Reset parameter
			currentBandIndex = index;
			firstItem = 0;
			lastHighlightedItem = -1;

			OutlookBarBand newBand = bands[currentBandIndex];
			childControl = newBand.ChildControl;
			if ( childControl != null )
			{
				// Make the outlookbar the parent of the child control
				// so that when we change the bounds of the control they
				// would be relative to the parent control
				// Don't do this every time since it causes flickering
				IntPtr hParent = WindowsAPI.GetParent(childControl.Handle);
				if ( hParent != Handle )
				{
					WindowsAPI.SetParent(childControl.Handle, Handle);

					// Hook up into control recreation
					childControl.HandleCreated += new EventHandler(HandleRecreated);
				}
				
				Rectangle rc = GetViewPortRect();
				childControl.Bounds = rc;
				childControl.Visible = true;
				childControl.Focus();
			}

			// update the bar
			Invalidate();

			// Fire property changed
			FirePropertyChanged(OutlookBarProperty.CurrentBandChanged);

		}

		#endregion

		#region Implementation
		void ProcessArrowScrolling(Rectangle arrowButton, ref bool arrowVisible, ref bool arrowPressed, ref bool timerTicking)
		{
			
			// Capture the mouse
			Capture = true;
			// Draw the arrow button pushed
			timerTicking = true;
			// Draw pushed button
			buttonPushed = true;
			DrawArrowButton(arrowButton, ButtonState.Pushed);
			
			// Start timer
			System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
			timer.Tick += new EventHandler(ScrollingTick);
			timer.Interval = 300;
			timer.Start();
             
			doScrollingLoop = true;           
			while ( doScrollingLoop ) 
			{
				// Check messages until we find a condition to break out of the loop
				Win32.MSG msg = new Win32.MSG();
				WindowsAPI.GetMessage(ref msg, 0, 0, 0);
				Point point = new Point(0,0);
				if ( msg.message == (int)Msg.WM_MOUSEMOVE || msg.message == (int)Msg.WM_LBUTTONUP )
				{
					point = WindowsAPI.GetPointFromLPARAM((int)msg.lParam);
				}

				switch(msg.message)
				{
					case (int)Msg.WM_MOUSEMOVE:
					{
						if ( arrowButton.Contains(point) )
						{
							if ( !buttonPushed )
							{
								DrawArrowButton(arrowButton, ButtonState.Pushed);
								arrowVisible =  true;
								arrowPressed = true;
								buttonPushed =  true;
							}
						}
						else
						{
							if ( buttonPushed )
							{
								DrawArrowButton(arrowButton, ButtonState.Normal);
								arrowVisible =  false;
								arrowPressed = false;
								buttonPushed =  false;
							}
						}
						break;
					}
					case (int)Msg.WM_LBUTTONUP:
					{
						if ( buttonPushed )
						{
							if ( !flatArrowButtons )
							{
								// Only if using regular buttons
								DrawArrowButton(arrowButton, ButtonState.Normal);
							}
							buttonPushed =  false;
						}
						arrowVisible = false;
						if ( arrowButton.Contains(point) ) 
						{
							if ( arrowButton.Equals(upArrowRect) )
							{
								if ( firstItem > 0 )
								{

⌨️ 快捷键说明

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