none
dwmapi的使用(毛玻璃效果的使用) RRS feed

  • 问题

  • 最近看到MSDN上面的一个视频,讲了如何在Vista下面用C#做毛玻璃效果的窗口。可是,他的代码我看了却不是很明白。我把他的代码稍作添加,代码及运行结果如下:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    
    namespace MyGlassForm1
    {
        public partial class Form1 : Form
        {
            private GlassMoth.VistaApi.Margins marg;
            private GlassMoth.VistaApi.Margins marg1;
    
            private Rectangle topRect = Rectangle.Empty;
            private Rectangle topRect1 = Rectangle.Empty;
    
            public Form1()
            {
                InitializeComponent();
    
                if (!this.IsGlassEnabled())
                {
                    return;
                }
    
                marg.Top = 100;
                marg.Left = 0;
                marg.Right = 0;
                marg.Bottum = 0;
    
                marg1 = marg;
                marg1.Top = 20;
                
                GlassMoth.VistaApi.DwmExtendFrameIntoClientArea(this.button1.Handle, ref marg1);
    
                this.button1.Paint += new PaintEventHandler(button1_Paint);
    
    
                GlassMoth.VistaApi.DwmExtendFrameIntoClientArea(this.Handle,ref marg);
    
                this.Paint += new PaintEventHandler(Form1_Paint);
    
            }
    
            void button1_Paint(object sender, PaintEventArgs e)
            {
                SolidBrush blackBrush = new SolidBrush(Color.Black);
    
                Graphics g = e.Graphics;
    
                if (this.IsGlassEnabled())
                {
                    topRect = new Rectangle(0, 0, this.ClientSize.Width, marg1.Top);
                    //topRect1 = this.ClientRectangle;
    
                    g.FillRectangle(blackBrush, topRect);
                }
    
                g.DrawString("Hello,I am on the Glass?", this.Font, blackBrush, 0, 0);
    
                blackBrush.Dispose();
            }
            
            void Form1_Paint(object sender, PaintEventArgs e)
            {
                SolidBrush blackBrush = new SolidBrush(Color.Black);
                SolidBrush redBrush = new SolidBrush(Color.Red);
    
                Graphics g = e.Graphics;
    
                if (this.IsGlassEnabled())
                {
                    topRect = new Rectangle(0, 0, this.ClientSize.Width, marg.Top);
                    //topRect = this.ClientRectangle;
    
                    g.FillRectangle(blackBrush, topRect);
                }
    
                g.DrawString("Hello,I am on the Glass?", this.Font, redBrush, 0, 0);
    
                blackBrush.Dispose();
            }
    
            private bool IsGlassEnabled()
            {
                if (Environment.OSVersion.Version.Major < 6)
                {
                    MessageBox.Show("How abouttrying this on Vista?");
                    return false;
                }
    
                bool isGlassSupported = false;
                GlassMoth.VistaApi.DwmIsCompositionEnabled(ref isGlassSupported);
                return isGlassSupported;
            }
        }
    }
    


    这里便有几个问题:

    1、这也是我认为最大的问题:我一直都不明白为什么这个程序里面要对Form的PAIN事件重写代码,而且,又为什么他要把那个区域用blackBrush涂成黑色?这个和DWM里面的API的工作方式有关系吗?如果有,有事什么样的关系呢?
    因为我曾经看到一个类似的VB.NET的代码,他用DWM里面的那个API对窗口做了处理之后,也是把窗口其中 第一个区域刷成了某种颜色,并且把窗口的transparentkey也设置成了那个颜色,他解释说这样做是因为DWM里面的那个API只能把窗口中的透明的区域设为毛玻璃效果。真的是这样吗?
    请问有没有比较全面的相关的中文资料?

    2、就是为什么我按照他的方式对我自己添加的button1做了同样的处理,可是我的button出来确实这个样子?

    3、为什么我的button1上面的字是透明 的?可能大家没有主要到,但是仔细看我发现,button1 上面字其实不是黑色,是透明的!

    4、我曾经试过用黑色作为窗口上面的那句话的颜色,而且程序的原有的代码也是这样的,可是在视频中,他显示出来的效果确实黑色的字,而我如果给那句话弄成黑色的话,我就看不到那句话了!而且我跟踪的时候,发现这句代码还确实运行了,所以我才给他换成了红色。

    5、button1上面的那句话为什么又是透明的?这个也很奇怪,我明明设置了用blackBrush,可是出来的效果确实透明的,同样给BUTTON1用blackBrush,出来确实黑色的。



    我之所以这样做,是希望能把button1也做成毛玻璃的效果。本人才疏学浅,还望各位高手耐心指导,在下感激不尽!
    • 已移动 小鱼儿 2009年5月19日 9:13 ([Loc]From:Windows Vista 开发相关讨论)
    • 已移动 Sheng Jiang 蒋晟Moderator 2009年5月20日 13:45 Vista开发问题 ([Loc]From:Visual C#)
    2009年4月28日 13:11

答案

  • 前些日子也在研究AeroGlass,您所说的这个视频(Daniel Moth的讲解吧)我也看过。
    虽然现在还没有弄明白,但是我还是来说说我的看法吧,希望对您有帮助。

    在视频中,DanielMoth对Paint方法进行了注释:

    Alpha-blending Paint after the glass extension

    也就是在Form_Load进行玻璃区域的扩展之后,用Paint方法对毛玻璃区域进行相应的绘制处理。所谓AlphaBlend技术,其实就是按照"Alpha"混合向量的值来混合源像素和目标像素,一般用来处理半透明效果。
    如果不设置Paint事件,窗体会在下一次更新后失去半透明的效果

    以前我也是通过设置Transparentkey进行半透明的绘制的,但是后来发现(其实视频里也提到了),这种方法会使窗体变成“可穿透”的。也就是说点击窗体的一部分后会使鼠标“穿透”然后点到后面的东西。

    设置为BlackBrush的原因我也不是很清楚,这是 SolidBrush blackBrush = new SolidBrush(Color.Black) 这一句的注释:
    Painting All Black using GDI, zeros out the alpha channel
    need to draw a content into a bitmap offscreen.
    and then use alphablend to get it into the window

    应该是说,通过设置Black使得Alpha通道为0(透明了),然后把它作为刷子刷到相关区域上(Aero Glass只能应用到窗体透明部分)。

    至于Button,个人猜测应该是没有办法在Button上创建毛玻璃效果的。您的代码中将form_paint照搬到button1_paint应该是行不通的。

    就这些,希望对您有所帮助



    ~~~~~ 如果我的回复对您有所帮助,请您点击一下此回复右上角的“投票认定帖子内容有帮助” ~~~~~
    ~~~~~ 向着三颗奖牌出发!^______^ ~~~~~
    2009年5月21日 5:36

全部回复

  • 很遗憾,Windows Vista 开发相关讨论论坛已经被取消。你可以去英文的UI Development for Windows论坛碰碰运气
    MSMVP VC++
    2009年5月20日 13:45
    版主
  • 前些日子也在研究AeroGlass,您所说的这个视频(Daniel Moth的讲解吧)我也看过。
    虽然现在还没有弄明白,但是我还是来说说我的看法吧,希望对您有帮助。

    在视频中,DanielMoth对Paint方法进行了注释:

    Alpha-blending Paint after the glass extension

    也就是在Form_Load进行玻璃区域的扩展之后,用Paint方法对毛玻璃区域进行相应的绘制处理。所谓AlphaBlend技术,其实就是按照"Alpha"混合向量的值来混合源像素和目标像素,一般用来处理半透明效果。
    如果不设置Paint事件,窗体会在下一次更新后失去半透明的效果

    以前我也是通过设置Transparentkey进行半透明的绘制的,但是后来发现(其实视频里也提到了),这种方法会使窗体变成“可穿透”的。也就是说点击窗体的一部分后会使鼠标“穿透”然后点到后面的东西。

    设置为BlackBrush的原因我也不是很清楚,这是 SolidBrush blackBrush = new SolidBrush(Color.Black) 这一句的注释:
    Painting All Black using GDI, zeros out the alpha channel
    need to draw a content into a bitmap offscreen.
    and then use alphablend to get it into the window

    应该是说,通过设置Black使得Alpha通道为0(透明了),然后把它作为刷子刷到相关区域上(Aero Glass只能应用到窗体透明部分)。

    至于Button,个人猜测应该是没有办法在Button上创建毛玻璃效果的。您的代码中将form_paint照搬到button1_paint应该是行不通的。

    就这些,希望对您有所帮助



    ~~~~~ 如果我的回复对您有所帮助,请您点击一下此回复右上角的“投票认定帖子内容有帮助” ~~~~~
    ~~~~~ 向着三颗奖牌出发!^______^ ~~~~~
    2009年5月21日 5:36