GetForegroundWindow() 更改时是否会触发任何系统事件? [英] Is there any system event which fires when GetForegroundWindow() changes?

查看:18
本文介绍了GetForegroundWindow() 更改时是否会触发任何系统事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个应用程序,它需要获取在应用程序运行时一直处于活动状态的窗口名称,目前我每半秒执行一次对 GetForegroundwindow() 的调用,但这几乎不准确,我不知道我想把它设置为 100 毫秒的间隔,我认为这很糟糕而且不准确,有没有系统事件可以为我做到这一点?

I'm developing an application which needs to get the windows names that have been active while the application is running, currently i'm performing a Call to GetForegroundwindow() every half a second, but that's hardly accurate and i don't wanna put it to 100ms interval, i think it's just bad and not accurate, is there any system event that can done that for me?

谢谢.

推荐答案

-- UPDATE --

-- UPDATE --

您可以使用 SetWindowsHookEx 监视当前桌面,但这在托管代码中不起作用.相反,您必须使用 SetWinEventHook.

You could use SetWindowsHookEx to monitor the current Desktop, but this doesn't work in managed code. Instead, you must use SetWinEventHook.

您曾询问如何使用 SetWinEventHook p/Invoke 方法.这是你的答案:

You had asked how to use the SetWinEventHook p/Invoke method. Here is your answer:

首先确保此行位于代码文件的顶部:

First make sure this line is at the top of your code file:

Imports System.Runtime.InteropServices

接下来,声明调用调用所需的所有内容:

Next, declare all that you need to invoke the call:

Public Const WINEVENT_OUTOFCONTEXT = &H0  
'' Events are ASYNC

Public Const WINEVENT_SKIPOWNTHREAD = &H1  
'' Don't call back for events on installer's thread

Public Const WINEVENT_SKIPOWNPROCESS = &H2  
'' Don't call back for events on installer's process

Public Const WINEVENT_INCONTEXT = &H4  
'' Events are SYNC, this causes your dll to be injected into every process

    Public Declare Function SetWinEventHook Lib "user32.dll" _
       (eventMin As UInteger, _
        eventMax As UInteger, _
        hmodWinEventProc As IntPtr, _
        lpfnWinEventProc As IntPtr, _
        idProcess As UInteger, _
        idThread As UInteger, _
        dwflags As UInteger) As IntPtr

    Public Declare Function UnhookWinEvent Lib "user32.dll" _
        (hWinEventHook As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean

    Public Delegate Sub WinEventProc( _
          hWinEventHook As IntPtr, _
          [event] As UInteger, _
          hwnd As IntPtr, _
          idObject As Integer, _
          idChild As Integer, _
          dwEventThread As UInteger, _
          dwmsEventTime As UInteger)

接下来,您将一个函数和一个新变量声明为一个带有该函数地址的函数:

Next, you declare a function and a new variable as a function with an address to that function:

    Public Sub EventCallBack( _
      hWinEventHook As IntPtr, _
      [event] As UInteger, _
      hwnd As IntPtr, _
      idObject As Integer, _
      idChild As Integer, _
      dwEventThread As UInteger, _
      dwmsEventTime As UInteger)

' Some code goes here
    End Sub

    Private eventProc As New WinEventProc(AddressOf EventCallBack)
    Private hEventHook As IntPtr

最后,您将它们联系在一起,并通过以下代码行来创建您的钩子(0 和 255 是任意数字,将它们替换为您想要观看的最小和最大消息代码):

Finally, you tie it all together, and you pass the following line of code to create your hook (0 and 255 are arbitrary numbers, replace them with the min and max message codes you want to watch):

hEventHook = SetWinEventHook(0, _
                             255, _
                             IntPtr.Zero, _
                             Marshal.GetFunctionPointerForDelegate(eventProc), _
                             0, _
                             0, _
                             WINEVENT_OUTOFCONTEXT)

当您的程序完成时,将以下行添加到应用程序终止事件或表单的 Dispose 或 Finalize 方法中:

And when your program has finished add the following line to an Application termination event, or the form's Dispose or Finalize methods:

        UnhookWinEvent(hEventHook)

这在我的测试应用程序上按预期运行.

And this runs as expected on my test application.

这篇关于GetForegroundWindow() 更改时是否会触发任何系统事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆