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

本文介绍了一个用C#和VB.NET编写的TaskbarNotifier组件,它能创建类似MSNMessenger风格的通知弹窗,支持自定义背景、字体、颜色等,并提供了详细使用教程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

这是我昨天(今天凌晨)说到的今天要介绍的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,ColortransparencyColor);
void SetBackgroundBitmap(Imageimage,ColortransparencyColor);
void SetCloseBitmap( string strFilename,ColortransparencyColor,Pointposition);
void SetCloseBitmap(Imageimage,ColortransparencyColor,Pointposition);

属性

string TitleText( get / set )
string ContentText( get / set )
TaskbarStatesTaskbarState(
get )
ColorNormalTitleColor(
get / set )
ColorHoverTitleColor(
get / set )
ColorNormalContentColor(
get / set )
ColorHoverContentColor(
get / set )
FontNormalTitleFont(
get / set )
FontHoverTitleFont(
get / set )
FontNormalContentFont(
get / set )
FontHoverContentFont(
get / set )
RectangleTitleRectangle(
get / set ) // mustbedefinedbeforecallingshow())
RectangleContentRectangle( get / set ) // mustbedefinedbeforecallingshow())
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 EventHandlerCloseClick
event EventHandlerTitleClick
event EventHandlerContentClick

[技术细节]
窗体的皮肤是通过给定图片和透明色来在一块区域中动态绘制实现的
protected RegionBitmapToRegion(Bitmapbitmap,ColortransparencyColor)
{
if(bitmap==null)
thrownewArgumentNullException("Bitmap","Bitmapcannotbenull!");

intheight=bitmap.Height;
intwidth=bitmap.Width;

GraphicsPathpath
=newGraphicsPath();

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

intx0=i;

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

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


Regionregion
=newRegion(path);
path.Dispose();
returnregion;
}

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

GraphicsoffScreenGraphics;
BitmapoffscreenBitmap;

offscreenBitmap
=newBitmap(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)来让窗体出现但不抢走当前窗口焦点的方法.


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值