Самая верхняя форма, нажав "через" возможно? - PullRequest
10 голосов
/ 06 октября 2009

Спасибо за предыдущие ответы, которые позволили мне завершить базовый инструмент, который показывает большой красный крест в координатах мыши, чтобы сделать его более заметным. Красный крест - это изображение с прозрачным фоном в прозрачной форме. Проблема в том, что вы не можете кликнуть, так как его верхняя часть и центр формы фактически расположены под мышью xy. Есть ли способ, как сделать это пригодным для использования, чтобы крестик по-прежнему отображался на курсоре, но был «кликабелен» до конца?

Ответы [ 2 ]

10 голосов
/ 06 октября 2009

Вы можете использовать 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;
0 голосов
/ 22 марта 2014

Чтобы предоставить более подробную / прокомментированную версию, которая также использует 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);
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...