I have a dock like application (a few images in a grid, like a widget) which needs to stay on top of Desktop only when Desktop is the current foreground window.
I'm currently using unmanaged code which I've collected here and there to get the name of the foreground window when the foreground window changes. I'm using Topmost to bring my app window to the front when ActiveWindowTitle() == null
because when switching to Desktop the foreground window becomes null. The problem is that other applications return null windows every now and then too.
How can I make sure that the current foreground window is Desktop and not some other program?
delegate void WinEventDelegate(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime);
private static WinEventDelegate stickyDelegate = null;
[DllImport("user32.dll")]
static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr hmodWinEventProc, WinEventDelegate lpfnWinEventProc, uint idProcess, uint idThread, uint dwFlags);
private const uint WINEVENT_OUTOFCONTEXT = 0;
private const uint EVENT_SYSTEM_FOREGROUND = 3;
[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
public static void ActivateStickToDesktop()
{
stickyDelegate = new WinEventDelegate(WinEventProc);
IntPtr m_hhook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, IntPtr.Zero, stickyDelegate, 0, 0, WINEVENT_OUTOFCONTEXT);
}
private static string GetActiveWindowTitle()
{
const int nChars = 256;
IntPtr handle = IntPtr.Zero;
StringBuilder Buff = new StringBuilder(nChars);
handle = GetForegroundWindow();
if (GetWindowText(handle, Buff, nChars) > 0)
{
return Buff.ToString();
}
return null;
}
public static void WinEventProc(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
{
activeWindowName = GetActiveWindowTitle();
Console.WriteLine("Current active window name: " + activeWindowName);
if(string.IsNullOrEmpty(activeWindowName))
{
AppWindow.Topmost = true;
} else
{
AppWindow.Topmost = false;
SendToBottom(AppWindow);
}
Console.WriteLine("Is Topmost: " + AppWindow.Topmost);
}