首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 實作任務列通知視窗:仿 QQ/MSN 浮動彈窗完整教學

     編輯:關於C語言

效果與核心技術

  • 無邊框異形視窗:FormBorderStyle = None + 位圖透明色建立 Region。
  • 不搶焦點顯示:P/Invoke ShowWindow(hWnd, SW_SHOWNOACTIVATE=4)。
  • 平滑動畫:雙緩衝繪圖(OnPaintBackground 繪製到記憶體位圖再一次貼上)+ Timer 控制升起/停留/降落。
  • 拖曳移動:攔截標題列區域滑鼠按下,發送 WM_NCLBUTTONDOWN + HT_CAPTION 模擬標題列拖曳。
  • 換膚機制:外部傳入 Image 與透明色,動態重建 Region。

關鍵程式碼架構

public class TaskbarForm : Form
{
    // P/Invoke 宣告
    [DllImport("user32.dll")] static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
    [DllImport("user32.dll")] static extern bool ReleaseCapture();
    [DllImport("user32.dll")] static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

    const int WM_NCLBUTTONDOWN = 0xA1;
    const int HT_CAPTION = 0x2;
    const int SW_SHOWNOACTIVATE = 4;

    // 狀態與動畫參數
    int currentTop = 1, intervalValue = 5;
    Rectangle TitlebarRectangle, CloseBtnRectangle, ContentRectangle;
    Image BackgroundBitmap;

    // 公開介面:顯示通知
    public void ShowForm(string title, string content, Rectangle titleRect, Rectangle titlebarRect, Rectangle contentRect, Rectangle closeRect)
    {
        TitlebarRectangle = titlebarRect; CloseBtnRectangle = closeRect; ContentRectangle = contentRect;
        WorkAreaRectangle = Screen.GetWorkingArea(WorkAreaRectangle);
        this.Top = WorkAreaRectangle.Height + this.Height; // 起始位置:螢幕下方外
        FormBorderStyle = FormBorderStyle.None;
        ShowWindow(this.Handle, SW_SHOWNOACTIVATE);
        timer1.Enabled = true; // 開始升起動畫
    }

    // 雙緩衝繪圖
    protected override void OnPaintBackground(PaintEventArgs e)
    {
        var offscreen = new Bitmap(BackgroundBitmap.Width, BackgroundBitmap.Height);
        using (var g = Graphics.FromImage(offscreen))
        {
            g.DrawImage(BackgroundBitmap, 0, 0);
            DrawText(g); // 繪製標題與內容
        }
        e.Graphics.DrawImage(offscreen, 0, 0);
    }

    // 滑鼠處理:拖曳、關閉、連結點擊
    private void TaskbarForm_MouseDown(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            if (TitlebarRectangle.Contains(e.Location)) { ReleaseCapture(); SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0); }
            if (CloseBtnRectangle.Contains(e.Location)) { Hide(); currentTop = 1; }
            if (ContentRectangle.Contains(e.Location)) Process.Start("https://www.example.com");
        }
    }

    // 計時器驅動動畫:升起 → 停留 → 降落 → 隱藏
    private void timer1_Tick(object sender, EventArgs e) { /* 更新 this.Top, 切換狀態 */ }
}

建立不規則視窗 Region

public void SetBackgroundBitmap(Image image, Color transparencyColor)
{
    BackgroundBitmap = new Bitmap(image);
    Width = BackgroundBitmap.Width; Height = BackgroundBitmap.Height;
    Region = BitmapToRegion(BackgroundBitmap, transparencyColor);
}

public Region BitmapToRegion(Bitmap bmp, Color transparent)
{
    var path = new GraphicsPath();
    for (int y = 0; y < bmp.Height; y++)
    for (int x = 0; x < bmp.Width; x++)
    {
        if (bmp.GetPixel(x, y) == transparent) continue;
        int x0 = x;
        while (x < bmp.Width && bmp.GetPixel(x, y) != transparent) x++;
        path.AddRectangle(new Rectangle(x0, y, x - x0, 1));
    }
    return new Region(path);
}

部署注意事項

  • 圖片背景色需統一(如 #FF00FF),且不可出現在前景圖案中。
  • 動畫速度可透過 intervalValue 與 Timer.Interval 調整。
  • 若需多顯示器支援,請使用 Screen.FromControl(this) 取得正確工作區。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved