C#获取顶层窗口标题与进程名:非焦点顶层窗口的获取方法咨询
获取非焦点状态下的顶层(Top-most)窗口信息
Absolutely! The GetForegroundWindow() API only returns the window with active input focus, but since your XYZ app is marked as top-most (it stays on top even when not focused), you can retrieve its details using a mix of Windows API functions to check window styles and enumerate top-level windows.
核心思路
Top-most windows are identified by the WS_EX_TOPMOST extended window style. We'll need to:
- Enumerate all top-level windows (children of the desktop window)
- Filter out visible windows that have the
WS_EX_TOPMOSTstyle - Extract details like title, class name, or HWND for the target window (XYZ)
完整C#代码示例
Here's a reusable helper class with methods to find all top-most windows, or target a specific one by title:
using System; using System.Runtime.InteropServices; using System.Text; public class TopMostWindowHelper { // Window style constants private const int WS_EX_TOPMOST = 0x00000008; private const int GWL_EXSTYLE = -20; private const uint GW_HWNDNEXT = 2; // Import required Windows APIs [DllImport("user32.dll", SetLastError = true)] private static extern int GetWindowLongPtr(IntPtr hWnd, int nIndex); [DllImport("user32.dll")] private static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd); [DllImport("user32.dll")] private static extern bool IsWindowVisible(IntPtr hWnd); [DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)] private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount); [DllImport("user32.dll")] private static extern IntPtr GetDesktopWindow(); [DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)] private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount); /// <summary> /// Enumerates all visible top-most windows and prints their details /// </summary> public static void ListAllTopMostWindows() { IntPtr currentWindow = GetWindow(GetDesktopWindow(), 0); // Start with first top-level window while (currentWindow != IntPtr.Zero) { if (IsWindowVisible(currentWindow)) { // Check if the window has the top-most extended style int exStyle = GetWindowLongPtr(currentWindow, GWL_EXSTYLE); if ((exStyle & WS_EX_TOPMOST) != 0) { // Fetch window title StringBuilder windowTitle = new StringBuilder(256); GetWindowText(currentWindow, windowTitle, windowTitle.Capacity); // Fetch window class name StringBuilder className = new StringBuilder(256); GetClassName(currentWindow, className, className.Capacity); Console.WriteLine($"Top-most Window:"); Console.WriteLine($" HWND: {currentWindow}"); Console.WriteLine($" Title: {windowTitle}"); Console.WriteLine($" Class Name: {className}\n"); } } // Move to the next top-level window currentWindow = GetWindow(currentWindow, GW_HWNDNEXT); } } /// <summary> /// Finds a specific top-most window by its title (case-insensitive) /// </summary> /// <param name="targetTitle">Title of the window to find</param> /// <returns>HWND of the target window, or IntPtr.Zero if not found</returns> public static IntPtr FindTopMostWindowByTitle(string targetTitle) { IntPtr currentWindow = GetWindow(GetDesktopWindow(), 0); while (currentWindow != IntPtr.Zero) { if (IsWindowVisible(currentWindow)) { int exStyle = GetWindowLongPtr(currentWindow, GWL_EXSTYLE); if ((exStyle & WS_EX_TOPMOST) != 0) { StringBuilder windowTitle = new StringBuilder(256); GetWindowText(currentWindow, windowTitle, windowTitle.Capacity); if (windowTitle.ToString().Equals(targetTitle, StringComparison.OrdinalIgnoreCase)) { return currentWindow; } } } currentWindow = GetWindow(currentWindow, GW_HWNDNEXT); } return IntPtr.Zero; } }
代码说明
GetDesktopWindow(): Retrieves the desktop window, which is the parent of all top-level windows.GetWindow(): Iterates through all top-level windows using theGW_HWNDNEXTflag to move to the next window.IsWindowVisible(): Skips hidden system windows that you don't care about.GetWindowLongPtr(): Checks the window's extended style to confirm it's top-most (usingWS_EX_TOPMOST).GetWindowText()/GetClassName(): Extracts identifying details to match your XYZ app.
使用示例
To get XYZ's HWND directly (assuming you know its title):
IntPtr xyzWindow = TopMostWindowHelper.FindTopMostWindowByTitle("XYZ"); if (xyzWindow != IntPtr.Zero) { // Do something with the window handle, e.g., get position/size, send messages, etc. }
注意事项
- Some system windows (like Task Manager) also use the
WS_EX_TOPMOSTstyle, so filtering by title or class name is essential to target your XYZ app. - Use
GetWindowLongPtrinstead ofGetWindowLongfor 64-bit compatibility to avoid pointer truncation issues. - You can add error handling with
Marshal.GetLastWin32Error()if you need to debug API calls.
内容的提问来源于stack exchange,提问作者Naveen Kumar
相关产品推荐
相关产品推荐

