当前位置:编程学习 > C#/ASP.NET >>

请教C#画图问题:画图时发生GDI+一般性错误

问题描述:
在一个主要窗口中中实现画图功能,主窗口设置了isMdiContainer = true。可以点击相关的菜单,即可弹出一个画图窗口dFrm(我设置的是在Form中绘图),画图功能应该没有问题。但现在的问题时,我做多了一个设置画笔粗细的窗口,点击相关菜单,可以把画图窗口dFrm隐藏起来,弹出设置画笔粗细的窗口PenWidth,点击确定按钮可以把数据传到dFrm中,并且此刻设置画笔粗细的窗口PenWidth隐藏起来,画图窗口dFrm继续显示出来。但现在画图的话,会提示GDI+一般性错误!

真心请教...
以下是一些源码:
//主窗口
namespace 实验1设计一个简易的_画图_程序
{
    public partial class MainForm : Form
    {
        public DrawForm dFrm;//绘图窗口对象
        public PenWidth pwFrm;//画笔粗细窗口对象
        public TransformForm tfFrm;//变形窗口

        public MainForm()
        {
            InitializeComponent();
        }

        //初始化
        private void MainForm_Load(object sender, EventArgs e)
        {
            dFrm = new DrawForm();
            dFrm.MdiParent = this;
            dFrm.Show();
        }

        //菜单“新建”
        private void FileMenuNewItem_Click(object sender, EventArgs e)
        {
            dFrm = new DrawForm();
            dFrm.MdiParent = this;
            dFrm.Show();
        }

        //菜单“编辑-粗细”
        private void EditMenuPenWidthItem_Click(object sender, EventArgs e)
        {
            pwFrm = new PenWidth();
            pwFrm.MdiParent = this;
            pwFrm.Show();

            dFrm.Hide();
        }

        //按钮“退出程序”
        private void tsbExit_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }
    }
}

//画图窗口
namespace 实验1设计一个简易的_画图_程序
{
    public partial class DrawForm : Form
    {
        public Graphics g;//声明Graphics对象
        public Pen p;//声明钢笔对象
        private bool isMouseDown;//用来判断是否按下鼠标键
        public Point pStart, pEnd,pStartTemp;//声明起始点和结束点
        public Cursor cursor;//鼠标指针对象

        public DrawForm()
        {
            InitializeComponent();

            this.MaximumSize = new Size(
                Screen.PrimaryScreen.WorkingArea.Width,
                Screen.PrimaryScreen.WorkingArea.Height);
            this.WindowState = FormWindowState.Maximized;

            this.Size = new Size(
                Screen.PrimaryScreen.WorkingArea.Width,
                Screen.PrimaryScreen.WorkingArea.Height);
        }

        private void DrawForm_Load(object sender, EventArgs e)
        {
            g = this.CreateGraphics();//创建Graphics对象
            p = new Pen(Color.Black);//创画笔笔对象
            p.StartCap = LineCap.Round;//防止当钢笔的粗细很大时,出现断断续续的情况
            isMouseDown = false;
            this.Cursor = Cursors.Cross;
        }

        //根据鼠标的动作绘图
        private void DrawForm_MouseDown(object sender, MouseEventArgs e)
        {
            isMouseDown = true;
            pStart = new Point(e.X, e.Y);
            pStartTemp = pStart;
        }

        private void DrawForm_MouseUp(object sender, MouseEventArgs e)
        {
            isMouseDown = false;
        }

        private void DrawForm_MouseMove(object sender, MouseEventArgs e)
        {
            try
            {
                if (isMouseDown)
                {
                    pEnd = new Point(e.X, e.Y);
                    g.DrawLine(p, pStart, pEnd);
                    pStart = pEnd;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                Application.Exit();
            }
        }
    }
}

//控制画笔粗细的窗口

namespace 实验1设计一个简易的_画图_程序
{
    public partial class PenWidth : Form
    {
        Graphics g;//声明Graphics对象
        Pen p;//声明钢笔对象
        Point pStart, pEnd;//声明起始点和结束点
        int width;//线条粗细

        public PenWidth()
        {
            InitializeComponent();
        }

        private void PenWidth_Load(object sender, EventArgs e)
        {
            g = this.CreateGraphics();//创建Graphics对象
            p = new Pen(Color.Black);//创建钢笔对象
            p.StartCap = LineCap.Round;//防止当钢笔的粗细很大时,出现断断续续的情况
            pStart = new Point(0, this.Height / 4);
            pEnd = new Point(this.Width, this.Height / 4);
            width = 1;
        }

        private void PenWidth_Paint(object sender, PaintEventArgs e)
        {
            g.DrawLine(p, pStart, pEnd);
        }

        private void psbWidth_ValueChanged(object sender, EventArgs e)
        {
            lblWidth.Text = "粗细:";
            width = psbWidth.Value;
            p.Width = width;
            lblWidth.Text += width;
            g.Clear(this.BackColor);//还原窗体的背景色
            g.DrawLine(p, pStart, pEnd); 
        }

        private void btnOk_Click(object sender, EventArgs e)
        {
            //将线条的粗细返回给DrawForm
            ((MainForm)this.MdiParent).dFrm.p.Width = width;

            this.Hide();

            ((MainForm)this.MdiParent).dFrm.Show();
        }
    }
}

c# gdi+ exception --------------------编程问答-------------------- 在 private void DrawForm_MouseMove(object sender, MouseEventArgs e)
处设置断点,不要抛异常,一步步看pen的width到底是多少 --------------------编程问答--------------------
引用 1 楼 c2606050113 的回复:
在 private void DrawForm_MouseMove(object sender, MouseEventArgs e)
处设置断点,不要抛异常,一步步看pen的width到底是多少

恩恩,行,谢谢,那我去看看.... --------------------编程问答-------------------- public void SetPenWidth(int width){

g = this.CreateGraphics();//创建Graphics对象
            p = new Pen(Color.Black);//创画笔笔对象
            p.StartCap = LineCap.Round;//防止当钢笔的粗细很大时,出现断断续续的情况
p.Width = width;
}

试试这个看看。 --------------------编程问答--------------------
引用 2 楼 keenleung1992 的回复:
引用 1 楼 c2606050113 的回复:在 private void DrawForm_MouseMove(object sender, MouseEventArgs e)
处设置断点,不要抛异常,一步步看pen的width到底是多少
恩恩,行,谢谢,那我去看看....

这样做好像不方便观察,我直接在控制画笔粗细的窗口中更改了:
private void btnOk_Click(object sender, EventArgs e)
        {
            //将线条的粗细返回给DrawForm
            ((MainForm)this.MdiParent).dFrm.p.Width = width;

            this.Hide();

            ((MainForm)this.MdiParent).dFrm.Show();
            MessageBox.Show("p.Width= "+((MainForm)this.MdiParent).dFrm.p.Width);
        }
显示了我选择的粗细,但当画图窗口弹出来时,再画时,提示:


应该p的Width值已经改变了,但当弹出画图界面后,再画就出错了
--------------------编程问答--------------------
引用 3 楼 lye2000000_super 的回复:
public void SetPenWidth(int width){

g = this.CreateGraphics();//创建Graphics对象
            p = new Pen(Color.Black);//创画笔笔对象
            p.StartCap = LineCap.Round;//防止当钢笔的粗细很大时,出现断断续续……

恩恩,行,谢谢,我看看.... --------------------编程问答--------------------
引用 3 楼 lye2000000_super 的回复:
public void SetPenWidth(int width){

g = this.CreateGraphics();//创建Graphics对象
            p = new Pen(Color.Black);//创画笔笔对象
            p.StartCap = LineCap.Round;//防止当钢笔的粗细很大时,出现断断续续……

p.Width的值应该没有问题,我修改了一下代码:
此段代码在画图窗口中:
private void DrawForm_MouseUp(object sender, MouseEventArgs e)
        {
            isMouseDown = false;

            //MessageBox.Show("p.Width= " + p.Width);
            MessageBox.Show("p.Width=" + p.Width + " pStart= " + pStart + " pEnd= " + pEnd);
        }
显示:

接着弹出:

说明了画图窗口中的p的值确实改变了... --------------------编程问答-------------------- 跟p值没关系。看看那个graphics。 --------------------编程问答-------------------- 还有种方法你画固定的线。看看是不是还有问题? --------------------编程问答--------------------
引用 7 楼 lye2000000_super 的回复:
跟p值没关系。看看那个graphics。

恩恩,好....今晚上课,回来再看...谢谢.... --------------------编程问答--------------------
引用 7 楼 lye2000000_super 的回复:
跟p值没关系。看看那个graphics。

修改了一下画图窗口代码:
private void DrawForm_MouseMove(object sender, MouseEventArgs e)
        {
            g = this.CreateGraphics();//增加了这段代码
            if (isMouseDown)
            {
                pEnd = new Point(e.X, e.Y);
                g.DrawLine(p, pStart, pEnd);
                pStart = pEnd;
            }
        }
结果就能够继续画图了...
但现在又出现一个问题,画图窗口一旦隐藏起来,再显示出来时,之前画的东西都不见了,这是为什么,请赐教...谢谢... --------------------编程问答-------------------- 再显示的的时候控件重绘了。你在隐藏的时候保存你画的。在form的activate事件里再画上去吧。 --------------------编程问答-------------------- 绘图,放在Paint事件中。 --------------------编程问答-------------------- 创建bitmap对象bt,在mousemove事件中,画到bitmap中, 
 Graphics g = Graphics.FromImage(bt);
 g.DrawLine(p, pStart, pEnd);
然后再paint事件中把位图画出来
private void panel1_Paint(object sender, PaintEventArgs e)
        {
            if (bt != null)
            {
                e.Graphics.Clear(Color.White);
                e.Graphics.DrawImage(bt, 0, 0);
            }
        } --------------------编程问答--------------------
引用 11 楼 lye2000000_super 的回复:
再显示的的时候控件重绘了。你在隐藏的时候保存你画的。在form的activate事件里再画上去吧。

恩恩,行,谢谢.... --------------------编程问答--------------------
引用 12 楼 assky124 的回复:
绘图,放在Paint事件中。

谢谢... --------------------编程问答--------------------
引用 13 楼 c2606050113 的回复:
创建bitmap对象bt,在mousemove事件中,画到bitmap中, 
 Graphics g = Graphics.FromImage(bt);
 g.DrawLine(p, pStart, pEnd);
然后再paint事件中把位图画出来
private void panel1_Paint(object sender, PaintEventArgs e)……

恩恩,行,谢谢,我去看看.... --------------------编程问答-------------------- 除 --------------------编程问答--------------------
引用 13 楼 c2606050113 的回复:
创建bitmap对象bt,在mousemove事件中,画到bitmap中, 
 Graphics g = Graphics.FromImage(bt);
 g.DrawLine(p, pStart, pEnd);
然后再paint事件中把位图画出来
private void panel1_Paint(object sender, PaintEventArgs e)……

这个方法我没用过,可以说详细点吗?谢谢....
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,