繁体   English   中英

C# - 停靠的外部应用程序 - 鼠标事件

[英]C# - Docked External application - Mouse events

我有一个 winform 应用程序(.NET C#)。 从这个应用程序中,我启动了另一个进程 (notepad.exe) 并将其停靠到我的窗口 - 类似于此处的操作: Docking Window inside another Window

现在我的问题是,我怎样才能捕捉/处理在这个停靠的应用程序上发生的鼠标事件? 我试过的:

  • 在停靠面板上创建一个透明面板。 当我无法“通过”隐形面板单击(或执行任何其他操作)时,问题就出现了
  • 全局鼠标钩子。 我不喜欢这个解决方案,因为我只对表单中的鼠标位置感兴趣。 另外,我需要鼠标相对于窗口的位置。

对于上下文,我想要实现的是在我的鼠标旁边有一个恒定的工具提示,通知我鼠标相对于面板的位置。 看下面的代码:

ToolTip trackTip;
public Form1
{
  trackTip = new ToolTip();
  transparentPanel1.MouseMove += new MouseEventHandler((object s, System.Windows.Forms.MouseEventArgs e) => trackTip.Hide(this));
  transparentPanel1.MouseLeave += new EventHandler(TransparentPanel1_MouseLeave);
}


void TransparentPanel1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
  String tipText = String.Format("({0}, {1})", e.X, e.Y);
  trackTip.Show(tipText, this, e.Location);
}

我找到了一个可行的解决方案,但是我非常希望避免将代码注入流程中,而且我觉得必须有更好的解决方案来解决我的特定问题。

我很感激你能给我的任何指示。 我是 .NET 编程的新手。

作为参考,我在这里将两个答案合并为一个:

在c#中获取鼠标位置

如何获取窗口的位置?

利用鼠标的全局位置和窗口的位置,我们可以计算出鼠标的相对位置。 下面是一些示例代码,其中包含非常基本的边界处理,并且没有处理句柄是否关闭等的真正错误处理等。但应该可以帮助您入门。

首先,基本上是上述答案的副本,引入了 Windows API 以获取窗口和鼠标位置:

    [StructLayout(LayoutKind.Sequential)]
    public struct POINT
    {
        public int X;
        public int Y;

        public static implicit operator Point(POINT point)
        {
            return new Point(point.X, point.Y);
        }
    }

    [DllImport("user32.dll")]
    public static extern bool GetCursorPos(out POINT lpPoint);

    public static Point GetCursorPosition()
    {
        POINT lpPoint;
        GetCursorPos(out lpPoint);

        return lpPoint;
    }

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr FindWindow(string strClassName, string strWindowName);

    [DllImport("user32.dll")]
    public static extern bool GetWindowRect(IntPtr hwnd, ref Rect rectangle);

    public struct Rect
    {
        public int Left { get; set; }
        public int Top { get; set; }
        public int Right { get; set; }
        public int Bottom { get; set; }
    }

然后是两者之间的一些数学运算:

    public Point GetRelativeMousePosition(IntPtr windowPtr)
    {
        Rect windowPostion = new Rect();
        GetWindowRect(windowPtr, ref windowPostion);
        var mousePosition = GetCursorPosition();

        var result = new Point();
        result.X = mousePosition.X - windowPostion.Left;
        result.Y = mousePosition.Y - windowPostion.Top;

        // set some boundaries so we can't go outside.
        if (result.X < 0)
            result.X = 0;

        var maxWidth = windowPostion.Right - windowPostion.Left;
        if (result.X > maxWidth)
            result.X = maxWidth;

        if (result.Y < 0)
            result.Y = 0;

        var maxHeight = windowPostion.Bottom - windowPostion.Top;
        if (result.Y > maxHeight)
            result.Y = maxHeight;

        return result;
    }

然后把它们放在一起:

    private void Sample()
    {
        Process[] processes = Process.GetProcessesByName("notepad");
        Process lol = processes[0];
        var ptr = lol.MainWindowHandle; // getting this reference is expensive. Better to store and reuse if possible.
        var relativePoint = GetRelativeMousePosition(ptr);
        Console.WriteLine($"relative mouse x:{relativePoint.X} y:{relativePoint.Y}");
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM