C # SetWinEventHook перестает отправлять сообщения при движении мыши - PullRequest
0 голосов
/ 26 июня 2019

В моем приложении C # WPF.

Я устанавливаю хук в окне. Инициализированный обратный вызов:

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

IntPtr hookHandle = SetWinEventHook(EVENT_MIN, EVENT_MAX, IntPtr.Zero, TestCallback, 0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS | WINEVENT_SKIPOWNTHREAD);

и я регистрирую сообщение в обратном вызове

private void TestCallback(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
{
    SetStatus("The eventType is: " + eventType);
}

Однако всякий раз, когда я наводю курсор мыши на пробел в моем окне WPF.

События прекращают отправку полностью.

На возможно не связанной ноте я получил

Ссылка на объект не установлена ​​для экземпляра объекта

Иногда необработанное исключение в одной из системных библиотек.

Почему при наведении мыши происходит сбой победного крючка?

Моя конечная цель - получать событие при каждом создании / отображении нового окна на рабочем столе, чтобы мне не приходилось опрашивать его в цикле, который занимает много ресурсов ЦП.

1 Ответ

0 голосов
/ 26 июня 2019

Я подозреваю, что ваша проблема здесь в том, что сборщик мусора (GC) в конечном итоге собирает делегат TestCallback, который вы передаете неуправляемой функции SetWinEventHook.

Поскольку GC не может отслеживать ссылки, хранящиеся в nativeкод, вы должны хранить ссылку на обратный вызов в поле WinEventDelegate самостоятельно, например:

private IntPtr hookHandle;
private readonly WinEventDelegate callback;

public Window1()
{
    InitializeComponent();
    callback = new WinEventDelegate(TestCallback);
}

protected override void OnInitialized(EventArgs e)
{
    hookHandle = SetWinEventHook(EVENT_MIN, EVENT_MAX, IntPtr.Zero, callback, 0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS | WINEVENT_SKIPOWNTHREAD);
}

//...

Обратите внимание, что вы также должны отслеживать IntPtr, возвращаемую функцией SetWinEventHook, чтобывозможность передать его методу UnhookWinEvent всякий раз, когда вы хотите удалить хук, например, когда окно закрыто.

...