c++ - SetWinEvent on a separate Class -
i have little problem qt , here code :
sessionsnatcher.h:
#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
sessionsnatcher.cpp :
#include "sessionsnatcher.h" sessionsnatcher::sessionsnatcher() { } sessionsnatcher::~sessionsnatcher() { unhookwinevent(hook); } void callback sessionsnatcher::handler(hwineventhook hook , dword event , long idchild , long idobject , dword dweventthread , dword dwmseventtime) { } void sessionsnatcher::run() { hook = setwineventhook(event_system_foreground , event_system_foreground , null , &sessionsnatcher::handler , pid , tid , winevent_outofcontext); } hwnd sessionsnatcher::getcoproductcontrol() { hwnd tpanel = findwindow(l"tpanel" , null); return tpanel; } void sessionsnatcher::setpid(int pid) { pid = pid; } void sessionsnatcher::settid(int tid) { tid = tid; } int sessionsnatcher::getpid() { return pid; } int sessionsnatcher::gettid() { return tid; }
and keep getting error :
d:\tt\sessionsnatcher.cpp:25: error: c2664: 'hwineventhook setwineventhook(dword,dword,hmodule,wineventproc,dword,dword,dword)' : cannot convert argument 4 'void (__stdcall sessionsnatcher::* )(hwineventhook,dword,long,long,dword,dword)' 'wineventproc' there no context in conversion possible
before using "handler" instead of "&sessionsnatcher::handler" had problem saying member , cant used that. cant work out. worked on visual studio when tried , had cast (wineventproc)handler , think since im using separate class cant anymore.
any tips ?
you have fallen victim hidden this
parameter in every non-static class methods. modern solution use std::bind
, won't c-based api or c++ api predates c++11.
the typical solution when std::bind
isn't available free function or static method
- meets prototype need supply,
- maps callback object, and
- invokes desired method on object found in 2.
often win32 api calls have pointer user argument can use make easy: cast pointer sessionsnatcher *
, call function. don't see user argument in wineventproc
's parameter list, you'll have creative , map 1 of event ids or handles wineventproc
provide , uniquely identifies sessionsnatcher
.
or if have 1 sessionsnatcher
can write function use 1 sessionsnatcher
.
here generic example:
#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 in // windows api class test { private: static std::map<int, test*> tests; // our map of id -> test objects int id; // test's id. included proof public: test(int id):id(id) { tests[id] = this; // put in map. in real world test collision first } // function called int func(int p1, int p2) { (void) p1; (void) p2; std::cout << "called func " << id << std::endl; return 0; } // static method can called api static int staticfunc(int id, int p1, int p2) { // object , call non-static method // recommend at() instead of [] because catchable exception // rather crash on null pointer if id unknown. return tests.at(id)->func(p1, p2); } }; // allocating storage static map std::map<int, test*> test::tests; // function mocking api. takes function , identifier used called function int caller(funcp func, int id) { return func(id, 100, 20); // calls function } // tester int main(void) { test a(1); // create test test b(2); // create 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 on unknown id } catch (std::exception &e) { std::cout << "failed call: " << e.what() << std::endl; } }
typical output:
called func 2 called func 1 failed call: map::at
"map::at" isn't of exception message, can converted useful log message. @ rate beats segfault no information.
Comments
Post a Comment