【问题标题】:How would I make my C# program do something each time the current active window changes?每次当前活动窗口更改时,我如何让我的 C# 程序执行某些操作?
【发布时间】:2013-09-16 14:23:45
【问题描述】:

我有一些代码可以截取活动窗口的屏幕截图。我的老板想要每次活动窗口更改时我必须运行的代码。示例:

  • 打开计算器 - 截屏
  • 将焦点切换到记事本 - 已截屏
  • 将焦点切换到 Chrome - 已截屏

我想到的第一个想法是将当前活动窗口的句柄的句柄存储在一个变量中,然后不断检查当前活动窗口的句柄是否与变量中的值相同。有没有办法订阅我的计算机中发生的事件并让它在活动窗口发生变化时告诉我?

【问题讨论】:

  • 我希望你的老板不要用这段代码来监控他的员工!如果是这样,我很高兴我不在那里工作! :P 此外,我认为已经有商业应用程序可以做到这一点。
  • 我在一个网络安全研究小组工作。据我所知,这实际上将用于研究恶意软件。至于已经有商业应用程序可以做到这一点 - 我想有。我自己做的原因是,一旦我完成了这个开发,它就会被添加到我老板正在自己开发的程序中。

标签: c# events window screenshot


【解决方案1】:

请查看 Win32 API 中可用的以下方法,

    SetWinEventHook()
    UnhookWinEvent()

这将帮助您检测窗口更改事件。

示例代码

using System;
using System.Windows;
using System.Windows.Forms;
using System.Runtime.InteropServices;

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

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

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

    const uint EVENT_OBJECT_NAMECHANGE = 0x800C;
    const uint WINEVENT_OUTOFCONTEXT = 0;

    // Need to ensure delegate is not collected while we're using it,
    // storing it in a class field is simplest way to do this.
    static WinEventDelegate procDelegate = new WinEventDelegate(WinEventProc);

    public static void Main()
    {
        // Listen for name change changes across all processes/threads on current desktop...
        IntPtr hhook = SetWinEventHook(EVENT_OBJECT_NAMECHANGE, EVENT_OBJECT_NAMECHANGE, IntPtr.Zero,
                procDelegate, 0, 0, WINEVENT_OUTOFCONTEXT);

        // MessageBox provides the necessary mesage loop that SetWinEventHook requires.
        // In real-world code, use a regular message loop (GetMessage/TranslateMessage/
        // DispatchMessage etc or equivalent.)
        MessageBox.Show("Tracking name changes on HWNDs, close message box to exit.");

        UnhookWinEvent(hhook);
    }

    static void WinEventProc(IntPtr hWinEventHook, uint eventType,
        IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
    {
        // filter out non-HWND namechanges... (eg. items within a listbox)
        if(idObject != 0 || idChild != 0)
        {
            return;
        }
        Console.WriteLine("Text of hwnd changed {0:x8}", hwnd.ToInt32()); 
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-07
    • 1970-01-01
    • 2019-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多