0

I have succesfully tested the following code with VB Messageboxes from a Microsoft Word template that have no notification icon. I am able to get the text and close the messagebox.

However, when the messageboxes have an icon, sb.ToString() returns an empty string.

Also, GetWindowTextLength(txtHandle) returns 0. The text handle is identified correctly because the Messageboxes closes at the SendMessage command.

I have used Spy++ to analyze the messagebox. Here is a screenshot of the output. enter image description here

From what it looks like, there are two windows with class name "Statis" and the code seems to take the first one. I need to get the "O eroare la salvarea documentului in baza de date." text.

What should I change in order to get this text?

[DllImport("user32.dll")] static extern int FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")] static extern int SendMessage(int hWnd, int wMsg, int wParam, int lParam);
[DllImport("user32.dll", SetLastError = true)] static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] static extern int GetWindowTextLength(IntPtr hWnd);
public static void KillMbox()
{
    for (int h = 0; h == 0;)
    {
        Thread.Sleep(1000);
        h = FindWindow(null, "Microsoft Word");
        if (h != 0)
        {
            IntPtr hAsIntPtr = new IntPtr(h); 
            IntPtr txtHandle = FindWindowEx(hAsIntPtr, IntPtr.Zero, "Static", null);
            int len = GetWindowTextLength(txtHandle);
            StringBuilder sb = new StringBuilder();
            GetWindowText(txtHandle, sb, len + 1);
            SendMessage(h, 16, 0, 0);
            MessageBox.Show(sb.ToString());
        }
    }
}
Cosmin
  • 411
  • 4
  • 16
  • Have you used a window spy to examine the structure of these different message boxes so you know how to adjust your code? – Caius Jard Nov 21 '19 at 07:35
  • @CaiusJard, my work computer has no administration rights so I am not able to install applications. – Cosmin Nov 21 '19 at 07:39
  • Actually you cannot get information in the form where it says that the icon is vbCritical or vbInformation . What you can do the most is this https://stackoverflow.com/questions/32122679/getting-icon-of-modern-windows-app-from-a-desktop-application/36495656#36495656 – Soumen Mukherjee Nov 21 '19 at 07:40
  • What are you actually doing? What is your overall task? Example "I am trying to automate with Word to perform 1000 mail merge operations" -> I want to know if this is an XY problem and there is maybe a better way to solve your original problem rather than solving this "got to find a way to kill the message boxes that appear when I'm trying to automate word to send 1000 mail merges" – Caius Jard Nov 21 '19 at 08:00
  • Will a human read these messages or are you hoping to dealing with them programmatically? I ask because it may be possible, once you found a window, to screenshot it and react to the contents of the bitmap rather than the text – Caius Jard Nov 21 '19 at 08:04
  • @CaiusJard, I want to deal with them programmatically, with scenarios based on the messsages that are displayed. I have used the windows spy script provided by AHK but it doesn't seem to help me. – Cosmin Nov 21 '19 at 08:10
  • @CaiusJard, I have used the Spy++ app and updated the question with info provided by it. – Cosmin Nov 23 '19 at 08:23

1 Answers1

0

I was able to get the content of the MessageBox using by referring to the second window with class name Static, using an index.

The following answer helped me -> https://stackoverflow.com/a/5685715/10468231

public void KillMbox()
{
        IntPtr h = FindWindow("#32770", "Microsoft Word"); 

        if (h != IntPtr.Zero)
        {
            IntPtr TextMesaj = FindWindowByIndex(h, 2);
            int len = GetWindowTextLength(TextMesaj);
            StringBuilder sb = new StringBuilder(len + 1);
            GetWindowText(TextMesaj, sb, len + 1);
            SendMessage(new HandleRef(null, h), 16, IntPtr.Zero, IntPtr.Zero);
            MessageBox.Show(sb.ToString());   
        }
}

static IntPtr FindWindowByIndex(IntPtr hWndParent, int index)
{
        if (index == 0)
            return hWndParent;
        else
        {
            int ct = 0;
            IntPtr result = IntPtr.Zero;
            do
            {
                result = FindWindowEx(hWndParent, result, "Static", null);
                if (result != IntPtr.Zero)
                    ++ct;
            }
            while (ct < index && result != IntPtr.Zero);
            return result;
        }
    }
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Cosmin
  • 411
  • 4
  • 16