TaskbarNotifier,一个可自定义皮肤的类似 MSN Messenger 的弹出窗口,支持 C# 和 VB.NET






4.94/5 (402投票s)
2002年12月2日
4分钟阅读

2890207

68483
TaskbarNotifier 类允许显示一个类似 MSN Messenger 的带自定义皮肤背景的动画弹出窗口
引言
由于我正在学习 C#,我认为将我之前用 C++ 编写的 CTaskbarNotifier
类移植过来会很有帮助(https://codeproject.org.cn/dialog/TaskbarNotifier.asp[^])。
因此,我编写了一个类似 MSN Messenger 的可自定义皮肤的弹出窗口,带有一个关闭按钮,外观几乎与微软的类似(带有相应的皮肤)。
TaskbarNotifier
类继承自 System.Windows.Forms.Form
并为其添加了一些方法。
特点
类似 MSN Messenger 的弹出窗口支持:
- 自定义透明位图背景
- 可自定义皮肤的 3 状态关闭按钮
- 可点击的标题文本
- 可点击的内容文本
- 选择框
- 文本不同状态(正常/悬停)下的自定义字体和颜色
- 动画速度参数
兼容性
此类是独立的,除了 .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);
详细说明
taskbarNotifier.SetBackgroundBitmap("skin.bmp",
Color.FromArgb(255,0,255));
taskbarNotifier.SetCloseBitmap("close.bmp",
Color.FromArgb(255,0,255),new Point(127,8));
第一行设置背景位图皮肤和透明色(必须存在),第二行设置 3 状态关闭按钮及其透明色和在窗口上的位置(如果您不需要关闭按钮,此行是可选的)。
taskbarNotifier.TitleRectangle=new Rectangle(40,9,70,25);
taskbarNotifier.ContentRectangle=new Rectangle(8,41,133,68);
这两行允许我们定义标题和内容文本将显示的矩形区域。
taskbarNotifier.TitleClick+=new EventHandler(OnTitleClick);
taskbarNotifier.ContentClick+=new EventHandler(OnContentClick);
taskbarNotifier.CloseClick+=new EventHandler(OnCloseClick);
这三行允许我们捕获弹出窗口上的事件,例如标题/内容或关闭按钮被点击
- 然后我们就完成了,只需要调用
taskbarNotifier.Show("TitleText","ContentText",500,3000,500);
这将以 500 毫秒/3000 毫秒/500 毫秒的显示/可见/隐藏动画时间显示弹出窗口动画。
您可以调整一些属性
- 标题、内容字体和颜色
- 标题/内容/关闭按钮的可点击性
- 您可以禁用焦点矩形
- ...(更多细节请参见下文)
类文档
方法
void Show(string strTitle, string strContent, int nTimeToShow,
int nTimeToStay, int nTimeToHide)
显示弹出窗口一段时间。
参数
strTitle
:将显示为弹出窗口标题的string
strContent
:将显示为弹出窗口内容的string
nTimeToShow
:显示动画的持续时间(以毫秒为单位)nTimeToStay
:可见状态的持续时间(在折叠之前)(以毫秒为单位)nTimeToHide
:隐藏动画的持续时间(以毫秒为单位)
void Hide()
强制弹出窗口隐藏。
void SetBackgroundBitmap(string strFilename, Color transparencyColor)
设置背景位图及其透明色。
参数
strFilename
:磁盘上背景位图的路径transparencyColor
:位图中不可见的颜色
void SetBackgroundBitmap(Image image, Color transparencyColor)
设置背景位图及其透明色。
参数
image
:背景位图transparencyColor
:位图中不可见的Color
void SetCloseBitmap(string strFilename,
Color transparencyColor, Point position)
设置 3 状态关闭按钮位图、其透明色和坐标。
参数
strFilename
:磁盘上 3 状态关闭按钮位图的路径(宽度必须是 3 的倍数)transparencyColor
:位图中不可见的颜色position
:关闭按钮在弹出窗口上的位置
void SetCloseBitmap(Image image, Color transparencyColor, Point position)
设置 3 状态关闭按钮位图、其透明色和坐标。
参数
image
:表示 3 状态关闭按钮位图的Image
/Bitmap
对象(宽度必须是 3 的倍数)transparencyColor
:位图中不可见的Color
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# 托管等效的 Win32 函数 ShowWindow(SW_SHOWNOACTIVATE)
来使弹出窗口不抢占活动窗口的焦点。
更新
- 2003 年 4 月 1 日:
OnMouseUp
处理程序中的一个小 bug 修复 - 2003 年 1 月 11 日:Patrick Vanden Driessche 更新了 C# 和 VB.NET 版本
- 当鼠标仍在上方时,弹出窗口现在不会自动关闭
- 当弹出窗口正在消失且鼠标移到它上面时,它会重新显示
- 其他一些 bug 已得到纠正
- 2003 年 1 月 10 日:Patrick Vanden Driessche 将
TaskbarNotifier
移植到了 VB.NET - 2002 年 12 月 5 日:现在使用 Win32 函数
ShowWindow(SW_SHOWNOACTIVATE)
显示弹出窗口,以防止弹出窗口抢占焦点。
结论
希望这段代码对您有所帮助。如果您有关于增强此类功能的建议,请发表评论。
许可证
本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。
作者可能使用的许可证列表可以在此处找到。