3

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

 1 year ago
source link: https://jiongks.name/blog/2009-09-26
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

浅浅浅谈将 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

Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK