You can use an AppBar
Minimal test with an AppBar at Top of the screen, 24 pixels height
For this test, don't forget to add a Button to close the window to remove the AppBar space with ABM_REMOVE
public partial class Form1 : Form
{
[DllImport("Shell32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern uint SHAppBarMessage(uint dwMessage, ref APPBARDATA pData);
public const int ABM_NEW = 0x00000000;
public const int ABM_REMOVE = 0x00000001;
public const int ABM_QUERYPOS = 0x00000002;
public const int ABM_SETPOS = 0x00000003;
public const int ABM_GETSTATE = 0x00000004;
public const int ABM_GETTASKBARPOS = 0x00000005;
public const int ABM_ACTIVATE = 0x00000006; // lParam == TRUE/FALSE means activate/deactivate
public const int ABM_GETAUTOHIDEBAR = 0x00000007;
public const int ABM_SETAUTOHIDEBAR = 0x00000008; // this can fail at any time. MUST check the result
// lParam = TRUE/FALSE Set/Unset
// uEdge = what edge
public const int ABM_WINDOWPOSCHANGED = 0x0000009;
public const int ABM_SETSTATE = 0x0000000a;
public const int ABM_GETAUTOHIDEBAREX = 0x0000000b; // multimon aware autohide bars
public const int ABM_SETAUTOHIDEBAREX = 0x0000000c;
// these are put in the wparam of callback messages
public const int ABN_STATECHANGE = 0x0000000;
public const int ABN_POSCHANGED = 0x0000001;
public const int ABN_FULLSCREENAPP = 0x0000002;
public const int ABN_WINDOWARRANGE = 0x0000003; // lParam == TRUE means hide
// flags for get state
public const int ABS_AUTOHIDE = 0x0000001;
public const int ABS_ALWAYSONTOP = 0x0000002;
public const int ABE_LEFT = 0;
public const int ABE_TOP = 1;
public const int ABE_RIGHT = 2;
public const int ABE_BOTTOM = 3;
[StructLayout(LayoutKind.Sequential)]
public struct APPBARDATA
{
public uint cbSize;
public IntPtr hWnd;
public uint uCallbackMessage;
public uint uEdge;
public RECT rc;
public IntPtr lParam; // message specific
}
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
public RECT(int Left, int Top, int Right, int Bottom)
{
left = Left;
top = Top;
right = Right;
bottom = Bottom;
}
}
[DllImport("User32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern uint RegisterWindowMessage(string lpString);
[DllImport("User32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
public const int WS_EX_TOPMOST = 0x00000008;
public const int WS_EX_TOOLWINDOW = 0x00000080;
public const int WS_EX_APPWINDOW = 0x00040000;
public Form1()
{
InitializeComponent();
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.button1.Top = 0;
}
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= (WS_EX_TOOLWINDOW | WS_EX_TOPMOST);
cp.ExStyle -= (WS_EX_APPWINDOW);
return cp;
}
}
uint nAppBarCallBackMessage = 0;
private void Form1_Load(object sender, EventArgs e)
{
APPBARDATA abd = new APPBARDATA();
abd.cbSize = (uint)Marshal.SizeOf(abd);
abd.hWnd = this.Handle;
nAppBarCallBackMessage = RegisterWindowMessage("Test CallBack");
abd.uCallbackMessage = nAppBarCallBackMessage;
SHAppBarMessage(ABM_NEW, ref abd);
int nX = 0, nY = 0;
int nWidth = Screen.PrimaryScreen.Bounds.Width, nHeight = 24;
abd.rc.left = nX;
abd.rc.top = nY;
abd.rc.right = nWidth;
abd.rc.bottom = nHeight;
abd.uEdge = ABE_TOP;
// In case program exited without ABM_REMOVE, BP in SHAppBarMessage, then stop to remove the AppBar space
// abd.rc.bottom = 0;
SHAppBarMessage(ABM_SETPOS, ref abd);
MoveWindow(this.Handle, nX, nY, nWidth, nHeight, true);
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
APPBARDATA abd = new APPBARDATA();
abd.hWnd = this.Handle;
SHAppBarMessage(ABM_REMOVE, ref abd);
}
private void button1_Click(object sender, EventArgs e)
{
this.Close();
}
}