C++ 在单独的类上设置WinEvent
我对Qt有点问题,下面是我的代码: SessionSnatcher.h:C++ 在单独的类上设置WinEvent,c++,qt,C++,Qt,我对Qt有点问题,下面是我的代码: SessionSnatcher.h: #ifndef SESSIONSNATCHER_H #define SESSIONSNATCHER_H #include <Windows.h> #include <QThread> #include <QtCore> #include <QDebug> class SessionSnatcher : public QThread { public: Sessi
#ifndef SESSIONSNATCHER_H
#define SESSIONSNATCHER_H
#include <Windows.h>
#include <QThread>
#include <QtCore>
#include <QDebug>
class SessionSnatcher : public QThread
{
public:
SessionSnatcher();
~SessionSnatcher();
void run();
void SetPID(int pid);
void SetTID(int tid);
int GetPID();
int GetTID();
HWND GetCOProductControl();
private:
//HWND GetCOProductControl();
void CALLBACK SessionSnatcher::handler(HWINEVENTHOOK hook , DWORD event , LONG idChild , LONG idObject , DWORD dwEventThread , DWORD dwmsEventTime);
HWINEVENTHOOK hook;
int PID , TID;
};
#endif // SESSIONSNATCHER_H
现在我不断地发现这个错误:
D:\TT\sessionsnatcher.cpp:25: error: C2664: 'HWINEVENTHOOK SetWinEventHook(DWORD,DWORD,HMODULE,WINEVENTPROC,DWORD,DWORD,DWORD)' : cannot convert argument 4 from 'void (__stdcall SessionSnatcher::* )(HWINEVENTHOOK,DWORD,LONG,LONG,DWORD,DWORD)' to 'WINEVENTPROC'
There is no context in which this conversion is possible
在此之前,我使用的是“handler”而不是“&SessionSnatcher::handler”,但我有一个问题,就是说它是一个成员,不能这样使用。
现在我想不出来了。
当我尝试它时,它在VisualStudio上运行得很好,我所要做的就是像(WINEVENTPROC)处理程序一样进行强制转换,但我认为因为我使用的是单独的类,所以我不能再这样做了
有什么提示吗?您已经成为每个非静态类方法中隐藏的
这个参数的牺牲品。一个现代的解决方案是使用,但这将帮助你没有C + API或C++ API,它比C++ 11早。p>
当std::bind
不可用时,典型的解决方案是使用
满足您需要提供的原型
将回调映射到对象,然后
对在2中找到的对象调用所需的方法
通常Win32 API调用都有一个指向用户参数的指针,您可以使用它来简化操作:只需将指针强制转换为SessionSnatcher*
,然后调用该函数。我在WinEventProc
的参数列表中看不到用户参数,因此您必须创造性地映射其中一个事件ID或句柄WinEventProc
提供并唯一地标识SessionSnatcher
或者,如果您只有一个SessionSnatcher
,则可以编写函数以始终使用该SessionSnatcher
以下是一个通用示例:
#include <iostream>
#include <map>
typedef int (*funcp)(int id, int p1, int p2);
// using typedef instead of using on purpose because that's what'll be in
// the Windows API
class test
{
private:
static std::map<int, test*> tests; // our map of id -> test objects
int id; // this test's id. Only included for proof
public:
test(int id):id(id)
{
tests[id] = this; // put in map. In the real world test for collision first
}
// function that will eventually be called
int func(int p1, int p2)
{
(void) p1;
(void) p2;
std::cout << "Called func for " << id << std::endl;
return 0;
}
// static method that can be called by API
static int staticfunc(int id, int p1, int p2)
{
// look up object and call non-static method
// I recommend at() instead of [] because you get a catchable exception
// rather than a crash over null pointer if id is unknown.
return tests.at(id)->func(p1, p2);
}
};
// allocating storage for static map
std::map<int, test*> test::tests;
// function mocking up API. Takes a function and an identifier used by called function
int caller(funcp func,
int id)
{
return func(id, 100, 20); // just calls the function
}
// tester
int main(void)
{
test a(1); // create a test
test b(2); // create a test
try
{
caller(test::staticfunc, 2); // call test 2 through API
caller(test::staticfunc, 1); // call test 1 through API
caller(test::staticfunc, 10); // throw exception over unknown id
}
catch (std::exception &e)
{
std::cout << "Failed call: " << e.what() << std::endl;
}
}
“map::at”不是什么异常消息,但它可以转换为有用的日志消息。无论如何,它胜过了没有信息的segfault。谢谢你的回答,我尝试过使用一个免费函数进行回调(我希望这就是你的意思),但我还是遇到了同样的错误!但是它与原始的处理程序
函数一起工作,是吗?当前SessionSnatcher::handler
似乎缺少WinEventProc
的第三个参数:HWND-HWND
。同时缺少此参数的自由函数将生成完全相同的错误消息。很抱歉,我之前没有发现。你知道我刚刚尝试从处理程序中删除(WINEVENTPROC),但仍然得到一个错误,顺便说一句,我注意到我从处理程序回调中漏掉了HWND的参数,我不知道我怎么漏掉了它!当前错误:sessionsnatcher.obj:-1:错误:LNK2019:未解析的外部符号\uu imp__SetWinEventHook@28在函数“public:virtualvoid\uu thiscall SessionSnatcher::run(void)”中引用(?run@SessionSnatcher@@UAEXXZ)
您是否已将User32
添加到项目->属性->配置属性->链接器->输入->其他依赖项?哇!虽然这是我经常做的第一件事,但这次我忘了!就这样,只需LIBS+=-luser32
解决了它。谢谢你的帮助@user4581301
#include <iostream>
#include <map>
typedef int (*funcp)(int id, int p1, int p2);
// using typedef instead of using on purpose because that's what'll be in
// the Windows API
class test
{
private:
static std::map<int, test*> tests; // our map of id -> test objects
int id; // this test's id. Only included for proof
public:
test(int id):id(id)
{
tests[id] = this; // put in map. In the real world test for collision first
}
// function that will eventually be called
int func(int p1, int p2)
{
(void) p1;
(void) p2;
std::cout << "Called func for " << id << std::endl;
return 0;
}
// static method that can be called by API
static int staticfunc(int id, int p1, int p2)
{
// look up object and call non-static method
// I recommend at() instead of [] because you get a catchable exception
// rather than a crash over null pointer if id is unknown.
return tests.at(id)->func(p1, p2);
}
};
// allocating storage for static map
std::map<int, test*> test::tests;
// function mocking up API. Takes a function and an identifier used by called function
int caller(funcp func,
int id)
{
return func(id, 100, 20); // just calls the function
}
// tester
int main(void)
{
test a(1); // create a test
test b(2); // create a test
try
{
caller(test::staticfunc, 2); // call test 2 through API
caller(test::staticfunc, 1); // call test 1 through API
caller(test::staticfunc, 10); // throw exception over unknown id
}
catch (std::exception &e)
{
std::cout << "Failed call: " << e.what() << std::endl;
}
}
Called func for 2
Called func for 1
Failed call: map::at