2013-06-18 2 views
1

У меня есть два класса, Win32 и Engine. Я пытаюсь передать мою функцию WindowProc из класса Engine в класс Win32. Я знаю, что ЬурейиЙ WNDPROC объявлен как:Передача нестатического указателя функции на другой класс?

typedef LRESULT(CALLBACK *WNDPROC)(HWND, UINT, WPARAM, LPARAM); 
заголовок

Моего Win32 объявлен как:

// 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); 
}; 

И мой класс двигателя объявлен как:

// 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. 
} 

Моего Win32 класс уже имеет статический MessageRouter, который предоставляется WNDCLASSEX. Поэтому мой вопрос заключается в том, как передать функцию Engine :: WindowProc классу Win32 без объявления его статическим или глобальным?

+0

У этого есть пять параметров, а 'WNDPROC' имеет четыре. Как вы планируете справиться с этим? – chris

ответ

1

Вы можете использовать std::function и std::bind() (в C++ 11), или boost::functionboost::bind() (на C++ 03). Эти два варианта в значительной степени эквивалентны функциональности, поэтому я покажу использование std::bind().

Вот как вы можете определить псевдоним типа под названием WNDPROC_FXN на основе std::function:

typedef std::function<LRESULT CALLBACK (HWND, UINT, WPARAM, LPARAM)> WNDPROC_FXN; 

Это, как вы будете использовать его в Win32 классе:

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); 
}; 

И это, как вы будет связывать функцию-член с указателем this и передавать его на 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); 
//      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
} 
1

Для полноты, есть способ сделать это и с языковыми конструкциями. Эта реализация использует указатель на функции-члены:

// 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; 
} 
Смежные вопросы