1

我正在从 C# 应用程序中启动一个进程(即 gnuplot.exe)。该进程可以打开一些窗口,对于该进程,我想拦截以下事件:

  • 打开的窗口
  • 关闭窗口
  • 聚焦窗口

基本思路是处理用户是否关闭了某些窗口或更改了活动窗口等,仅指启动的进程。换句话说,我不想处理 gnuplot 窗口未抛出的其他焦点更改或关闭窗口事件。

你能帮助我吗?是否可以避免轮询?我应该参考哪个api?您可以粘贴/链接 mwe 或一些示例代码吗?先感谢您

更新

正如埃里克布朗所建议的那样,我尝试了这种方式,但仍然无法正常工作。你能帮我找出我哪里错了吗?

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System;
    using System.Windows;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    using System.Diagnostics;
    using System.Windows.Automation;

    namespace WinApiEvents
    {
        class Program
        {
            public static void Main()
            {
                Process gp = new Process();
                gp.StartInfo.FileName = @"C:\Software\gp463-win32\gnuplot\bin\gnuplot.exe";
                gp.StartInfo.UseShellExecute = false;
                gp.StartInfo.RedirectStandardInput = true;
                gp.StartInfo.CreateNoWindow = true;
                gp.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                gp.Start();

                AutomationElement targetElement = 
                    AutomationElement.FromHandle(gp.Handle);

                StructureChangedEventHandler structChangedHandler =
                    new StructureChangedEventHandler(OnGnuplotWindowStructureChanged);
                Automation.AddStructureChangedEventHandler(
                    targetElement, TreeScope.Element, structChangedHandler);

                AutomationEventHandler focusHandler =
                    new AutomationEventHandler(OnGnuplotWindowFocusGained);
                Automation.AddAutomationEventHandler(
                    AutomationElement.AutomationFocusChangedEvent, targetElement, TreeScope.Element, focusHandler);

                StringBuilder sb = new StringBuilder();
                sb.AppendLine("set term wxt 1 enhanced");
                sb.AppendLine("plot sin(x)");
                gp.StandardInput.WriteLine(sb.ToString());
                gp.StandardInput.Flush();
                                    sb.Clear();


                sb.AppendLine("set term wxt 2 enhanced");
                sb.AppendLine("plot cos(x)");
                gp.StandardInput.WriteLine(sb.ToString());
                gp.StandardInput.Flush();
                                    sb.Clear();


                sb.AppendLine("set term wxt 3 enhanced");
                sb.AppendLine("plot atan(x)");
                gp.StandardInput.WriteLine(sb.ToString());
                gp.StandardInput.Flush();
                                    sb.Clear();

                MessageBox.Show("Click to exit.");

            }

            private static void OnGnuplotWindowStructureChanged(object src, StructureChangedEventArgs e)
            {
                Console.WriteLine("structure changed window, id=" + e.EventId.ProgrammaticName);
            }

            private static void OnGnuplotWindowFocusGained(object src, AutomationEventArgs e)
            {
                Console.WriteLine("focused window, id=" + e.EventId.ProgrammaticName);
            }

        }
    }

先感谢您

4

1 回答 1

0

我会为此使用UI 自动化框架。

我假设您拥有(或可以获得)gnuplot 窗口句柄。一旦你有了它,你就可以获得那个窗口的 UI 自动化元素,并设置FocusChanged事件处理程序和StructureChanged处理程序来检测子窗口的打开和关闭。WindowClosed事件将告诉您 gnuplot 窗口本身是否关闭。(您也可以在子窗口上使用它,但您仍然需要侦听 StructureChanged 事件以检测子窗口打开事件。)

于 2013-10-09T20:17:26.577 回答