Window捕获消息机制-C#
C#捕獲鼠標消息
在C#中怎樣禁用鼠標按鍵,我們可以通過ImessageFilter接口下的PreFilterMessage方法、Application類的AddMessageFilter方法,RemoveMessageFilter方法和Message結構的Msg屬性來禁用鼠標左鍵。Message結構包裝Windows發送的消息,可使用該結構包裝消息,并將其分配給窗口過程以進行調度,還可以使用該結構獲取系統向應用程序或控件發送的關于某個消息的信息。
使用PreFilterMessage方法在調度消息之前將其篩選出來。語法格式如下:?
Bool PreFilterMessage(ref Message m)
參數說明:
m:要調度的消息,無法修改此消息。
返回值:如果篩選消息并禁止消息被調度,則為True;如果允許消息繼續到達下一個篩選器或控件,則為False。使用AddMessageFilter方法添加消息篩選器以便在向目標傳送Windows消息時監視這些消息。使RemoveMessageFilter?從應用程序的消息泵移除一個消息篩選器。
示例一:在ComboBox選擇值的時候,選擇的值會隨鼠標滾輪的滑動而改變,有時候不小心滑動了滑輪,導致選擇的值改變,在下面的示例中,通過禁用鼠標滾輪,防止鼠標滾輪的滑動改變ComboBox選擇的值。
界面:
代碼實現:
1 using System;2 using System.Collections.Generic;3 using System.ComponentModel;4 using System.Data;5 using System.Drawing;6 using System.Linq;7 using System.Text;8 using System.Threading.Tasks;9 using System.Windows.Forms; 10 11 namespace MouseDemo 12 { 13 public partial class FrmMain : Form,IMessageFilter 14 { 15 public FrmMain() 16 { 17 InitializeComponent(); 18 } 19 20 public bool PreFilterMessage(ref Message m) 21 { 22 if (m.Msg == 522) 23 { 24 return true; 25 } 26 else 27 { 28 return false; 29 } 30 } 31 32 /// <summary> 33 /// 窗體加載 34 /// </summary> 35 /// <param name="sender"></param> 36 /// <param name="e"></param> 37 private void FrmMain_Load(object sender, EventArgs e) 38 { 39 InitComboBox(); 40 } 41 42 /// <summary> 43 /// 初始化ComboBox 44 /// </summary> 45 private void InitComboBox() 46 { 47 Dictionary<int, string> dictGrade = new Dictionary<int, string>(); 48 dictGrade.Add(1, "一年級"); 49 dictGrade.Add(2, "二年級"); 50 dictGrade.Add(3, "三年級"); 51 dictGrade.Add(4, "四年級"); 52 dictGrade.Add(5, "五年級"); 53 dictGrade.Add(6, "六年級"); 54 55 BindingSource dataSource = new BindingSource(); 56 dataSource.DataSource = dictGrade; 57 cmb_Grade.DataSource = dataSource; 58 cmb_Grade.DisplayMember = "Value"; 59 cmb_Grade.ValueMember = "Key"; 60 } 61 62 /// <summary> 63 /// 索引改變事件 64 /// </summary> 65 /// <param name="sender"></param> 66 /// <param name="e"></param> 67 private void cmb_Grade_SelectedIndexChanged(object sender, EventArgs e) 68 { 69 //添加消息過濾 70 Application.AddMessageFilter(this); 71 } 72 73 74 } 75 }示例二:窗體設置右鍵控件,演示禁用和解除禁用右鍵功能,右鍵菜單只有復制、剪切、粘貼三項
界面:
代碼:
1 using System;2 using System.Collections.Generic;3 using System.ComponentModel;4 using System.Data;5 using System.Drawing;6 using System.Linq;7 using System.Text;8 using System.Threading.Tasks;9 using System.Windows.Forms; 10 11 namespace MouseRightDemo 12 { 13 public partial class FrmMouseRight : Form ,IMessageFilter 14 { 15 public FrmMouseRight() 16 { 17 InitializeComponent(); 18 } 19 20 /// <summary> 21 /// 實現方法 22 /// </summary> 23 /// <param name="m"></param> 24 /// <returns></returns> 25 public bool PreFilterMessage(ref Message m) 26 { 27 //不響應鼠標右鍵 28 if (m.Msg >= 516 && m.Msg <= 517) 29 { 30 return true; 31 } 32 else 33 { 34 return false; 35 } 36 } 37 38 /// <summary> 39 /// 禁用鼠標右鍵 40 /// </summary> 41 /// <param name="sender"></param> 42 /// <param name="e"></param> 43 private void button1_Click(object sender, EventArgs e) 44 { 45 //添加消息 46 Application.AddMessageFilter(this); 47 MessageBox.Show("鼠標右鍵已被禁止使用", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); 48 } 49 50 /// <summary> 51 /// 解決禁用鼠標右鍵 52 /// </summary> 53 /// <param name="sender"></param> 54 /// <param name="e"></param> 55 private void button2_Click(object sender, EventArgs e) 56 { 57 //移除消息 58 Application.RemoveMessageFilter(this); 59 MessageBox.Show("鼠標右鍵已被解除禁止使用,可以使用鼠標右鍵", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); 60 } 61 } 62 }鼠標動作常見參數:
鼠標移動:512
鼠標左鍵:
down:513 up:514
double click:515
鼠標右鍵:
down:516 up:517
鼠標滾輪:522
//**************************
利用windows消息機制截獲特定應用程序里鼠標、鍵盤的消息事件
通過學習知道鉤子機制可以幫助我們截獲處理windows消息或特定事件,現將本人所掌握的知識內容總結如下:
1.調用windows底層API,定義winAPI類
??using System.Runtime.InteropServices;
? ? public class WinApi
? ? {
? ? ? ? [StructLayout(LayoutKind.Sequential)]
? ? ? ? public class POINT
? ? ? ? {
? ? ? ? ? ? public int x;
? ? ? ? ? ? public int y;
? ? ? ? }
? ? ? ? [StructLayout(LayoutKind.Sequential)]
? ? ? ? public class MouseHookStruct
? ? ? ? {
? ? ? ? ? ? public POINT pt;
? ? ? ? ? ? public int hwnd;
? ? ? ? ? ? public int wHitTestCode;
? ? ? ? ? ? public int dwExtraInfo;
? ? ? ? }
? ? ? ? [StructLayout(LayoutKind.Sequential)]
? ? ? ? public class KeyboardHookStruct
? ? ? ? {
? ? ? ? ? ? public int vkCode;
? ? ? ? ? ? public int scanCode;
? ? ? ? ? ? public int flags;
? ? ? ? ? ? public int time;
? ? ? ? ? ? public int dwExtraInfo;
? ? ? ? }
? ? ? ? public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);
? ? ? ? //安裝鉤子
? ? ? ? [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
? ? ? ? public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
? ? ? ? //卸載鉤子
? ? ? ? [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
? ? ? ? public static extern bool UnhookWindowsHookEx(int idHook);
? ? ? ? //調用下一個鉤子
? ? ? ? [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
? ? ? ? public static extern int CallNextHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam);?
? ? ? ? //獲得系統當前窗體句柄
? ? ? ? [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
? ? ? ? public static extern IntPtr GetForegroundWindow();
? ? ? ? //獲得窗體名稱
? ? ? ? [DllImport("user32.dll", CharSet = CharSet.Auto)]
? ? ? ? public static extern int GetWindowText();
? ?}
2.定義鼠標鉤子和鍵盤鉤子
? ? public class MouseHook
? ? { ? ? ? ?
? ? ? ? private Point point;
? ? ? ? private Point Point
? ? ? ? {
? ? ? ? ? ? get { return point; }
? ? ? ? ? ? set
? ? ? ? ? ? {
? ? ? ? ? ? ? ? if (point != value)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? point = value;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? private int hHook;
? ? ? ? public const int WH_MOUSE_LL = 14;
? ? ? ? public WinApi.HookProc hProc;
? ? ? ? public MouseHook()
? ? ? ? {
? ? ? ? ? ? this.Point = new Point();?
? ? ? ? }
? ? ? ? public int SetHook()
? ? ? ? {
? ? ? ? ? ? hProc = new WinApi.HookProc(MouseHookProc);
? ? ? ? ? ? hHook = WinApi.SetWindowsHookEx(WH_MOUSE_LL, hProc, IntPtr.Zero,0);
? ? ? ? ? ? return hHook;
? ? ? ? }
? ? ? ? public void UnHook()
? ? ? ? {
? ? ? ? ? ? WinApi.UnhookWindowsHookEx(hHook);
? ? ? ? }
? ? ? ? private int MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam)
? ? ? ? { ? ? ? ? ? ?
? ? ? ? ? ? if (nCode < 0)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? return WinApi.CallNextHookEx(hHook, nCode, wParam, lParam);
? ? ? ? ? ? }
? ? ? ? ? ? else
? ? ? ? ? ? {
? ? ? ? ? ? ? ?WinApi.MouseHookStruct MyMouseHookStruct = (WinApi.MouseHookStruct)Marshal.PtrToStructure
? ? ? ? ? ? ? ? ? ? ? (lParam, typeof(WinApi.MouseHookStruct));
? ? ? ? ? ? ? ?MouseButtons button = MouseButtons.None;
? ? ? ? ? ? ? ?int clickCount = 0;
? ? ? ? ? ? ? ?switch ((Int32)wParam)
? ? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ? ?case WM_LBUTTONDOWN:?
? ? ? ? ? ? ? ? ? ? ? ? button = MouseButtons.Left;
? ? ? ? ? ? ? ? ? ? ? ? clickCount = 1;
? ? ? ? ? ? ? ? ? ? ? ? var e = new MouseEventArgs(button, clickCount, point.X, point.Y, 0);
? ? ? ? ? ? ? ? ? ? ? ? MouseClick(this, e);
? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ?case WM_MOUSEMOVE:?
? ? ? ? ? ? ? ? ? ? ? ? var e = new MouseEventArgs(button, clickCount, point.X, point.Y, 0);
? ? ? ? ? ? ? ? ? ? ? ? MouseMove(this, e);
? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ?this.Point = new Point(MyMouseHookStruct.pt.x, MyMouseHookStruct.pt.y);
? ? ? ? ? ? ? ?return WinApi.CallNextHookEx(hHook, nCode, wParam, lParam);
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? //委托+事件(把鉤到的消息封裝為事件,由調用者處理)
? ? ? ? public delegate void MouseMoveHandler(object sender, MouseEventArgs e);
? ? ? ? public event MouseMoveHandler MouseMove;
?
? ? ? ? public delegate void MouseClickHandler(object sender, MouseEventArgs e);
? ? ? ? public event MouseClickHandler MouseClick;
? ? } ? ?
? ? public class KeyboardHook
? ? { ? ? ? ?
? ? ? ? private int hHook;
? ? ? ? public WinApi.HookProc hProc;
?
? ? ? ? public int SetHook()
? ? ? ? {
? ? ? ? ? ? hProc = new WinApi.HookProc(KeyboardHookProc);
? ? ? ? ? ? hHook = WinApi.SetWindowsHookEx(WH_KEYBOARD_LL, hProc, IntPtr.Zero,0);
? ? ? ? ? ? return hHook;
? ? ? ? }
? ? ? ? public void UnHook()
? ? ? ? {
? ? ? ? ? ? WinApi.UnhookWindowsHookEx(hHook);
? ? ? ? }
? ? ? ? private int KeyboardHookProc(int nCode, IntPtr wParam, IntPtr lParam)
? ? ? ? { ? ? ? ? ? ?
? ? ? ? ? ? if (nCode >= 0)
? ? ? ? ? ? {
? ? ? ? ? ? ? ?WinApi.KeyboardHookStruct kbhs= (WinApi.KeyboardHookStruct)Marshal.PtrToStructure(lParam,
? ? ? ? ? ? ? ? ? ? ? typeof(WinApi.KeyboardHookStruct));
? ? ? ? ? ? ? Keys key = (Keys)kbhs.vkCode;
? ? ? ? ? ? ? ?switch ((Int32)wParam)
? ? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ? ?case WM_KEYDOWN: ? ? ? ? ? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? ? ? ? ? var e = new KeyEventArgs(key);
? ? ? ? ? ? ? ? ? ? ? ? KeyDown(this, e);
? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ?case WM_KEYUP:?
? ? ? ? ? ? ? ? ? ? ? ? var e1 = new KeyEventArgs(key);
? ? ? ? ? ? ? ? ? ? ? ? KeyUp(this, e1);
? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? } ? ? ? ? ? ? ??
? ? ? ? ? ? }
? ? ? ? ? ? return WinApi.CallNextHookEx(hHook, nCode, wParam, lParam);
? ? ? }
? ? ? //委托+事件(把鉤到的消息封裝為事件,由調用者處理)?
? ? ? public delegate void KeyDownEventHandler(object sender, KeyEventArgs e);?
? ? ? public delegate void KeyUpEventHandler(object sender, KeyEventArgs e);?
?
? ? ? public event KeyDownEventHandler KeyDown;?
? ? ? public event KeyUpEventHandler KeyUp;?
? ?}
3.應用程序調用
MouseHook mh;
KeyboardHook kh;
public Form1()
{
? ? ? InitializeComponent();
? ? ? //啟動程序自動隱藏窗體
? ? ?this.WindowState = FormWindowState.Minimized;
? ? ?this.ShowInTaskbar = false;
? ? ?SetVisibleCore(false);
}
private void Form1_Load(object sender, EventArgs e)
{
? ? ? mh = new MouseHook();
? ? ? mh.SetHook();
? ? ? mh.MouseMove += mh_MouseMove;
? ? ? mh.MouseClick += mh_MouseClick;
? ? ? kh = new KeyboardHook();
? ? ? kh.SetHook();
? ? ? kh.KeyDown += kh_KeyDown;
? ? ? kh.KeyUp += kh_KeyUp;
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
? ? ? ?mh.UnHook();
? ? ? ?kh.UnHook();
}
private void mh_MouseMove(object sender, MouseEventArgs e)
{
}
private void mh_MouseClick(object sender, MouseEventArgs e)
{
}
private void kh_KeyDown(object sender, KeyEventArgs e)
{
}
private void kh_KeyUp(object sender, KeyEventArgs e)
{
}
?
總結
以上是生活随笔為你收集整理的Window捕获消息机制-C#的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: idea 版本控制忽略文件、文件夹设置
- 下一篇: 35 岁之前不应该错过的 30 本书