浅浅浅谈将 Aero 特效应用到整个窗体

本文摘自 勾三股四 更早时期的 不老歌 博客。

传说中的 Aero 这个词,是指 Windows 窗体的一种半透明的显示效果。
在 Vista+ 的操作系统里,窗体是自动有 Aero 边框的,但有些程序不仅仅是边框才有 Aero 特效。比如 IE / Media Player 等等。(这两个例子都快被人举烂了……)

前阵子看到了 Firefox 4.0 的未来设计图,整个窗体都是 Aero 特效的,看过一直流口水。经过一些无聊的探索,我发现了将 Aero 特效从边框扩展到其它区域的实现方法。

以下是 C# 代码

在 C# 代码出现之前
好吧
表问我为什么 Ajax 程序员会写 C#
表问我为什么会写 C# 却去做低贱的 Ajax
表问我为什么决定了要做 Ajax,还回头去看 C# ……

internal class DwmApi
{
    [DllImport("dwmapi.dll", PreserveSig = false)]
    public static extern void DwmExtendFrameIntoClientArea(IntPtr hWnd, MARGINS pMargins);

    [DllImport("dwmapi.dll", PreserveSig = false)]
    public static extern bool DwmIsCompositionEnabled();

    [StructLayout(LayoutKind.Sequential)]
    public class MARGINS
    {
        public int cxLeftWidth, cxRightWidth, cyTopHeight, cyBottomHeight;

        public MARGINS(int left, int top, int right, int bottom)
        {
            cxLeftWidth = left; cyTopHeight = top;
            cxRightWidth = right; cyBottomHeight = bottom;
        }
    }
}
这段代码引入了:
1. 扩展窗体“实体”区域的方法
2. 判断当前操作系统是否开启了 Aero 显示方式的方法
3. 描述“实体”区域的数据格式

有了这些东西,代码就基本会写了吧^_^
private void Form1_Load(object sender, EventArgs e)
{
    if (DwmApi.DwmIsCompositionEnabled()) {
        DwmApi.DwmExtendFrameIntoClientArea(this.Handle, new DwmApi.MARGINS(-1, -1, -1, -1));
    }
}

private void OnPaint(object sender, PaintEventArgs e)
{
    if (DwmApi.DwmIsCompositionEnabled())
    {
        e.Graphics.FillRectangle(Brushes.Black, this.ClientRectangle);
    }
}

protected override void WndProc(ref Message m)
{
    base.WndProc(ref m);

    const int WM_DWMCOMPOSITIONCHANGED = 0x031E;

    switch (m.Msg)
    { 
        case WM_DWMCOMPOSITIONCHANGED:
            if (DwmApi.DwmIsCompositionEnabled())
            {
                DwmApi.DwmExtendFrameIntoClientArea(this.Handle, new DwmApi.MARGINS(-1, -1, -1, -1));
            }
            break;
    }
}
这三个函数分别做的是:
1. 窗体载入成功后将“实体”窗体区域扩展到“窗体外面”,这样窗体就仿佛全 Aero 了,实际是“实体”区域不可见罢了——当然这不影响我们往非“实体”区域放置控件或别的任何对象
2. 绘制窗体时,将“实体”区域涂黑(这样做的缘由还没完全研究明白,总之这个函数不可或缺,等我弄明白了会把理由补上)
3. 窗体监听到操作系统显示方式改变是,判断是否还支持 Aero 特效,如果是,则“实体”区域需要重新扩展

一点浅浅的认识
最后补一个链接:http://tech.ddvip.com/2008-11/122569523088390.html

向本文提出修改或勘误建议