当 MessageBox 有图标时如何获取其文本?

Jam*_*mes 6 c# user32 findwindowex

我正在努力尝试关闭特定的内容MessageBox(如果它根据标题和文本显示)。MessageBox当没有图标时我可以使用它。

IntPtr handle = FindWindowByCaption(IntPtr.Zero, "Caption");
if (handle == IntPtr.Zero)
    return;

//Get the Text window handle
IntPtr txtHandle = FindWindowEx(handle, IntPtr.Zero, "Static", null);
int len = GetWindowTextLength(txtHandle);

//Get the text
StringBuilder sb = new StringBuilder(len + 1);
GetWindowText(txtHandle, sb, len + 1);

//close the messagebox
if (sb.ToString() == "Original message")
{
    SendMessage(new HandleRef(null, handle), WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
}
Run Code Online (Sandbox Code Playgroud)

MessageBox当显示没有像下面这样的图标时,上面的代码工作得很好。

MessageBox.Show("Original message", "Caption");
Run Code Online (Sandbox Code Playgroud)

但是,如果它包含如下所示的图标(来自MessageBoxIcon),则它不起作用;GetWindowTextLength返回 0 并且什么也没有发生。

MessageBox.Show("Original message", "Caption", MessageBoxButtons.OK, MessageBoxIcon.Information);
Run Code Online (Sandbox Code Playgroud)

我最好的猜测是需要更改第三个和/或第四个参数FindWindowEx,但我不确定要传递什么。或者也许需要更改第二个参数以跳过图标?我不太确定。

Ahm*_*eed 4

看起来,当 MessageBox 有图标时,FindWindowEx返回第一个子项的文本(在本例中是图标),因此长度为零。现在,在这个答案的帮助下,我想到了迭代孩子们,直到找到一个带有文本的孩子。这应该有效:

IntPtr handle = FindWindowByCaption(IntPtr.Zero, "Caption");

if (handle == IntPtr.Zero)
    return;

//Get the Text window handle
IntPtr txtHandle = IntPtr.Zero;
int len;
do
{
    txtHandle = FindWindowEx(handle, txtHandle, "Static", null);
    len = GetWindowTextLength(txtHandle);
} while (len == 0 && txtHandle != IntPtr.Zero);

//Get the text
StringBuilder sb = new StringBuilder(len + 1);
GetWindowText(txtHandle, sb, len + 1);

//close the messagebox
if (sb.ToString() == "Original message")
{
    SendMessage(new HandleRef(null, handle), WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
}
Run Code Online (Sandbox Code Playgroud)

显然,您可以调整它以适应您的特定情况(例如,继续迭代,直到找到您正在寻找的实际文本),尽管我认为带有文本的孩子可能永远是第二个:

Spy++ 中的消息框