6

我想检测另一个进程是否说 process.exe 当前正在显示一个对话框?有没有办法在 C# 中做到这一点?

看看我能不能得到对话框的句柄。我尝试过 Spy++ 的查找窗口工具,当我尝试将查找器拖动到对话框顶部时,它不会突出显示对话框,而是填充详细信息并提及 AppCustomDialogBox 并提及句柄编号

请告知我如何以编程方式检测到..

谢谢,

4

2 回答 2

5

当应用程序显示一个对话框时,Windows 操作系统的(对我来说非常烦人的)行为是将新创建的窗口显示在所有其他窗口之上。因此,如果我假设您知道要监视哪个进程,那么检测新窗口的一种方法是设置一个 windows 挂钩:

    delegate void WinEventDelegate(IntPtr hWinEventHook, uint eventType,
    IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime);

    [DllImport("user32.dll")]
    public static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr
       hmodWinEventProc, WinEventDelegate lpfnWinEventProc, uint idProcess,
       uint idThread, uint dwFlags);

    [DllImport("user32.dll")]
    public static extern bool UnhookWinEvent(IntPtr hWinEventHook);

    // Constants from winuser.h
    public const uint EVENT_SYSTEM_FOREGROUND = 3;
    public const uint WINEVENT_OUTOFCONTEXT = 0;

    //The GetForegroundWindow function returns a handle to the foreground window.
    [DllImport("user32.dll")]
    public static extern IntPtr GetForegroundWindow();
    // For example, in Main() function
    // Listen for foreground window changes across all processes/threads on current desktop
    IntPtr hhook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, IntPtr.Zero,
            new WinEventDelegate(WinEventProc), 0, 0, WINEVENT_OUTOFCONTEXT);


    void WinEventProc(IntPtr hWinEventHook, uint eventType,
    IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
    {     
          IntPtr foregroundWinHandle = GetForegroundWindow();
          //Do something (f.e check if that is the needed window)
    }

    //When you Close Your application, remove the hook:
    UnhookWinEvent(hhook);

我没有为对话框明确尝试该代码,但对于单独的进程,它运行良好。请记住,该代码不能在 Windows 服务或控制台应用程序中运行,因为它需要消息泵(Windows 应用程序有)。你必须创建一个自己的。

希望这可以帮助

于 2012-07-02T07:55:44.683 回答
3

由于模式对话框通常会禁用父窗口,因此您可以枚举进程的所有顶级窗口并查看它们是否已使用该IsWindowEnabled()功能启用。

于 2012-07-02T10:26:57.680 回答