c# - 禁用鼠标单击 Windows 屏幕的某些区域 C# WPF

标签 c# wpf windows mouseevent

我有一种情况,我想使用 TightVNC 向客户端提供远程访问权限,以允许他们在第三方应用程序上执行某些任务。

我只想允许他们点击屏幕的某些部分,例如禁用“关闭”按钮,并禁用一些区域。我想知道是否有一种方法可以以编程方式拦截窗口上的鼠标按下事件,并且如果它们在特定区域上按下鼠标只是返回而不是执行单击?或者是否有办法覆盖透明背景,该背景始终位于所选区域的屏幕前面?

我的应用程序是用 WPF c# 编写的,因此如果有任何示例可以实现此目的,我们将不胜感激。我尝试创建一些虚拟的透明窗口,问题是当用户单击其他应用程序时,他们会转到后台,从而破坏了目标。

提前致谢。

最佳答案

选项 1:

从技术上讲,您应该能够attach global hooks用于鼠标事件并在需要时抑制它们。 globalmousekeyhook是可用于将处理程序分配给鼠标事件并通过设置e.Handled = true有条件抑制它们的库之一。

选项 2:

如果您只需要阻止特定应用程序的鼠标事件 - 那么您可以覆盖它们的 WindowProc过滤或抑制基于特定区域的鼠标事件的方法。

例如,对于Windows 窗体应用程序,您可以使用以下代码来禁用窗口第四象限区域中的鼠标单击。 (注意:需要将此代码添加到您尝试阻止访问的应用程序中)

public class Setup
{
    //call this method during application start/load
    public static bool Start()
    {
        Application.AddMessageFilter(new MessageFilter());
        return true;
    }
}

public class MessageFilter : IMessageFilter
{
    public bool PreFilterMessage(ref Message m)
    {
        // and use other params to determine mouse click location 
        switch (m.Msg)
        {
            case 0x201:
                //left button down 
                return IsInFourthQuadrant();//(filter the message and don't let app process it)
            case 0x202:
                //left button up, ie. a click
                break;
            case 0x203:
                //left button double click 
                return IsInFourthQuadrant(); //(filter the message and don't let app process it)
        }

        return false;
    }

    private static bool IsInFourthQuadrant()
    {
        var window = Application.OpenForms[0];
        var screen_coords = Cursor.Position;

        var bounds = window.Bounds;
        var fourthQuadrant = new Rectangle(bounds.X + bounds.Width / 2, bounds.Y + bounds.Height / 2, bounds.Width / 2, bounds.Height / 2);

        return fourthQuadrant.Contains(screen_coords);
    }
}

同样,您可以使用以下示例代码来禁用 WPF 应用程序第四象限区域中的鼠标单击:

public class Setup
{
    public static bool Start()
    {
        HwndSource source = PresentationSource.FromVisual(Application.Current.MainWindow) as HwndSource;
        source.AddHook(WndProc);

        return true;
    }

    private static IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    {
        switch (msg)
        {
            case 0x201:
                //left button down 
                handled = IsInFourthQuadrant();//(filter the message and don't let app process it)
                break;
            case 0x202:
                //left button up, ie. a click
                break;
            case 0x203:
                //left button double click 
                handled = IsInFourthQuadrant(); //(filter the message and don't let app process it)
                break;
        }

        return IntPtr.Zero;
    }

    private static bool IsInFourthQuadrant()
    {
        var window = Application.Current.MainWindow;
        var coords = Mouse.GetPosition(Application.Current.MainWindow);

        var fourthQuadrant = new Rect(window.Width / 2, window.Height / 2, window.Width / 2, window.Height / 2);

        return fourthQuadrant.Contains(coords);
    }
}

选项 3:

如果您需要阻止鼠标点击特定的现有正在运行的进程,只要目标应用程序使用 .NET 和基于 Windows 窗体的 UI 或 WPF - 那么您可以 inject your .NET assemblies into the existing process/application 并重写其 WindowsProc 行为,如选项 2 中所述。您也可以引用这个sample code对于同样的。

关于c# - 禁用鼠标单击 Windows 屏幕的某些区域 C# WPF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45398860/

相关文章:

ruby - 如何在 Windows 上编译 Ruby?

python - 来自外部驱动器的 Subprocess.call()

wpf - 类型列表的附加属性

wpf - Silverlight 错误 : AG_E_UNKNOWN_ERROR

python - 导入错误 : cannot import name Thread

c# - ASP.NET MVC : The model item passed into the dictionary is of type 'ClassA' , 但此字典需要类型为 'ClassA' 的模型项

c# - 在标签中显示数学

c# - 计算包含 Unicode 字符的字符串的长度

c# - 在整数列表的列表中查找重复项

wpf - WPF中的复选框网格