C# WinForm實現(xiàn)鼠標穿透的操作代碼
在winform項目開發(fā)時,會遇到這樣一個場景,需要鼠標穿透操作,此功能主要用到windows系統(tǒng)的API函數(shù)。
知識點
SetWindowLong
更改指定窗口的屬性
注意:
此函數(shù)已被 setWindowLongPtr 函數(shù) 取代。 若要編寫與 32 位和 64 位版本的 Windows 兼容的代碼,請使用 SetWindowLongPtr 函數(shù)。
語法:
LONG SetWindowLong( HWND hWnd, LONG nIndex, LONG dwNewLong );
參數(shù)
- HWND hWnd:要修改的窗口句柄。
- LONG nIndex:指定要設置的窗口屬性的索引。
- LONG dwNewLong:新設置的值。
返回:該函數(shù)返回修改前的值。
nIndex:

函數(shù)調用
#region 在窗口結構中為指定的窗口設置信息
/// <summary>
/// 在窗口結構中為指定的窗口設置信息
/// </summary>
/// <param name="hwnd">欲為其取得信息的窗口的句柄</param>
/// <param name="nIndex">欲取回的信息</param>
/// <param name="dwNewLong">由nIndex指定的窗口信息的新值</param>
/// <returns></returns>
[DllImport("user32", EntryPoint = "SetWindowLong")]
private static extern uint SetWindowLong(IntPtr hwnd, int nIndex, uint dwNewLong);
#endregion
GetWindowLong
檢索有關指定窗口的信息。 該函數(shù)還將檢索 32 位(DWORD) 值,該值在指定的偏移量處進入額外的窗口內存。
注意:此函數(shù)已被 GetWindowLongPtr 函數(shù) 取代。 若要編寫與 32 位和 64 位版本的 Windows 兼容的代碼,請使用 GetWindowLongPtr 函數(shù)。 2025-11-18
語法結構
LONG GetWindowLongA( [in] HWND hWnd, [in] int nIndex );
參數(shù)
- HWND 窗口的句柄,間接地是窗口所屬的類。
- nIndex 類型:int

函數(shù)調用
#region 從指定窗口的結構中取得信息
/// <summary>
/// 從指定窗口的結構中取得信息
/// </summary>
/// <param name="hwnd">欲為其獲取信息的窗口的句柄</param>
/// <param name="nIndex">欲取回的信息</param>
/// <returns></returns>
[DllImport("user32", EntryPoint = "GetWindowLong")]
private static extern uint GetWindowLong(IntPtr hwnd, int nIndex);
sender
作為事件對象,用于管理多個控件。
應用場景1:在多個控件共享同一個事件處理方法時,區(qū)分出是哪個控件觸發(fā)了事件
private void btnObj1_Click(object sender, RoutedEventArgs e)
{
Button btn = (Button)sender;
if (btn == btnObj1)
{
MessageBox.Show("Btn1 被點擊了");
}
else
{
MessageBox.Show("Btn2 被點擊了");
}
}
本項目使用場景為獲取所選菜單名,執(zhí)行不同的操作
字符串操作
IndexOf
字符串中查找指定字符或字符串的第一個匹配項的索引。如果未找到字符或字符串,則返回-1
string value = "fox"; string sample = "The quick brown fox jumps over the lazy dog."; int index = sample.IndexOf(value, StringComparison.CurrentCultureIgnoreCase); Console.WriteLine(index); // 輸出:16
Substring
從字符串中檢索子字符串,包含兩種重載方法
1、從指定位置開始截取到字符串末尾
string example = "Hello, world!"; string sub = example.Substring(7); // 結果: "world!"
2、從指定位置開始截取特定長度的字符串
string example = "Hello, world!"; string sub = example.Substring(0, 5); // 結果: "Hello"
代碼展示
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace MouseThroughForm
{
public partial class Frm_Main : Form
{
public Frm_Main()
{
InitializeComponent();
}
private const uint WS_EX_LAYERED = 0x80000;
private const int WS_EX_TRANSPARENT = 0x20;
private const int GWL_EXSTYLE = (-20);
private string Var_genre = "";//記錄當前操作的類型
#region 在窗口結構中為指定的窗口設置信息
/// <summary>
/// 在窗口結構中為指定的窗口設置信息
/// </summary>
/// <param name="hwnd">欲為其取得信息的窗口的句柄</param>
/// <param name="nIndex">欲取回的信息</param>
/// <param name="dwNewLong">由nIndex指定的窗口信息的新值</param>
/// <returns></returns>
[DllImport("user32", EntryPoint = "SetWindowLong")]
private static extern uint SetWindowLong(IntPtr hwnd, int nIndex, uint dwNewLong);
#endregion
#region 從指定窗口的結構中取得信息
/// <summary>
/// 從指定窗口的結構中取得信息
/// </summary>
/// <param name="hwnd">欲為其獲取信息的窗口的句柄</param>
/// <param name="nIndex">欲取回的信息</param>
/// <returns></returns>
[DllImport("user32", EntryPoint = "GetWindowLong")]
private static extern uint GetWindowLong(IntPtr hwnd, int nIndex);
#endregion
#region 使窗口有鼠標穿透功能
/// <summary>
/// 使窗口有鼠標穿透功能
/// </summary>
private void CanPenetrate()
{
uint intExTemp = GetWindowLong(this.Handle, GWL_EXSTYLE);
uint oldGWLEx = SetWindowLong(this.Handle, GWL_EXSTYLE, WS_EX_TRANSPARENT | WS_EX_LAYERED);
}
#endregion
private void Frm_Main_Load(object sender, EventArgs e)
{
this.ShowInTaskbar = false;//窗體不出現(xiàn)在Windows任務欄中
CanPenetrate();
this.TopMost = true;//使窗體始終在其它窗體之上
}
#region 設置顏色和透明度的狀態(tài)
/// <summary>
/// 設置顏色和透明度的狀態(tài)
/// </summary>
private void SetEstate(Form Frm, object sender)
{
Var_genre = ((ToolStripMenuItem)sender).Name;
string Tem_Str = Var_genre;
if (Var_genre.IndexOf('_') >= 0)
{
Var_genre = Tem_Str.Substring(0, Tem_Str.IndexOf('_'));
}
switch (Var_genre)
{
case "ToolColor":
{
Color Tem_Color=Color.Gainsboro;
switch (Convert.ToInt32(((ToolStripMenuItem)sender).Tag.ToString()))
{
case 1: Tem_Color = Color.Gainsboro; break;
case 2: Tem_Color = Color.DarkOrchid; break;
case 3: Tem_Color = Color.RoyalBlue; break;
case 4: Tem_Color = Color.Gold; break;
case 5: Tem_Color = Color.LightGreen; break;
}
Frm.BackColor = Tem_Color;
break;
}
case "ToolClarity":
{
double Tem_Double = 0.0;
switch (Convert.ToInt32(((ToolStripMenuItem)sender).Tag.ToString()))
{
case 1: Tem_Double = 0.1; break;
case 2: Tem_Double = 0.2; break;
case 3: Tem_Double = 0.3; break;
case 4: Tem_Double = 0.4; break;
case 5: Tem_Double = 0.5; break;
case 6: Tem_Double = 0.6; break;
case 7: Tem_Double = 0.7; break;
case 8: Tem_Double = 0.8; break;
case 9: Tem_Double = 0.9; break;
}
Frm.Opacity = Tem_Double;
break;
}
case "ToolAcquiescence":
{
Frm.BackColor = Color.Gainsboro;
Frm.Opacity = 0.6;
break;
}
case "ToolClose":
{
Close();
break;
}
}
}
#endregion
private void ToolColor_Glass_Click(object sender, EventArgs e)
{
SetEstate(this, sender);
}
}
}
注意事項
1、注意控件名稱。ToolColor_Gainsboro
到此這篇關于C# WinForm實現(xiàn)鼠標穿透的操作代碼的文章就介紹到這了,更多相關C# WinForm鼠標穿透內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

