TaskbarNotifier: 可换肤的 MSN Messenger-like 风格窗体( C# & VB.NET)

marginwidth="0" marginheight="0" src="http://218.16.120.35:65001/PC/Global/images/b.html" frameborder="0" width="728" scrolling="no" height="90">

这是我昨天(今天凌晨)说到的今天要介绍的TaskbarNotifier, a skinnable MSN Messenger-like popup in C# and now in VB.NET too By John O'Byrne. 可惜昨天晚上写好的那篇文章,因为过了24:00,日期只能记在今天名下了,没找到博客园里改文章时间的地方:|



[介绍]
笔者在学习C#时移植自己C++的CTaskbarNotifier类,实现了这个可换肤的 MSN Messenger-like 风格窗体, 在某种风格下看起来和MSN Messenger的弹出窗口很相像.

[特色]
支持:
1. 可定制的透明位图背景
2. 可换肤且有3种状态的关闭按钮
3. 可以点击的标题文本
4. 可以点击的内容文本
5. A selection rectangle
6. 可定制文本在不同状态(平常/鼠标悬停)下的字体,颜色
7. 有参数可控制动画移进移出的速度

[兼容性]
该类可独立运行,除.NET基础类库不需其他库.以托管代码编写,可移植性较好

[如何使用]

  • 首先,复制TaskbarNotifier.cs到你的项目目录下.
  • 在你的代码顶部加上: using CustomUIControls;
  • 在你的类中加上一个成员变量: TaskbarNotifier taskbarNotifier;
  • 在你的类构造函数中中加上:
    taskbarNotifier = new  TaskbarNotifier();
    taskbarNotifier.SetBackgroundBitmap(
    " skin.bmp " ,
                        Color.FromArgb(
    255 , 0 , 255 ));
    taskbarNotifier.SetCloseBitmap(
    " close.bmp " ,
            Color.FromArgb(
    255 , 0 , 255 ), new  Point( 127 , 8 ));
    taskbarNotifier.TitleRectangle
    = new  Rectangle( 40 , 9 , 70 , 25 );
    taskbarNotifier.ContentRectangle
    = new  Rectangle( 8 , 41 , 133 , 68 );
    taskbarNotifier.TitleClick
    += new  EventHandler(TitleClick);
    taskbarNotifier.ContentClick
    += new  EventHandler(ContentClick);
    taskbarNotifier.CloseClick
    += new  EventHandler(CloseClick);

(译者:比较直观简单,略去介绍)最后一行表示窗体的弹出耗时500ms, 显示持续3000ms,消失耗时500ms.

[手册文档]

方法

void  Show( string  strTitle,  string  strContent,  int  nTimeToShow,  int  nTimeToStay,  int  nTimeToHide);
void  Hide();
void  SetBackgroundBitmap( string  strFilename, Color transparencyColor);
void  SetBackgroundBitmap(Image image, Color transparencyColor);
void  SetCloseBitmap( string  strFilename, Color transparencyColor, Point position);
void  SetCloseBitmap(Image image, Color transparencyColor, Point position);

 属性

string  TitleText ( get / set )
string  ContentText ( get / set )
TaskbarStates TaskbarState (
get )
Color NormalTitleColor (
get / set )
Color HoverTitleColor (
get / set )
Color NormalContentColor (
get / set )
Color HoverContentColor (
get / set )
Font NormalTitleFont (
get / set )
Font HoverTitleFont (
get / set )
Font NormalContentFont (
get / set )
Font HoverContentFont (
get / set )
Rectangle TitleRectangle (
get / set // must be defined before calling show())
Rectangle ContentRectangle ( get / set // must be defined before calling show())
bool  TitleClickable ( get / set ) ( default   =   false );
bool  ContentClickable ( get / set ) ( default   =   true );
bool  CloseClickable ( get / set ) ( default   =   true );
bool  EnableSelectionRectangle ( get / set ) ( default   =   true );

 

事件

event  EventHandler CloseClick
event  EventHandler TitleClick
event  EventHandler ContentClick

[技术细节]
窗体的皮肤是通过给定图片和透明色来在一块区域中动态绘制实现的
protected  Region BitmapToRegion(Bitmap bitmap, Color transparencyColor)
{
    
if (bitmap == null)
        
throw new ArgumentNullException("Bitmap""Bitmap cannot be null!");

    
int height = bitmap.Height;
    
int width = bitmap.Width;

    GraphicsPath path 
= new GraphicsPath();

    
for (int j=0; j<height; j++ )
        
for (int i=0; i<width; i++)
        
{
            
if (bitmap.GetPixel(i, j) == transparencyColor)
                
continue;

            
int x0 = i;

            
while ((i < width) && 
                    (bitmap.GetPixel(i, j) 
!= transparencyColor))
                i
++;

            path.AddRectangle(
new Rectangle(x0, j, i-x0, 1));
        }


    Region region 
= new Region(path);
    path.Dispose();
    
return region;
}

窗体的Refresh()使用了双缓冲技术避免闪烁
protected   override   void  OnPaintBackground(PaintEventArgs pea)
{
    Graphics grfx 
= pea.Graphics;
    grfx.PageUnit 
= GraphicsUnit.Pixel;

    Graphics offScreenGraphics;
    Bitmap offscreenBitmap;

    offscreenBitmap 
= new Bitmap(BackgroundBitmap.Width, 
                                BackgroundBitmap.Height);
    offScreenGraphics 
= Graphics.FromImage(offscreenBitmap);

    
if (BackgroundBitmap != null)
    
{
        offScreenGraphics.DrawImage(BackgroundBitmap, 
            
00, BackgroundBitmap.Width, BackgroundBitmap.Height);
    }


    DrawCloseButton(offScreenGraphics);
    DrawText(offScreenGraphics);

    grfx.DrawImage(offscreenBitmap, 
00);
}

[Bug/限制]

为了只使用托管代码, 用了 Screen.GetWorkingArea(WorkAreaRectangle) 函数来取得任务栏位置,结果窗体总出现在WorkAreaRectangle的底部.

在C#托管代码中没找到 ShowWindow(SW_SHOWNOACTIVATE)来让窗体出现但不抢走当前窗口焦点的方法.

 
id="alimamaifrm" style="WIDTH: 760px; HEIGHT: 90px" border="0" name="alimamaifrm" marginwidth="0" marginheight="0" src="http://p.alimama.com/code.php?t=2&i=mm_10071892_160082_182479&w=760&h=90&sz=11&bgc=FFFFFF&bdc=E6E6E6&tc=0000FF&lc=008000&dc=000000" frameborder="0" width="760" scrolling="no" height="90">
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值