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

📄 progressbarex.cs

📁 c#编写的仿OUTLOOK工具条的Winform菜单
💻 CS
📖 第 1 页 / 共 2 页
字号:
		{
			base.OnPaint(e);
			
			// Get window area
			Win32.RECT rc = new Win32.RECT();
			WindowsAPI.GetWindowRect(Handle, ref rc);

			// Convert to a client size rectangle
			Rectangle rect = new Rectangle(0, 0, rc.right - rc.left, rc.bottom - rc.top);

			Graphics g = e.Graphics;
			DrawBackground(g, rect);
			DrawBorder(g, rect);
			DrawForeground(g, rect);
		
		}
	
		void DrawBorder(Graphics g, Rectangle windowRect)
		{
			if ( enableBorder3D == false )
			{
				g.DrawRectangle(new Pen(borderColor), windowRect.Left, windowRect.Top,
					windowRect.Width-1, windowRect.Height-1);
			}
			else 
			{
				ControlPaint.DrawBorder3D(g, windowRect, border3D);
			}
		}

		void DrawBackground(Graphics g, Rectangle windowRect)
		{
			if ( barType == ProgressBarType.Standard )
			{
				DrawStandardBackground(g, windowRect);
			}
			else if ( barType == ProgressBarType.Bitmap ) 
			{
				DrawBitmapBackground(g, windowRect);
			}
			else if ( barType == ProgressBarType.Gradient )
			{
				DrawGradientBackground(g, windowRect);
			}
		}

		void DrawStandardBackground(Graphics g, Rectangle windowRect)
		{
			windowRect.Inflate(-1, -1);
			g.FillRectangle(new SolidBrush(backgroundColor), windowRect);
		}

		void DrawBitmapBackground(Graphics g, Rectangle windowRect)
		{
			if (  backgroundBitmap != null )
			{
				// If we strech the bitmap most likely than not the bitmap
				// won't look good. I will draw the background bitmap just 
				// by sampling a portion of the bitmap equal to the segment width
				// -- if we were drawing segments --- and draw this over and over
				// without leaving gaps
				int segmentWidth = (windowRect.Height-4)*3/4;
				segmentWidth -= 2;
				Rectangle drawingRect = new Rectangle(windowRect.Left+1, windowRect.Top+1, segmentWidth, windowRect.Height-2);
				for ( int i = 0; i < windowRect.Width-2; i += segmentWidth) 
				{
					g.DrawImage(backgroundBitmap, drawingRect.Left + i, drawingRect.Top,
						segmentWidth, windowRect.Height);
					// If last segment does not fit, just draw a portion of it
					if ( i + segmentWidth > windowRect.Width-2 )
						g.DrawImage(backgroundBitmap, drawingRect.Left + i + segmentWidth, drawingRect.Top,
							windowRect.Width-2 - (drawingRect.Left + i + segmentWidth), windowRect.Height);
				}
			}
			else 
			{
				windowRect.Inflate(-1, -1);
				g.FillRectangle(new SolidBrush(backgroundColor), windowRect);
			}
		}


		void DrawGradientBackground(Graphics g, Rectangle windowRect)
		{
			// Same as the standard background
			windowRect.Inflate(-1, -1);
			g.FillRectangle(new SolidBrush(backgroundColor), windowRect);
		}

		void DrawForeground(Graphics g, Rectangle windowRect)
		{
			if ( barType == ProgressBarType.Standard )
			{
				DrawStandardForeground(g, windowRect);
			}
			else if ( barType == ProgressBarType.Bitmap ) 
			{
				DrawBitmapForeground(g, windowRect);
			}
			else if ( barType == ProgressBarType.Gradient )
			{
				DrawGradientForeground(g, windowRect);
			}
		}

		void DrawStandardForeground(Graphics g, Rectangle windowRect)
		{
			if ( smooth )
				DrawStandardForegroundSmooth(g, windowRect);
			else
				DrawStandardForegroundSegmented(g, windowRect);

		}

		void DrawBitmapForeground(Graphics g, Rectangle windowRect)
		{

			// We should have a valid foreground bitmap if the type of
			// the progress bar is bitmap
			Debug.Assert(foregroundBitmap != null);
			
			// If we strech the bitmap most likely than not the bitmap
			// won't look good. I will draw the foreground bitmap just 
			// by sampling a portion of the bitmap equal to the segment width
			// -- if we were drawing segments --- and draw this over and over
			// without leaving gaps
			int segmentWidth = (windowRect.Height-4)*3/4;
			segmentWidth -= 2;
                        
			Rectangle segmentRect = new Rectangle(2, 
				windowRect.Top + 2, segmentWidth, windowRect.Height-4);
			   			
			int progressWidth = (GetScaledValue() - 2);
			if ( progressWidth < 0 ) progressWidth = 0;
			int gap = 2;
			if ( smooth ) gap = 0;
			
			for ( int i = 0; i < progressWidth; i += segmentRect.Width+gap )
			{
				if ( i+segmentRect.Width+gap > progressWidth && (i+segmentRect.Width+gap > windowRect.Width-2-gap) ) 
				{
					// if we are about to leave because next segment does not fit
					// draw the portion that fits
					int partialWidth = progressWidth-i-2;
					Rectangle drawingRect = new Rectangle(segmentRect.Left+i, 
						segmentRect.Top, partialWidth, segmentRect.Height);
					g.DrawImage(foregroundBitmap, drawingRect, 0, 0, drawingRect.Width, drawingRect.Height, GraphicsUnit.Pixel);
					break;
				}
				Rectangle completeSegment = new Rectangle(segmentRect.Left+i, segmentRect.Top, segmentRect.Width, segmentRect.Height);
				g.DrawImage(foregroundBitmap, completeSegment, 0, 0, completeSegment.Width, completeSegment.Height, GraphicsUnit.Pixel);
			}
		}


        void DrawGradientForeground(Graphics g, Rectangle windowRect)
		{
			// Three color gradient?
			bool useMiddleColor = false;
			if ( gradientMiddleColor != Color.Empty )
				useMiddleColor = true;

			if ( useMiddleColor )
				DrawThreeColorsGradient(g, windowRect);
			else
				DrawTwoColorsGradient(g, windowRect);
		}

		void DrawTwoColorsGradient(Graphics g, Rectangle windowRect)
		{
			// Calculate color distance
			int redStep = Math.Max(gradientEndColor.R, gradientStartColor.R) 
				- Math.Min(gradientEndColor.R, gradientStartColor.R);
			int greenStep = Math.Max(gradientEndColor.G, gradientStartColor.G) 
				- Math.Min(gradientEndColor.G, gradientStartColor.G);
			int blueStep = Math.Max(gradientEndColor.B, gradientStartColor.B) 
				- Math.Min(gradientEndColor.B, gradientStartColor.B);

			// Do we need to increase or decrease
			int redDirection; 
			if ( gradientEndColor.R > gradientStartColor.R ) 
				redDirection = 1;
			else
				redDirection = -1;

			int greenDirection;
			if (  gradientEndColor.G >  gradientStartColor.G )
				greenDirection = 1;
			else
				greenDirection = -1;

			int blueDirection;
			if ( gradientEndColor.B > gradientStartColor.B )
				blueDirection = 1;
			else
				blueDirection = -1;
						
			// The progress control won't allow its height to be anything other than
			// and even number since the width of the segment needs to be a perfect 3/4
			// of the control (height - 4) -- Four pixels are padding --
			int segmentWidth = (windowRect.Height-4)*3/4;
			segmentWidth -= 2;

			// how many segements we need to draw
			int gap = 2;
			if ( smooth ) gap = 0;
			int numOfSegments = (windowRect.Width - 4)/(segmentWidth + gap);
			
			// calculate the actual RGB steps for every segment
			redStep /= numOfSegments;
			greenStep /= numOfSegments;
			blueStep /= numOfSegments;

			Rectangle segmentRect = new Rectangle(2, 
				windowRect.Top + 2, segmentWidth, windowRect.Height-4);
			   			
			int progressWidth = (GetScaledValue() - 2);
			if ( progressWidth < 0 ) progressWidth = 0;
			int counter = 0;
			for ( int i = 0; i < progressWidth; i += segmentRect.Width+gap )
			{
				Color currentColor = Color.FromArgb(gradientStartColor.R+(redStep*counter*redDirection), 
					gradientStartColor.G+(greenStep*counter*greenDirection), gradientStartColor.B+(blueStep*counter*blueDirection));
				if ( i+segmentRect.Width+gap > progressWidth && (i+segmentRect.Width+gap > windowRect.Width-2-gap) ) 
				{
					// if we are about to leave because next segment does not fit
					// draw the portion that fits
					int partialWidth = progressWidth-i-2;
					Rectangle drawingRect = new Rectangle(segmentRect.Left+i, 
						segmentRect.Top, partialWidth, segmentRect.Height);
					g.FillRectangle(new SolidBrush(currentColor), drawingRect);
					break;
				}
				Rectangle completeSegment = new Rectangle(segmentRect.Left+i, segmentRect.Top, segmentRect.Width, segmentRect.Height);
				g.FillRectangle(new SolidBrush(currentColor), completeSegment);
				counter++;
			}

		}

		void DrawThreeColorsGradient(Graphics g, Rectangle windowRect)
		{
			// Calculate color distance for the first half
			int redStepFirst = Math.Max(gradientStartColor.R, gradientMiddleColor.R) 
				- Math.Min(gradientStartColor.R, gradientMiddleColor.R);
			int greenStepFirst = Math.Max(gradientStartColor.G, gradientMiddleColor.G) 
				- Math.Min(gradientStartColor.G, gradientMiddleColor.G);
			int blueStepFirst = Math.Max(gradientStartColor.B, gradientMiddleColor.B) 
				- Math.Min(gradientStartColor.B, gradientMiddleColor.B);
   
			// Calculate color distance for the second half
			int redStepSecond = Math.Max(gradientEndColor.R, gradientMiddleColor.R) 
				- Math.Min(gradientEndColor.R, gradientMiddleColor.R);
			int greenStepSecond = Math.Max(gradientEndColor.G, gradientMiddleColor.G) 
				- Math.Min(gradientEndColor.G, gradientMiddleColor.G);
			int blueStepSecond = Math.Max(gradientEndColor.B, gradientMiddleColor.B) 
				- Math.Min(gradientEndColor.B, gradientMiddleColor.B);
			
			// Do we need to increase or decrease for the first half
			int redDirectionFirst; 
			if ( gradientStartColor.R < gradientMiddleColor.R ) 
				redDirectionFirst = 1;
			else
				redDirectionFirst = -1;

			int greenDirectionFirst;
			if (  gradientStartColor.G <  gradientMiddleColor.G )
				greenDirectionFirst = 1;
			else
				greenDirectionFirst = -1;

			int blueDirectionFirst;
			if ( gradientStartColor.B < gradientMiddleColor.B )
				blueDirectionFirst = 1;
			else
				blueDirectionFirst = -1;

			// Do we need to increase or decrease for the second half
			int redDirectionSecond; 
			if ( gradientMiddleColor.R < gradientEndColor.R ) 
				redDirectionSecond = 1;
			else
				redDirectionSecond = -1;

			int greenDirectionSecond;
			if (  gradientMiddleColor.G <  gradientEndColor.G )
				greenDirectionSecond = 1;
			else
				greenDirectionSecond = -1;

			int blueDirectionSecond;
			if ( gradientMiddleColor.B < gradientEndColor.B )
				blueDirectionSecond = 1;
			else
				blueDirectionSecond = -1;

			// The progress control won't allow its height to be anything other than
			// and even number since the width of the segment needs to be a perfect 3/4
			// of the control (height - 4) -- Four pixels are padding --
			int segmentWidth = (windowRect.Height-4)*3/4;
			segmentWidth -= 2;

			// how many segements we need to draw
			int gap = 2;
			if ( smooth ) gap = 0;
			int numOfSegments = (windowRect.Width - 4)/(segmentWidth + gap);
			
			// calculate the actual RGB step for every segment
			redStepFirst /= (numOfSegments/2);
			greenStepFirst /= (numOfSegments/2);
			blueStepFirst /= (numOfSegments/2);
			redStepSecond /= (numOfSegments/2);
			greenStepSecond /= (numOfSegments/2);
			blueStepSecond /= (numOfSegments/2);

			Rectangle segmentRect = new Rectangle(2, 
				windowRect.Top + 2, segmentWidth, windowRect.Height-4);
			   			
			int progressWidth = (GetScaledValue() - 2);
			if ( progressWidth < 0 ) progressWidth = 0;
			int counter = 0;
			bool counterReset = true;
			for ( int i = 0; i < progressWidth; i += segmentRect.Width+gap )
			{
				Color currentColor = Color.Empty;
				if ( i < (windowRect.Width-4)/2 )
				{
					currentColor = Color.FromArgb(gradientStartColor.R+(redStepFirst*counter*redDirectionFirst), 
						gradientStartColor.G+(greenStepFirst*counter*greenDirectionFirst), 
						gradientStartColor.B+(blueStepFirst*counter*blueDirectionFirst));
				}
				else
				{
					if ( counterReset )
					{
						counterReset = false;
						counter = 0;
					}
					currentColor = Color.FromArgb(gradientMiddleColor.R+(redStepSecond*counter*redDirectionSecond), 
						gradientMiddleColor.G+(greenStepSecond*counter*greenDirectionSecond), 
						gradientMiddleColor.B+(blueStepSecond*counter*blueDirectionSecond));
				}
								
				if ( i+segmentRect.Width+gap > progressWidth && (i+segmentRect.Width+gap > windowRect.Width-2-gap) ) 
				{
					// if we are about to leave because next segment does not fit
					// draw the portion that fits
					int partialWidth = progressWidth-i-2;
					Rectangle drawingRect = new Rectangle(segmentRect.Left+i, 
						segmentRect.Top, partialWidth, segmentRect.Height);
					g.FillRectangle(new SolidBrush(currentColor), drawingRect);
					break;
				}
				Rectangle completeSegment = new Rectangle(segmentRect.Left+i, segmentRect.Top, segmentRect.Width, segmentRect.Height);
				g.FillRectangle(new SolidBrush(currentColor), completeSegment);
				counter++;
			}
		}

		void DrawStandardForegroundSegmented(Graphics g, Rectangle windowRect)
		{
			// The progress control won't allow its height to be anything other than
			// and even number since the width of the segment needs to be a perfect 3/4
			// of the control (height - 4) -- Four pixels are padding --
			int segmentWidth = (windowRect.Height-4)*3/4;
			segmentWidth -= 2;
                        
			Rectangle segmentRect = new Rectangle(2, 
				windowRect.Top + 2, segmentWidth, windowRect.Height-4);
			
			int progressWidth = (GetScaledValue() - 2);
			if ( progressWidth < 0 ) progressWidth = 0;
			for ( int i = 0; i < progressWidth; i += segmentRect.Width+2 )
			{
				if ( i+segmentRect.Width+2 > progressWidth && (i+segmentRect.Width+2 > windowRect.Width-4) ) 
				{
					// if we are about to leave because next segment does not fit
					// draw the portion that fits
					int partialWidth = progressWidth-i-2;
					g.FillRectangle(new SolidBrush(foregroundColor), 
						segmentRect.Left+i, segmentRect.Top, partialWidth, segmentRect.Height);
					break;
				}
				g.FillRectangle(new SolidBrush(foregroundColor), segmentRect.Left+i, segmentRect.Top, 
					segmentRect.Width, segmentRect.Height);
			}
		}

		void DrawStandardForegroundSmooth(Graphics g, Rectangle windowRect)
		{
			int progressWidth = (GetScaledValue() - 4);
			g.FillRectangle(new SolidBrush(foregroundColor), windowRect.Left + 2, windowRect.Top+2, 
				progressWidth, windowRect.Height-4);
			if ( ShowProgressText)
			{
				int percent = GetScaledValue()*100/windowRect.Width;
				string percentageValue = percent.ToString() + " " + "%";	
				Size size = TextUtil.GetTextSize(g, percentageValue, Font);
			
				// Draw first part of the text in hightlight color in case it needs to be
				Rectangle clipRect = new Rectangle(windowRect.Left + 2, windowRect.Top+2,
					progressWidth, windowRect.Height-4);
				Point pos = new Point((windowRect.Width - size.Width)/2, (windowRect.Height - size.Height)/2);
				g.Clip = new Region(clipRect);
				Color textColor = progressTextHiglightColor;
				if ( textColor == Color.Empty )
					textColor = SystemColors.HighlightText;
				g.DrawString(percentageValue, Font, new SolidBrush(textColor), pos);

				// Draw rest in control text color if it needs to be
				clipRect = new Rectangle(progressWidth+2, windowRect.Top+2,
					windowRect.Width, windowRect.Height-4);
				g.Clip = new Region(clipRect);
				textColor = progressTextColor;
				if ( textColor == Color.Empty )
					textColor = SystemColors.ControlText;
				g.DrawString(percentageValue, Font, new SolidBrush(textColor), pos);
			}
		}
				
		int GetScaledValue()
		{
			int scaledValue = _value;
			Size currentSize = Size;
			scaledValue = (_value-min)*currentSize.Width/(max - min);
			return scaledValue;
		}
		
	}
}

⌨️ 快捷键说明

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