這是我昨天(今天淩晨)說到的今天要介紹的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基礎類庫不需其他庫.以Managed 程式碼編寫,可移植性較好
[如何使用]
- 首先,複製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/限制]
為了只使用Managed 程式碼, 用了 Screen.GetWorkingArea(WorkAreaRectangle) 函數來取得工作列位置,結果表單總出現在WorkAreaRectangle的底部.
在C#Managed 程式碼中沒找到 ShowWindow(SW_SHOWNOACTIVATE)來讓表單出現但不搶走當前視窗焦點的方法.