如何捕获在 (WPF) 窗口之外发生的鼠标事件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13732070/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 06:29:38  来源:igfitidea点击:

How can I capture mouse events that occur outside of a (WPF) window?

c#wpfwindowmouseeventcapture

提问by Hymanson Dean Goodwin

I have a Windowelement that has WindowStyle="None"and AllowsTransparency="True", therefore it has no title bar and supports transparency.

我有一个Window具有WindowStyle="None"和的元素AllowsTransparency="True",因此它没有标题栏并支持透明度。

I want the user to be able to move the Window to any position on the screen by left-clicking anywhere within the Window and dragging. The Window should drag along with the mouse as long as the left mouse button is pressed down.

我希望用户能够通过左键单击窗口内的任意位置并拖动来将窗口移动到屏幕上的任何位置。只要按下鼠标左键,窗口就会随鼠标一起拖动。

I was able to get this functionality to work with one exception: when the mouse moves outside of the Window (such as when the left mouse button was pressed down near the edge of the Window and the mouse is moved quicly), the Window no longer captures the mouse position and does not drag along with the mouse.

我能够使用此功能,但有一个例外:当鼠标移出窗口时(例如在窗口边缘附近按下鼠标左键并且鼠标快速移动时),窗口不再捕捉鼠标位置,不随鼠标拖动。

Here is the code from the code-behind that I use to get the job done:

这是我用来完成工作的代码隐藏代码:

public Point MouseDownPosition { get; set; }
public Point MousePosition { get; set; }
public bool MouseIsDown { get; set; }

private void window_MyWindowName_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    MouseDownPosition = e.GetPosition(null);
    MouseIsDown = true;
}

private void window_MyWindowName_MouseMove(object sender, MouseEventArgs e)
{
    if (MouseIsDown)
    {
        MousePosition = e.GetPosition(null);
        Left += MousePosition.X - MouseDownPosition.X;
        Top += MousePosition.Y - MouseDownPosition.Y;
    }
}

private void window_MyWindowName_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    MouseIsDown = false;
}

采纳答案by Joe

I believe you are reinventing the wheel. Search for "Window.DragMove".

我相信你正在重新发明轮子。搜索“Window.DragMove”。

Example:

例子:

    private void title_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        this.DragMove();
    }

回答by Ofear

I think you are looking for this: Processing Global Mouse and Keyboard Hooks in C#

我想你正在寻找这个:用 C# 处理全局鼠标和键盘挂钩

Url: Processing Global Mouse and Keyboard Hooks in C#

Url:在 C# 中处理全局鼠标和键盘挂钩

This class allows you to tap keyboard and mouse and/or to detect their activity even when an application runs in the background or does not have any user interface at all.

此类允许您点击键盘和鼠标和/或检测它们的活动,即使应用程序在后台运行或根本没有任何用户界面。

This class raises common .NET events with KeyEventArgs and MouseEventArgs, so you can easily retrieve any information you need.

此类通过 KeyEventArgs 和 MouseEventArgs 引发常见的 .NET 事件,因此您可以轻松检索所需的任何信息。

There is an example and explain and demo to use.

有一个例子,解释和演示使用。

Great tutorial!

很棒的教程!

Example:

例子:

UserActivityHook actHook;
void MainFormLoad(object sender, System.EventArgs e)
{
    actHook= new UserActivityHook(); // crate an instance

    // hang on events

    actHook.OnMouseActivity+=new MouseEventHandler(MouseMoved);
    actHook.KeyDown+=new KeyEventHandler(MyKeyDown);
    actHook.KeyPress+=new KeyPressEventHandler(MyKeyPress);
    actHook.KeyUp+=new KeyEventHandler(MyKeyUp);
}

Now, an example of how to process an event:

现在,一个如何处理事件的例子:

public void MouseMoved(object sender, MouseEventArgs e)
{
    labelMousePosition.Text=String.Format("x={0}  y={1}", e.X, e.Y);
    if (e.Clicks>0) LogWrite("MouseButton     - " + e.Button.ToString());
}

回答by jlang

Try it this way:

试试这个方法:

// method to convert from 'old' WinForms Point to 'new' WPF Point structure:
public System.Windows.Point ConvertToPoint(System.Drawing.Point p)
{
    return new System.Windows.Point(p.X,p.Y);
}

// some locals you will need:
bool mid = false; // Mouse Is Down
int x=0, y=0;

// Mouse down event
private void MainForm_MouseDown(object sender, MouseButtonEventArgs e)
{
   mid=true;
   Point p =  e.GetPosition(this);

   x = (int)p.X; 
   y = (int)p.Y;
}

// Mouse move event
private void MainForm_MouseMove(object sender, MouseButtonEventArgs e)
{
   if(mid)
   {
        int x1 = e.GetPosition(this).X;
        int y1 = e.GetPosition(this).Y;

        Left = x1-x;
        Top = y1-y;
   }
}

// Mouse up event
private void MainForm_MouseUp(object sender, MouseButtonEventArgs e)
{
    mid = false;
}