GetForegroundWindow()更改时是否会触发任何系统事件?

时间:2013-12-16 19:01:18

标签: vb.net

我正在开发一个应用程序,它需要获取在应用程序运行时已经处于活动状态的Windows名称,目前我每隔半秒执行一次对GetForegroundwindow()的调用,但这几乎不准确,我不知道我想把它放到100毫秒间隔,我认为它只是坏的而且不准确,是否有任何系统事件可以为我做到这一点?

感谢。

1 个答案:

答案 0 :(得分:2)

- 更新 -

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

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

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

Imports System.Runtime.InteropServices

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

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)

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

    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是任意数字,用你想要观察的最小和最大消息代码替换它们):

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

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

        UnhookWinEvent(hEventHook)

这在我的测试应用程序中按预期运行。