2013-12-16 3 views
1

Я разрабатываю приложение, которое должно получить имена окон, которые были активны во время работы приложения, в настоящее время я выполняю вызов GetForegroundwindow() каждые полсекунды, но это вряд ли точно, и я не уверен хочу поставить его на интервал 100 мс, я думаю, что это просто плохо и неточно, есть ли системное событие, которое может сделать это для меня?Есть ли системное событие, которое срабатывает при изменении GetForegroundWindow()?

Спасибо.

ответ

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 

Fin союзник, вы связать все это вместе, и вы передаете следующую строку кода, чтобы создать крюк (0 и 255 произвольные числа, заменить их с минимальным и максимальным кодов сообщений вы хотите смотреть):

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

И когда ваша программа закончит добавить следующую строку в случае прекращения применения или Dispose формы или Доработка методы:

 UnhookWinEvent(hEventHook) 

И это работает, как ожидалось на моем тестовом приложении.

+0

Не забудьте позвонить CallNextHookEx(), когда вы закончите, чтобы другие программы, подключенные к рабочему столу, продолжали функционировать должным образом. –

+0

Ну, я никогда не работал с SetWindowsHookEx или Hooks вообще раньше, и эта ссылка имеет только C++ xyntax, можете ли вы предоставить правильное объявление для того, что я пытаюсь сделать в коде vb.net? Мне кажется, что-то меня смущает, спасибо. – SomeNickName

+0

Конечно, дай мне секунду. –

Смежные вопросы