tags:

views:

78

answers:

1

Thank you for previous answers that enabled to me complete the basic tool that shows large red cross in the mouse coordinates in order to let be more visible. The red cross is an image with transparent background in the transparent form. The problem is that you cannot click through, since its topmost and the center of form is actually positioned to mouse xy. Is there any way how to make this usable in order to have the cross still displayed on the cursor but "clickable" through?

+1  A: 

You can use SetWindowLong to set the WS_EX_TRANSPARENT window style:

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 the other windows underneath the layered window.

CodeProject has this article detailing the technique. Though it's in VB.NET it should be easy to convert to C#.

I have used the following code in the past:

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);
}

but it also was copied from somewhere else. The important lines here are in the OnShown method. Though I have to admit that the line

wl = wl | 0x80000 | 0x20;

is a little cryptic, setting the WS_EX_LAYERED and WS_EX_TRANSPARENT extended styles.

You can probably also set it like

wl = wl | WS_EX.Layered | WS_EX.Transparent;
Joey
Please could you provide me a bit more details? Im not experienced in this low level API, thank you!
Petr
Thank you very much, this is really awesome place, such quick answers.
Petr
With the SetLayeredWindowAttributes the transparency, previously set in VS Designer, get lost and the form was semitransparent.But disabling this line doesnt affect the "clickable" effects, it works great!
Petr
BTW, why I need to set transparency? It works great with //added before SetLayeredWindowAttributes(this.Handle, 0, 128, LWA.Alpha);
Petr
Yes, you can remove that part. It's just that I needed a partially transparent window at that time. I think the important part for WS_EX_TRANSPARENT to work is that you set the WS_EX_LAYERED window style too, even though you don't have to set a transparency value.
Joey