最顶层的forms,点击“通过”可能吗?

感谢您之前的答案,这些答案使我能够完成在鼠标坐标中显示大红十字的基本工具,以便更加明显。 红十字是透明forms的透明背景图像。 问题是你无法点击,因为它的最顶层和窗体的中心实际上是鼠标xy。 有没有什么方法可以使这个可用,以便交叉仍然显示在光标上但“可点击”通过?

您可以使用SetWindowLong设置WS_EX_TRANSPARENT窗口样式:

如果分层窗口具有WS_EX_TRANSPARENT扩展窗口样式,则将忽略分层窗口的形状,并将鼠标事件传递到分层窗口下的其他窗口。

CodeProject有本文详细介绍了该技术。 虽然它在VB.NET中,但转换为C#应该很容易。

我过去使用过以下代码:

public enum GWL { ExStyle = -20 } public enum WS_EX { Transparent = 0x20, Layered = 0x80000 } public enum LWA { ColorKey = 0x1, Alpha = 0x2 } [DllImport("user32.dll", EntryPoint = "GetWindowLong")] public static extern int GetWindowLong(IntPtr hWnd, GWL nIndex); [DllImport("user32.dll", EntryPoint = "SetWindowLong")] public static extern int SetWindowLong(IntPtr hWnd, GWL nIndex, int dwNewLong); [DllImport("user32.dll", EntryPoint = "SetLayeredWindowAttributes")] public static extern bool SetLayeredWindowAttributes(IntPtr hWnd, int crKey, byte alpha, LWA dwFlags); protected override void OnShown(EventArgs e) { base.OnShown(e); int wl = GetWindowLong(this.Handle, GWL.ExStyle); wl = wl | 0x80000 | 0x20; SetWindowLong(this.Handle, GWL.ExStyle, wl); SetLayeredWindowAttributes(this.Handle, 0, 128, LWA.Alpha); } 

但它也是从其他地方复制而来的。 这里的重要部分是在OnShown方法中。 虽然我不得不承认这一行

 wl = wl | 0x80000 | 0x20; 

有点神秘,设置WS_EX_LAYERED和WS_EX_TRANSPARENT扩展样式。

你也可以设置它

 wl = wl | WS_EX.Layered | WS_EX.Transparent; 

提供更详细/评论的版本,它也使用TransparencyKey作为透明度键(不是上面版本的黑色),并且可以根据需要设置_alpha。

  ///  /// 0: the window is completely transparent ... 255: the window is opaque ///  private byte _alpha; private enum GetWindowLong { ///  /// Sets a new extended window style. ///  GWL_EXSTYLE = -20 } private enum ExtendedWindowStyles { ///  /// Transparent window. ///  WS_EX_TRANSPARENT = 0x20, ///  /// Layered window. http://msdn.microsoft.com/en-us/library/windows/desktop/ms632599%28v=vs.85%29.aspx#layered ///  WS_EX_LAYERED = 0x80000 } private enum LayeredWindowAttributes { ///  /// Use bAlpha to determine the opacity of the layered window. ///  LWA_COLORKEY = 0x1, ///  /// Use crKey as the transparency color. ///  LWA_ALPHA = 0x2 } [DllImport("user32.dll", EntryPoint = "GetWindowLong")] private static extern int User32_GetWindowLong(IntPtr hWnd, GetWindowLong nIndex); [DllImport("user32.dll", EntryPoint = "SetWindowLong")] private static extern int User32_SetWindowLong(IntPtr hWnd, GetWindowLong nIndex, int dwNewLong); [DllImport("user32.dll", EntryPoint = "SetLayeredWindowAttributes")] private static extern bool User32_SetLayeredWindowAttributes(IntPtr hWnd, int crKey, byte bAlpha, LayeredWindowAttributes dwFlags); protected override void OnShown(EventArgs e) { base.OnShown(e); //Click through int wl = User32_GetWindowLong(this.Handle, GetWindowLong.GWL_EXSTYLE); User32_SetWindowLong(this.Handle, GetWindowLong.GWL_EXSTYLE, wl | (int)ExtendedWindowStyles.WS_EX_LAYERED | (int)ExtendedWindowStyles.WS_EX_TRANSPARENT); //Change alpha User32_SetLayeredWindowAttributes(this.Handle, (TransparencyKey.B << 16) + (TransparencyKey.G << 8) + TransparencyKey.R, _alpha, LayeredWindowAttributes.LWA_COLORKEY | LayeredWindowAttributes.LWA_ALPHA); }