    InputImpl.cpp
    //@STATE=嶌惉拞
    //@DESCRIPTION ---------------------------------------------------------------
    //  InputImpl 拪徾僋儔僗偺嬶徾乮幚憰乯僋儔僗
    //  僒儞僾儖偐傜僷僋儕傑偔偭偰傑偡丅
    //  棜楌:
    // $Log: InputImpl.cpp,v $
    // Revision 1.5  2001/07/09 20:30:08  fujiwara
    // 椺奜張棟偺慻傒崬傒
    //
    // Revision 1.4  2001/07/01 21:30:34  fujiwara
    // 儊儌儕儕乕僋僠僃僢僋尒捈偟
    //
    // Revision 1.3  2001/07/01 01:03:44  fujiwara
    // const 偺尒捈偟
    // 攝抲僄僨傿僞偼搑拞宱夁
    //
    // Revision 1.2  2001/05/29 01:12:45  fujiwara
    // 嶨嫑僉儍儔(旘峴暔乯偺嶌惉丅攝抲僄僨傿僞偺僶僌廋惓
    //
    // Revision 1.1  2001/05/12 01:07:33  fujiwara
    // 俠倁俽傪摫擖偟丄儘僌昞帵傪捛壛
    //
    //  2001/01/29 儊儌儕乕儕乕僋専弌梡儔僀僽儔儕偺捛壛
    //@DESCRIPTION_END -----------------------------------------------------------
    //@AUTHOR=S.F.
    // Copyright (C) 2000 Satoshi Fujiwara. All Rights Reserved.
    ///////////////////////////////////////////////////////////////////////////////
    #pragma warning( disable : 4786 )   //STL偺寈崘奜偟

    // 儊儌儕乕儕乕僋専弌梡
    #include "sfdebug.h"

    #define WIN32_LEAN_AND_MEAN
    #define _WIN32_WINNT  0x0400
    #include "math.h"
    #include <list>
    #include <queue>
    #include <memory>
    #include <map>

    #include "windows.h"
    #include "windowsx.h"
    #include "d3d8.h"
    #include "d3dx8.h"
    #include "dmusici.h"
    #include "dinput.h"
    #include "dxerr8sf.h"

    // PROJECT INCLUDES
    //

    #include "exception.h"
    #include "resource.h"
    #include "System.h"
    #include "Console.h"
    #include "Obj.h"
    #include "singleton.h"
    #include "AbstractSprite.h"
    #include "ConsoleImpl.h"
    #include "SoundImpl.h"

    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif

    #include "InputImpl.h"
    #include "Scene.h"
    #include "MainApp.h"
    #include "SystemImpl.h"

    //////////////////////////////////////////////////////////////////////
    // 峔抸/徚柵
    //////////////////////////////////////////////////////////////////////

    using namespace sf::system::input;

    // 僨僼僅儖僩僐儞僗僩儔僋僞 ---------------------------------------------------
    InputImpl::InputImpl()
    {

    }

    // 僐儞僗僩儔僋僞 -------------------------------------------------------------
    InputImpl::InputImpl(HWND hwnd)
    {
        mHWND = hwnd;
    //  initialize();
    }

    // 僨僗僩儔僋僞 ---------------------------------------------------------------
    InputImpl::~InputImpl()
    {
        uninitialize();
    }// ~InputImpl()

    // 弶婜壔 ---------------------------------------------------------------------
    void InputImpl::initialize(void)
    {

        mpDI = NULL;
        mpJoystick = NULL;
        mpKeyboard = NULL;
        mbEnabled = false;

        mbLeft = false;
        mbRight = false;
        mbUp = false;
        mbDown = false;

        mbButtonA = false;
        mbButtonB = false;
        mbButtonC = false;
        mbButtonD = false;

        mbStart = false;
        mbExit = false;

        mbBeforeLeft = false;
        mbBeforeRight = false;
        mbBeforeUp = false;
        mbBeforeDown = false;

        mbBeforeButtonA = false;
        mbBeforeButtonB = false;
        mbBeforeButtonC = false;
        mbBeforeButtonD = false;

        mbBeforeStart = false;
        mbBeforeExit = false;
    //  uninitialize();
        mbEnabled = false;
        mbMouseCursor = false;

        HRESULT hr;

        // DirectInput 僆僽僕僃僋僩偺惗惉
        if( FAILED( hr = DirectInput8Create( GetModuleHandle(NULL), DIRECTINPUT_VERSION,
                                             IID_IDirectInput8, (VOID**)&mpDI, NULL ) ) )
        {   std::string tmp("DirectInput8Create() Error : ");
            tmp += DXGetErrorString8(hr);
            tmp += " ";
            throw FatalErrorException(tmp,__FILE__,__LINE__);
        }

        // Joystick偺弶婜壔
        try {
            initJoystick();
        } catch (RecoverbleErrorException e)
        {
            if(mpJoystick != NULL){
                mpJoystick->Release();
                mpJoystick = NULL;
            }
        } catch (...){
            throw;
        }

        // KeyBoard偺弶婜壔

        try {
            initKeyboard();
        } catch (RecoverbleErrorException e) {
            if(mpKeyboard != NULL)
            {
                mpKeyboard->Release();
                mpKeyboard = NULL;
            }

        } catch (...){
            throw;
        }

        // 擖椡僨僶僀僗偑懚嵼偟側偄応崌偼丄僄儔乕偱廔椆偡傞丅

        if(NULL == mpJoystick && NULL == mpKeyboard)
        {
            throw FatalErrorException("InputImpl Device Not Found\r\n",__FILE__,__LINE__);
        };

        addWindowMessageMap();

        mbEnabled = true;
    }// intialize()

    // 廔椆 -----------------------------------------------------------------------
    void InputImpl::uninitialize(void)
    {
        KeyboardListenerList::iterator it = mKeyboardListenerList.begin();

        while(it != mKeyboardListenerList.end())
        {
            if(*it != NULL){
                (*it)->keyboardTalkerIsDeleted();
    //          ++it;
            }
            it = mKeyboardListenerList.erase(it);
        }

        it = mKeyboardListenerQ.begin();

        while(it != mKeyboardListenerQ.end())
        {
            if(*it != NULL){
                (*it)->keyboardTalkerIsDeleted();

            }
            it = mKeyboardListenerQ.erase(it);
        }

        MouseListenerList::iterator itm = mMouseListenerList.begin();

        while(itm != mMouseListenerList.end())
        {
            if(*itm != NULL){
                (*itm)->mouseTalkerIsDeleted();
    //          ++itm;
            }
            itm = mMouseListenerList.erase(itm);
        }

        itm = mMouseListenerQ.begin();

        while(itm != mMouseListenerQ.end())
        {
            if(*itm != NULL){
                (*itm)->mouseTalkerIsDeleted();
    //          ++itm;
            }
            itm = mMouseListenerQ.erase(itm);
        }

        if(mpJoystick){
            mpJoystick->Release();
            mpJoystick = NULL;
        }

        if(mpKeyboard){
            mpKeyboard->Release();
            mpKeyboard = NULL;
        }

        if(mpDI){
            mpDI->Release();
            mpDI = NULL;
        }

    }// uninitialize()

    // 僕儑僀僗僥傿僢僋僨僶僀僗楍嫇梡僐乕儖僶僢僋 ---------------------------------
    BOOL InputImpl::enumJoysticksCallback(const DIDEVICEINSTANCE *pdidInstance)
    {
        HRESULT hr;

        // Obtain an interface to the enumerated joystick.
        hr = mpDI->CreateDevice( pdidInstance->guidInstance, &mpJoystick, NULL );

        // If it failed, then we can't use this joystick. (Maybe the user unplugged
        // it while we were in the middle of enumerating it.)
        if( FAILED(hr) )
            return DIENUM_CONTINUE;

        // Stop enumeration. Note: we're just taking the first joystick we get. You
        // could store all the enumerated joysticks and let the user pick.
        return DIENUM_STOP;
    }

    // 僕儑僀僗僥傿僢僋偺弶婜壔 ---------------------------------------------------
    void InputImpl::initJoystick(void)
    {

        HRESULT hr = E_FAIL;

        // DirectInput僨僶僀僗偺楍嫇
        if( FAILED(hr = mpDI->EnumDevices( DI8DEVCLASS_GAMECTRL,
                                             enumJoysticksCallback,
                                             (VOID*)this, DIEDFL_ATTACHEDONLY ) ) )
        {
            throw RecoverbleErrorException(DXGetErrorString8(hr),__FILE__,__LINE__);
        }

        // Make sure we got a joystick
        if( NULL == mpJoystick )
        {   throw RecoverbleErrorException(" NULL == mpJoystick",__FILE__,__LINE__);}

        if( FAILED(mpJoystick->SetDataFormat( &c_dfDIJoystick2 ) ) )
        {
            throw RecoverbleErrorException(DXGetErrorString8(hr),__FILE__,__LINE__);
        }

        // Set the cooperative level to let DInputImpl know how this device should
        // interact with the system and with other DInputImpl applications.
        if( FAILED(mpJoystick->SetCooperativeLevel( mHWND, DISCL_EXCLUSIVE |
                                                                 DISCL_FOREGROUND ) ) )
        {
            throw RecoverbleErrorException(DXGetErrorString8(hr),__FILE__,__LINE__);}

        // Determine how many axis the joystick has (so we don't error out setting
        // properties for unavailable axis)
        mDIJoystickDevCaps.dwSize = sizeof(DIDEVCAPS);
        if ( FAILED(mpJoystick->GetCapabilities(&mDIJoystickDevCaps) ) )
        {
            throw RecoverbleErrorException(DXGetErrorString8(hr),__FILE__,__LINE__);

        }

        // Enumerate the axes of the joyctick and set the range of each axis. Note:
        // we could just use the defaults, but we're just trying to show an example
        // of enumerating device objects (axes, buttons, etc.).
        if ( FAILED(mpJoystick->EnumObjects( enumAxesCallback,
                                                    (VOID*)this, DIDFT_AXIS ) ) )
        {
            throw RecoverbleErrorException(DXGetErrorString8(hr),__FILE__,__LINE__);

        }
    }// InitJoystick()

    // 僕儑僀僗僥傿僢僋偺愝掕僐乕儖僶僢僋丂-------------------------------------------------
    BOOL InputImpl::enumAxesCallback( const DIDEVICEOBJECTINSTANCE* pdidoi)
    {

        DIPROPRANGE diprg;
        diprg.diph.dwSize       = sizeof(DIPROPRANGE);
        diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER);
        diprg.diph.dwHow        = DIPH_BYID;
        diprg.diph.dwObj        = pdidoi->dwType; // Specify the enumerated axis
        diprg.lMin              = -1000;
        diprg.lMax              = +1000;

        // Set the range for the axis
        if( FAILED( mpJoystick->SetProperty( DIPROP_RANGE, &diprg.diph ) ) )
        {
            return DIENUM_STOP;
        }

        return DIENUM_CONTINUE;
    }// enumAxesCallback

    // 僉乕儃乕僪僨僶僀僗偺弶婜壔 -------------------------------------------------
    void InputImpl::initKeyboard(void)
    {
        HRESULT hr = E_FAIL;

        // 僉乕儃乕僪僨僶僀僗偺嶌惉
        if( FAILED( hr = mpDI->CreateDevice( GUID_SysKeyboard, &mpKeyboard, NULL ) ) )
        {   //system::Factory::getInstance()->outputError(DXGetErrorString8(hr));
            throw RecoverbleErrorException(DXGetErrorString8(hr),__FILE__,__LINE__);
        }

        if( FAILED( hr = mpKeyboard->SetDataFormat( &c_dfDIKeyboard ) ) )
        {
            //system::Factory::getInstance()->outputError(DXGetErrorString8(hr));
            throw RecoverbleErrorException(DXGetErrorString8(hr),__FILE__,__LINE__);
        }

        // 嫤挷儗儀儖偺愝掕
        if(FAILED(mpKeyboard->SetCooperativeLevel( mHWND, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND )))
        {
            throw RecoverbleErrorException(DXGetErrorString8(hr),__FILE__,__LINE__);
        }

        // Acquire the newly created device
        mpKeyboard->Acquire();
    }// initKeyboard

    // 僉乕儃乕僪丒僕儑僀僗僥傿僢僋偺尰嵼偺忬懺傪庢摼 -----------------------------
    void InputImpl::update(void)
    {
        HRESULT hr = E_FAIL;
        bool b_joystick = false;
        bool b_keyboard = false;

        // 僕儑僀僗僥傿僢僋偺尰嵼忬懺傪庢摼 //
        if(mpJoystick){
            mpJoystick->Poll();
            hr = mpJoystick->GetDeviceState(sizeof(DIJOYSTATE2),(LPVOID)&mDIJoyState);
            if(FAILED(hr)){
                mpJoystick->Acquire();
                while( hr == DIERR_INPUTLOST )
                    hr = mpJoystick->Acquire();
            } else {
                b_joystick = true;
            }

        }

        // 僉乕儃乕僪偺尰嵼忬懺傪庢摼 //
        if(mpKeyboard){
    //      ZeroMemory( &mDIKeys, sizeof(mDIKeys) );
            hr = mpKeyboard->GetDeviceState(sizeof(mDIKeys),(LPVOID)&mDIKeys);
            if(FAILED(hr)){
    #ifdef _DEBUG
                OutputDebugString(DXGetErrorString8(hr));
    #endif
                mpKeyboard->Acquire();
                while( hr == DIERR_INPUTLOST )
                    hr = mpKeyboard->Acquire();
            } else {
                b_keyboard = true;
            }
        }

        //
        mbBeforeLeft = mbLeft;
        mbBeforeRight = mbRight;
        mbBeforeUp = mbUp;
        mbBeforeDown = mbDown;

        mbBeforeButtonA = mbButtonA;
        mbBeforeButtonB = mbButtonB;
        mbBeforeButtonC = mbButtonC;
        mbBeforeButtonD = mbButtonD;

        mbBeforeStart = mbStart;
        mbBeforeExit = mbExit;

        mbLeft = mbRight = mbUp = mbDown = false;
        mbButtonA = mbButtonB = mbButtonC = mbButtonD = false;
        mbStart = mbExit = false;

        if(b_joystick){

            if(mDIJoyState.lX > 300){
                mbRight = true;
            } else {
                if(mDIJoyState.lX < -300)
                {

                    mbLeft = true;
                }
            }

            if(mDIJoyState.lY > 300)
                mbDown = true;
            else
                if(mDIJoyState.lY < -300)
                    mbUp = true;

            if(mDIJoyState.rgbButtons[0])
            {
                mbButtonA = true;
                mbStart = true;
            }

            if(mDIJoyState.rgbButtons[1])
                mbButtonB = true;

            if(mDIJoyState.rgbButtons[2])
                mbButtonC =  true;

            if(mDIJoyState.rgbButtons[3])
                mbButtonD =  true;
        }

        if(b_keyboard){

            if(mDIKeys[DIK_LEFT] & 0x80)
                mbLeft = true;

            if(mDIKeys[DIK_RIGHT] & 0x80)
                mbRight = true;

            if(mDIKeys[DIK_UP] & 0x80)
                mbUp = true;

            if(mDIKeys[DIK_DOWN] & 0x80)
                mbDown =  true;

            if(mDIKeys[DIK_Z] & 0x80)
                mbButtonA = true;

            if(mDIKeys[DIK_X] & 0x80)
                mbButtonB = true;

            if(mDIKeys[DIK_C] & 0x80)
                mbButtonC = true;

            if(mDIKeys[DIK_V] & 0x80)
                mbButtonD = true;

            if(mDIKeys[DIK_SPACE] & 0x80)
                mbStart = true;

            if(mDIKeys[DIK_ESCAPE] & 0x80)
                mbExit = true;

        }

        // 僀儀儞僩儕僗僫乕Q仺僀儀儞僩儕僗僫乕儕僗僩傊 //
        MouseListenerList::iterator it = mMouseListenerQ.begin();

        while(it != mMouseListenerQ.end())
        {
            if(*it != NULL){
                mMouseListenerList.push_back(*it);
            }
            it = mMouseListenerQ.erase(it);

        }

        KeyboardListenerList::iterator itk = mKeyboardListenerQ.begin();

        while(itk != mKeyboardListenerQ.end())
        {
            if(*itk != NULL){
                mKeyboardListenerList.push_back(*itk);
            }
            itk = mKeyboardListenerQ.erase(itk);
        }
    }// update()

    LRESULT     InputImpl::onSetCursor(const HWND hwnd, const WPARAM wParam, const LPARAM lParam)
    {
        if(system::Factory::getInstance()->isActive() && !mouseCursorVisibility())
        {
            SetCursor(NULL);//儅僂僗僇乕僜儖傪徚偡丅
            return 0;
        }
        return DefWindowProc (hwnd, WM_SETCURSOR,wParam, lParam);
    }// onSetCursor()

    // 儅僂僗偺嵍儃僞儞偑墴偝傟偨 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
    LRESULT     InputImpl::onLButtonDown(const HWND hwnd, const WPARAM wParam, const LPARAM lParam)
    {
        return callMouseListenerMethod(hwnd,wParam,lParam,input::mouse::Listener::leftButtonDown);
    }// onLButtonDown()

    // 儅僂僗偺嵍儃僞儞偑棧偝傟偨 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
    LRESULT     InputImpl::onLButtonUp(const HWND hwnd, const WPARAM wParam, const LPARAM lParam)
    {
        return callMouseListenerMethod(hwnd,wParam,lParam,input::mouse::Listener::leftButtonUp);
    }// onLButtonUp()

    // 儅僂僗偺嵍儃僞儞偑僟僽儖僋儕僢僋偝傟偨丂亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
    LRESULT     InputImpl::onLButtonDoubleClick(const HWND hwnd, const WPARAM wParam, const LPARAM lParam)
    {
        return callMouseListenerMethod(hwnd,wParam,lParam,input::mouse::Listener::leftButtonDoubleClick);
    }// onLButtonDoubleClick()

    // 儅僂僗偺塃儃僞儞偑棧偝傟偨 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
    LRESULT     InputImpl::onRButtonDown(const HWND hwnd, const WPARAM wParam, const LPARAM lParam)
    {
        return callMouseListenerMethod(hwnd,wParam,lParam,input::mouse::Listener::rightButtonDown);
    }// onRButtonDown()

    // 儅僂僗偺塃儃僞儞偑墴偝傟偨 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
    LRESULT     InputImpl::onRButtonUp(const HWND hwnd, const WPARAM wParam, const LPARAM lParam)
    {
        return callMouseListenerMethod(hwnd,wParam,lParam,input::mouse::Listener::rightButtonUp);
    }// onRButtonUp()

    // 儅僂僗偺塃儃僞儞偑僟僽儖僋儕僢僋偝傟偨丂亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
    LRESULT     InputImpl::onRButtonDoubleClick(const HWND hwnd, const WPARAM wParam, const LPARAM lParam)
    {
        return callMouseListenerMethod(hwnd,wParam,lParam,input::mouse::Listener::rightButtonDoubleClick);
    }// onRButtonDoubleClick()

    // 儅僂僗偑摦偄偨丂亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
    LRESULT     InputImpl::onMouseMove(const HWND hwnd, const WPARAM wParam, const LPARAM lParam)
    {
        return callMouseListenerMethod(hwnd,wParam,lParam,input::mouse::Listener::mouseMove);
    }// onMouseMove()

    // 儂僀乕儖偑摦偄偨丂亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
    LRESULT     InputImpl::onMouseWheel(const HWND hwnd, const WPARAM wParam, const LPARAM lParam)
    {
        return callMouseListenerMethod(hwnd,wParam,lParam,input::mouse::Listener::mouseWheel);
    }// onMouseWheel()

    // MouseListener偺儊僜僢僪傪屇傃弌偡 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
    LRESULT InputImpl::callMouseListenerMethod(const HWND hwnd, const WPARAM wParam, const LPARAM lParam,void(mouse::Listener::* pMethod)(const int,const int,const DWORD))
    {
        using namespace sf::system::input;

        if(mMouseListenerList.size() == 0)
            return 0;

        POINT pt;

        pt.x = LOWORD(lParam);
        pt.y = HIWORD(lParam);

        ClientToScreen(hwnd,&pt);

        DWORD mkey = 0;

        if(MK_CONTROL & wParam)
            mkey |= mouse::MKEY_CONTROL;

        if(MK_SHIFT & wParam)
            mkey |= mouse::MKEY_SHIFT;

        mkey |= (wParam & 0xffff0000);

        MouseListenerList::iterator it = mMouseListenerList.begin();

        while(it != mMouseListenerList.end())
        {
            if(*it == NULL){
                it = mMouseListenerList.erase(it);
            } else {
                if((*it)->isListeningMouse()){
                    ((*it)->*pMethod)(pt.x,pt.y,mkey);
                }
                ++it;
            }
        }

        return 0;
    }// callListener

    // 僉乕墴壓帪偺張棟 -----------------------------------------------------------
    LRESULT InputImpl::onKeyDown(const HWND hwnd, const WPARAM wParam, const LPARAM lParam)
    {
        DWORD extKey = 0;

        // 偲傝偁偊偢丄ESC僉乕偑墴偝傟偨傜廔椆偡傞傛偆偵偟偰偄傞
        switch(wParam)
        {
        case 'Q':
            PostMessage( hwnd, WM_CLOSE, 0, 0L );
            break;
        default:

            if(GetAsyncKeyState(VK_SHIFT))
                extKey |= keyboard::SHIFT;

            if(GetAsyncKeyState(VK_CONTROL))
                extKey |= keyboard::CONTROL;

            KeyboardListenerList::iterator it = mKeyboardListenerList.begin();

            while(it != mKeyboardListenerList.end())
            {
                if(*it == NULL){
                    it = mKeyboardListenerList.erase(it);
                } else {
                    if((*it)->isListeningKeyboard()){
                            (*it)->keyDown(wParam,extKey);
                    }
                    ++it;
                }
            }

        }
        return 0; // WM_KEYDOWN
    }// onKeyDown

    // 僉乕偑棧偝傟偨帪偺張棟 -----------------------------------------------------------
    LRESULT InputImpl::onKeyUp(const HWND hwnd, const WPARAM wParam, const LPARAM lParam)
    {
        return 0;
    }// onKeyUp

    // 僂傿儞僪僂儊僢僙乕僕僴儞僪儔傪SystemImpl偵搊榐 亅亅亅亅亅亅亅亅
    void InputImpl::addWindowMessageMap()
    {
        SystemImpl *pSys = dynamic_cast<SystemImpl *>(system::Factory::getInstance());

        pSys->addWindowMessage(WM_SETCURSOR, new WindowMessageImpl<InputImpl>(this,&InputImpl::onSetCursor));
        pSys->addWindowMessage(WM_LBUTTONDOWN,new WindowMessageImpl<InputImpl>(this,&InputImpl::onLButtonDown));
        pSys->addWindowMessage(WM_LBUTTONUP,new WindowMessageImpl<InputImpl>(this,&InputImpl::onLButtonUp));
        pSys->addWindowMessage(WM_LBUTTONDBLCLK,new WindowMessageImpl<InputImpl>(this,&InputImpl::onLButtonDoubleClick));

        pSys->addWindowMessage(WM_RBUTTONDOWN,new WindowMessageImpl<InputImpl>(this,&InputImpl::onRButtonDown));
        pSys->addWindowMessage(WM_RBUTTONUP,new WindowMessageImpl<InputImpl>(this,&InputImpl::onRButtonUp));
        pSys->addWindowMessage(WM_RBUTTONDBLCLK,new WindowMessageImpl<InputImpl>(this,&InputImpl::onRButtonDoubleClick));

        pSys->addWindowMessage(WM_MOUSEMOVE,new WindowMessageImpl<InputImpl>(this,&InputImpl::onMouseMove));
        pSys->addWindowMessage(WM_MOUSEWHEEL,new WindowMessageImpl<InputImpl>(this,&InputImpl::onMouseWheel));

        pSys->addWindowMessage(WM_KEYDOWN,new WindowMessageImpl<InputImpl>(this,&InputImpl::onKeyDown));
        pSys->addWindowMessage(WM_KEYUP,new WindowMessageImpl<InputImpl>(this,&InputImpl::onKeyUp));

    }