http://topic.csdn.net/u/20110110/10/b913cdf5-6d17-4284-b337-3bd4d2262b08.html上面是原帖,我的问题就出自于这个帖子。我在第三页提了个问题,不过帖主并没有回答。东西确实做的不错,我挺喜欢这个效果。特拿出来就某些部分的实现与君探讨。先来看看该帖子中的几张图:我的问题是这样的,大家应该注意到了,很明显帖主使用了 DWM(Desktop Window Manager),外加 DevExpress 第三方控件,本人也是使用 DevExpress 的,该第三方控件本身并没有对窗体的磨砂效果进行任何扩展。也就是说,在前两张图中,窗体内边框的不规则形状是自己实现的。应该是使用到了 DWM,但是在网上查了资料,DWM 能扩展客户区,将边框磨砂玻璃效果的范围延伸至 ClientRectangle 内部,但是当我使用了 DwmEnableBlurBehindWindow,设定填充磨砂的区域后,虽然能模仿出顶部左半边效果 和 底部右半边效果,但是另半边却始终是白色,而且没有清晰的内测框的描边。对于 DWM 不规则矩形边框的扩展,网上也没能找到。各位,这个如何实现呀?有知道的吗?大家一起探讨一下吧。

解决方案 »

  1.   

    完全取消ClientRectangle 然后界面自己重绘?...
      

  2.   

    看看这个吧!
    改改应该能实现上面的效果
    http://www.codeproject.com/KB/vista/textonglass.aspx
      

  3.   


    http://i54.tinypic.com/2qbc1op.png
    http://i56.tinypic.com/r74q4j.png
    http://i56.tinypic.com/2zy93cx.jpg你看看,能不能看到。
    取消 ClientRectangle 应该是不太会,如果取消 ClientRectangle,控件放哪里?DWM 可以将磨砂玻璃效果的这只“手”伸向标准客户区,所以也就可以在标准客户区绘制磨砂玻璃效果。但是问题是我不清楚那个不规则的 Polygon 是怎么做的。
    呵呵,真的不是图做成的。我的第一反应就告诉我不是图做成的,而且在原帖的第 100 楼,帖主说的那句话已经表明了不是图做成的。
      

  4.   

    Graphics.DrawPolygon 绘制多边形,自己算坐标,不过我不知道这个"DWM 可以将磨砂玻璃效果的这只“手”伸向标准客户区"是怎么做的
      

  5.   

    是winform做的吗?  见识了
      

  6.   

    说不太清楚,不是光定义一个Polygon就没事了的。下面是我做的测试程序的图,你可以看看,和下面的效果还是有差别的。其中,白色不是自己填充的,是扩展了客户区之后,以为没有用黑色填充而呈现为白色。这个颜色我改不过来,而且 Polygon 区域周边没有清晰的边框。你可以看看这位仁兄,貌似你很焦虑,图,不是我发的,另外给你的三张图的地址也是从那个论坛中帖主给的,在那个帖子中,也有人说看不到图片,但是我这里可以正常显示,别人也看到了,或许是你浏览器的问题。如果实在看不到,你可以留个 email,我可以 save 一下,然后发给你。
      

  7.   

    谢谢,这个我看了,但是并未涉及到不规则多边形边框。在那个程序中,仅用到了 DwmExtendFrameIntoClientArea,单靠这个还是不够的,该方法只能进行矩形区域的扩展。:)
      

  8.   

    WPF可以比较容易的实现这个。
      

  9.   

    怎么都上来就这么一句话,有代码可以 Share 一下吗?参看一下。
      

  10.   

    WPF确实容易实现,不过这个是调用win7的界面控件来实现的
      

  11.   

    不难实现,只是整个窗体开启AERO效果,就不能使用双缓冲绘图了,那样的话,自绘窗体就会闪烁。
      

  12.   

    代码,需要添加引用DWM.NET,网上可以下载。
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using DWM;
    using System.Drawing.Drawing2D;namespace Win7AeroFormTest
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
                base.ResizeRedraw = true;
            }        protected override void OnLoad(EventArgs e)
            {
                base.OnLoad(e);
                EnableAero();
            }        private void EnableAero()
            {
                if (DWMManager.IsCompositionSupported &&
                    DWMManager.IsCompositionEnabled)
                {
                    DWMManager.EnableGlassFrame(base.Handle, new Margins(-1));
                }
            }        protected override void OnPaint(PaintEventArgs e)
            {
                if (DWMManager.IsCompositionSupported &&
                   DWMManager.IsCompositionEnabled)
                {
                    e.Graphics.FillRectangle(Brushes.Black, base.ClientRectangle);
                }
                else
                {
                    base.OnPaint(e);
                }            //Draw(e.Graphics);            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
                using (GraphicsPath path = new GraphicsPath())
                {
                    path.AddPolygon(new Point[] {
                        new Point(10,40),
                        new Point(150,40),
                        new Point(190,10),
                        new Point(base.ClientSize.Width - 10,10),
                        new Point(base.ClientSize.Width - 10,base.ClientSize.Height - 40),
                        new Point(base.ClientSize.Width / 2 + 20,base.ClientSize.Height - 40),
                        new Point(base.ClientSize.Width / 2 - 20,base.ClientSize.Height - 10),
                        new Point(10,base.ClientSize.Height - 10),
                    });                using (Brush brush = new SolidBrush(Color.FromArgb(128, 255, 255, 255)))
                    {
                        e.Graphics.FillPath(brush, path);
                    }                using (Pen pen = new Pen(Color.FromArgb(128, 0, 0, 0)))
                    {
                        e.Graphics.DrawPath(pen, path);
                    }                path.Reset();                path.AddPolygon(new Point[] {
                        new Point(9,39),
                        new Point(149,39),
                        new Point(189,9),
                        new Point(base.ClientSize.Width - 9,9),
                        new Point(base.ClientSize.Width - 9,base.ClientSize.Height - 39),
                        new Point(base.ClientSize.Width / 2 + 20,base.ClientSize.Height - 39),
                        new Point(base.ClientSize.Width / 2 - 20,base.ClientSize.Height - 9),
                        new Point(9,base.ClientSize.Height - 9),
                    });                using (Pen pen = new Pen(Color.FromArgb(160, 255, 255, 255)))
                    {
                        e.Graphics.DrawPath(pen, path);
                    }
                }
            }        private void Draw(Graphics graphics)
            {
                using (Bitmap bmp = new Bitmap(base.ClientSize.Width, base.ClientSize.Height))
                {
                    using (Graphics g = Graphics.FromImage(bmp))
                    {
                        g.FillRectangle(Brushes.Transparent, base.ClientRectangle);
                        g.SmoothingMode = SmoothingMode.AntiAlias;
                        using (GraphicsPath path = new GraphicsPath())
                        {
                            path.AddPolygon(new Point[] {
                                new Point(10,40),
                                new Point(150,40),
                                new Point(190,10),
                                new Point(base.ClientSize.Width - 10,10),
                                new Point(base.ClientSize.Width - 10,base.ClientSize.Height - 40),
                                new Point(base.ClientSize.Width / 2 + 20,base.ClientSize.Height - 40),
                                new Point(base.ClientSize.Width / 2 - 20,base.ClientSize.Height - 10),
                                new Point(10,base.ClientSize.Height - 10),
                            });                        using (Brush brush = new SolidBrush(Color.FromArgb(128, 255, 255, 255)))
                            {
                                g.FillPath(brush, path);
                            }                        using (Pen pen = new Pen(Color.FromArgb(128, 0, 0, 0)))
                            {
                                g.DrawPath(pen, path);
                            }                        path.Reset();                        path.AddPolygon(new Point[] {
                                new Point(9,39),
                                new Point(149,39),
                                new Point(189,9),
                                new Point(base.ClientSize.Width - 9,9),
                                new Point(base.ClientSize.Width - 9,base.ClientSize.Height - 39),
                                new Point(base.ClientSize.Width / 2 + 20,base.ClientSize.Height - 39),
                                new Point(base.ClientSize.Width / 2 - 20,base.ClientSize.Height - 9),
                                new Point(9,base.ClientSize.Height - 9),
                            });                        using (Pen pen = new Pen(Color.FromArgb(160, 255, 255, 255)))
                            {
                                g.DrawPath(pen, path);
                            }
                        }                    graphics.DrawImage(bmp, 0, 0);
                    }
                }
            }
        }
    }
      

  13.   

    实际上所谓的不规则还是规则的使整个区域都透明化,中间的不规则区域只是绘制上去的不规则图形,仍然是矩形规格的.视觉效果而已.不过这种效果很吃内存也耗CPU,不建议华丽效果用在操作量大的界面上.
      

  14.   


    我手头没有代码,我也从来不存这种代码,因为你去google一下: transparent window WPF,就可以得到一堆的例子。
      

  15.   


    starts_2000,我刚刚试了你的代码,程序运行报错:整个 Form 的 ClientRectangle 变成一个白底红叉。我的做法是如下的:1. 按照你的指示,我到 http://dwmnet.codeplex.com/ 上去下载了 DWM.dll。并添加程序集引用。
    2. 程序代码如下:public FrmPolygon2()
    {
    InitializeComponent(); base.ResizeRedraw = true;
    }protected override void OnLoad(EventArgs e)
    {
    base.OnLoad(e);
    EnableAero();
    }private void EnableAero()
    {
    if (DWMManager.IsCompositionSupported && DWMManager.IsCompositionEnabled)
    {
    DWMManager.EnableGlassFrame(base.Handle, new Margins(-1));
    }
    }
    protected override void OnPaint(PaintEventArgs e)
    {
    if (DWMManager.IsCompositionSupported && DWMManager.IsCompositionEnabled)
    {
    e.Graphics.FillRectangle(Brushes.Black, base.ClientRectangle);
    }
    else
    {
    base.OnPaint(e);
    } e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
    using (GraphicsPath path = new GraphicsPath())
    {
    path.AddPolygon(new Point[] {
                new Point(10, 40),
                new Point(150, 40),
                new Point(190, 10),
                new Point(base.ClientSize.Width - 10, 10),
                new Point(base.ClientSize.Width - 10, base.ClientSize.Height - 40),
                new Point(base.ClientSize.Width / 2 + 20, base.ClientSize.Height - 40),
                new Point(base.ClientSize.Width / 2 - 20, base.ClientSize.Height - 10),
                new Point(10, base.ClientSize.Height - 10),
            }); using (Brush brush = new SolidBrush(Color.FromArgb(128, 255, 255, 255)))
    {
    e.Graphics.FillPath(brush, path);
    } using (Pen pen = new Pen(Color.FromArgb(128, 0, 0, 0)))
    {
    e.Graphics.DrawPath(pen, path);
    } path.Reset(); path.AddPolygon(new Point[] {
                new Point(9,39),
                new Point(149,39),
                new Point(189,9),
                new Point(base.ClientSize.Width - 9,9),
                new Point(base.ClientSize.Width - 9,base.ClientSize.Height - 39),
                new Point(base.ClientSize.Width / 2 + 20,base.ClientSize.Height - 39),
                new Point(base.ClientSize.Width / 2 - 20,base.ClientSize.Height - 9),
                new Point(9,base.ClientSize.Height - 9),
            }); using (Pen pen = new Pen(Color.FromArgb(160, 255, 255, 255)))
    {
    e.Graphics.DrawPath(pen, path);
    }
    }
    }
    出了 Form 名称不同,其它均相同,但是运行程序就出现红叉。
    我在 "EnableAero();" 这里设了断点,F11 进不去,然后界面就挂了。
    我的项目使用的是 .net framework 2.0 的。改成 3.5 的以后也是那样。运行的图片:
    请问这是什么问题?我断点都跟不了,查不到。
      

  16.   

    starts_2000,我将 OnPaint 事件里面开头的如下代码做修改,可以正常运行,但是效果和你的完全不一样。请问可否把你的 Demo 给我看看?谢谢。Email: [email protected]