试图获得“;按钮“;从儿童窗口
本文关键字:窗口 按钮 | 更新日期: 2024-06-14 08:57:50
我首先要说的是,我使用pinvoke的经验非常有限。我对C++也知之甚少。但我的情况是。。。
我在C#中有一个程序,它使用pinvoke从C++中获得SendMessage
和FindWindow
等函数。它会查找窗口的名称、获取句柄等。这现在很好。我会把代码放低一点。
现在我有一种情况,我想在其中一个儿童窗口上找到一个"按钮"。我有实际子窗口的IntPtr
,至少我认为是。我对什么是窗口和什么不是窗口感到非常困惑。
我正在尝试使用EnumChildWindows
、FindWindowByCaption
和FindWindowEx
等来浏览所有的孩子并找到这个按钮。我可以用Spy++获得它的"标题",但将其提供给FindWindowByCaption
不会产生任何效果。
这是实际查找父窗口的代码。如果它令人困惑,我很抱歉,它是在非常旧的软件上运行的。
这一切都在C#中,使用pInvoke。我试着用这种方法先得到我想要的按钮。。
FindWindowByCaption(IntPtr.Zero, "{{Caption as shown by Spy++}}");
这不起作用,尽管我给了它正确的标题。所以我试试这个。。。在本例中,Handle
是包含我要查找的按钮的父窗口的IntPtr
。
// create a small counter so that we do not try to check
// too many windows and crash the program.
int i = 0;
var previous = new Window();
var current = new Window();
do {
current =
new Window(
InteropServices.FindWindowEx(
Handle,
previous.Handle,
null, null
)
);
if (current == IntPtr.Zero)
break;
// add current to list
// continue
previous = current; // never finds the right button, either.
++i;
} while (i < 500);
但即便如此,我想要的控制权也从未找到。有人能帮我吗?这变得非常令人沮丧。我可以在Spy++中看到Caption
,我可以看到它有一个句柄。它似乎没有什么特别之处。
您需要执行以下操作:
- 调用
FindWindow
查找顶级窗口。使用类名或窗口标题,或同时使用这两个名称来标识它 - 反复调用
FindWindowEx
查找子窗口。将父窗口作为hwndParent
传递,将NULL
作为hwndChildAfter
传递。再次使用类名或窗口标题,或同时使用两者来标识子窗口 - 最终,您将下降父/子窗口层次结构,直到到达目标窗口
因此,举个例子,考虑以下层次结构,使用Spy++表示法:
Window 00001000"我的MainForm窗口标题"MainFormWindowClass"|--Window 00002000"面板容器"PanelWindowClass"|--Window 00003000"点击我!"按钮WindowClass"
您可以通过以下调用序列找到这一点:
HWND main = FindWindow("MainFormWindowClass", NULL); // just use class name
HWND panel = FindWindowEx(main, NULL, "PanelWindowClass", "Panel container");
HWND button = FindWindowEx(panel, NULL, "ButtonWindowClass", "Click me!");
请注意,我用C++编写了这篇文章,以避免将p/invoke混淆。为了一个简洁的例子,我也省略了所有的错误检查。你显然会检查错误。
我建议您将Spy++放在手边,并尝试编写一个简单的C++控制台应用程序来定位您的窗口。一旦您知道了对FindWindow
和FindWindowEx
的调用顺序,就可以将它们转换为C#。