浅浅浅谈将 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; } } }这段代码引入了:
- 扩展窗体“实体”区域的方法
- 判断当前操作系统是否开启了 Aero 显示方式的方法
- 描述“实体”区域的数据格式
有了这些东西,代码就基本会写了吧^_^
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; } }这三个函数分别做的是:
- 窗体载入成功后将“实体”窗体区域扩展到“窗体外面”,这样窗体就仿佛全 Aero 了,实际是“实体”区域不可见罢了——当然这不影响我们往非“实体”区域放置控件或别的任何对象
- 绘制窗体时,将“实体”区域涂黑(这样做的缘由还没完全研究明白,总之这个函数不可或缺,等我弄明白了会把理由补上)
- 窗体监听到操作系统显示方式改变是,判断是否还支持 Aero 特效,如果是,则“实体”区域需要重新扩展
一点浅浅的认识
最后补一个链接:http://tech.ddvip.com/2008-11/122569523088390.html