Thursday, 5 September 2013

C# click-through is not working - is SetWindowLong the proper technique?

C# click-through is not working - is SetWindowLong the proper technique?

I've been struggling with this a lot and have looked at several
stackoverflow posts that recommend this as the correct procedure:
Transparent window layer that is click-through and always stays on top
In my code, I'm following this technique almost exactly. And yet, my code
is not working and I'm a little confused to why. I'm wondering if I'm
using the wrong procedure? To be clear, my desired effect is for the user
to click my form and to access something underneath it. For example, I am
running on top of visual studio. If I try to click the app, I click visual
studio instead.
UPDATE:
When I call my code, one of two things happens (depending on where I call
the setwindowlong method):
The window does not draw
The window draws, but is clickable
Option 1 happens when I run the code right after initializecomponent
Option 2 happens when I run it before initializecomponent
Here is the complete code to draw my form before anything else:
[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("user32.dll")]
static extern bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey,
byte bAlpha, uint dwFlags);
public frmPhoneQueueViewer()
{
InitializeComponent();
// Set the form click-through
int initialStyle = GetWindowLong(this.Handle, -20);
SetWindowLong(this.Handle, -20, initialStyle | 0x80000 | 0x20);
//Get height of taskbar to exclude it, then bind to lower right of
screen
int nTaskBarHeight = Screen.PrimaryScreen.Bounds.Bottom
-Screen.PrimaryScreen.WorkingArea.Bottom;
Rectangle workingArea = Screen.GetWorkingArea(this);
this.Location = new Point(Screen.PrimaryScreen.Bounds.Right -
this.Size.Width, workingArea.Bottom - Size.Height +
nTaskBarHeight);
this.TopMost = true;
this.FormBorderStyle = FormBorderStyle.None;
this.ControlBox = false;
this.Text = string.Empty;
this.ShowInTaskbar = false;
PopulatePhoneQueueData();
}

No comments:

Post a Comment