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