0

I draw some rectangles using GDI on my transparent form.

The form is fullscreen and always on top. In addition, it's clickable through using this method: Topmost form, clicking "through" possible?

However, drawn rectangles are not clickable through like my form and my app is losing focus everytime I click on them. Also when I hover over them I can see my app cursor (window under the form is a game so it has a custom cursor).

Can you tell me how can I make all controls not focusable and clickable through? Is it possible or I have to use things like DirectX drawing?

I've searched entire web and stackoverflow, used various solutions but nothing worked.

Thanks.

Community
  • 1
  • 1
Frank
  • 1
  • 1

1 Answers1

0

I am not sure I fully understand what you are trying to accomplish, however if you wish to make a control that can receive mouse clicks, but does not 'steal' focus, this is quite possible:

public class Box : Control
{
    public Box()
    {
        // Prevent mouse clicks from 'stealing' focus:
        TabStop = false;
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        DrawText(e.Graphics);
    }

    // Display control text so we know what the button does:
    private void DrawText(Graphics graphics)
    {
        using (var brush = new SolidBrush(this.ForeColor))
        {
            graphics.DrawString(
                this.Text, this.Font, brush,
                new PointF()
                {
                    X = ((float)this.Width / 2f),
                    Y = (((float)this.Height / 2f) - (this.Font.GetHeight(graphics) / 2f))
                },
                new StringFormat()
                {
                    Alignment = StringAlignment.Center
                });
        }
    }
}


This simple control will display as a rectangle which is still able to receive mouse clicks and fire click events, but will not steal focus from other controls on the form (nor the form itself).


Setting a transparency key on the form to its background color will make the rest of the form invisible, such that only the rectangular "buttons" will be visible. This can also be combined with the Opacity property to make what is displayed semi-transparent, but a form with an opacity of exactly zero will not interact with the mouse (by Windows design).


Simply setting the form's TopMost property to true may not be sufficient to keep the window on top of all other windows. You may need to make the following API call from within the form when it is first created (e.g., place in constructor, OnLoad event, etc.):

SetWindowPos(this.Handle, HWND_TOPMOST, 0, 0, 0, 0, (SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW));


MSDN documentation on this function can be found here.

In order to make this call you will need to add the following Windows API declaration to the form class:

[DllImport("user32.dll")]
static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

and also add the following constants:

private const int SWP_NOMOVE     = 0x0002;
private const int SWP_NOSIZE     = 0x0001;
private const int SWP_SHOWWINDOW = 0x0040;

private static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);


I hope this helps!

Lemonseed
  • 1,644
  • 1
  • 15
  • 29