Access object field in a CALLBACK function (WINAPI - C++) - c++

I'm using the SetWinEventHook() function like in the example by MSDN: https://msdn.microsoft.com/en-us/library/windows/desktop/dd373640(v=vs.85).aspx.
Like in the example above, to handle events I use the CALLBACK functionHandleWinEvent().I'm pretty new in using this type of function: what I've understood is that this function is called
asynchronously and parameters are passed automatically. Now I want to access to the list inside the function. I declared this function inside my class:
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.
}
}
and I simply want to add the event's identifier to my list, but it doesn't recognize events. There's a way to make the function know what the list is?More specifically, I declared the CALLBACK function in the .cpp file, but I have to declare it as void CALLBACK HandleWinEvent(...) instead of void CALLBACK Example::HandleWinEvent(...) as I always do because the second choice gives an error in SetWinEventHook().

Following the hint provided by #David Heffernan, I decided to declare the list as static. Then I wrote a static method to get the list.In this way, inside the CALLBACK function I could get the reference to the list:
private: static std::list <int> events;
std::list <int>& 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);
};
(I didn't try with int, with a list of Example2 class worked).

Related

C++ How does a relation of pointers and class members work?

in the example below I've made a very simple class and there are a couple of things which I don't understand.
class Keylogger {
public:
void Hook();
void Unhook();
private:
HHOOK hHook;
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
};
void Keylogger::Hook() {
HINSTANCE hInstance = GetModuleHandle(NULL);
hHook = SetWindowsHookEx(WH_KEYBOARD_LL, this->LowLevelKeyboardProc, hInstance, 0);
}
void Keylogger::Unhook() {
UnhookWindowsHookEx(hHook);
}
If I understand correctly, all members of a class are local (in stack) when the class object is defined and destroyed once operations ends. (function exits).
In the example above, I'm trying to assign HHOOK to a private member hHook, thus receiving an error: "non-standard syntax; use '&' to create a pointer to member"
Why can't a variable just be assigned that way and what does the error exactly mean?
In which case should pointers be created to members and how exactly should those be used with this->? Thanks!
In this call:
hHook = SetWindowsHookEx(WH_KEYBOARD_LL, this->LowLevelKeyboardProc, hInstance, 0);
you are trying to pass a member function : this->LowLevelKeyboardProc as if this was a free function (non-member). This will not work, member functions are not like free functions. You can call them only using class instance pointer and pointer to member function.
This API function SetWindowsHookEx requires free function, so you should either make LowLevelKeyboardProc static, or move it outside the class.

How to incorporate a pImpl Interface while also allowing WndProc to interact with it?

Currently developing a 2-D game-dev environment with a Wrapper/GameEngine class combination in Win32 (C/C++ language). As it stands, I use the Wrapper to set up and initialize all items with the Window as well as to initialize the GameEngine class before entering the message loop.
To do this, I redirect Windows messages sent to WndProc(...) to HandleEvent(...) methods found in both the Wrapper and the GameEngine classes. This is done via static, private shared_ptrs found in the Wrapper class. One such pointer points to the contained GameEngine, and the other points to the Wrapper itself.
An example WndProc function may look like this:
LRESULT CALLBACK WndProc(HWND hWindow, UINT msg, WPARAM wParam, LPARAM lParam)
{
// Initialize via wrapper, else route to engine
switch (msg)
{
case WM_CREATE:
return GEN::Wrapper::GetWrapper()->HandleEvent(hWindow, msg, wParam, lParam);
break;
default:
return GEN::Wrapper::GetEngine()->HandleEvent(hWindow, msg, wParam, lParam) // DefWndProc called from this HandleEvent
}
}
Where GetEngine() and GetWrapper() are static accessor methods that return their respective shared_ptr.
What I'd like to do is incorporate the pImpl idiom in this design. That is, I want to create a wrapper interface class that removes implementation details from the specific wrapper being used. One of the problems ailing me is that I need (or at least think I need) that static accessor method for the Wrapper in question. This is because as I have it each derived Wrapper initializes the window in a game-specific way, and WndProc needs to know where to forward that initial message, as one can see in the code above. Of course, the static method is tied to the wrapper class, so GetWrapper() would be impossible to put into that interface.
Essentially, I want to have the WrapperInterface declared like this:
class WrapperInterface
{
public:
static std::tr1::shared_ptr<WrapperInterface> // factory function
create_Wrapper(...); // returns pImpl
// ... Pure virtuals here
};
Derive Wrapper publicly from WrapperInterface, and then implement a primitive version of create_Wrapper more or less like this:
std::tr1::shared_ptr<WrapperInterface> WrapperInterface::create_Wrapper(...)
{
return std::tr1::shared_ptr<WrapperInterface>(new Wrapper(...));
}
so I can put this line in WinMain:
std::tr1::shared_ptr<WrapperInterface>
Wrapper(WrapperInterface::create(...));
And still have WndProc be able to forward messages to the Interface methods?
Update:
A thought occurred to me to store a static pointer to the WrapperInterface itself and have create_wrapper set that member variable to whatever wrapper the interface is using. I then eliminated Wrapper's static pointer altogether and made the Engine pointer non-static. This somehow feels like cheating, though, as now I'm introducing a private member variable into the interface, albeit a static one. Any thoughts or tips on redesign methods without storing statics would be great!
In any event, thank you all for reading and any advice you may give.
You can associate a pointer to the actual Wrapper object with the window that it creates for itself. To do that, you can either:
use RegisterClass/Ex() with the cbWndExtra field set to sizeof(Wrapper*) to reserve extra memory inside the HWND, then use SetWindowLong/Ptr() with the nIndex parameter set to 0 to store the Wrapper* pointer value inside the allocated memory:
WNDCLASS wc;
wc.lpszClassName = TEXT("MyWrapperWindow");
wc.cbWndExtra = sizeof(Wrapper*);
...
RegisterClass(&wc);
hwnd = CreateWindow(TEXT("MyWrapperWindow"), ...);
SetWindowLongPtr(hwnd, 0, (LONG_PTR) this);
use SetWindowsLong/Ptr() with the nIndex parameter set to GWLP_USERDATA:
hwnd = CreateWindow(...);
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) this);
use SetProp() with a custom name in the lpString parameter:
static const LPCTSTR szMyProp = TEXT("MyProp");
hwnd = CreateWindow(...);
SetProp(hwnd, szMyProp, (HANDLE) this);
use SetWindowSubclass() with the Wrapper* pointer passed in its dwRefData parameter:
hwnd = CreateWindow(...);
SetWindowSubclass(hwnd, &MySubClassProc, 1, (DWORD_PTR) this);
In cases 1-3, at least (not sure about case 4), you can alternatively pass the Wrapper* pointer in the lpParam parameter of CreateWindow/Ex() and then call one of the mentioned functions inside your window procedure's WM_NCCREATE or WM_CREATE handler:
hwnd = CreateWindow(..., this);
case WM_CREATE:
{
Wrapper *pThis = (Wrapper*) ((LPCREATESTRUCT)lParam)->lpCreateParams;
// SetWindowLongPtr(hwnd, 0, (LONG_PTR) pThis);
// SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) pThis);
// SetProp(hwnd, szMyProp, (HANDLE) pThis);
break;
}
For all other messages, your window/subclass procedure can extract the Wrapper* pointer when needed. This way, it does not need to use any global statics to hunt for the object:
GetWindowLong/Ptr() with the nIndex parameter set to 0:
Wrapper *pThis = (Wrapper*) GetWindowLongPtr(hwnd, 0);
GetWindowsLong/Ptr() with the nIndex parameter set to GWLP_USERDATA:
Wrapper *pThis = (Wrapper*) GetWindowLongPtr(hwnd, GWLP_USERDATA);
GetProp(), passing the same lpString pointer that was passed to SetProp() (important!):
Wrapper *pThis = (Wrapper*) GetProp(hwnd, szMyProp);
the subclass procedure's dwRefData parameter:
Wrapper *pThis = (Wrapper*) dwRefData;

WinApi SetTimer cannot compile

I need timer to start function every 1 second.
I have tried SetTimer, my code:
const UINT_PTR TIMER_ID = 1000;
DWORD DownloadThread()
{
SetTimer(NULL, TIMER_ID, 1000, (TIMERPROC)DownloadSpeedCounter);
/*some stuff*/
}
void DownloadSpeedCounter()
{
/*some stuff*/
}
I cannot compile this code and get error C2440: 'type cast' : cannot convert from 'overloaded-function' to 'TIMERPROC'
Also it is class member method.
This is because you are trying to use a normal function as an application-defined callback function. What you are probably looking for is this application-defined callback function which could look like this:
VOID CALLBACK DownloadSpeedCounter(
HWND hwnd, // handle to window for timer messages
UINT message, // WM_TIMER message
UINT idTimer, // timer identifier
DWORD dwTime) {
/* some stuff */
}
For additional information on using callback functions for timers see this article.
One of the problems is that TIMERPROC functions should look like this: typedef VOID (CALLBACK* TIMERPROC)(HWND, UINT, UINT_PTR, DWORD); So your method definition should look like this:
VOID CALLBACK DownloadSpeedCounter(HWND, UINT, UINT_PTR, DWORD);
Also, as this is a method, not just a function, it must be static. So it is calling like static but to access private non-static data may be used this technique.

Passing User Data with SetTimer

I am calling SetTimer in a function of a Class.
SetTimer(NULL, 0, 10000, (TIMERPROC) TimerCallBack);
Where TimerCallBack is:
static VOID CALLBACK TimerCallBack(HWND, UINT, UINT, DWORD)
Now my need is to call one of the method of class which initiated timer, since TimerCallBack is static it has no access to the class object anymore.
I cant find any way to pass object pointer along with the SetTimer so that I can receive it back on Callback function.
Is there any other way to achieve this, if its not supported using SetTimer then which other way I can implement this.
You don't need a map. Use the idEvent parameter. Microsoft gave it the UINT_PTR type so it fits a pointer, even in 64 bits:
SetTimer(hwnd, (UINT_PTR)bar, 1000, MyTimerProc);
void CALLBACK MyTimerProc(HWND, UINT, UINT_PTR idEvent, DWORD)
{
Bar* bar = (Bar*)idEvent;
}
Note that you need to use an actual HWND. If the HWND is null, Windows will generate the idEvent internally.
Obviously, if you were directing timer messages at a window, you could just store the user data with the window.
The only way to do this with a TimerProc is to make a class that manages a statically scoped map of timer-id's to user data objects.
Something like this (As this is a c++ question, Im just implementing a quick and dirty functor type thing so that the TimerMgr can arrange callbacks directly to members of classes, which is usually why you are trying to store user data:
// Timer.h
#include <map>
class CTimer {
public:
class Callback {
public:
virtual void operator()(DWORD dwTime)=0;
};
template<class T>
class ClassCallback : public Callback {
T* _classPtr;
typedef void(T::*fnTimer)(DWORD dwTime);
fnTimer _timerProc;
public:
ClassCallback(T* classPtr,fnTimer timerProc):_classPtr(classPtr),_timerProc(timerProc){}
virtual void operator()(DWORD dwTime){
(_classPtr->*_timerProc)(dwTime);
}
};
static void AddTimer(Callback* timerObj, DWORD interval){
UINT_PTR id = SetTimer(NULL,0,interval,TimerProc);
// add the timer to the map using the id as the key
_timers[id] = timerObj;
}
static void CALLBACK TimerProc(HWND hwnd,UINT msg,UINT_PTR timerId,DWORD dwTime){
_timers[timerId]->operator()(dwTime);
}
private:
static std::map<UINT_PTR, Callback*> _timers;
};
// In Timer.cpp
#include <windows.h>
#include <Timer.h>
std::map<UINT_PTR,CTimer::Callback*> CTimer::_timers;
// In SomeOtherClass.cpp
class CSomeClass {
void OnTimer1(DWORD dwTime){
}
public:
void DoTimerStuff(){
CTimer::AddTimer( new CTimer::ClassCallback<CSomeClass>(this,&CSomeClass::OnTimer1), 100);
}
};
Removing timers from the map is left as an exercise for the reader :)
ClassCallback needed to inherit Callback.
static variables need to be defined
Code now builds and runs correctly on MSVC 9.0
Given that you don't appear to be using MFC (CWnd::OnTimer means you'd have access to the class), and you don't have a HWND (you could conceivably set a property on the HWND on timer-creation and get it back in your proc), there is another option.
SetTimer returns a UINT_PTR which is the timer ID. This is what you'll get in your TimerProc and will also pass to KillTimer when you're done with it. Using this, we can create a map that maps a timer ID to some user-defined object of your creation:
class MyAppData
{
}; // eo class MyAppData
typedef std::map<UINT_PTR, MyAppData*> MyDataMap;
MyDataMap dataMap;
Then we create your timer:
MyAppData* _data = new MyAppData(); // application-specific data
dataMap[SetTimer(NULL, 0, 10000, (TIMERPROC)TimerCallBack)] = _data;
And in your procedure:
static void CALLBACK TimerCallBack(HWND _hWnd, UINT _msg. UINT_PTR _idTimer, DWORD _dwTime)
{
MyAppData* data = dataMap[_idTimer];
} // eo TimerCallBack
There exists one more solution, but in order to use that one - HWND parameter in SetTimer should be non-NULL.
It's possible to store extra data into window itself, using API function SetWindowLongPtr with parameter GWLP_USERDATA.
So you could add into your class following function:
void SetLocalTimer(UINT_PTR nIDEvent, UINT nElapse)
{
SetWindowLongPtr(m_hWnd, GWLP_USERDATA, (LONG_PTR)this);
SetTimer(nIDEvent, nElapse, _TimerRouter);
}
and timer router function, which determines what to do on given timer.
static void CALLBACK _TimerRouter(HWND hwnd, UINT, UINT_PTR nEventID, DWORD)
{
YourClassName* inst = (YourClassName*)GetWindowLong(hwnd, GWLP_USERDATA);
if( !inst )
return;
switch (nEventID)
{
case 0:
inst->DoThis();
break;
case 1:
inst->DoThat();
break;
}
}
This allows also to use nEventID as function identifier to be called.
There still exists a risk that user data will be used from more than one place, but I think it's good practice to keep UI window matching it's class model this pointer.

Subclassing a window with a functor (Win32)

Quick sanity check: Is it possible to subclass a window using a functor? I'm running into a situation where I want to have some data available in the win proc, but GWLP_USERDATA is already being used. A functor seems like a good alternative, but I'm having trouble getting it to work.
Here's the basics:
class MyWinProc { // Win Proc Functor
public:
MyWinProc(ExternalClass* obj, HWND window) :
obj(obj), window(window) {
oldWinProc = SubclassWindow(window, this); // Apply Subclass
}
virtual ~MyWinProc() {
SubclassWindow(window, oldWinProc); // Remove Subclass
}
LRESULT CALLBACK operator()(HWND, UINT, WPARAM, LPARAM) {
switch( uMsg ) {
case WM_MOUSEMOVE: {
obj->onMouseMove(/*etc*/);
break;
}
}
return CallWindowProc(oldWinProc, hWnd, uMsg, wParam, lParam);
}
private:
ExternalClass* obj;
HWND window;
WNDPROC oldWinProc;
};
Seems all well and good, but when I hit DispatchMessage() in me message pump, I "Access Violation Writing Location 0x00000000", obviously not a good sign. Remove the call to the above code and life is happy again. :( So is this even possible, or am I going about it entirely the wrong way?
A CALLBACK function must be a static member function or an otherwise straight C-style function. The Windows API doesn't really know anything about C++ objects.
Something along the lines of this should work:
class MyWinProc {
public:
MyWinProc(ExternalClass* obj, HWND window) :
obj(obj), window(window) {
pContext = this;
oldWinProc = SubclassWindow(window, &MyWinProc::wndproc); // Apply Subclass
}
virtual ~MyWinProc() {
SubclassWindow(window, oldWinProc); // Remove Subclass
}
private:
static MyWinProc* pContext;
static
LRESULT CALLBACK wndproc( HWND, UINT, WPARAM, LPARAM) {
MyWndProc& me = *pContext;
// do your WndProc work...
}
ExternalClass* obj;
HWND window;
WNDPROC oldWinProc;
};
The problem with using a functor is the calling convention: Windows is expecting the address to be the address of a static function, and will use/invoke that address as such; whereas the 'this' which you're passing is not the address of a static function.
Windows is going to use the address like this (pseudo-coded assembly):
; push the necessary parameters
push [hWnd]
push etc...
; invoke the specified address (of the static function)
call [callback]
To invoke a functor, the Windows code would need to be like this
; push the necessary parameters
push [hWnd]
push etc...
; invoke the specified address (of the functor object)
; ... first, put the 'this' pointer as a hidden parameter into the ecx register
mov ecx,[callback]
; ... next, invoke the address (where is it?) of the class' functor method
call MyWinProc::operator()
... or instead of the last two statements, the following statements if the operator is virtual ...
; ... first, put the 'this' pointer as a hidden parameter into the ecx register
mov ecx,[callback]
; ... next, invoke the address of the operator via an (which?) entry
; in the class' vtable
call [ecx+8]
Neither of these is possible because the O/S isn't aware of the calling conventions for non-static C++ methods, especially including:
The way in which the implicit 'this' parameter is passed
The address of the class' non-virtual methods
The vtable entries of the class' virtual methods
GWLP_USERDATA is not the only way to store data associated with a window, you can also use SetProp().
And at least on x86, you can do ATL style thunking (A small piece of asm code that puts your class pointer in ecx and then jumps to your wndproc) You can find some links about that in a answer I posted here
GWLP_USERDATA is already being used
I don't know what your SubclassWindow function is, but CWnd::SubclassWindow says, "The window must not already be attached to an MFC object when this function is called".
I'm running into a situation where I want to have some data available in the win proc
A usual (non-MFC) way to implement that is to have a global/static dictionary, whose key/index is the HWND value of the subclassed windows, and whose data is the data that you want to associate with that window: that data is often the this pointer of a C++ class of yours.
You subclass the window procedure with a static callback function of yours: your static callback function then, when it's invoked, uses the HWND which it's passed to look up the data in the static dictionary.
You can still use the value stored in GWLP_USERDATA...
class MyWinProc { // Win Proc Functor
public:
MyWinProc(ExternalClass* obj, HWND window) :
obj(obj), window(window) {
oldUserData = GetWindowLongPtr(GWLP_USERDATA);
oldWinProc = SubclassWindow(window, this); // Apply Subclass
}
virtual ~MyWinProc() {
SubclassWindow(window, oldWinProc); // Remove Subclass
}
LRESULT CALLBACK operator()(HWND, UINT, WPARAM, LPARAM) {
switch( uMsg ) {
case WM_MOUSEMOVE: {
obj->onMouseMove(/*etc*/);
break;
}
}
LONG userDataToRestore = SetWindowLongPtr(GWLP_USERDATA, oldUserData);
LRESULT lRet = CallWindowProc(oldWinProc, hWnd, uMsg, wParam, lParam);
SetWindowLongPtr(GWLP_USERDATA, userDataToRestore);
}
private:
ExternalClass* obj;
HWND window;
LONG oldUserData;
WNDPROC oldWinProc;
};