貌似Windows Vista昨天正式发布了,也是该写写东西的时候啦,其实这篇文章我很早就写了的,不过是用E文写的,发表在codeproject上:
http://www.codeproject.com/useritems/textonglass.asp
当时用的是Windows Vista Beta2 做的测试,演示有些地方已经和现在正式版(或者RC1)的系统不一样,不过功能还是照样能实现的。
现在我们就直入正题吧。Windows Vista给我们带来了磨砂玻璃的半透明窗体边框,其实这个效果是可以扩展到整个窗口区域的,让整个窗体成为一个“玻璃片”,效果就像在Vista下按alt+Tab键后看到的切换窗口一样。要达到这个效果,我们得借助于Vista提供的一组新API :DWM(Desktop Windows Manager) API。主要用到以下几个函数:DwmIsCompositionEnabled 和 DwmExtendFrameIntoClientArea.
当然,调用API的话,P/Invoke代码不可避免,这是这两个API的C#引用声明:
[System.Runtime.InteropServices.DllImport("dwmapi.dll")]
public extern static int DwmIsCompositionEnabled(ref int en ) ; //该函数用于判断Aero合成效果是否打开,否则无法看到磨砂效果
[System.Runtime.InteropServices.DllImport("dwmapi.dll")]
public extern static int DwmExtendFrameIntoClientArea(IntPtr hwnd, ref MARGINS margin ) ; //该函数用于扩展玻璃区域
要注意DwmExtendFrameIntoClientArea函数最后一个参数为MARGINS 结构体,用于确定要扩展的玻璃区域距离窗体上下左右边框的距离大小,它的定义为:
public struct MARGINS
...{
public int m_left;
public int m_right;
public int m_top;
public int m_buttom
};
如果你要把整个窗口都变成玻璃,只需把MARGINS所有成员设为-1。下面是一段示例代码:
int en=0;
MARGINS mg=new MARGINS();
mg.m_Buttom = -1;
mg.m_Left = -1;
mg.m_Right = -1;
mg.m_Top = -1 ;
//确保你使用的是Vista
if (System.Environment.OSVersion.Version.Major >= 6)
...{
DwmIsCompositionEnabled(ref en); //检测Aero合成已经被打开
if(en>0)
...{
DwmExtendFrameIntoClientArea(this.Handle, ref mg);
}else...{
MessageBox.Show("Desktop Composition is Disabled!");
}
}else...{
MessageBox.Show("Please run this on Windows Vista.");
}
如果你这时按下F5,会发现看不到任何特殊的效果:窗体还是和原来一样。那是因为系统在本来应该是玻璃的区域自动用默认背景色填充了,以致于看不到效果。这个时候,我们必须在Paint事件上做写些脚,把整个窗体用纯黑填充(RGB(0,0,0)刚好和ARGB的100%透明有着一样的bit pattern ),本来还有一个办法能看到效果,就是设置透明颜色让背景透明,但是这个方法已经在RC1的Vista之后不可用,就不做介绍了。
void Form1_Paint(object sender, PaintEventArgs e)
...{
//throw new Exception("The method or operation is not implemented.");
SolidBrush bsh;
bsh = new SolidBrush(Color.FromArgb(Convert.ToInt32(bgAlpha.Text ),Color.Black ));
Graphics g = e.Graphics;
g.FillRectangle(bsh, this.pictureBox2.ClientRectangle ); //pictureBox2铺满整个窗体
bsh.Dispose();
}
这样就可以看到效果:
实现了玻璃效果后你很快会发现问题:图片框和Label不能正确的显示文字,文本框文字的黑色部分也会变成玻璃效果:
用Graphics的DrawString也无法在玻璃上面画出正常的文本。为了能正确的画出文本,我们不能直接使用Graphic对象,而必须先把要画的字“写”在一个Path对象上面,最后再把Path用Graphics.FillPath填充到窗体上:
Graphics g = this.CreateGraphics();
GraphicsPath blackfont = new GraphicsPath();
SolidBrush brsh = new SolidBrush(Color.White);
blackfont.AddString("Hello Vista", new FontFamily("Tahoma",
(int)FontStyle.Regular, 26, new Point(0, 0), StringFormat.GenericDefault);
//SmoothingMode 是必须的, 否则会看到文本的锯齿边缘
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality ;
g.FillPath(brsh, blackfont); //用白色填充文本
效果:
当然,如果你只是画图片到玻璃区域,Graphics的DrawImage就足够了:
当然,这种画文本的方法并不是Windows的“标准方法”,至于如何利用API在玻璃区域上画出像标题文字一样的带白色渐变效果的文本,我会在后面的文章里介绍,这里先给大家看看效果图:
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。