2

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"ファイルにストリーミングしたことに注意してください。次に、キャプションのキーワードのテキスト ベース検索を実行しましたが、失敗しました。探しているウィンドウが列挙で見つからない場合と見つかる場合があるのはなぜですか?

4

1 に答える 1

2

どのように 100 回実行しましたか?..タイトなループで、アプリケーションを再起動しましたか?

あなたのコードによると、コレクションをクリアせずにループで実行すると、エラー状態のために最初に見つかったエントリの後に、見つかったすべてのエントリでエラーが発生しますif (collection.Count != 1)

次に、すべてEnumDesktopWindowsの呼び出しでコレクションに追加してから、呼び出し元に戻ります。コレクションは決してクリアまたはリセットされないため、2 番目のアイテムを追加した後、失敗条件は true になります。

于 2012-11-05T23:35:59.840 に答える