开发者

How to detect if a message box is visible?

开发者 https://www.devze.com 2022-12-21 11:53 出处:网络
I have 2 forms that are visible. Is it possible to detect if a message box is visible/being displayed on from one of the for开发者_高级运维ms on the other?It is possible, but requires a fairly heavy s

I have 2 forms that are visible. Is it possible to detect if a message box is visible/being displayed on from one of the for开发者_高级运维ms on the other?


It is possible, but requires a fairly heavy serving of P/Invoke. The trick is to enumerate the windows owned by the UI thread and check if one of them is a Windows dialog window. This code will do the trick. I can't guarantee a 100% accuracy, there might be another unmanaged dialog in an app that resembles the message box template.

using System;
using System.Text;
using System.Runtime.InteropServices;

static class MessageBoxFinder {
  public static bool IsPresent() {
    // Enumerate windows to find the message box
    EnumThreadWndProc callback = new EnumThreadWndProc(checkWindow);
    return false == EnumThreadWindows(GetCurrentThreadId(), callback, IntPtr.Zero);
  }
  private static bool checkWindow(IntPtr hWnd, IntPtr lp) {
    // Checks if <hWnd> is a dialog
    StringBuilder sb = new StringBuilder(260);
    GetClassName(hWnd, sb, sb.Capacity);
    if (sb.ToString() != "#32770") return true;
    // Got a dialog, check if the the STATIC control is present
    IntPtr hText = GetDlgItem(hWnd, 0xffff);
    return hText == IntPtr.Zero;
  }
  // P/Invoke declarations
  private delegate bool EnumThreadWndProc(IntPtr hWnd, IntPtr lp);
  [DllImport("user32.dll")]
  private static extern bool EnumThreadWindows(int tid, EnumThreadWndProc callback, IntPtr lp);
  [DllImport("kernel32.dll")]
  private static extern int GetCurrentThreadId();
  [DllImport("user32.dll")]
  private static extern int GetClassName(IntPtr hWnd, StringBuilder buffer, int buflen);
  [DllImport("user32.dll")]
  private static extern IntPtr GetDlgItem(IntPtr hWnd, int item);
}


The simplest way to do this would be to make your own wrapper around MessageBox.Show that tracks calls in a Shared property, then call it exclusively instead of MessageBox.Show and MsgBox.


I figured it out, the easiest answer is using this and looking for the title of the message box:

<System.Runtime.InteropServices.DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function FindWindow(ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
End Function
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号