2009-11-19 74 views
1

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

编辑好的,我明白了

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

我忘了在(无效*)this指针传递。 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); 
} 

调用该函数:

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

然后,我从EngineBase继承。现在WndRouter总是被调用,而总是导致base == NULL,所以它实际上永远不会调用WndProc函数。

我在做什么错了?

编辑

继承人我如何获得INTIAL消息进入发动机:

while (returnValue == 9999) 
{ 
    engine->Update(); 
    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
    { 
     if (msg.message == WM_QUIT) 
     {     
      returnValue = static_cast<int>(msg.wParam); 
     } 

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

} 

继承人的标题:

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

编辑这是我如何设置我的windProc def

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

注册做到这一点:从EngineBase

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

至少对我来说,有点难以理解你没有看到呼叫所做的事情,例如,谁打电话给你的WndRouter,你有没有改变应用的入口点?标题的片段也可能有帮助。 – 2009-11-19 04:31:50

回答

1

什么继承?

你如何获得初始消息流入EngineBase的WndProc?

您是否使用GWL_WNDPROC调用SetWindowLong以将窗口指向您的WndProc? (你可能错过了一些初始信息)。或者窗口的WNDCLASS指向你的EngineBase :: WndProc?

+0

我标记你为接受,因为你让我意识到我的错误:) – UberJumper 2009-11-19 05:20:01