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

C# 建立滑鼠點擊穿透的透明視窗

     編輯:關於C語言

核心原理

透過 Win32 API 設定視窗擴充樣式:

  • WS_EX_LAYERED (0x80000):啟用分層視窗,支援透明度
  • WS_EX_TRANSPARENT (0x20):啟用滑鼠穿透,點擊事件傳遞給下層視窗
  • SetLayeredWindowAttributes:設定透明度 (Alpha 值 0-255)

完整實作程式碼

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

public class ClickThroughForm : Form {
    // Win32 API 簽名
    private const int GWL_EXSTYLE = -20;
    private const int WS_EX_LAYERED = 0x80000;
    private const int WS_EX_TRANSPARENT = 0x20;
    private const int LWA_ALPHA = 0x2;

    [DllImport("user32.dll", SetLastError = true)]
    private static extern int GetWindowLong(IntPtr hWnd, int nIndex);

    [DllImport("user32.dll", SetLastError = true)]
    private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

    [DllImport("user32.dll", SetLastError = true)]
    private static extern bool SetLayeredWindowAttributes(IntPtr hWnd, int crKey, byte bAlpha, int dwFlags);

    public ClickThroughForm() {
        // 必須設為無邊框,否則標題列會擋住穿透效果
        this.FormBorderStyle = FormBorderStyle.None;
        this.BackColor = Color.Black; // 任意顏色,配合 Alpha 顯示
    }

    /// 
    /// 啟用滑鼠穿透與透明度
    /// 
    /// 0=完全透明, 255=不透明
    public void EnableClickThrough(byte alpha = 100) {
        // 1. 取得目前擴充樣式
        int exStyle = GetWindowLong(this.Handle, GWL_EXSTYLE);
        // 2. 加入 LAYERED + TRANSPARENT
        SetWindowLong(this.Handle, GWL_EXSTYLE, exStyle | WS_EX_LAYERED | WS_EX_TRANSPARENT);
        // 3. 設定透明度
        SetLayeredWindowAttributes(this.Handle, 0, alpha, LWA_ALPHA);
    }

    /// 
    /// 還原正常視窗 (取消穿透)
    /// 
    public void DisableClickThrough() {
        int exStyle = GetWindowLong(this.Handle, GWL_EXSTYLE);
        // 移除 LAYERED 與 TRANSPARENT 旗標
        SetWindowLong(this.Handle, GWL_EXSTYLE, exStyle & ~WS_EX_LAYERED & ~WS_EX_TRANSPARENT);
        this.FormBorderStyle = FormBorderStyle.Sizable; // 或原本的樣式
    }

    protected override void OnHandleDestroyed(EventArgs e) {
        DisableClickThrough(); // 確保資源釋放時還原
        base.OnHandleDestroyed(e);
    }
}

使用範例

// 程式進入點
static class Program {
    [STAThread]
    static void Main() {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        
        var form = new ClickThroughForm();
        form.Size = new Size(400, 300);
        form.StartPosition = FormStartPosition.CenterScreen;
        form.EnableClickThrough(128); // 半透明 + 穿透
        Application.Run(form);
    }
}

常見應用場景

  • 螢幕標記/輔助線工具:繪製十字準星、尺規,不干擾下層應用操作。
  • 桌面小工具:時鐘、CPU 監控覆蓋層,點擊穿透到桌面圖示。
  • 教學示範標註:螢幕繪圖批註,滑鼠仍可操作被標註視窗。

注意事項

問題解決
啟用穿透後無法關閉視窗需保留熱鍵 (如 Esc) 呼叫 DisableClickThrough() 或 Close()
WPF 視窗同樣原理,但需在 SourceInitialized 事件中取得 WindowInteropHelper.Handle
多顯示器 DPI 縮放設定 SetProcessDpiAwareness 或在 manifest 標註 DPI Aware
ClickOnce 部署需 FullTrust 權限才能呼叫 SetWindowLong
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved