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