[CodeProject每日一荐] TaskbarNotifier: 可换肤的 MSN Messenger-like 风格窗体( C# & VB.NET)

这是我昨天(今天凌晨)说到的今天要介绍的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,
           
0, 0, BackgroundBitmap.Width, BackgroundBitmap.Height);
    }


    DrawCloseButton(offScreenGraphics);
    DrawText(offScreenGraphics);

    grfx.DrawImage(offscreenBitmap,
0, 0);
}

[Bug/限制]

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

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

 

 

http://www.codeproject.com/Articles/3285/TaskbarNotifier-a-skinnable-MSN-Messenger-like-pop

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值