Làm cách nào để tôi có thể dễ dàng nắm bắt các sự kiện "di chuyển chuột" của tất cả các điều khiển trong biểu mẫu mà không cần đăng ký theo cách thủ công vào từng sự kiện? (C#) Một cái gì đó giống như tính năng "KeyPreview", nhưng đối với các sự kiện chuột.Đăng ký sự kiện chuột của tất cả các điều khiển dưới dạng
Trả lời
Giải pháp 1
Đang đăng ký cho mỗi và mọi sự kiện trên tất cả các điều khiển trong một hình thức chắc chắn là đơn giản nhất cách tiếp cận nhất để lấy, vì bạn chỉ cần sử dụng mã do Ramesh.
Tuy nhiên, một kỹ thuật khác liên quan đến việc ghi đè phương thức xử lý thông báo cửa sổ mặc định ("WndProc") trên điều khiển chính - trong trường hợp này, biểu mẫu chứa tất cả các điều khiển. Điều này có tác dụng phụ mà bạn sẽ không thể phát hiện khi con trỏ chuột di chuyển qua các điều khiển chứa bên trong một điều khiển chính khác.
Ví dụ: bạn sẽ không thể phát hiện khi con trỏ chuột trên TextBox
được chứa bên trong một TabControl
. Điều này là do TabControl
sẽ tiếp tục xử lý tất cả các sự kiện chuột.
Giải pháp 2
Các giải pháp sau đây sẽ khắc phục được tất cả các vấn đề trong việc cố gắng để phát hiện mà điều khiển con trỏ chuột đã qua sử dụng một kỹ thuật gọi là cửa sổ móc.
Hooks về cơ bản cho phép chúng tôi bẫy sự kiện chuột và bàn phím ngay cả trước khi chúng được gửi đến cửa sổ bằng tiêu điểm.
Dưới đây là một ví dụ:
public enum HookType : int
{
WH_JOURNALRECORD = 0,
WH_JOURNALPLAYBACK = 1,
WH_KEYBOARD = 2,
WH_GETMESSAGE = 3,
WH_CALLWNDPROC = 4,
WH_CBT = 5,
WH_SYSMSGFILTER = 6,
WH_MOUSE = 7,
WH_HARDWARE = 8,
WH_DEBUG = 9,
WH_SHELL = 10,
WH_FOREGROUNDIDLE = 11,
WH_CALLWNDPROCRET = 12,
WH_KEYBOARD_LL = 13,
WH_MOUSE_LL = 14
}
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int X;
public int Y;
}
[StructLayout(LayoutKind.Sequential)]
public struct MouseHookStruct
{
public POINT pt;
public int hwnd;
public int hitTestCode;
public int dwExtraInfo;
}
[DllImport("user32.dll", SetLastError = true)]
static extern int SetWindowsHookEx(HookType hook, HookProc callback, IntPtr hInstance, uint dwThreadId);
[DllImport("user32.dll", SetLastError= true)]
static extern int CallNextHookEx(int hook, int code, IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll")]
static extern int GetLastError();
[DllImport("kernel32.dll")]
static extern int GetCurrentThreadId();
public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);
private static int hHook;
public Form1()
{
InitializeComponent();
hHook = SetWindowsHookEx(HookType.WH_MOUSE, MouseHookProc, IntPtr.Zero, (uint)GetCurrentThreadId());
if (hHook == 0)
MessageBox.Show("GetLastError: " + GetLastError());
}
private int MouseHookProc(int code, IntPtr wParam, IntPtr lParam)
{
//Marshall the data from the callback.
MouseHookStruct mouseInfo = (MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseHookStruct));
if (code < 0)
{
return CallNextHookEx(hHook, code, wParam, lParam);
}
else
{
//Create a string variable that shows the current mouse coordinates.
String strCaption = "x = " + mouseInfo.pt.X.ToString("d") +
" y = " + mouseInfo.pt.Y.ToString("d");
//You must get the active form because it is a static function.
Form tempForm = Form.ActiveForm;
Control c = Control.FromHandle((IntPtr)mouseInfo.hwnd);
if (c != null)
label1.Text = c.Name;
else
label1.Text = "Control not found";
//Set the caption of the form.
tempForm.Text = strCaption;
return CallNextHookEx(hHook, code, wParam, lParam);
}
}
Conttrols khác trong biểu mẫu không thể nghe trình xử lý sự kiện chuột của biểu mẫu. Bởi vì mỗi điều khiển đều có trình nghe sự kiện chuột của riêng nó.
Nhưng Bạn có thể đăng ký mỗi sự kiện điều khiển chuột để các sự kiện dạng chuột
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Form1_MDown);
this.label1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Form1_MDown);
this.ListBox1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Form1_MDown);
cách này bạn có thể có điều khiển duy nhất cho tất cả các sự kiện điều khiển chuột.
Tôi thấy điều này là giải pháp tốt nhất cho mục đích của tôi.
Tạo một lớp mới có nguồn gốc từ IMessageFilter
:
public class GlobalMouseHandler : IMessageFilter
{
private const int WM_LBUTTONDOWN = 0x201;
public bool PreFilterMessage(ref Message m)
{
if (m.Msg == WM_LBUTTONDOWN)
{
// do something
((YourMainForm)Form.ActiveForm).YourMainForm_Click(null, null);
}
return false;
}
}
Sau đó, trong hình thức chính của bạn thêm này để đăng ký bộ lọc thông điệp:
GlobalMouseHandler globalClick = new GlobalMouseHandler();
Application.AddMessageFilter(globalClick);
Và thêm chức năng này để làm bất cứ điều gì bạn có, trong biểu mẫu của bạn:
public void YourMainForm_Click(object sender, EventArgs e)
{
// do anything here...
}
- 1. Xóa tất cả đăng ký sự kiện (Clone linked)
- 2. Tôi có phải hủy đăng ký tất cả các trình xử lý sự kiện không?
- 3. Xử lý tất cả các sự kiện chuột trong Android
- 4. Một trình xử lý sự kiện cho tất cả các điều khiển trên biểu mẫu
- 5. Đăng mảng dưới dạng JSON tới Bộ điều khiển MVC
- 6. Backbone Sự kiện: đăng nhập tất cả các sự kiện khi chúng được kích hoạt
- 7. Ghi lại hoặc đăng nhập tất cả (các) sự kiện DOM/JQuery của trình duyệt
- 8. Ẩn tất cả các bộ điều khiển xem phương thức
- 9. Thay đổi kiểu cho tất cả các yếu tố bằng một sự kiện nhấp chuột
- 10. Giám sát tất cả các sự kiện JavaScript trong bảng điều khiển trình duyệt
- 11. Chuột điều khiển dành cho cha mẹ Nhập/Rời khỏi sự kiện Với điều khiển con
- 12. iOS không nhận dạng các sự kiện nhấp chuột
- 13. Điều khiển người dùng được nạp động với Trình xử lý sự kiện - Hủy đăng ký
- 14. Sự kiện .NET - chặn người đăng ký đăng ký một sự kiện
- 15. Nhiều sự kiện MouseHover trong Điều khiển
- 16. Nhân bản với tất cả các sự kiện của nó
- 17. View.onTouchEvent chỉ đăng ký sự kiện ACTION_DOWN
- 18. C# Đăng ký sự kiện động
- 19. Sự kiện đăng ký trong VB.NET
- 20. Đặt thuộc tính VerticalAlignment cho tất cả các điều khiển
- 21. Tìm tất cả các bộ điều khiển trong ứng dụng
- 22. OpenMPI: Tất cả các nút chạy dưới dạng nút 0
- 23. Làm thế nào để chuyển hướng các sự kiện chuột đến một điều khiển khác?
- 24. Nghe tất cả các sự kiện onClick của tất cả trẻ em trong jQuery
- 25. Đăng ký tất cả các loại tệp (CFBundleDocumentTypes)
- 26. Trong Web.config Có thể đăng ký tất cả các điều khiển người dùng trong thư mục chỉ định
- 27. phương pháp liên kết trên sự kiện nhấp chuột của điều khiển "LabelLink" trong WPF - Caliburn
- 28. Trạng thái ghi nhật ký đối tượng. Nhận tất cả các giá trị thuộc tính của nó dưới dạng chuỗi
- 29. Tại sao Firefox không vượt qua tất cả các sự kiện bánh xe chuột vào ứng dụng javascript của tôi?
- 30. Điều khiển chồng chéo C# wpf không nhận sự kiện chuột