form上面有个menustrip控件,保存图像时是保存整个窗体的图像,但是把整个menustrip也保存下来了,于是在保存时把menustrip设置为不可见,可保存后还是出现了控件的灰色条条,还有个问题就是点击菜单“保存图片”后也出现一块灰色区域,保存后那块灰色区域也保存了,有什么办法解决啊?

解决方案 »

  1.   

    MenuStrip也属于窗体的一部分,保存窗体图像自然也会把它一起保存。
    至于菜单区域的问题,可以在点击菜单之时启动一个定时器,稍微等待一会儿之后再启动保存方法。
      

  2.   


        FormBorderStyle FmBdr = new FormBorderStyle(); 
        FmBdr = this.FormBorderStyle; 
        this.FormBorderStyle = Windows.Forms.FormBorderStyle.None; 
        using (Bitmap BP = new Bitmap(this.Width, this.Height - MenuStrip1.Height)) { 
            using (Bitmap tmpBP = new Bitmap(this.Width, this.Height)) { 
                this.DrawToBitmap(tmpBP, new Rectangle(0, 0, this.Width, this.Height)); 
                using (Graphics G = Graphics.FromImage(BP)) { 
                    G.DrawImage(tmpBP, new Rectangle(0, 0, BP.Width, BP.Height), new Rectangle(0, MenuStrip1.Height, BP.Width, BP.Height - Height), GraphicsUnit.Pixel); 
                } 
                BP.Save("c:\\123.bmp");  //保存图像
            } 
        } 
        this.FormBorderStyle = FmBdr; 
      

  3.   

    光减去MenuStrip的高度够么?如果只保存客户区的话,直接就可以使用ClientRectangle。
    减去MenuStrip的高度,实际上标题栏没了,而MenuStrip可能还在。
      

  4.   

    顶。。[align=center]
    ****************************************************************
                看帖一定要回,分也一定要接哦 ^_^
    ****************************************************************[/align]
      

  5.   

    你可以把图像绘制在panel上。在panel里写Paint事件。
    然后保存panel里的图像,这样就不会把menu也给弄下来了。
      

  6.   

    还有就是去用老的菜单控件MainMenu,.net 1.0 里的控件。
    .net 2.0里默认的编程MenuStrip。
    不过MainMenu的属性里没有快捷键的设置,少了一些功能,
    但是他在窗体上保存图像的时候不会跟图像一起保存下来。
      

  7.   


    你没有仔细看代码,我是从MenuStrip1下面开始截图的,也就是图的左上角是左MenuStrip1下面.这样截出来的图当然没有MenuStrip1了.
      

  8.   

    看到了,看到你使用的是menuStrip1.Height而不是menuStrip1.Bottom。
    而MenuStrip的上方应该还有个标题栏的。
      

  9.   

    终于看到这个了,但是,这样会不会有闪烁呢?
    另外,为什么不干脆使用menuStrip1.Bottom或this.ClientRectangle?
      

  10.   


    不同的系统ClientRectangle是不同的,比如在XP下,它的X值不是0,而是经过了一条边框,然而在VISTA下,由于VISTA的玻璃特效,窗体本身的ClientRectangle的X值就是0,我是为了该代码能够兼容各种不同的操作系统,才想出这种方法.
      

  11.   

    对于VISTA或VISTA以上系统来说,窗体边框已经不属于程序窗体本身,而是交由系统绘制,实际上窗体已经被设置了"无边框"了,我们看到的边框,包括标题栏,是系统合成上去的.这就导致了在一边自绘系统,包括一些第三方主题工具如WindowBlinds等,在美化系统主题后,窗体的工作区已经变成了,因为边框已经被设置无了,即使你还能看到边框和标题栏,那是窗体合成的了.在这种情况下,"工作区"和"非工作区"的坐标已经没有意义了,所以可以直接考虑X就是0值.如上面代码所示.
    如果是XP系统,工作区和非工作区的坐标还是不同的,然而为了适应各种系统的兼容,我采用了无设置无边框然后截图,然后再恢复边框,或许会闪一下,但这使得截的图能很精确.
      

  12.   

    嗯嗯,的确专业...不过我还是好奇,为什么不使用menuStrip1.Bottom?
      

  13.   


    当一个控件的顶部是0时,bottom跟height有何区别?
      

  14.   

    哦上面少打了几个字.
    当一个控件的顶部是0时,form.height-bottom跟height有何区别?
    相反,还省一个计算过程.
      

  15.   

    用Bottom的话,还需要去掉边框么?
      

  16.   

    还是没仔细看代码哦.
    已经设置了窗体为无边框FormBorderStyle=None
    此时MenuStrip就是最顶部的,它的Top就是0.
    既然已经无边框了,就不需要再考虑边框不边框了.
      

  17.   

    我知道,我的意思,如果使用menuStrip.Bottom的话,根本就不需要这一步骤,不需要去掉边框的这一步骤。没有去掉边框的步骤,就不用担心闪烁不闪烁的问题了。
      

  18.   

    无论如何之前都要先"无边框",否则就会有兼容性问题,比如连边框也截进去了.你说的Bottom之前都已经无边框了,而且也必须要无边框,闪不闪,那不能成为问题了.
      

  19.   

       private void button3_Click(object sender, EventArgs e)
            {
                Bitmap _FormImage = new Bitmap(this.Width, this.Height);            this.DrawToBitmap(_FormImage, new Rectangle(0, 0, this.Width, this.Height));            Rectangle _Height = this.RectangleToScreen(menuStrip1.Bounds);
                int _Index = _Height.Y - this.Location.Y + menuStrip1.Height;            _FormImage.Clone(new Rectangle(0, _Index, this.Width, this.Height - _Index), PixelFormat.Format24bppRgb).Save(@"C:\1.bmp");            
            }这样看看.