我首先要说的是,我对pinvoke的体验非常有限。我也很少了解C ++。但这是我的情况......
我在C#中有一个程序,它使用pinvoke从C ++中获取SendMessage
和FindWindow
之类的函数。它查找窗口的名称,获取句柄等。现在工作正常。我会把代码放低一点。
现在我有一种情况,我想在其中一个子窗口上找到一个“按钮”。我有{strong>实际子窗口的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
,我可以看到它有一个句柄。它看起来并不特别。
答案 0 :(得分:3)
您需要执行以下操作:
FindWindow
以查找顶级窗口。使用类名或窗口标题或两者来标识它。FindWindowEx
以查找子窗口。将父窗口传递为hwndParent
,将NULL
传递为hwndChildAfter
。再次使用类名或窗口标题或两者来标识子窗口。因此,举个例子,使用Spy ++表示法考虑以下层次结构:
Window 00001000 "My MainForm window title" "MainFormWindowClass" | -- Window 00002000 "Panel container" "PanelWindowClass" | -- Window 00003000 "Click me!" "ButtonWindowClass"
您可以通过以下调用序列找到它:
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#。