Самая верхняя форма, нажав "через" возможно?
Спасибо за предыдущие ответы, которые позволили мне завершить базовый инструмент, который показывает большой красный крест в координатах мыши, чтобы сделать его более заметным. Красный крест - изображение с прозрачным фоном в прозрачной форме. Проблема в том, что вы не можете кликнуть, так как его верхняя часть и центр формы фактически расположены под мышью xy. Есть ли способ, как сделать это пригодным для использования, чтобы крестик все еще отображался на курсоре, но был "кликабельным" до конца?
2 ответа
Вы можете использовать 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 по желанию.
/// <summary>
/// 0: the window is completely transparent ... 255: the window is opaque
/// </summary>
private byte _alpha;
private enum GetWindowLong
{
/// <summary>
/// Sets a new extended window style.
/// </summary>
GWL_EXSTYLE = -20
}
private enum ExtendedWindowStyles
{
/// <summary>
/// Transparent window.
/// </summary>
WS_EX_TRANSPARENT = 0x20,
/// <summary>
/// Layered window. http://msdn.microsoft.com/en-us/library/windows/desktop/ms632599%28v=vs.85%29.aspx#layered
/// </summary>
WS_EX_LAYERED = 0x80000
}
private enum LayeredWindowAttributes
{
/// <summary>
/// Use bAlpha to determine the opacity of the layered window.
/// </summary>
LWA_COLORKEY = 0x1,
/// <summary>
/// Use crKey as the transparency color.
/// </summary>
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);
}