欢迎光临
我们一直在努力

利用.net(C#)在Vista磨砂玻璃窗口上正确画出文字和图片(GDI+版)-.NET教程,.NET Framework

建站超值云服务器,限时71元/月

貌似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 vistanew fontfamily(tahoma,
(
int)fontstyle.regular, 26new point(00), stringformat.genericdefault);

//smoothingmode 是必须的, 否则会看到文本的锯齿边缘

g.smoothingmode 
= system.drawing.drawing2d.smoothingmode.highquality  ;   
g.fillpath(brsh, blackfont);    
//用白色填充文本

效果:

当然,如果你只是画图片到玻璃区域,graphics的drawimage就足够了:

当然,这种画文本的方法并不是windows的“标准方法”,至于如何利用api在玻璃区域上画出像标题文字一样的带白色渐变效果的文本,我会在后面的文章里介绍,这里先给大家看看效果图:

赞(0)
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 » 利用.net(C#)在Vista磨砂玻璃窗口上正确画出文字和图片(GDI+版)-.NET教程,.NET Framework
分享到: 更多 (0)