开发者

Encapsulating WndProc Problem

开发者 https://www.devze.com 2022-12-12 11:24 出处:网络
Okay so i wrote a basic class to do encapsulation of a win32 window. I ended up creating a static router callback function to route the messages into another function of the class.

Okay so i wrote a basic class to do encapsulation of a win32 window. I ended up creating a static router callback function to route the messages into another function of the class.

EDIT OKAY I Got it

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

I forgot to pass in the (void*)this pointer. 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);
}

Which calls this function:

LRESULT CALLBACK Test::EngineBase::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;

    switch (message)
    {
    case WM_KEYDOWN:
        m_InputManager->GetKeyboard()->SetKeyPressed(static_cast<int>(wParam));
        break;
    case WM_KEYUP:
        m_InputManager->GetKeyboard()->SetKeyUnpressed(static_cast<int>(wParam));
        break;
    case WM_MOUSEMOVE:
    case WM_NCMOUSEMOVE:
        m_InputManager->GetMouse()->SetMouseMouse(LOWORD(lParam),HIWORD(lParam));
        break;
    case WM_MOUSEWHEEL:
        break;
    case WM_COMMAND:
        wmId    = LOWORD(wParam);
        wmEvent = HIWORD(wParam);
        // Parse the menu selections:
        switch (wmId)
        {
            //case IDM_ABOUT:
            //    //DialogBox(m_EngineInstance, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
            //    //break;
        case IDM_EXIT:
            DestroyWindow(hWnd);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

Then i inherit from EngineBase. Now WndRouter always gets called, instead always results in base == NULL, so it never actually calls the WndProc function.

What am i doing wrong?

EDIT

Heres how i get the intial messages into the engine:

while (returnValue == 9999)
{
    engine->Upd开发者_运维技巧ate();
    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
        if (msg.message == WM_QUIT)
        {                
            returnValue = static_cast<int>(msg.wParam);
        }

        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

}

Heres The header:

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

EDIT This is how i set my windProc def

In main.cpp

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

Register does this:

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


What inherits from EngineBase?

How do you get the initial messages flowing into EngineBase's WndProc?

Did you call SetWindowLong with GWL_WNDPROC to point the window at your WndProc? (You probably missed some initial messages if you did). Or does the window's WNDCLASS point to your EngineBase::WndProc?

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号