我有一种情况,我希望使用TightVNC远程访问客户端,以允许他们在第三方应用程序上执行某些任务。
我只想让他们点击屏幕的某些部分,例如禁用“关闭”按钮,禁用一些区域。我想知道是否有一种方法可以在Windows上以编程方式拦截鼠标按下事件,如果他们在特定区域上按下鼠标,只返回而不是执行点击?或者,如果有办法覆盖始终位于所选区域屏幕前方的透明背景?
我的应用程序是用WPF c#编写的,所以如果有任何实例可以实现这一点,我们将不胜感激。我试过创建一些虚拟透明窗口,问题是,当用户点击其他应用程序时,他们会转到后台,从而击败目标。
提前致谢。
答案 0 :(得分:1)
从技术上讲,您应该能够attach global hooks获取鼠标事件,并在需要时禁止它们。 globalmousekeyhook是可用于为鼠标事件分配处理程序的库之一,并通过设置e.Handled = true
来有条件地抑制它们。
如果您需要仅针对特定应用程序阻止鼠标事件 - 那么您可以覆盖其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);
}
}
如果你需要阻止鼠标点击特定的现有正在运行的进程,只要目标应用程序使用基于Windows窗体的UI或WPF的.NET,那么你可以inject your .NET assemblies into the existing process / application覆盖它的{{ 1}} 选项2 中所述的行为。您也可以参考此sample code来获取相同内容。