2

子ダイアログ ウィンドウのハンドルを取得しようとしています。FindWindowEx を使用してみましたが、うまくいきませんでした。代わりに、FindWindow が機能しました。

次のコードを使用して、ビジュアル スタジオのオプション ウィンドウで実験を行いました。

IntPtr vsHandle = Process.GetProcessById(vsProcessId).MainWindowHandle; // consistent with spy++'s parent handle of options window

IntPtr optionsHandle = FindWindowEx(vsHandle, IntPtr.Zero, "#32770", "Options"); // returns 0

IntPtr optionsHandle2 = FindWindow("#32770", "Options"); // returns correct handle

私の理解では、FindWindowEx は動作するはずでした。これは子ウィンドウです。

Windows XP を実行していますが、FindWindowEx(vsHandle, IntPtr.Zero, "#32770", null) も使用してみました。うまくいきませんでした。それを取得する唯一の方法は、同じダイアログを持つ2つの親インスタンスを開くことができるため、FindWindowを使用することです。

これは宣言です:

[DllImport("user32.dll")]
Private static extern IntPtr FindWindow(string className, string windowTitle);
[DllImport("user32.dll")]
Private static extern IntPtr FindWindowEx(IntPtr parentHWnd, IntPtr childAfterHWnd,     string className, string windowTitle);

前もって感謝します。

4

1 に答える 1

6

これに対する解決策を見つけました。FindWindowEx が機能しなかった理由は、WS_CHILD スタイルを持つ子ウィンドウでのみ機能し、明らかにダイアログ ウィンドウにはこのスタイルがないためです。そのため、EnumChildWindows も機能しません (私は試しました)。

したがって、醜い解決策は、EnumWindows と GetParent を組み合わせて、ハンドルとテキストを比較することです。

        struct SearchData
        {
            public string WindowText;
            public IntPtr ParentHandle;
            public IntPtr ResultHandle;
        }

        delegate bool EnumWindowsCallback(IntPtr currentWindowHandle, ref SearchData searchData);

        [DllImport("user32.dll")] static extern bool EnumWindows(EnumWindowsCallback callback, ref SearchData searchData);

        [DllImport("user32.dll")] static extern IntPtr GetParent(IntPtr childHandle);

        [DllImport("user32.dll")] static extern void GetWindowText(IntPtr handle, StringBuilder resultWindowText, int maxTextCapacity);


        static bool Callback(IntPtr currentWindowHandle, ref SearchData searchData)
        {
            bool continueEnumeration = true;

            IntPtr currentWindowParentHandle = GetParent(currentWindowHandle);

            if (currentWindowParentHandle == searchData.ParentHandle)
            {
                var windowText = new StringBuilder(1024);
                GetWindowText(currentWindowHandle, windowText, windowText.Capacity);

                if (windowText.ToString() == searchData.WindowText)
                {
                    searchData.ResultHandle = currentWindowHandle;
                    continueEnumeration = false;
                }
            }

            return continueEnumeration;
        }


        IntPtr GetChildWindowHandle(string windowText, IntPtr parentHandle)
        {
            var searchData = new SearchData{ParentHandle=parentHandle, WindowText=windowText};

            EnumWindows(Callback, ref searchData);

            return searchData.ResultHandle;
        }
于 2013-06-05T08:16:06.783 に答える