#c #class #winapi #callback
#c #класс #winapi #обратный вызов
Вопрос:
Я использую SetWinEventHook()
функцию, подобную приведенной в примере MSDN: https://msdn.microsoft.com/en-us/library/windows/desktop/dd373640 (v=против85).aspx.
Как и в примере выше, для обработки событий я использую функцию ОБРАТНОГО ВЫЗОВА HandleWinEvent()
.
Я довольно новичок в использовании функций такого типа: я понял, что эта функция вызывается
асинхронно, а параметры передаются автоматически.
Теперь я хочу получить доступ к списку внутри функции.
Я объявил эту функцию внутри своего класса:
Class Example
{
private: std::list <int> events;
void CALLBACK HandleWinEvent(HWINEVENTHOOK hook, DWORD event, HWND hwnd,
LONG idObject, LONG idChild,
DWORD dwEventThread, DWORD dwmsEventTime)
{
events.add((int)event);
};
void Initialize_Hook()
{
cout << "Initialization Thread messages..........." << endl;
CoInitialize(NULL);
g_hook = SetWinEventHook(
EVENT_SYSTEM_FOREGROUND, EVENT_OBJECT_FOCUS, // Range of events (4 to 5).
NULL, // Handle to DLL.
HandleWinEvent, // The callback.
0, 0, // Process and thread IDs of interest (0 = all)
WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS); // Flags.
}
}
и я просто хочу добавить идентификатор события в свой список, но он не распознает events
. Есть способ заставить функцию узнать, что это за список?
Более конкретно, я объявил функцию ОБРАТНОГО ВЫЗОВА в файле .cpp, но я должен объявить ее как void CALLBACK HandleWinEvent(...)
вместо void CALLBACK Example::HandleWinEvent(...)
, как я всегда делаю, потому что второй вариант выдает ошибку в SetWinEventHook()
.
Комментарии:
1. Обратному вызову не разрешается быть методом экземпляра. Итак, спросите себя, где он собирается найти ваш экземпляр?
2. Я не знаю. Например, я могу передать через SetWinEventHook указатель на список, но я изобретаю (также потому, что в прототипе нет указателя для передачи). Как я могу это сделать?
3. Используйте либо thunk, либо единственную глобальную переменную, содержащую ваш экземпляр
4. Глобальная переменная для списка? Извините, но я не знаю, что означает thunk.
5. Google скажет вам, что такое thunk в этом контексте. По сути, вы генерируете код во время выполнения, который содержит указатель экземпляра.
Ответ №1:
Следуя подсказке, предоставленной @David Heffernan, я решил объявить список как static
. Затем я написал статический метод для получения списка.
Таким образом, внутри функции ОБРАТНОГО вызова я мог бы получить ссылку на список:
private: static std::list <int> events;
std::list <int>amp; getList() {
return *events;
}
// the callback is now declared in Example.cpp file
void CALLBACK HandleWinEvent(HWINEVENTHOOK hook, DWORD event, HWND hwnd,
LONG idObject, LONG idChild,
DWORD dwEventThread, DWORD dwmsEventTime)
{
Example::getList().add((int)event);
};
(Я не пробовал с int
, со списком Example2
класса сработало).