Reputation: 447
I have two classes, Win32 and Engine. I'm trying to pass my WindowProc function from my Engine class to the Win32 class. I know that the typedef WNDPROC is declared as:
typedef LRESULT(CALLBACK *WNDPROC)(HWND, UINT, WPARAM, LPARAM);
My Win32 header is declared as:
// Win32.h
#include <Windows.h>
class Win32
{
public:
Win32() {};
~Win32() {};
void Initialize(WNDPROC);
private:
// Route messages to non static WindowProc that is declared in Engine class.
static LRESULT CALLBACK MessageRouter(HWND, UINT, WPARAM, LPARAM);
};
And my Engine class is declared as:
// Engine.h
#include "Win32.h"
class Engine
{
public:
Engine() {};
~Engine() {};
void Initialize();
private:
LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM);
Win32* m_win32;
};
// Engine.cpp
#include "Engine.h"
void Engine::Initialize()
{
m_win32 = new Win32;
m_win32->Initialize(&WindowProc); // How can I pass this function without making
// it static or global.
}
My Win32 class already has a static MessageRouter that is given to WNDCLASSEX. So my question is, how do I pass the Engine::WindowProc function to class Win32 without declaring it static or global?
Upvotes: 1
Views: 754
Reputation: 432
For the sake of completeness, there is a way to do it with language constructs as well. This implementation uses pointer to member functions:
// Win32.h
#include <Windows.h>
class Engine;
class Win32
{
public:
Win32() {};
~Win32() {};
void Initialize(LRESULT(CALLBACK Engine::* function)(HWND, UINT, WPARAM, LPARAM));
private:
// Route messages to non static WindowProc that is declared in Engine class.
static LRESULT CALLBACK MessageRouter(HWND, UINT, WPARAM, LPARAM);
};
class Engine
{
public:
Engine() {};
~Engine() {};
void Initialize();
private:
LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM);
Win32* m_win32;
};
void Engine::Initialize()
{
m_win32 = new Win32;
m_win32->Initialize(&Engine::WindowProc); // How can I pass this function without making
// it static or global.
}
int main(void)
{
Engine engine;
engine.Initialize();
return 0;
}
Upvotes: 1
Reputation: 126432
You can use std::function
and std::bind()
(in C++11), or boost::function
boost::bind()
(in C++03). The two are pretty much equivalent in functionality, so I will show the use of std::bind()
.
Here is how you could define a type alias called WNDPROC_FXN
based on std::function
:
typedef std::function<LRESULT CALLBACK (HWND, UINT, WPARAM, LPARAM)> WNDPROC_FXN;
This is how you would use it in your Win32
class:
class Win32
{
public:
Win32() {};
~Win32() {};
void Initialize(WNDPROC_FXN);
// ^^^^^^^^^^^
private:
// Route messages to non static WindowProc that is declared in Engine class.
static LRESULT CALLBACK MessageRouter(HWND, UINT, WPARAM, LPARAM);
};
And this is how you would would bind a member function to the this
pointer and pass it to Win32::Initialize()
:
#include <functional>
// ...
void Engine::Initialize()
{
using namespace std::placeholders;
m_win32 = new Win32;
m_win32->Initialize(std::bind(&Engine::WindowProc, this, _1, _2, _3 _4);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
Upvotes: 1