Introduction
To create a topmost window is simple, thanks to window style WS_EX_TOPMOST or Form.TopMost propertie in .NET. But unfortunately the counter part style BOTTOMMOST is not out of the box.
Background
An application window Z order, along with other parameters, can be enforced at runtime by modifying WINDOWPOS structure received with WM_WINOWPOSCHANGING message.
Using the code
To create a bottommost window, on the window message WM_WINOWPOSCHANGING add this code:
((LPWINDOWPOS)lParam)->hwndInsertAfter = HWND_BOTTOM;
This works in C or C++. For .NET, the code can be included in a dll and used inside the window procedure.
The resulted window behave like it is embedded in the wallpaper.
dll code (C):
__declspec(dllexport) void Bottommost(LPARAM lParam);
void Bottommost(LPARAM lParam)
{
((LPWINDOWPOS)lParam)->hwndInsertAfter = HWND_BOTTOM;
}
C# code:
using System.Runtime.InteropServices;
[DllImport("mydll.dll")]
static extern void Bottommost(IntPtr lParam);
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
protected override void WndProc(ref Message Message)
{
if (Message.Msg == 0x46)
{
Bottommost(Message.LParam);
}
base.WndProc(ref Message);
}
VB code:
Imports System.Runtime.InteropServices
<DllImport("mydll.dll")>
Shared Function Bottommost(lParam As IntPtr) As Boolean
End Function
<System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name:="FullTrust")>
Protected Overrides Sub WndProc(ByRef Message As Message)
If (Message.Msg = &H46) Then
Bottommost(Message.LParam)
End If
MyBase.WndProc(Message)
End Sub
Win32 code (C, C++):
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
switch(Message)
{
case WM_WINDOWPOSCHANGING:
((LPWINDOWPOS)lParam)->hwndInsertAfter = HWND_BOTTOM;
return 0L;
break;
}
return DefWindowProc(hwnd, Message, wParam, lParam);
}