当前位置: 代码迷 >> C# >> GetHdc步骤报参数无效,为什么呢
  详细解决方案

GetHdc步骤报参数无效,为什么呢

热度:689   发布时间:2016-05-05 02:53:02.0
GetHdc方法报参数无效,为什么呢?
http://download.csdn.net/detail/sa481453/373083
在这里找到个颜色拾取器的代码,觉得不错就下载来看了看,运行的时候发现会在运行一段时间(几分钟)后就出现异常,但又找不到出现异常的原因,特来求大神指点。
这是其中一段代码,代码我有修改以定位异常位置,但结果还是没用,想不明白:


        public static object isOut = "obj";
        private void timer1_Tick(object sender, EventArgs e)
        {
            lock (isOut)
            {
                if (isOut.ToString() == "now")
                    return;
                isOut = "now";
                Bitmap bmp = null;
                Graphics gfxDisplay = null;
                Graphics gfxBmp = null;
                try
                {
                    //创建显示器的DC
                    IntPtr hdlDisplay = CreateDC("DISPLAY", null, null, IntPtr.Zero);
                    if (hdlDisplay != null)
                    {
                        //从指定设备的句柄创建新的 Graphics 对象
                        gfxDisplay = Graphics.FromHdc(hdlDisplay);
                        if (gfxDisplay != null)
                        {
                            //创建只有一个象素大小的 Bitmap 对象
                            bmp = new Bitmap(1, 1, gfxDisplay);
                            if (bmp != null)
                            {
                                //从指定 Image 对象创建新的 Graphics 对象
                                gfxBmp = Graphics.FromImage(bmp);
                                if (gfxBmp != null)
                                {
                                    //得到屏幕句柄
                                    IntPtr hdlScreen = gfxDisplay.GetHdc();
                                    if (hdlScreen != null)
                                    {
                                        //得到位图句柄
                                        IntPtr hdlBmp = gfxBmp.GetHdc();
                                        if (hdlBmp != null)
                                        {
                                            //把当前屏幕中鼠标指针所在位置的一个象素拷贝到位图中
                                            BitBlt(hdlBmp, 0, 0, 1, 1, hdlScreen, MousePosition.X, MousePosition.Y, 13369376);
                                            //释放屏幕句柄
                                            gfxDisplay.ReleaseHdc(hdlScreen);
                                            //释放位图句柄
                                            gfxBmp.ReleaseHdc(hdlBmp);

                                            //获取象素的颜色
                                            Color c = bmp.GetPixel(0, 0);
                                            panelColorBox.BackColor = c;
                                            txtWeb.Text = ColorTranslator.ToHtml(c);
                                            txtRGB.Text = c.R.ToString() + "," + c.G.ToString() + "," + c.B.ToString();
                                        
                                            if (gfxDisplay != null)
                                                gfxDisplay.Dispose();
                                            if (gfxBmp != null)
                                                gfxBmp.Dispose();
                                            if (bmp != null)
                                                bmp.Dispose();//释放BMP使用的资源
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    string test = ex.ToString();
                    StreamWriter log = new StreamWriter(@"C:\Users\USER\Desktop\颜色捕捉器\ceshi.txt", true);
                    log.WriteLine("异常发生时间:" + DateTime.Now + "\r\n" + test + "\r\n");
                    log.Close();
                    this.Dispose();
                    this.Close();
                }
                finally
                { //MessageBox.Show(ex.Message);
                    if (gfxDisplay != null)
                        gfxDisplay.Dispose();
                    if (gfxBmp != null)
                        gfxBmp.Dispose();
                    if (bmp != null)
                        bmp.Dispose();//释放BMP使用的资源
                }

                isOut = "ok";
            }
        }


报的异常为:
System.ArgumentException: 参数无效。
   在 System.Drawing.Graphics.GetHdc()
   在 SeLang.Form1.timer1_Tick(Object sender, EventArgs e) 位置 C:\Users\USER\Desktop\颜色捕捉器\颜色捕捉器\Form1.cs:行号 115

想不明白一个无参的方法怎么会说参数错误……


这个是主方法:


        //定义工儿区的尺寸
        Size workingArea;
        //窗体的初始位置和左下角及右下角的位置
        Point ptLeftBottom, ptRightBottom;
        //Point formLoc;
        public Form1()
        {
            InitializeComponent();

            FormBorderStyle = FormBorderStyle.FixedToolWindow;
            ShowInTaskbar = false;
            this.StartPosition = FormStartPosition.CenterScreen;

            //获取屏幕工作区域的大小
            Rectangle rect = SystemInformation.WorkingArea;
            workingArea = new Size(rect.Width, rect.Height);

            ptLeftBottom = new Point(0, workingArea.Height - this.Height);
            ptRightBottom = new Point(workingArea.Width - this.Width, workingArea.Height = this.Height);

            string tipmsg = "F8开始取色,按ESC停止取色";
            toolTip1.SetToolTip(this, tipmsg);
            toolTip1.SetToolTip(panelColorBox, tipmsg);
            toolTip1.SetToolTip(txtWeb, tipmsg);
            toolTip1.SetToolTip(lblRGB, tipmsg);
            toolTip1.SetToolTip(lblWeb, tipmsg);
        }


------解决思路----------------------
看到那n层的嵌套 我也是醉了 颜色拾取那么这么复杂

public partial class Form2 : Form
{
    public Form2() {
        InitializeComponent();
        Timer timer = new Timer();
        timer.Tick += timer_Tick;
        timer.Interval = 50;
        timer.Start();
    }

    private void timer_Tick(object sender, EventArgs e) {
        Color clr;
        using (Bitmap bmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height)) {
            using (Graphics g = Graphics.FromImage(bmp)) {
                g.CopyFromScreen(0, 0, 0, 0, bmp.Size);     //获取屏幕图像
            }
            this.Text = (clr = bmp.GetPixel(MousePosition.X, MousePosition.Y)).ToString(); //窗体的标题上显示 rgb
            using (Graphics g = this.CreateGraphics()) {
                g.DrawImage(bmp, 
                    new Rectangle(0, 0, 41, 41),            //绘制到窗体的区域
                    new Rectangle(MousePosition.X - 20, MousePosition.Y - 20, 41, 41), //需要绘制的原图
                    GraphicsUnit.Pixel);                    //注意 按理来说 这里的图像 应该放大绘制 这里省去了
                using (SolidBrush sb = new SolidBrush(clr)) {
                    g.FillRectangle(sb, 45, 0, 20, 20);     //用对应颜色绘制一个矩形框
                }
            }
        }
    }
}

根据这个代码 自己diy吧  不过这个确实很粗糙
详细一点的话 就看我曾经 写过的一个自定义控件上面的代码把 连接地址
一个图像裁剪控件 有颜色拾取部分
  相关解决方案