C++ 封装WndProc问题

C++ 封装WndProc问题,c++,winapi,C++,Winapi,好的,我写了一个基本类来封装win32窗口。我最终创建了一个静态路由器回调函数,将消息路由到该类的另一个函数中 编辑好的,我知道了 m_MainWindowHandle = CreateWindowEx( windowFormat, L"LUDO ENGINE", m_WindowName.c_str(), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, m_WindowDimensions.first,

好的,我写了一个基本类来封装win32窗口。我最终创建了一个静态路由器回调函数,将消息路由到该类的另一个函数中

编辑好的,我知道了

m_MainWindowHandle = CreateWindowEx(
    windowFormat, 
    L"LUDO ENGINE", 
    m_WindowName.c_str(), 
    WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT,
    0,
    m_WindowDimensions.first,
    m_WindowDimensions.second,
    NULL, 
    NULL,
    m_EngineInstance,
    (void*)this);
我忘了把这个指针输入(void*)。AJKFHDJKDF

LRESULT CALLBACK Test::EngineBase::WndRouter(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{


    Test::EngineBase *base = NULL;

    if(message == WM_NCCREATE)
    {
        base = reinterpret_cast<Test::EngineBase*>((LONG)((LPCREATESTRUCT)lParam)->lpCreateParams);
        SetWindowLongPtr(hWnd, GWL_USERDATA, (LONG_PTR)base);
    }
    else
    {
        base = reinterpret_cast<Test::EngineBase*>(GetWindowLongPtr(hWnd, GWL_USERDATA));
    }

    if(base == NULL)
    {
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    base->SetHWnd(hWnd);
    return base->WndProc(hWnd, message, wParam, lParam);
}
标题如下:

namespace Test
{   
    //forward defines
    namespace Input
    {
        class InputManager;
    }


    // main classs
    class EngineBase
    {
    protected:
        virtual HRESULT SetKeyBindings();
        virtual HRESULT LoadResources();

        static LRESULT CALLBACK WndRouter(HWND hWnd,  UINT message,  WPARAM wParam,  LPARAM lParam);
        virtual LRESULT CALLBACK WndProc(HWND hWnd,  UINT message,  WPARAM wParam,  LPARAM lParam);

        // Use reference counting schematics to prevent deletion.
        boost::shared_ptr<Test::Input::InputManager> m_InputManager;
    public:
        EngineBase(__in const HINSTANCE engineHandleInstance);
        ~EngineBase();

        // Engine Specific things
        HRESULT InitializeEngine(__in const int nCmdShow, __in const std::pair<INT, INT>& windowDimensions, __in const Test::String& windowName);
        HRESULT Register(__in const WNDCLASSEX& windowDefs);

        // Game Specific things
        virtual HRESULT Initialize() = 0;
        virtual HRESULT Update();

        inline void SetHWnd(__in const HWND windowHandle)
        {
            m_MainWindowHandle = windowHandle;
        }

        inline const std::pair<INT, INT> GetWindowDimensions()
        {
            return m_WindowDimensions;
        }

    private:
        HRESULT InitializeSubSystems();

        // Win32 stuff
        HRESULT CheckForOtherInstance();
        WORD    RegisterEngineClass();
        WNDCLASSEX  m_WindowClass;
        HWND        m_MainWindowHandle;
        HINSTANCE   m_EngineInstance;
        HANDLE      m_Mutex;

        std::pair<INT, INT> m_WindowDimensions;
        Test::String m_WindowName;
    };
}
注册中心这样做:

HRESULT Test::EngineBase::Register(__in const WNDCLASSEX& windowDefs)
{
    HRESULT hr = S_OK;
    m_WindowClass = windowDefs;
    m_WindowClass.lpfnWndProc = WndRouter;
    m_WindowClass.hInstance = m_EngineInstance;

    if(!RegisterClassEx(&m_WindowClass))
    {
        hr = E_CANNOT_CREATE_WINDOW_CLASS;
        return hr;
    }
    return hr;
}
从EngineBase继承了什么

如何使初始消息流入EngineBase的WndProc

您是否通过GWL_WNDPROC调用SetWindowLong将窗口指向您的WNDPROC?(如果您这样做了,可能会错过一些初始消息)。或者窗口的WNDCLASS是否指向EngineBase::WndProc?

从EngineBase继承了什么

如何使初始消息流入EngineBase的WndProc


您是否通过GWL_WNDPROC调用SetWindowLong将窗口指向您的WNDPROC?(如果您这样做了,可能会错过一些初始消息)。或者窗口的WNDCLASS是否指向您的EngineBase::WndProc?

至少对我来说,在没有看到调用的情况下理解您所做的有点困难,例如,谁调用了您的WndDrooter,您是否以某种方式更改了应用程序的入口点?标题的一小段可能也会有帮助。至少对我来说,在没有看到呼叫的情况下理解您所做的有点困难,例如,谁呼叫了您的Wndrower,您是否以某种方式更改了应用程序的入口点?标题的一个片段也可能有帮助。
namespace Test
{   
    //forward defines
    namespace Input
    {
        class InputManager;
    }


    // main classs
    class EngineBase
    {
    protected:
        virtual HRESULT SetKeyBindings();
        virtual HRESULT LoadResources();

        static LRESULT CALLBACK WndRouter(HWND hWnd,  UINT message,  WPARAM wParam,  LPARAM lParam);
        virtual LRESULT CALLBACK WndProc(HWND hWnd,  UINT message,  WPARAM wParam,  LPARAM lParam);

        // Use reference counting schematics to prevent deletion.
        boost::shared_ptr<Test::Input::InputManager> m_InputManager;
    public:
        EngineBase(__in const HINSTANCE engineHandleInstance);
        ~EngineBase();

        // Engine Specific things
        HRESULT InitializeEngine(__in const int nCmdShow, __in const std::pair<INT, INT>& windowDimensions, __in const Test::String& windowName);
        HRESULT Register(__in const WNDCLASSEX& windowDefs);

        // Game Specific things
        virtual HRESULT Initialize() = 0;
        virtual HRESULT Update();

        inline void SetHWnd(__in const HWND windowHandle)
        {
            m_MainWindowHandle = windowHandle;
        }

        inline const std::pair<INT, INT> GetWindowDimensions()
        {
            return m_WindowDimensions;
        }

    private:
        HRESULT InitializeSubSystems();

        // Win32 stuff
        HRESULT CheckForOtherInstance();
        WORD    RegisterEngineClass();
        WNDCLASSEX  m_WindowClass;
        HWND        m_MainWindowHandle;
        HINSTANCE   m_EngineInstance;
        HANDLE      m_Mutex;

        std::pair<INT, INT> m_WindowDimensions;
        Test::String m_WindowName;
    };
}
WNDCLASSEX windowClass;
windowClass.cbSize = sizeof(WNDCLASSEX);
windowClass.style = NULL;
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = 0;
windowClass.hIcon = LoadIcon(NULL, MAKEINTRESOURCE(1));
windowClass.hIconSm = LoadIcon(NULL, MAKEINTRESOURCE(2));
windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
windowClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
windowClass.lpszMenuName = NULL;
windowClass.lpszClassName = L"ENGINE";

if(FAILED(engine->Register(windowClass)))
{
    return FAIL;
}
HRESULT Test::EngineBase::Register(__in const WNDCLASSEX& windowDefs)
{
    HRESULT hr = S_OK;
    m_WindowClass = windowDefs;
    m_WindowClass.lpfnWndProc = WndRouter;
    m_WindowClass.hInstance = m_EngineInstance;

    if(!RegisterClassEx(&m_WindowClass))
    {
        hr = E_CANNOT_CREATE_WINDOW_CLASS;
        return hr;
    }
    return hr;
}