You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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_TOPMOST style
  • 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 the GW_HWNDNEXT flag 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 (using WS_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_TOPMOST style, so filtering by title or class name is essential to target your XYZ app.
  • Use GetWindowLongPtr instead of GetWindowLong for 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 14:17:31