可是我是想通过鼠标来画出出这个区域,而这个区域是不规则的。我发现鼠标事件不起作用啊。
using System;
using System.Collections.Generic;
using
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Text;
using System.Windows.Forms;
namespace HandDrawer
{
public partial class MainForm : Form
{
/// <summary>
/// 存放所有的线条。
/// </summary>
/// <remarks>
/// 图片是由很多条线构成的。每条线又是由鼠标经过的很多点构成的。
/// 因此一个List<Point>表示一条线。List<List<Point>>就表示所有的线条。
/// </remarks>
private List<List<Point>> m_lines;
/// <summary>
/// 存放新的一条线。
/// </summary>
private List<Point> m_newLine;
public MainForm()
{
InitializeComponent();
m_lines = new List<List<Point>>();
}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
// 鼠标按下的时候新建一个线条。
m_newLine = new List<Point>();
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
// 将经过的点添加到当前线条列表,并连接。
m_addPoint(e.X, e.Y);
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
// 将经过的点添加到当前线条列表,并连接。
m_addPoint(e.X, e.Y);
// 将线条添加到所有线条列表。
m_lines.Add(m_newLine);
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
// Create a local version of the graphics object for the PictureBox.
Graphics g = e.Graphics;
// Draw a line in the PictureBox.
Pen pens = new Pen(Color.Red);
g.DrawLine(pens, pictureBox1.Left, pictureBox1.Top,
pictureBox1.Right, pictureBox1.Bottom);
// 重绘所有线条。
m_drawAllLines(e.Graphics);
}
private void m_mnuClear_Click(object sender, EventArgs e)
{
// 首先清除所有线条中的点。
foreach(List<Point> line in m_lines)
line.Clear();
// 清除所有线条。
m_lines.Clear();
// 重绘整个窗体。
this.Invalidate();
}
private void m_mnuSave_Click(object sender, EventArgs e)
{
// 显示对话框,获取用户要保存的文件名。
if(DialogResult.OK != m_saveFileDialog.ShowDialog())
return;
// 所需的资源
Bitmap bmp = null; // 待保存的图片
Graphics g = null; // 从图片获得的绘图表面
Brush b = null; // 用于绘制背景色的画刷
try
{
// 创建或获取所需的资源。
bmp = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);
g = Graphics.FromImage(bmp);
b = new SolidBrush(Color.White);
// 首先把背景填充为白色。
g.FillRectangle(b, this.ClientRectangle);
// 绘制所有的线条。
m_drawAllLines(g);
// 保存位图。
bmp.Save(m_saveFileDialog.FileName, ImageFormat.Bmp);
}
catch(Exception ex)
{
MessageBox.Show(
String.Format("Cannot save the picture, detailes: {0}", ex.Message),
"Error",
MessageBoxButtons.OK,
MessageBoxIcon.Hand,
MessageBoxDefaultButton.Button1);
}
finally
{
// 清理已经获取的资源。
if(bmp != null)
bmp.Dispose();
if(g != null)
g.Dispose();
if(b != null)
b.Dispose();
}
}
/// <summary>
/// 向当前线条中添加一个点,并将其与线条中的最后一个点连接起来。
/// </summary>
/// <param name="x">新添加的点的横坐标。</param>
/// <param name="y">新添加的点的纵坐标。</param>
private void m_addPoint(int x, int y)
{
// 将经过的点添加到线条。
m_newLine.Add(new Point(x, y));
// 绘制线段,连接当前线条的最后一点和新经过的这一点。
int points = m_newLine.Count;
if(points > 1)
{
Graphics g = this.CreateGraphics();
Pen p = new Pen(Color.Black);
// m_newLine[points - 2]是原线条最后一点
// m_newLine[points - 1]是新添加的点
g.DrawLine(
p,
m_newLine[points - 2].X, m_newLine[points - 2].Y,
m_newLine[points - 1].X, m_newLine[points - 1].Y);
g.Dispose();
p.Dispose();
}
}
/// <summary>
/// 用来绘制所有的线条。用于 1.窗体重绘 2.保存时绘制到位图。
/// </summary>
/// <param name="g">用于绘图的Graphics。</param>
private void m_drawAllLines(Graphics g)
{
Pen p = new Pen(Color.Black);
int totalLines = m_lines.Count;
for(int i = 0; i < totalLines; i++)
{
g.DrawLines(p, m_lines[i].ToArray());
}
p.Dispose();
}
private void MainForm_Load(object sender, System.EventArgs e)
{
pictureBox1.Dock = DockStyle.Fill;
pictureBox1.BackColor = Color.White;
pictureBox1.Paint += new System.Windows.Forms.PaintEventHandler(this.pictureBox1_Paint);
this.Controls.Add(pictureBox1);
}
}
}