Захват событий мыши из каждого компонента на C # WInForm
У меня проблема с MouseEvents на моем приложении WinForm C #. Я хочу получить ВСЕ щелчки мыши в моем приложении, но я не хочу, чтобы слушатель в каждом дочернем компоненте не использовал крючок для мыши Windows.
На Flash я мог бы поставить слушателя на сцене, чтобы получить все MouseEvents в фильме. Есть ли такая вещь на C #? Глобальный MouseListener?
Изменить: я создаю этот class из IMessageFilter и используемого Application.AddMessageFilter.
- C #: многострочный текст в элементе управления DataGridView
- Безопасно ли просто устанавливать CheckForIllegalCrossThreadCalls на false, чтобы избежать ошибок сквозной streamовой передачи во время отладки?
- Как пользователь может изменять размер управления во время выполнения в winforms
- Проблема с PictureBox
- Обнаружение незанятых пользователей в Winforms
public class GlobalMouseHandler : IMessageFilter{ private const int WM_LBUTTONDOWN = 0x201; public bool PreFilterMessage(ref Message m){ if (m.Msg == WM_LBUTTONDOWN) { // Do stuffs } return false; } }
И поместите этот код в элементы управления, которым необходимо прослушивать глобальные клики:
GlobalMouseHandler globalClick = new GlobalMouseHandler(); Application.AddMessageFilter(globalClick);
Спасибо вам за помощь!
- C # Force Form Focus
- Как обеспечить отображение формы на «дополнительном» мониторе в сценарии с двумя мониторами?
- Как удалить фокус из TextBox в WinForms?
- Как вызвать метод ежедневно, в определенное время, на C #?
- Найти элемент управления в Windows Forms по имени
- копирование свободного рисования с панели в visual studio 2013
- SynchronizationContext.Current имеет значение null в продолжении в основном streamе пользовательского интерфейса
- Сложный пользовательский интерфейс внутри ListBoxItem
Один простой способ сделать это – добавить фильтр цикла сообщения, вызвав Application.AddMessageFilter
и написать class, который реализует интерфейс IMessageFilter
.
Через IMessageFilter.PreFilterMessage
ваш class получает сообщения о входах, которые проходят через цикл сообщений вашего приложения. PreFilterMessage
также принимает решение о передаче этих сообщений конкретному PreFilterMessage
управления, которому они предназначены.
Одна из сложностей, которую вводит этот подход, заключается в том, чтобы иметь дело с сообщениями Windows через структуру Message, переданную вашему методу PreFilterMessage
. Это означает WM\_LBUTTONDOWN, WM\_MOUSEMOVE
на документацию Win32 на WM\_LBUTTONDOWN, WM\_MOUSEMOVE
, WM\_LBUTTONUP
т. Д. Вместо обычных MouseDown
, MouseMove
и MouseUp
.
Примерный class
class CaptureEvents : IMessageFilter { #region IMessageFilter Members public delegate void Callback(int message); public event Callback MessageReceived; IntPtr ownerWindow; Hashtable interestedMessages = null; CaptureEvents(IntPtr handle, int[] messages) { ownerWindow = handle; for(int c = 0; c < messages.Length ; c++) { interestedMessages[messages[c]] = 0; } } public bool PreFilterMessage(ref Message m) { if (m.HWnd == ownerWindow && interestedMessages.ContainsKey(m.Msg)) { MessageReceived(m.Msg); } return true; } #endregion }
Если вы не хотите обрабатывать сообщения, переопределяя Form.PreProcessMessage или Form.WndProc, тогда вы можете подclassировать Form для привязки обработчика событий ко всем событиям MouseClick из различных элементов управления в форме.
EDIT: забыл переписать через дочерние элементы управления элементами формы.
public class MousePreviewForm : Form { protected override void OnClosed(EventArgs e) { UnhookControl(this as Control); base.OnClosed(e); } protected override void OnLoad(EventArgs e) { base.OnLoad(e); HookControl(this as Control); } private void HookControl(Control controlToHook) { controlToHook.MouseClick += AllControlsMouseClick; foreach (Control ctl in controlToHook.Controls) { HookControl(ctl); } } private void UnhookControl(Control controlToUnhook) { controlToUnhook.MouseClick -= AllControlsMouseClick; foreach (Control ctl in controlToUnhook.Controls) { UnhookControl(ctl); } } void AllControlsMouseClick(object sender, MouseEventArgs e) { //do clever stuff here... throw new NotImplementedException(); } }
Затем ваши формы должны были бы выводиться из MousePreviewForm, а не из System.Windows.Forms.Form.
Взгляните на эту статью . Он рекурсивно подхватывает все контрольные события и транслирует их. Вы также можете переопределить WndProc в своей форме.