1

I am looking for a sample of a transparent window (C# Winforms) that I can click-through.

I have found a similar question here, but that does not work the way I want. I want to be able to have controls (Buttons, Treeview, etc) that are clickable and are on top of a transparent window, where its transparent areas are click-through.

EDIT: Sorry for the incomplete post. Think this time I made myself a bit clearer.

I have tried using WS_EX_LAYERED to make the window click-through and it didnt work, then I added WS_EX_TRANSPARENT and it became click-through. Even non keyed colors and non-alpha zero colors became click-trhough. OK. In this MSDN article it says it would be this way:

... if the layered window has the WS_EX_TRANSPARENT extended window style, the shape of the layered window will be ignored and the mouse events will be passed to other windows underneath the layered window.

The problem is with what says a bit before that:

Hit testing of a layered window is based on the shape and transparency of the window. This means that the areas of the window that are color-keyed or whose alpha value is zero will let the mouse messages through.

I dont know what I may have been doing wrong, but simply overriding CreateParams and setting WS_EX_LAYERED does not make the form click-through.

Follows my code:

public class ControlLayer : Form
{
    public ControlLayer()
    {
        this.Visible = true;
        this.TopMost = true; // make the form always on top
        this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; // hidden border
        this.WindowState = FormWindowState.Maximized; // maximized
        this.MinimizeBox = this.MaximizeBox = false; // not allowed to be minimized
        this.MinimumSize = this.MaximumSize = this.Size; // not allowed to be resized
        this.TransparencyKey = this.BackColor = Color.Red; // the color key to transparent, choose a color that you don't use

        Button button = new Button()
            {
                Text = "Test",
                BackColor = Color.White,
                ForeColor = Color.Black,
                Location = new Point(250, 50),
                Size = new Size(75, 23),
            };

        button.Click += (sender, e) => MessageBox.Show("click");

        this.Controls.Add(button);

        // Extend aero glass style on form init
        OnResize(null);
    }

    protected override void OnResize(EventArgs e)
    {
        int[] margins = new int[] { 0, 0, Width, Height };

        // Extend aero glass style to whole form
        DwmExtendFrameIntoClientArea(this.Handle, ref margins);  
    }

    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams cp = base.CreateParams;
            // Set the form click-through
            cp.ExStyle |= 0x80000 /* WS_EX_LAYERED */ | 0x20 /* WS_EX_TRANSPARENT */;
            return cp;
        }
    }

    protected override void OnPaintBackground(PaintEventArgs e)
    {
        // do nothing here to stop window normal background painting
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        e.Graphics.Clear(Color.Red);

        e.Graphics.DrawEllipse(Pens.Orange, 10, 10, 100, 100);
        e.Graphics.FillEllipse(Brushes.Orange, 110, 10, 100, 100);

        e.Graphics.DrawRectangle(Pens.White, 0, 0, this.Size.Width-1, this.Size.Height-1);
    }

    protected override void OnMouseDown(MouseEventArgs e)
    {
        base.OnMouseDown(e);
        MessageBox.Show("layered");
    }

    [DllImport("user32.dll", SetLastError = true)]
    static extern int GetWindowLong(IntPtr hWnd, int nIndex);

    [DllImport("user32.dll")]
    static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

    [DllImport("dwmapi.dll")]
    static extern void DwmExtendFrameIntoClientArea(IntPtr hWnd, ref int[] pMargins);
}

I would like to receive mousedown notifications when I click the filled orange ellipse, receive click notifications from the button, and do not receive notifications when I click the inside of the other ellipse. If you test the form the way it is, it should let the mouse through. If you change CreateParams by removing the | 0X20 (WS_EX_TRANSPARENT) it does not let the mouse events through. My understanding of the microsoft article about Layered Windows is that it should let mouse events through where it has color keyed and alpha value zero.

So, any thoughts?

Community
  • 1
  • 1
Filipe Scur
  • 133
  • 1
  • 9
  • 4
    Please note the difference between that question and yours; that question has details of what the asker already tried. – Andrew Barber May 06 '14 at 19:21
  • Did you try to implement MouseEnter events for your controls, making them focusable? I didn't read the linked topic for too long. – Kilazur May 07 '14 at 07:44
  • The code posted above (+ commenting out WS_EX_TRANSPARENT) works 100% as I understand you to expect. How are you LAUNCHING the overlay form.? It must not have a parent - per your linked article. – John Arlen May 20 '14 at 20:14

0 Answers0