We use SetWindowPos with HWND_TOPMOST rather than just setting the WS_EX_TOPMOST extended style because:
- Immediate Effect:
SetWindowPosimmediately repositions the window in the Z-order - Atomic Operation: Combines style change + repositioning in one API call
- No Activation: Using
SWP_NOACTIVATEflag prevents stealing focus
// Our approach (preferred)
SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
// Alternative (less reliable)
int exStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
SetWindowLong(hWnd, GWL_EXSTYLE, exStyle | WS_EX_TOPMOST);Windows maintains windows in a Z-order list (doubly-linked list internally):
[Front] → HWND_TOPMOST windows → HWND_NOTOPMOST windows → [Back]
When we call SetWindowPos(hWnd, HWND_TOPMOST, ...):
- Window is moved to the topmost region of the Z-order
- All topmost windows stay above all non-topmost windows
- Within topmost region, order is determined by
SetWindowPoscalls
foreach (var window in managedWindows)
{
SetWindowPos(window.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
}Result: All managed windows now have topmost flag, but relative order may be wrong.
// Sort by priority: [1, 2, 3, 4, ...]
var sorted = windows.OrderBy(w => w.Priority);
// Apply in reverse order (lowest priority first)
for (int i = count - 1; i >= 0; i--)
{
SetWindowPos(sorted[i].Handle, HWND_TOPMOST, ...);
}Why reverse? Each SetWindowPos call places the window at the front of the topmost region. By processing from lowest to highest priority, the highest priority window is placed last (on top).
foreach (var window in sorted) // Now in priority order
{
SetWindowPos(window.Handle, IntPtr.Zero, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
}Purpose: Ensures strict ordering by bringing each window to front in priority sequence.
- Too Fast (< 100ms): Excessive CPU usage, may interfere with user interactions
- Too Slow (> 1000ms): User may notice windows briefly appearing out of order
- 500ms: Sweet spot balancing responsiveness and efficiency
CPU Impact:
Interval | CPU Usage | Response Time | UX Impact
---------|-----------|---------------|----------
100ms | ~5% | Excellent | Choppy animations
500ms | ~1-2% | Good | Imperceptible
1000ms | <1% | Fair | Noticeable delays
Problem: DirectX/Vulkan games in exclusive fullscreen bypass DWM (Desktop Window Manager).
Technical:
- Exclusive mode renders directly to display, bypassing window manager
WS_EX_TOPMOSTflag is ignored- No other windows can appear on top
Detection:
// Check if window is fullscreen
RECT rect;
GetWindowRect(hWnd, out rect);
bool isFullscreen = (rect.Width == screenWidth && rect.Height == screenHeight);
// Alternative: Check window style
int style = GetWindowLong(hWnd, GWL_STYLE);
bool hasCaption = (style & WS_CAPTION) != 0; // Fullscreen usually lacks captionWorkarounds:
- Game in borderless windowed mode → topmost works
- Use window hooks (advanced, requires injecting DLL)
- Accept limitation and document it
Problem: Windows running with higher integrity level cannot be controlled by lower-level apps.
UIPI (User Interface Privilege Isolation):
High Integrity (Admin) ← Cannot be controlled by → Medium Integrity (User)
├─ UAC Dialogs ├─ Normal Applications
├─ Admin Apps ├─ AlwaysOnTop Manager
└─ System Processes └─ Browsers, etc.
Solution: Run AlwaysOnTop Manager as Administrator
<!-- Add to app.manifest -->
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />Trade-off:
- ✓ Can manage admin windows
- ✗ UAC prompt on every launch
- ✗ Breaks drag-and-drop from normal apps
Recommended: Default to normal mode, provide "Run as Admin" shortcut for power users.
Windows 10+ Virtual Desktops:
- Each virtual desktop has its own window set
- Windows on Desktop 2 are "cloaked" when viewing Desktop 1
Detection via DWM API:
const int DWMWA_CLOAKED = 14;
int result = DwmGetWindowAttribute(hWnd, DWMWA_CLOAKED, out bool cloaked, sizeof(bool));
// Cloaked reasons:
// 0 = Not cloaked
// 1 = Cloaked by app (UWP suspend)
// 2 = Cloaked by shell (virtual desktop)
// 4 = Cloaked by another window (?)Our Implementation:
public static bool IsWindowCloaked(IntPtr hWnd)
{
try
{
DwmGetWindowAttribute(hWnd, DWMWA_CLOAKED, out bool cloaked, sizeof(bool));
return cloaked;
}
catch
{
return false; // Assume not cloaked if API fails
}
}Filter Strategy: Exclude cloaked windows from enumeration to show only current desktop windows.
Challenge: User has 3 monitors with different windows on each.
Windows Behavior:
- Topmost windows are topmost across all monitors
- Z-order is global, not per-monitor
User Expectation:
- "Priority 1 window on Monitor 1 should stay above other windows on Monitor 1"
- But NOT cover windows on Monitor 2
Reality: Cannot achieve true per-monitor Z-order with standard Win32 API.
Partial Solution:
- Group windows by monitor
- Assign priority ranges: Monitor 1 (1-10), Monitor 2 (11-20), etc.
- Document that topmost is global
Advanced Solution (not implemented):
- Use window hooks to detect focus changes
- Dynamically adjust topmost flag based on active monitor
- Complexity: High, Performance: Impact moderate
Scenario: User applies topmost to a window, then minimizes it.
What Happens:
bool isMinimized = IsIconic(hWnd); // Returns true
// Window is minimized BUT:
GetWindowLong(hWnd, GWL_EXSTYLE) & WS_EX_TOPMOST // Still has topmost flagResult: When restored, window immediately appears on top (correct behavior).
Edge Case: Clicking taskbar button to restore
1. User clicks taskbar
2. Window begins restoring (animation)
3. Window appears briefly below other windows
4. Our monitor (500ms later) detects it
5. Re-applies topmost → window jumps to front
Improvement: React to WM_WINDOWPOSCHANGED message instead of polling.
Scenario: User rapidly clicks Apply → Remove → Apply
Thread Safety:
private readonly object _lockObject = new object();
public void EnforceZOrder()
{
lock (_lockObject) // Critical section
{
// Z-order manipulation here
}
}Why Needed:
- Background timer thread runs
EnforceZOrder()every 500ms - UI thread calls
EnforceZOrder()when user clicks Apply - Without lock → concurrent
SetWindowPoscalls → undefined behavior
Deadlock Prevention:
- All locks acquired in same order
- No nested locks
- Lock scope is minimal (only Z-order operations)
Scenario: Browser tab changes → window title updates.
Our Approach:
public bool UpdateWindowInfo(WindowInfo windowInfo)
{
windowInfo.Title = GetWindowTitle(windowInfo.Handle);
windowInfo.LastUpdated = DateTime.Now;
}UI Refresh:
- Title is bound to
WindowInfo.Titleproperty - Implements
INotifyPropertyChanged - UI automatically updates when property changes
Performance: Title retrieval is fast (~0.1ms per window).
Managed Windows List:
private readonly List<WindowInfo> _managedWindows; // Typically < 10 itemsMemory per WindowInfo:
IntPtr Handle = 8 bytes
string Title ≈ 50 bytes (average)
string ProcessName ≈ 20 bytes
int Priority = 4 bytes
bool flags × 3 = 3 bytes
DateTime = 8 bytes
-----------------------------------
Total ≈ 93 bytes per window
For 100 managed windows: ~9.3 KB (negligible).
Enumeration Efficiency:
EnumWindows((hWnd, lParam) => {
// Early exits reduce API calls
if (!IsWindowVisible(hWnd)) return true; // ~60% of windows filtered here
if (string.IsNullOrWhiteSpace(GetWindowTitle(hWnd))) return true; // ~20% more
// Expensive operations only for valid windows
GetWindowThreadProcessId(...);
Process.GetProcessById(...);
}, IntPtr.Zero);Benchmark (typical Windows 11 system):
- Total windows: ~200
- Visible windows: ~80
- Windows with titles: ~30
- Enumeration time: ~50ms
Our Choice: Timer (500ms)
private readonly Timer _monitorTimer = new Timer(500);Alternative: WH_CALLWNDPROC hook
SetWindowsHookEx(WH_CALLWNDPROC, CallWndProc, IntPtr.Zero, GetCurrentThreadId());
IntPtr CallWndProc(int nCode, IntPtr wParam, IntPtr lParam)
{
// Intercept all window messages
if (nCode >= 0)
{
CWPSTRUCT msg = Marshal.PtrToStructure<CWPSTRUCT>(lParam);
if (msg.message == WM_WINDOWPOSCHANGED)
{
// React immediately to Z-order changes
EnforceZOrder();
}
}
return CallNextHookEx(IntPtr.Zero, nCode, wParam, lParam);
}Comparison:
| Approach | Pros | Cons |
|---|---|---|
| Timer | Simple, safe, no injection | 500ms latency |
| Hooks | Instant response | Crashes if buggy, global hooks require DLL |
Decision: Timer provides sufficient UX with zero crash risk.
- Data Binding:
INotifyPropertyChanged→ automatic UI updates - Modern UI: XAML styling, animations, vector graphics
- MVVM Pattern: Clean separation of concerns (future maintainability)
- Composition: Easier to create complex layouts
Trade-off: Larger binary size (WPF runtime ~30 MB added to self-contained exe).
WinRT Pros: Modern API, fluent design WinRT Cons:
- Sandboxed → cannot enumerate arbitrary windows
- Limited Win32 interop
- Requires Windows 10 1809+
Win32 Pros: Full system access, works on Windows 7+ Win32 Cons: C++/COM complexity
Our Choice: Win32 via P/Invoke (best of both worlds).
Alternatives:
- Framework-Dependent: User must install .NET → friction
- Self-Contained: Includes runtime → larger size, no dependencies
Decision: Prioritize user experience over file size.
- Target users may not be developers
- One-click run without installation
- 75 MB is acceptable for modern systems
[DllImport("user32.dll")]
static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
// Register Ctrl+Alt+T
RegisterHotKey(this.Handle, HOTKEY_ID, MOD_CONTROL | MOD_ALT, VK_T);
// Handle in WndProc
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_HOTKEY)
{
// Toggle topmost for foreground window
IntPtr hWnd = GetForegroundWindow();
ToggleTopmostForWindow(hWnd);
}
base.WndProc(ref m);
}public class AppSettings
{
public List<ManagedWindowSettings> Windows { get; set; }
public int MonitorInterval { get; set; } = 500;
public bool StartMinimized { get; set; }
}
// Serialize to JSON
var json = JsonSerializer.Serialize(settings);
File.WriteAllText(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"AlwaysOnTop", "settings.json"), json);private NotifyIcon _trayIcon;
void InitializeTrayIcon()
{
_trayIcon = new NotifyIcon
{
Icon = SystemIcons.Application,
Text = "Always On Top Manager",
Visible = true
};
_trayIcon.DoubleClick += (s, e) => { this.Show(); this.WindowState = WindowState.Normal; };
}- Save/load named profiles (e.g., "Coding Setup", "Gaming Setup")
- Auto-apply profiles based on running applications
- Exclude by process name
- Include only specific window classes
- Regex pattern matching for titles
- No DLL injection used
- No code execution in other processes
- All operations use documented Win32 APIs
- No network access
- No telemetry
- No external dependencies
- All data in memory only (no disk writes by default)
Some antivirus software may flag the app due to:
- EnumWindows: Enumerating all windows (common in keyloggers)
- SetWindowPos: Manipulating other processes' windows
- Single-file executable: Packed format can resemble malware
Mitigation:
- Sign executable with code signing certificate
- Submit to Microsoft SmartScreen (via Windows Dev Center)
- Publish source code on GitHub for transparency
[Test]
public void SetWindowTopmost_ValidWindow_ReturnsTrue()
{
// Arrange
IntPtr hWnd = CreateTestWindow();
// Act
bool result = WindowsApi.SetWindowTopmost(hWnd, true);
// Assert
Assert.IsTrue(result);
Assert.IsTrue(WindowsApi.IsWindowTopmost(hWnd));
// Cleanup
DestroyWindow(hWnd);
}- Launch Notepad
- Apply topmost via AlwaysOnTop Manager
- Launch Calculator
- Verify Notepad stays above Calculator
- Close Notepad
- Verify app removes it from managed list
[Benchmark]
public void BenchmarkEnumeration()
{
var stopwatch = Stopwatch.StartNew();
var windows = _enumerator.GetAllWindows();
stopwatch.Stop();
Assert.Less(stopwatch.ElapsedMilliseconds, 100, "Enumeration took too long");
}#if DEBUG
Console.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] Setting window {hWnd} to topmost");
#endifUse built-in Windows tools:
# PowerShell: List all windows with handles
Add-Type @"
using System;
using System.Runtime.InteropServices;
using System.Text;
public class WindowInfo {
[DllImport("user32.dll")]
public static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
}
"@
[WindowInfo]::EnumWindows({
param($hWnd, $lParam)
Write-Host "HWND: $hWnd"
return $true
}, [IntPtr]::Zero)Document Version: 1.0
Last Updated: January 2026
Audience: Developers, Security Auditors, Power Users