我正在使用 C# 表单创建一个程序,该程序充当另一个应用程序窗口顶部的叠加层。整个表单几乎是一个透明的 PictureBox,它横跨整个区域并在这里和那里绘制形状。
现在,我只能与覆盖完全透明的底层窗口进行交互,如何使非透明区域不拦截鼠标事件?
为清楚起见,这是一个屏幕截图:
Skype 是底层应用程序。我的叠加层绘制了蓝色(和灰色)框。我需要能够单击框下方的链接。
不幸的是,我没有要显示的代码,因为我不确定程序的哪个部分实际上处理了这样的事情。
谢谢。
我正在使用 C# 表单创建一个程序,该程序充当另一个应用程序窗口顶部的叠加层。整个表单几乎是一个透明的 PictureBox,它横跨整个区域并在这里和那里绘制形状。
现在,我只能与覆盖完全透明的底层窗口进行交互,如何使非透明区域不拦截鼠标事件?
为清楚起见,这是一个屏幕截图:
Skype 是底层应用程序。我的叠加层绘制了蓝色(和灰色)框。我需要能够单击框下方的链接。
不幸的是,我没有要显示的代码,因为我不确定程序的哪个部分实际上处理了这样的事情。
谢谢。
您可以尝试订阅形状单击事件,然后通过一些 Windows API 将事件转发到“覆盖”窗口。如果您有一个指向应用程序主窗口的指针(您可以通过 Process 对象自己启动它,或者通过其他方式获得它),您可以简单地将鼠标事件发送到该窗口。
这是一个获取屏幕当前点并将其发送到 Skype 的第一个实例的示例。
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
[StructLayout(LayoutKind.Explicit)]
struct LParamLocation
{
[FieldOffset(0)]
int Number;
[FieldOffset(0)]
public short X;
[FieldOffset(2)]
public short Y;
public static implicit operator int(LParamLocation p)
{
return p.Number;
}
}
private void Form1_MouseClick(object sender, MouseEventArgs e)
{
var process = Process.GetProcessesByName("skype");
LParamLocation points = new LParamLocation();
points.X = (short)PointToScreen(e.Location).X;
points.Y = (short)PointToScreen(e.Location).Y;
SendMessage(process[0].MainWindowHandle, 0x201, 0, points); //MouseLeft down message
SendMessage(process[0].MainWindowHandle, 0x202, 0, points); //MouseLeft up message
}
或者,您可以尝试添加一个窗口样式来告诉它通过所有鼠标事件。
[DllImport("user32.dll")]
static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("user32.dll")]
static extern int GetWindowLong(IntPtr hWnd, int nIndex);
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
int style = GetWindowLong(Handle, -20);
style |= 0x00000020; // Enables Pass-Through of events
style |= 0x00080000; // Enables Pass-Through to layered windows
SetWindowLong(Handle, -20, style);
}