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

📄 consolecontrol.cs

📁 c#源代码
💻 CS
📖 第 1 页 / 共 2 页
字号:
			else if(csbi.dwSize.x * csbi.dwSize.y < cols * bufferRows)
			{
				if(csbi.dwSize.y < bufferRows)
				{
					bufferRows = coordConsoleSize.y = csbi.dwSize.y;
					scrollbar.Maximum = bufferRows - rows - 6;
				}
				Win32Interop.SetConsoleScreenBufferSize(hStdOut, coordConsoleSize);
				Win32Interop.SetConsoleWindowInfo(hStdOut, true, ref srConsoleRect);
			}
			
			pScreenBuffer = new Win32Interop.CHAR_INFO[rows * cols];
		}
		
		void refreshScreenBuffer()
		{
			Win32Interop.COORD coordBufferSize;
			Win32Interop.COORD coordStart;
			Win32Interop.SMALL_RECT srRegion;
			
			Win32Interop.CONSOLE_SCREEN_BUFFER_INFO csbi = new Win32Interop.CONSOLE_SCREEN_BUFFER_INFO();
			Win32Interop.GetConsoleScreenBufferInfo(hStdOut, ref csbi);
			
			if((csbi.srWindow.Right - csbi.srWindow.Left + 1 != cols) || (csbi.srWindow.Bottom - csbi.srWindow.Top + 1 != rows) || (csbi.dwSize.y != bufferRows))
			{
				resizeConsoleWindow();
			}
			
			rowOffset = csbi.srWindow.Top;
			scrollbar.Value = Math.Min(scrollbar.Maximum, csbi.srWindow.Top);
			
			coordBufferSize.x = (short)cols;
			coordBufferSize.y = (short)bufferRows;
			
			coordStart.x = 0;
			coordStart.y = 0;
			
			srRegion.Top = (short)(csbi.srWindow.Top);
			srRegion.Left = 0;
			srRegion.Bottom = (short)(csbi.srWindow.Top + rows - 1);
			srRegion.Right = (short)(cols - 1);
			
			Win32Interop.ReadConsoleOutput(hStdOut, pScreenBuffer, coordBufferSize, coordStart, ref srRegion);
		}
		
		protected override void OnPaint(PaintEventArgs e)
		{
			int t = Environment.TickCount;
			refreshScreenBuffer();
			
			Win32Interop.CONSOLE_SCREEN_BUFFER_INFO csbi = new Win32Interop.CONSOLE_SCREEN_BUFFER_INFO();
			Win32Interop.GetConsoleScreenBufferInfo(hStdOut, ref csbi);
			
			Win32Interop.CONSOLE_CURSOR_INFO cinf;
			Win32Interop.GetConsoleCursorInfo(hStdOut, out cinf);
			
			e.Graphics.FillRectangle(Brushes.Black, 0, 0, charWidth * cols, charHeight * rows);
			
			for(int i = 0; i < rows; ++i)
			{
				int dwX = 0;
				int dwY = i * charHeight;
				
				int sameColor = 0;
				Color lastColor = Color.Empty;
				
				for(int j = 0; j < cols; ++j) {
					
					int attrBG = pScreenBuffer[i * cols + j].Attributes >> 4;
					
					Color color;
					if(ColorTranslator.ToWin32(consoleColors[attrBG]) == (csbi.wAttributes >> 4))
					{
						// transparent
						color = Color.Empty;
					}
					else
					{
						color = consoleColors[attrBG];
					}
					
					if(color == lastColor && j != cols-1)
					{
						sameColor++;
					}
					else
					{
						if(color != Color.Empty)
						{
							int x = dwX - sameColor * charWidth;
							int width = (sameColor  + 1) * charWidth;
							Brush backgroundBrush = new SolidBrush(color);
							e.Graphics.FillRectangle(backgroundBrush, x, dwY, width, charHeight);
							backgroundBrush.Dispose();
						}
						lastColor = color;
					}
					dwX += charWidth;
				}
			}
			
			for(int i = 0; i < rows; ++i)
			{
				int dwX = 0;
				int dwY = i * charHeight;
				for(int j = 0; j < cols; ++j)
				{
					string s = ((char)pScreenBuffer[i * cols + j].Character.UnicodeChar).ToString();
					if(s != " ")
					{
						Color fontColor = consoleColors[pScreenBuffer[i  * cols + j].Attributes & 0xF];
						Brush fontBrush = new SolidBrush(fontColor);
						e.Graphics.DrawString(s, font, fontBrush, dwX, dwY);
						fontBrush.Dispose();
					}
					dwX += charWidth;
				}
			}
			
			if(csbi.dwCursorPosition.y >= csbi.srWindow.Top && csbi.dwCursorPosition.y <= csbi.srWindow.Bottom)
			{
				if(cinf.bVisible)
				{
					csbi.dwCursorPosition.y -= csbi.srWindow.Top;
					Rectangle cursorRectangle = new Rectangle(csbi.dwCursorPosition.x * charWidth,
					                                          csbi.dwCursorPosition.y * charHeight,
					                                          charWidth,
					                                          charHeight);
					cursor.Draw(e.Graphics, cursorRectangle);
				}
			}
			
			Brush selectionBrush = new SolidBrush(selectionColor);
			e.Graphics.FillRectangle(selectionBrush, rectSelection);
			selectionBrush.Dispose();
		}
		
		void drawingTimerTick(object sender, EventArgs e)
		{
			this.Invalidate();
		}
		
		#endregion
		
		#region Selection handling
		
		public void ClearSelection()
		{
			textSelection = TextSelection.None;
			rectSelection = Rectangle.Empty;
			Invalidate();
		}
		
		protected void CopySelectionToClipboard()
		{
			int nSelX = rectSelection.Left / charWidth;
			int nSelY = rectSelection.Top / charHeight;
			int nSelColumns = (rectSelection.Right - rectSelection.Left) / charWidth;
			int nSelRows = (rectSelection.Bottom - rectSelection.Top) / charHeight;
			
			if ((nSelColumns == 0) || (nSelRows == 0))
			{
				ClearSelection();
				return;
			}
			
			StringBuilder selectedText = new StringBuilder();
			
			for(int i = 0; i < nSelRows; ++i)
			{
				for (int j = 0; j < nSelColumns; ++j)
				{
					selectedText.Append((char)pScreenBuffer[(nSelY + i + rowOffset) * cols + nSelX + j].Character.UnicodeChar);
				}
				selectedText.Append(Environment.NewLine);
			}
			
			ClearSelection();
			Clipboard.SetDataObject(selectedText.ToString());
		}
		
		protected override void OnMouseUp(MouseEventArgs e)
		{
			if(e.Button == MouseButtons.Left)
			{
				if(textSelection == TextSelection.Selected)
				{
					// if the user clicked inside the selection rectangle, copy data
					if(rectSelection.Contains(e.X, e.Y))
					{
						CopySelectionToClipboard();
					}
					ClearSelection();
				}
				else if(textSelection == TextSelection.Selecting)
				{
					if((rectSelection.Left == rectSelection.Right) && (rectSelection.Top == rectSelection.Bottom))
					{
						textSelection = TextSelection.None;
					}
					else
					{
						textSelection = TextSelection.Selected;
					}
				}
			}
		}
		
		protected override void OnMouseMove(MouseEventArgs e)
		{
			int deltaX;
			int deltaY;
			Point point = Point.Empty;
			
			if(e.Button == MouseButtons.Left)
			{
				point.X = e.X;
				point.Y = e.Y;
				
				deltaX = point.X - this.Left - mouseCursorOffset.Y;
				deltaY = point.Y - this.Top - mouseCursorOffset.Y;
				
				if (deltaX  > 0 || deltaY > 0)
				{
					if (textSelection != TextSelection.None)
					{
						if (textSelection == TextSelection.Selected) return;
						
						// selecting text for copy/paste
						Point coordSel = Point.Empty;
						
						coordSel.X = Math.Min(Math.Max(e.X, 0) / charWidth, cols - 1);
						coordSel.Y = Math.Min(Math.Max(e.Y, 0) / charHeight, rows - 1);
						
						if(coordSel.X >= coordSelOrigin.X)
						{
							rectSelection.X = coordSelOrigin.X * charWidth;
							rectSelection.Width = (coordSel.X + 1) * charWidth - rectSelection.X;
						}
						else
						{
							rectSelection.X = coordSel.X * charWidth;
							rectSelection.Width = (coordSelOrigin.X + 1) * charWidth - rectSelection.X;
						}
						
						if (coordSel.Y >= coordSelOrigin.Y)
						{
							rectSelection.Y = coordSelOrigin.Y * charHeight;
							rectSelection.Height = (coordSel.Y + 1) * charHeight - rectSelection.Y;
						}
						else
						{
							rectSelection.Y = coordSel.Y * charHeight;
							rectSelection.Height = (coordSelOrigin.Y + 1) * charHeight - rectSelection.Y;
						}
						Invalidate();
					}
				}
			}
		}
		
		protected override void OnMouseDown(MouseEventArgs e)
		{
			if(e.Button == MouseButtons.Left)
			{
				mouseCursorOffset.X -= this.Left;
				mouseCursorOffset.Y -= this.Top;
				
				if(textSelection == TextSelection.Selected)
				{
					return;
				}
				
				textSelection = TextSelection.Selecting;
				
				coordSelOrigin.X = Math.Min(Math.Max(e.X, 0) / charWidth, cols - 1);
				coordSelOrigin.Y = Math.Min(Math.Max(e.Y, 0) / charHeight, rows - 1);
				
				int left = coordSelOrigin.X * charWidth;
				int top = coordSelOrigin.Y * charHeight;
				
				rectSelection = new Rectangle(left, top, 0, 0);
			}
		}
		#endregion
		
		#region Scrolling
		
		private void vScrolled(object sender, ScrollEventArgs e)
		{
			int delta = e.NewValue - scrollbar.Value;
			Win32Interop.SMALL_RECT sr;
			sr.Top = (short)delta;
			sr.Bottom = (short)(delta);
			sr.Left = 0;
			sr.Right = 0;
			Win32Interop.SetConsoleWindowInfo(hStdOut, false, ref sr);
			
			Invalidate();
		}
		#endregion
	}
}

⌨️ 快捷键说明

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