关于子对话视窗上的c#:FindWindowEx

FindWindowEx on child dialog window

我正在尝试获取子对话框窗口的句柄。 我试过使用FindWindowEx,但没有用。 相反,FindWindow确实起作用。

我使用以下代码对Visual Studio的"选项"窗口进行了实验:

1
2
3
4
5
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)。 没用 似乎唯一的获取方法是使用FindWindow,因为打开具有相同对话框的两个父实例并不足够。

这是声明:

1
2
3
4
[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);

提前致谢。


我找到了解决方案。 FindWindowEx不起作用的原因是,它仅适用于具有WS_CHILD样式的子窗口,而对话框窗口显然不具有此样式。 这就是为什么EnumChildWindows也不起作用的原因(我已经尝试过了)。

因此,丑陋的解决方案是将EnumWindows与GetParent结合使用以比较句柄和文本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
        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;
        }