Input类主要实现的功能是 监听用户鼠标键盘事件,当收到操作系统回调之后首先会调到场景管理类,然后通过场景管理类,会调到Input类,然后Input类会传递给KeyInput类和MouseInput处理鼠标和键盘相关的逻辑代码。
MouseInput被调起的时候,会记录当前鼠标在屏幕中的坐标点,然后更新鼠标的状态。代码详见程序1.1
KeyInput被调起的时候,会更新当前键盘的状态,按下或者是抬起。详见程序1.2
程序1.1
LRESULT MouseInput::msgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { if (_code == LButton) { if (msg == WM_LBUTTONDOWN) { ptLast.x = LOWORD(lParam); ptLast.y = HIWORD(lParam); _event = MouseDown; } else if (msg == WM_LBUTTONUP) { _event = MouseUp; } } else if (_code == MButton) { if (msg == WM_MBUTTONDOWN) { ptLast.x = LOWORD(lParam); ptLast.y = HIWORD(lParam); _event = MouseDown; } else if (msg == WM_MBUTTONUP) { _event = MouseUp; } } else if (_code == RButton) { if (msg == WM_RBUTTONDOWN) { ptLast.x = LOWORD(lParam); ptLast.y = HIWORD(lParam); _event = MouseDown; } else if (msg == WM_RBUTTONUP) { _event = MouseUp; } } else if (_code == Moving) { if (msg == WM_MOUSEMOVE) { ptLast.x = LOWORD(lParam); ptLast.y = HIWORD(lParam); _event = MouseMove; } } else if (_code == Wheel) { if (msg == 0x020A/*WM_MOUSEWHEEL*/) { scroll = HIWORD(wParam); _event = WheelScroll; } } return 0; }
程序1.2
LRESULT KeyInput::msgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { if (msg == WM_KEYDOWN) { if (_event == None && _code == wParam) { _event = KeyDown; } } else if (msg == WM_KEYUP) { if (_code == wParam) { _event = KeyUp; } } return 0; }
完整代码
Input.h
#pragma once enum InputEvent//输入消息的事件 { None, MouseDown, Mouseing, MouseUp, WheelScroll, KeyDown, Keying, KeyUp, MouseMove }; class InputBase { protected: InputEvent _event; int _code; public: virtual void nextState() = 0; virtual LRESULT msgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) = 0; }; class KeyInput :public InputBase { public: KeyInput(int code); void nextState(); LRESULT msgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); bool getKey() { return _event == Keying; } bool getKeyDown() { return _event == KeyDown; } bool getKeyUp() { return _event == KeyUp; } }; struct MouseData { short scroll; //滚动码 POINT delta; //鼠标根据上一个点的偏移值 POINT mousePos; //现在的点 }; enum MouseCode { LButton, MButton, RButton, Wheel, Moving }; class MouseInput :public InputBase { private: short scroll; POINT ptLast; POINT pt; public: MouseInput(MouseCode code); void nextState(); LRESULT msgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); bool getMouse(MouseData * mouseData = NULL); bool getMouseMove(MouseData * mouseData = NULL); bool getMouseDown(MouseData * mouseData = NULL); bool getMouseUp(MouseData * mouseData = NULL); bool getMouseWheel(MouseData * mouseData = NULL); }; class Input//管理类 { private: static map<string, InputBase*> inputList; public: static LRESULT msgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); static void flush(); static bool getKey(int keyCode); static bool getKeyDown(int keyCode); static bool getKeyUp(int keyCode); static bool getMouse(MouseCode mouseCode, MouseData * mouseData = NULL); static bool getMouseDown(MouseCode mouseCode, MouseData * mouseData = NULL); static bool getMouseUp(MouseCode mouseCode, MouseData * mouseData = NULL); static bool getMouseWheel(MouseData * mouseData = NULL); static bool getMouseMove(MouseData * mouseData = NULL); };
Input.cpp
#include "Engine.h" KeyInput::KeyInput(int code) { _event = None; _code = code; } void KeyInput::nextState() { if (_event == KeyDown) { _event = Keying; } else if (_event == KeyUp) { _event = None; } } LRESULT KeyInput::msgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { if (msg == WM_KEYDOWN) { if (_event == None && _code == wParam) { _event = KeyDown; } } else if (msg == WM_KEYUP) { if (_code == wParam) { _event = KeyUp; } } return 0; } MouseInput::MouseInput(MouseCode code) { _event = None; _code = code; } void MouseInput::nextState() { if (_event == MouseDown) { _event = Mouseing; } else if (_event == MouseUp) { _event = None; } else if (_event == WheelScroll) { _event = None; } else if (_event==MouseMove&&_event==MouseUp) { _event = MouseMove; } else if (_event==Mouseing) { ptLast = pt; } } LRESULT MouseInput::msgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { if (_code == LButton) { if (msg == WM_LBUTTONDOWN) { ptLast.x = LOWORD(lParam); ptLast.y = HIWORD(lParam); _event = MouseDown; } else if (msg == WM_LBUTTONUP) { _event = MouseUp; } } else if (_code == MButton) { if (msg == WM_MBUTTONDOWN) { ptLast.x = LOWORD(lParam); ptLast.y = HIWORD(lParam); _event = MouseDown; } else if (msg == WM_MBUTTONUP) { _event = MouseUp; } } else if (_code == RButton) { if (msg == WM_RBUTTONDOWN) { ptLast.x = LOWORD(lParam); ptLast.y = HIWORD(lParam); _event = MouseDown; } else if (msg == WM_RBUTTONUP) { _event = MouseUp; } } else if (_code == Moving) { if (msg == WM_MOUSEMOVE) { ptLast.x = LOWORD(lParam); ptLast.y = HIWORD(lParam); _event = MouseMove; } } else if (_code == Wheel) { if (msg == 0x020A/*WM_MOUSEWHEEL*/) { scroll = HIWORD(wParam); _event = WheelScroll; } } return 0; } bool MouseInput::getMouse(MouseData *mouseData) { bool f = _event == Mouseing; if (f == true && mouseData != NULL) { GetCursorPos(&pt); ScreenToClient(CPlateForm::getInstance()->getHwnd(), &pt); mouseData->mousePos.x = pt.x; mouseData->mousePos.y = pt.y; mouseData->delta.x = pt.x - ptLast.x; mouseData->delta.y = pt.y - ptLast.y; mouseData->scroll = 0; } return f; } bool MouseInput::getMouseMove(MouseData *mouseData) { bool f = _event == MouseMove; if (f == true && mouseData != NULL) { GetCursorPos(&pt); ScreenToClient(CPlateForm::getInstance()->getHwnd(), &pt); mouseData->mousePos.x = pt.x; mouseData->mousePos.y = pt.y; mouseData->delta.x = pt.x - ptLast.x; mouseData->delta.y = pt.y - ptLast.y; mouseData->scroll = 0; ptLast = pt; GLint viewport[4]; //视口 glGetIntegerv(GL_VIEWPORT, viewport); //得到的是最后一个设置视口的参数 POINT st; st.x = viewport[2] * 0.5; st.y = viewport[3] * 0.5; ClientToScreen(CPlateForm::getInstance()->getHwnd(), &st);//应该是吧鼠标锁在窗口的中心点 SetCursorPos(st.x, st.y); } return f; } bool MouseInput::getMouseDown(MouseData * mouseData) { bool f = _event == MouseDown; if (f == true && mouseData != NULL) { POINT pt; GetCursorPos(&pt); ScreenToClient(CPlateForm::getInstance()->getHwnd(), &pt); memset(mouseData, 0, sizeof(MouseData)); mouseData->mousePos.x = pt.x; mouseData->mousePos.y = pt.y; } return f; } bool MouseInput::getMouseUp(MouseData * mouseData) { bool f = _event == MouseUp; if (f == true && mouseData != NULL) { POINT pt; GetCursorPos(&pt); ScreenToClient(CPlateForm::getInstance()->getHwnd(), &pt);//转换成像素点 memset(mouseData, 0, sizeof(MouseData)); mouseData->mousePos.x = pt.x; mouseData->mousePos.y = pt.y; } return f; } bool MouseInput::getMouseWheel(MouseData * mouseData) { bool f = _event == WheelScroll; if (f == true && mouseData != NULL) { POINT pt; GetCursorPos(&pt); ScreenToClient(CPlateForm::getInstance()->getHwnd(), &pt); mouseData->mousePos.x = pt.x; mouseData->mousePos.y = pt.y; mouseData->scroll = scroll; ptLast = pt; } return f; } map<string, InputBase*> Input::inputList; LRESULT Input::msgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { map<string, InputBase*>::iterator iter; for (iter = inputList.begin(); iter != inputList.end(); iter++) { iter->second->msgProc(hWnd, msg, wParam, lParam); } return 0; } void Input::flush() { map<string, InputBase*>::iterator iter; for (iter = inputList.begin(); iter != inputList.end(); iter++) { iter->second->nextState(); } } bool Input::getKey(int keyCode) { static char str[20]; sprintf(str, "key_%d", keyCode); if (inputList[str] == NULL) { inputList[str] = new KeyInput(keyCode); } return ((KeyInput*)inputList[str])->getKey(); } bool Input::getKeyDown(int keyCode) { static char str[20]; sprintf(str, "key_%d", keyCode); if (inputList[str] == NULL) { inputList[str] = new KeyInput(keyCode); } return ((KeyInput*)inputList[str])->getKeyDown(); } bool Input::getKeyUp(int keyCode) { static char str[20]; sprintf(str, "key_%d", keyCode); if (inputList[str] == NULL) { inputList[str] = new KeyInput(keyCode); } return ((KeyInput*)inputList[str])->getKeyUp(); } bool Input::getMouse(MouseCode mouseCode, MouseData * mouseData) { static char str[20]; sprintf(str, "mouse_%d", mouseCode); if (inputList[str] == NULL) { inputList[str] = new MouseInput(mouseCode); } return ((MouseInput*)inputList[str])->getMouse(mouseData); } bool Input::getMouseDown(MouseCode mouseCode, MouseData * mouseData) { static char str[20]; sprintf(str, "mouse_%d", mouseCode); if (inputList[str] == NULL) { inputList[str] = new MouseInput(mouseCode); } return ((MouseInput*)inputList[str])->getMouseDown(mouseData); } bool Input::getMouseUp(MouseCode mouseCode, MouseData * mouseData) { static char str[20]; sprintf(str, "mouse_%d", mouseCode); if (inputList[str] == NULL) { inputList[str] = new MouseInput(mouseCode); } return ((MouseInput*)inputList[str])->getMouseUp(mouseData); } bool Input::getMouseWheel(MouseData * mouseData) { if (inputList["wheel"] == NULL) { inputList["wheel"] = new MouseInput(MouseCode::Wheel); } return ((MouseInput*)inputList["wheel"])->getMouseWheel(mouseData); } bool Input::getMouseMove(MouseData * mouseData) { if (inputList["move"] == NULL) { inputList["move"] = new MouseInput(MouseCode::Moving); } return ((MouseInput*)inputList["move"])->getMouseMove(mouseData); }