【问题标题】:How do I get a window caption?如何获得窗口标题?
【发布时间】:2012-10-25 20:35:18
【问题描述】:

我想获得 spy++ 给出的窗口标题(以红色突出显示)

我有获取窗口标题的代码。它通过通过调用GetWindowText 来检查窗口标题的回调枚举所有窗口来做到这一点。如果标题 = "window title | my application" 的窗口是打开的,那么我希望窗口标题包含在枚举中并被发现。

如果窗口计数不为 1,则该函数释放所有窗口句柄并返回 null。在返回 null 的情况下,这被视为失败。在我运行此代码 100 次的一个测试用例中,我的失败计数为 99。

public delegate bool EnumDelegate(IntPtr hWnd, int lParam);

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool IsWindowVisible(IntPtr hWnd);

        [DllImport("user32.dll", EntryPoint = "GetWindowText", ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true)]
        static extern int GetWindowText(IntPtr hWnd, StringBuilder lpWindowText, int nMaxCount);

        [DllImport("user32.dll", EntryPoint = "EnumDesktopWindows", ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true)]
        static extern bool EnumDesktopWindows(IntPtr hDesktop, EnumDelegate lpEnumCallbackFunction, IntPtr lParam);

        static List<NativeWindow> collection = new List<NativeWindow>();

public static NativeWindow GetAppNativeMainWindow()
        {            
            GetNativeWindowHelper.EnumDelegate filter = delegate(IntPtr hWnd, int lParam)
            {
                StringBuilder strbTitle = new StringBuilder(255);
                int nLength = GetNativeWindowHelper.GetWindowText(hWnd, strbTitle, strbTitle.Capacity + 1);
                string strTitle = strbTitle.ToString();

                if (!string.IsNullOrEmpty(strTitle))
                {
                    if (strTitle.ToLower().StartsWith("window title | my application"))
                    {
                        NativeWindow window = new NativeWindow();
                        window.AssignHandle(hWnd);
                        collection.Add(window);
                        return false;//stop enumerating
                    }
                }
                return true;//continue enumerating
            };

            GetNativeWindowHelper.EnumDesktopWindows(IntPtr.Zero, filter, IntPtr.Zero);
            if (collection.Count != 1)
            {
                //log error

                ReleaseWindow();
                return null;
            }                    
            else
                return collection[0];
        }

        public static void ReleaseWindow()
        {
            foreach (var item in collection)
            {
                item.ReleaseHandle();
            }
        }

请注意,我已将 "strTitle" 的所有值流式传输到一个文件中。然后对我的标题中的关键字进行了文本库搜索,但没有成功。为什么枚举在某些情况下找不到我要查找的窗口,而在其他情况下却可以?

【问题讨论】:

  • 您对错误/意外行为“工作非常糟糕”有非常非描述性的解释...考虑添加详细信息。

标签: c# winapi


【解决方案1】:

你是如何运行它 100 次的?...在​​一个紧密的循环中,重新启动应用程序等?

根据您的代码,如果您在循环中运行它而不清除集合,由于错误条件if (collection.Count != 1),您将在找到的第一个条目之后的每个找到的条目上出错。

然后在每次EnumDesktopWindows 调用时,您只需将其添加到集合中,然后返回给调用者。集合永远不会被清除或重置,因此在添加第二个项目后,失败条件为真。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-30
    • 2016-01-29
    • 2010-12-05
    • 2012-04-16
    • 1970-01-01
    • 1970-01-01
    • 2012-03-28
    相关资源
    最近更新 更多