我想捕獲我的主窗體中的鼠標移動事件。儘管我可以爲主窗體連接MouseEventHandler
,但當光標位於UserControl或其他任何控件上時,事件不再觸發。我如何確保我始終擁有鼠標位置。如何捕獲鼠標移動事件
回答
您可以使用低級別的鼠標鉤子。請參閱this示例,並檢查HookCallback中的WM_MOUSEMOVE消息。
您也可以使用IMessageFilter類抓老鼠事件和觸發事件,以獲得位置(注意:這隻會位置在窗口,它不是外面):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace GlobalMouseEvents
{
public partial class Form1 : Form
{
public Form1()
{
GlobalMouseHandler gmh = new GlobalMouseHandler();
gmh.TheMouseMoved += new MouseMovedEvent(gmh_TheMouseMoved);
Application.AddMessageFilter(gmh);
InitializeComponent();
}
void gmh_TheMouseMoved()
{
Point cur_pos = System.Windows.Forms.Cursor.Position;
System.Console.WriteLine(cur_pos);
}
}
public delegate void MouseMovedEvent();
public class GlobalMouseHandler : IMessageFilter
{
private const int WM_MOUSEMOVE = 0x0200;
public event MouseMovedEvent TheMouseMoved;
#region IMessageFilter Members
public bool PreFilterMessage(ref Message m)
{
if (m.Msg == WM_MOUSEMOVE)
{
if (TheMouseMoved != null)
{
TheMouseMoved();
}
}
// Always allow message to continue to the next filter control
return false;
}
#endregion
}
}
這很好,謝謝。我使用了您在此處發佈的來源。不過,我注意到,即使鼠標沒有移動,MouseMoved函數也會不斷調用。當鼠標不在應用程序上時,它停止發射。 – 2013-05-28 21:10:25
@ SwDevMan81人們如何找出查找消息ID的十六進制代碼的位置?我看到所有這些導入調用與User32 dll調用,我真的想知道在哪裏可以找到有關此信息 – Dbl 2014-08-01 13:35:41
@AndreasMüller - [鍵盤通知](http://msdn.microsoft.com/en-us/library/windows/desktop/ ff468861(v = vs.85).aspx)和[鼠標通知](http://msdn.microsoft.com/en-us/library/windows/desktop/ff468877(v = vs.85).aspx) – SwDevMan81 2014-08-01 14:27:44
這是解決方案。儘管我可以用類似的方法看到另一個答案。但是自從我寫了它以後,我想發佈它。這裏MouseMessageFilter有一個靜態事件調用MouseMove,你可以從應用程序中的任何地方訂閱。
static class Program
{
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.AddMessageFilter(new MouseMessageFilter());
MouseMessageFilter.MouseMove += new MouseEventHandler(OnGlobalMouseMove);
Application.Run(new MainForm());
}
static void OnGlobalMouseMove(object sender, MouseEventArgs e) {
Console.WriteLine(e.Location.ToString());
}
}
class MouseMessageFilter : IMessageFilter
{
public static event MouseEventHandler MouseMove = delegate { };
const int WM_MOUSEMOVE = 0x0200;
public bool PreFilterMessage(ref Message m) {
if (m.Msg == WM_MOUSEMOVE) {
Point mousePosition = Control.MousePosition;
MouseMove(null, new MouseEventArgs(
MouseButtons.None, 0, mousePosition.X, mousePosition.Y,0));
}
return false;
}
}
只有當wm_mousemove發送給你的應用程序(當它的一個窗口的活動狀態或它的鼠標光標下),如果只有單一表單感興趣,那麼你需要檢查該表單是否有效。 .btw它會在其他窗口處於活動狀態時觸發。並且在運行應用程序之前,您不必添加過濾器。 – TakeMeAsAGuest 2015-07-09 19:32:21
public partial class frmCaptureMouse : Form
{
[DllImport("user32.dll")]
static extern IntPtr SetCapture(IntPtr hWnd);
public frmCaptureMouse()
{
InitializeComponent();
}
private void frmCaptureMouse_MouseMove(object sender, MouseEventArgs e)
{
try
{
lblCoords.Text = e.Location.X.ToString() + ", " + e.Location.Y.ToString();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void btnCapture_Click(object sender, EventArgs e)
{
try
{
SetCapture(this.Handle);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
我試圖通過@ SwDevMan81提供上述solutoution。雖然它的效果很好,但我也遇到了@Randy Gamage的問題,「即使鼠標沒有移動,MouseMoved函數也會被連續調用,當鼠標不在應用程序時它會停止觸發。 在這無論如何是我想出了:
在窗體的構造函數:
的事件處理程序:
private void GlobalMouseHandler_MouseMovedEvent(object sender, MouseEventArgs e)
{
try
{
//Do whatever ...
}
catch { }
}
而且我稍微改變GlobalMouseHandler類:
public class GlobalMouseHandler : IMessageFilter
{
private const int WM_MOUSEMOVE = 0x0200;
private System.Drawing.Point previousMousePosition = new System.Drawing.Point();
public static event EventHandler<MouseEventArgs> MouseMovedEvent = delegate { };
#region IMessageFilter Members
public bool PreFilterMessage(ref System.Windows.Forms.Message m)
{
if (m.Msg == WM_MOUSEMOVE)
{
System.Drawing.Point currentMousePoint = Control.MousePosition;
if (previousMousePosition != currentMousePoint)
{
previousMousePosition = currentMousePoint;
MouseMovedEvent(this, new MouseEventArgs(MouseButtons.None, 0, currentMousePoint.X, currentMousePoint.Y, 0));
}
}
// Always allow message to continue to the next filter control
return false;
}
#endregion
}
我希望有人可以使用它。
這有一個很好的答案,但它調用方法兩次 – 2016-08-16 08:53:44
我弄清楚爲什麼它調用該方法兩次,因爲當第一次觸發事件'previousMousePosition'有一個值'x = 0; y = 0',當程序跳轉到'if(previousMousePosition!= currentMousePoint)'它返回true,我只是添加一個條件來檢查'previousMousePosition'是否有一個默認值並在'if'語句之前退出函數。這解決了這個問題 – 2016-08-19 01:57:38
- 1. 如何用python捕獲鼠標移動?
- 2. 捕獲鼠標移動SVG
- 3. 鼠標移動捕獲
- 4. 捕獲鼠標事件
- 5. 鼠標移動過快,以捕獲事件
- 6. 如何在Dashcode小部件中捕獲鼠標拖動事件?
- 7. 鼠標移動捕獲(鼠標離開和鼠標輸入)
- 8. 如何將鼠標移動事件轉換爲鼠標滾動/拖動事件
- 9. JQuery:鼠標移動事件?
- 10. X11鼠標移動事件
- 11. 鼠標移動事件
- 12. 獲取鼠標座標不斷,而鼠標移動onmousedown事件
- 13. Qt鼠標移動事件沒有被事件過濾器捕獲
- 14. 如何在C++ Win32中捕獲鼠標移動過標題欄?
- 15. Skin UIComponents如何捕捉鼠標事件?
- 16. JOGL不捕獲Java鼠標事件
- 17. ç詛咒不捕獲鼠標事件
- 18. Cocoa - 捕獲NSStatusItem鼠標懸停事件
- 19. 捕獲鼠標鬆開事件/窗口
- 20. 捕獲鼠標事件在Python
- 21. 在C(linux)中捕獲鼠標事件
- 22. Pyside QgraphicsScene無法捕獲鼠標事件
- 23. 停止從水平移動鼠標光標,但仍然要捕獲MouseMove事件
- 24. 鼠標向下,鼠標移動和鼠標事件的圖像?
- 25. 捕捉鼠標事件
- 26. 捕捉鼠標事件
- 27. 如何捕獲WindowsFormsHost控件中的鼠標單擊事件?
- 28. 如何捕獲控件上的所有鼠標事件?
- 29. 如何捕獲C#表單應用程序的鼠標移動?
- 30. 如何在按鈕上捕獲鼠標移動
按照dup線程中的說明使用IMessageFilter。 – 2010-01-14 12:46:30