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

📄 outlookbar.cs

📁 c#编写的仿OUTLOOK工具条的Winform菜单
💻 CS
📖 第 1 页 / 共 5 页
字号:
			Point pt = new Point(0,0);
			// Set clip region so that we don't draw outside the viewport
			Rectangle viewPortRect = GetViewPortRect();
			if ( targetRect != Rectangle.Empty )
				viewPortRect = targetRect;
				
			Region clippingRegion = new Region(viewPortRect);
			g.Clip = clippingRegion;
			// Clip the arrow buttons
			g.ExcludeClip(downArrowRect);
			g.ExcludeClip(upArrowRect);
			
			Color textColor = band.TextColor;
			Color backColor = band.Background; 
			Color highLight = band.Background;

			if ( ColorUtil.UsingCustomColor )
			{
				backColor = ColorUtil.VSNetControlColor;
				highLight = ColorUtil.VSNetControlColor;
			}

			if ( hot )
			{
				backColor = ColorUtil.VSNetSelectionColor;
				highLight = ColorUtil.VSNetBorderColor;
			}
			
			if ( pressed ) backColor = ColorUtil.VSNetPressedColor;
			
			if ( band.IconView == IconView.Large && band.LargeImageList != null ) 
			{
				Size largeImageSize = band.LargeImageList.ImageSize;
				pt.X = itemRect.Left + (viewPortRect.Width - largeImageSize.Width) / 2;
				pt.Y = itemRect.Top;

				Rectangle iconRect = new Rectangle(pt, largeImageSize);
				using ( Brush b = new SolidBrush(backColor) )
				{
					iconRect.Inflate(2,2);
					if ( backgroundBitmap != null )
					{
						g.DrawImage(backgroundBitmap, iconRect, iconRect, GraphicsUnit.Pixel);
						// If we have a background bitmap, draw the item background
						// only during the hot state
						if ( hot)
						{
							g.FillRectangle(b, iconRect.Left, iconRect.Top, 
								iconRect.Width, iconRect.Height);
						}
					}
					else 
					{

						// If we don't have a background, always draw the 
						// item backgound
						g.FillRectangle(b, iconRect.Left, iconRect.Top, 
							iconRect.Width, iconRect.Height);
					}
					
					using ( Pen p = new Pen(highLight) )
					{
						if ( backgroundBitmap == null || hot == true )
						{
							g.DrawRectangle(p,  iconRect.Left, iconRect.Top, iconRect.Width-1, iconRect.Height-1);
						}
					}
				}
				
				// I dont' use the image list to do the drawing because cliping does not work
				if ( band.Items[index].ImageIndex != -1 && band.LargeImageList != null )
				{
					// Only if we have a valid image index
					g.SmoothingMode  = SmoothingMode.HighQuality;
					g.DrawImage(band.LargeImageList.Images[band.Items[index].ImageIndex], pt);
					g.SmoothingMode  = SmoothingMode.Default;
				}

				// Draw the label
				int top = itemRect.Top + largeImageSize.Height + Y_LARGEICON_LABEL_OFFSET;
				Size textSize = GetLabelSize(g, band, index);
				int left = itemRect.Left + (viewPortRect.Width - textSize.Width) / 2;
				using ( Brush b = new SolidBrush(textColor) )
				{
					g.DrawString(band.Items[index].Text, Font, b, new Point(left, top));
				}

				// Reset clip region to the whole rectangle so that the arrows can be painted
				clippingRegion.Dispose();
				g.Clip = new Region(viewPortRect);


			}
			else if ( band.IconView == IconView.Small && band.SmallImageList != null ) 
			{
				
				Size smallImageSize = band.SmallImageList.ImageSize;
				pt.X = itemRect.Left;
				pt.Y = itemRect.Top + (itemRect.Height - smallImageSize.Height)/2;

				Rectangle iconRect = new Rectangle(pt, smallImageSize);
				using ( Brush b = new SolidBrush(backColor) )
				{
					iconRect.Inflate(1,1);
					if ( backgroundBitmap != null )
					{
						g.DrawImage(backgroundBitmap, iconRect, iconRect, GraphicsUnit.Pixel);
						// If we have a background bitmap, draw the item background
						// only during the hot state
						if ( hot)
						{
							g.FillRectangle(b, iconRect.Left, iconRect.Top, 
								iconRect.Width, iconRect.Height);
						}
					}
					else 
					{
						// If we don't have a background, always draw the 
						// item backgound
						g.FillRectangle(b, iconRect.Left, iconRect.Top, 
							iconRect.Width, iconRect.Height);
					}
					
					using ( Pen p = new Pen(highLight) )
					{
						if ( backgroundBitmap == null || hot == true )
						{
							g.DrawRectangle(p,  iconRect.Left, iconRect.Top, iconRect.Width-1, iconRect.Height-1);
						}
					}
				}
			
				// I dont' use the image list to do the drawing because cliping does not work
				if ( band.Items[index].ImageIndex != -1 && band.SmallImageList != null )
				{
					// Only if we have a valid image index
					g.DrawImage(band.SmallImageList.Images[band.Items[index].ImageIndex], pt);
				}

				// Draw the label
				Size labelSize = GetLabelSize(g, band, index);
				pt.X = pt.X + smallImageSize.Width + X_SMALLICON_LABEL_OFFSET;
				pt.Y = itemRect.Top + (itemRect.Height - labelSize.Height)/2;
				using ( Brush b = new SolidBrush(textColor) )
				{
					g.DrawString(band.Items[index].Text, Font, b, pt);
				}
			}
	
		}

		void AnimateScroll(int From, int To)
		{
			if ( currentBandIndex == -1 || bands.Count == 0 ) return;
			
			OutlookBarBand band = bands[currentBandIndex];
			// Make sure we are whithin bounds
			Debug.Assert(From >= 0 && From < bands.Count);
			Debug.Assert(To >= 0 &&  To < bands.Count);

			// Get needed dimensions
			Rectangle viewPortRect = GetViewPortRect();
			Rectangle headerRect = new Rectangle(0, 0, viewPortRect.Width, BAND_HEADER_HEIGHT);
			Rectangle drawingRect = new Rectangle(0, 0, viewPortRect.Width, viewPortRect.Height + headerRect.Height * 2);

			// Use straight GDI to do the drawing	
			IntPtr hDC = WindowsAPI.GetDC(Handle);
            IntPtr hDCFrom = WindowsAPI.CreateCompatibleDC(hDC);
			IntPtr hDCTo = WindowsAPI.CreateCompatibleDC(hDC);
			IntPtr bmFrom = WindowsAPI.CreateCompatibleBitmap(hDC, drawingRect.Width, drawingRect.Height);
			IntPtr bmTo = WindowsAPI.CreateCompatibleBitmap(hDC, drawingRect.Width, drawingRect.Height);
			
			// Select in the drawing surface
			IntPtr hOldFromBitmap = WindowsAPI.SelectObject(hDCFrom, bmFrom);
			IntPtr hOldToBitmap = WindowsAPI.SelectObject(hDCTo, bmTo);
            
			// Draw in the memory device context
			Graphics gHeaderDC;
			if ( To > From )
				gHeaderDC = Graphics.FromHdc(hDCTo);
			else
			    gHeaderDC = Graphics.FromHdc(hDCFrom);

			DrawBandBitmap(hDCFrom, bands[From], From, drawingRect);
			DrawBandBitmap(hDCTo,  bands[To], To, drawingRect);
			DrawHeader(gHeaderDC, To, new Rectangle(drawingRect.Left, drawingRect.Top, 
				drawingRect.Width, drawingRect.Top + BAND_HEADER_HEIGHT), Border3DStyle.RaisedInner);
			
			Rectangle rectFrom = GetHeaderRect(From);
			Rectangle rectTo = GetHeaderRect(To);
			int headerHeight = rectFrom.Height;

			// Do the animation with the bitmaps
			if ( To > From)
			{
				for (int y = rectTo.Top - headerHeight; y > rectFrom.Bottom; y -= headerHeight)
				{
					// Draw From bitmap
					WindowsAPI.BitBlt(hDC, viewPortRect.Left ,rectFrom.Bottom + 1, 
						viewPortRect.Width, y - rectFrom.Bottom - 1, hDCFrom, 0 , 0, (int)PatBltTypes.SRCCOPY);

					// Draw To Bitmap
					WindowsAPI.BitBlt(hDC, viewPortRect.Left, y, viewPortRect.Width, 
						viewPortRect.Bottom - y + headerHeight, hDCTo, 0, 0, (int)PatBltTypes.SRCCOPY);
					Thread.Sleep(animationSpeed);
				}
			}
			else
			{
				Rectangle rcTo = new Rectangle(viewPortRect.Left, 
					viewPortRect.Bottom, viewPortRect.Width, viewPortRect.Bottom - headerHeight);
				for (int y = rectFrom.Top + 1; y < rcTo.Top - headerHeight; y += headerHeight)
				{
					
					// Draw To Bitmap
					WindowsAPI.BitBlt(hDC, viewPortRect.Left, rectFrom.Top,  viewPortRect.Width, 
						y - rectFrom.Top - 1, hDCTo, 0, 0, (int)PatBltTypes.SRCCOPY);
										
					// Draw From bitmap
					WindowsAPI.BitBlt(hDC, viewPortRect.Left , y, 
						viewPortRect.Width, viewPortRect.Bottom - y, hDCFrom, 0 , 0, (int)PatBltTypes.SRCCOPY);
					Thread.Sleep(animationSpeed);
					
				}
			}

			// Cleanup
			WindowsAPI.ReleaseDC(Handle, hDC);
			WindowsAPI.DeleteDC(hDCFrom);
			WindowsAPI.DeleteDC(hDCTo);
			WindowsAPI.SelectObject(hDCFrom, bmFrom);
			WindowsAPI.SelectObject(hDCTo, bmTo);
			WindowsAPI.DeleteObject(bmFrom);
			WindowsAPI.DeleteObject(bmTo);
            
		}

		void DrawBandBitmap(IntPtr hDC, OutlookBarBand band, int bandIndex, Rectangle drawingRect)
		{
			// Don't do GDI+ calls since you cannot mix them with GDI calls
			if ( !HasChild(bandIndex))
			{
				Color cb = band.Background;
				IntPtr brush = WindowsAPI.CreateSolidBrush(ColorUtil.RGB(cb.R, cb.G, cb.B));
			
				RECT rect;
				rect.left = drawingRect.Left;
				rect.top = drawingRect.Top;
				rect.right = drawingRect.Left + drawingRect.Width;
				rect.bottom = drawingRect.Top + drawingRect.Height;

				WindowsAPI.FillRect(hDC, ref rect, brush);
				WindowsAPI.DeleteObject(brush);
			}
				
			if ( HasChild(bandIndex) )
			{
				// Paint child control into memory device context
				Control child = bands[bandIndex].ChildControl;
				bool visible = child.Visible;
				child.Visible = true;
				
				// Change viewport if needed
				POINT pt = new POINT();
				WindowsAPI.SendMessage( child.Handle, 
					(int)Msg.WM_ERASEBKGND, (int)hDC, 0);
				WindowsAPI.SendMessage( child.Handle, 
					(int)Msg.WM_PAINT, (int)hDC, 0);
				if ( !visible) child.Visible = false;
			}
			else 
			{
				DrawItems(Graphics.FromHdc(hDC), drawingRect, bands[bandIndex]);
			}
		}

		bool HasChild()
		{
			// Flag that tell us if the current band 
			// has a child window
			Control childControl = null;
			if ( currentBandIndex != -1 && bands.Count > 0)
			{
				OutlookBarBand band = bands[currentBandIndex];
				childControl = band.ChildControl;
			}
			return childControl != null;
		}

		bool HasChild(int index)
		{
			// Flag that tell us if the current band 
			// has a child window
			Control childControl = null;
			if ( index != -1 && bands.Count > 0 && index >= 0 && index < bands.Count)
			{
				OutlookBarBand band = bands[index];
				childControl = band.ChildControl;
			}
			return childControl != null;
		}

		void GetVisibleRange(Graphics g, out int first, out int last)
		{
			first = firstItem;
			last = 0;
			
			OutlookBarBand band = bands[currentBandIndex];
			Rectangle rc = GetViewPortRect();
			Rectangle itemRect;
			for ( int i = firstItem; i < band.Items.Count; i++ )
			{
                itemRect = GetItemRect(g, band, i, Rectangle.Empty);
				if ( itemRect.Bottom > rc.Bottom )
				{
					last = i-1;
					break;
				}
				else 
				{
					last = i;
				}
			}
		}

		Size GetItemSize(Graphics g, OutlookBarBand band, int itemIndex, ItemSizeType itemSizeType)
		{
			Size iconSize = new Size(0,0);
			Size labelSize = new Size(0,0);

			if ( itemSizeType == ItemSizeType.Icon || itemSizeType == ItemSizeType.All )
			{
				iconSize = GetIconSize(band);
				if (itemSizeType == ItemSizeType.Icon)
					return iconSize;
			}
			
			if ( itemSizeType == ItemSizeType.Label || itemSizeType == ItemSizeType.All )
			{
				labelSize = GetLabelSize(g, band, itemIndex);
				if ( itemSizeType == ItemSizeType.Label )
					return labelSize;
			}
			
			if ( itemSizeType == ItemSizeType.All )
			{
				if ( band.IconView == IconView.Small )
					return new Size(iconSize.Width + labelSize.Width + X_SMALLICON_LABEL_OFFSET, 
						iconSize.Height > labelSize.Height?iconSize.Height:labelSize.Height);
				else
					return new Size(iconSize.Width>labelSize.Width?iconSize.Width:labelSize.Width, iconSize.Height +
					labelSize.Height + Y_LARGEICON_LABEL_OFFSET + Y_LARGEICON_SPACING);
			}

			return new Size(0,0);
		}

		Size GetIconSize(OutlookBarBand band)
		{
			
			if ( band.IconView == IconView.Large && band.LargeImageList != null )
				return band.LargeImageList.ImageSize;
			else if ( band.IconView == IconView.Small && band.SmallImageList != null )
				return band.SmallImageList.ImageSize;
			return new Size(0,0);
		}

		Size GetLabelSize(Graphics g, OutlookBarBand band, int itemIndex)
		{
            
			Size textSize = new Size(0,0);
			if ( band.IconView == IconView.Large )
			{
				// Calculate text rectangle including word breaks if needed
				Rectangle rect = GetViewPortRect();
				Rectangle textRect = Rectangle.FromLTRB(rect.Left, rect.Top, rect.Width, rect.Top);
				
				// The TextUtil function is going to call GDI, but the Graphics object
				// is already being used by GDI+. Pass a null reference so that the TextUtil
				// function uses the Screen Device to calculate the text size
				if ( band.Items[itemIndex].Text != null )
				{
					textSize = TextUtil.GetTextSize(null, band.Items[itemIndex].Text, 
						Font, ref textRect, DrawTextFormatFlags.DT_CALCRECT | 
						DrawTextFormatFlags.DT_CENTER|DrawTextFormatFlags.DT_WORDBREAK); 				
				}
				return textSize;
			}
			else
			{
				// Same as above
				// Calculate text rectangle single line
				if ( band.Items[itemIndex].Text != null )
				{
					textSize = TextUtil.GetTextSize(null, band.Items[itemIndex].Text, Font); 				
				}
				return textSize;
			}
		}

		Rectangle GetIconRect(int index)
		{
			Rectangle viewPortRect = GetViewPortRect();
			OutlookBarBand band = bands[currentBandIndex];
            Debug.Assert(band != null);
            Size imageSize = Size.Empty;
			Rectangle itemRect = Rectangle.Empty;
			Point pt = new Point(0,0);
			
			using ( Graphics g = Graphics.FromHwnd(Handle) )
			{
				itemRect = GetItemRect(g, band, index, Rectangle.Empty);
			}

			if (  band.IconView == IconView.Small )
			{
				if ( band.SmallImageList != null )
				{
					imageSize = band.SmallImageList.ImageSize;
					pt.X = itemRect.Left;
					pt.Y = itemRect.Top + (itemRect.Height - imageSize.Height)/2;
				}
				return new Rectangle(pt, imageSize);
			}
			else
			{
				if ( band.LargeImageList != null )
				{
					imageSize = band.LargeImageList.ImageSize;
					pt.X = itemRect.Left + (viewPortRect.Width - imageSize.Width) / 2;
					pt.Y = itemRect.Top;
				}
				return new Rectangle(pt, imageSize);
			}
		}

		Rectangle GetLabelRect(int index)
		{
			Rectangle viewPortRect = GetViewPortRect();
			OutlookBarBand band = bands[currentBandIndex];
			Debug.Assert(band != null);
			Size imageSize = Size.Empty;
			Rectangle itemRect = Rectangle.Empty;
			Size labelSize = Size.Empty;
			Point pt = new Point(0,0);
			
			using ( Graphics g = Graphics.FromHwnd(Handle) )
			{
				itemRect = GetItemRect(g, band, index, Rectangle.Empty);
				labelSize = GetLabelSize(g, band, index);
			}

			if (  band.IconView == IconView.Small )
			{
				if ( band.SmallImageList != null )
				{ 
					imageSize = band.SmallImageList.ImageSize;
					// Don't include the offset between the icon and the label
					// so that we don't leave a miss hit gap
					pt.X = itemRect.Left + imageSize.Width;
					pt.Y = itemRect.Top + (itemRect.Height - labelSize.Height)/2;
				}
				return new Rectangle(pt.X, pt.Y  , labelSize.Width + X_SMALLICON_LABEL_OFFSET+2 , labelSize.Height);
			}
			else
			{
				if ( band.LargeImageList != null )
				{
					imageSize = band.LargeImageList.ImageSize;
					pt.X = itemRect.Left + (viewPortRect.Width - labelSize.Width) / 2;
					// Don't include the offset between the icon and the label
		

⌨️ 快捷键说明

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