按钮消息处理方式优化

This commit is contained in:
Nomango 2018-07-28 22:22:58 +08:00
parent 614873dfb6
commit 35ed2427c1
11 changed files with 149 additions and 211 deletions

View File

@ -13,9 +13,7 @@ e2d::Input::Input()
CoInitialize(nullptr);
ZeroMemory(_keyBuffer, sizeof(_keyBuffer));
ZeroMemory(_keyRecordBuffer, sizeof(_keyRecordBuffer));
ZeroMemory(&_mouseState, sizeof(_mouseState));
ZeroMemory(&_mouseRecordState, sizeof(_mouseRecordState));
// ³õʼ»¯½Ó¿Ú¶ÔÏó
HRESULT hr = DirectInput8Create(
@ -116,7 +114,6 @@ void e2d::Input::update()
}
else
{
strcpy_s(_keyRecordBuffer, 256, _keyBuffer);
_keyboardDevice->GetDeviceState(sizeof(_keyBuffer), (void**)&_keyBuffer);
}
}
@ -132,7 +129,6 @@ void e2d::Input::update()
}
else
{
_mouseRecordState = _mouseState;
_mouseDevice->GetDeviceState(sizeof(_mouseState), (void**)&_mouseState);
}
}
@ -145,22 +141,6 @@ bool e2d::Input::isDown(KeyCode key)
return false;
}
bool e2d::Input::isPress(KeyCode key)
{
if ((_keyBuffer[static_cast<int>(key)] & 0x80) &&
!(_keyRecordBuffer[static_cast<int>(key)] & 0x80))
return true;
return false;
}
bool e2d::Input::isRelease(KeyCode key)
{
if (!(_keyBuffer[static_cast<int>(key)] & 0x80) &&
(_keyRecordBuffer[static_cast<int>(key)] & 0x80))
return true;
return false;
}
bool e2d::Input::isDown(MouseCode code)
{
if (_mouseState.rgbButtons[static_cast<int>(code)] & 0x80)
@ -168,22 +148,6 @@ bool e2d::Input::isDown(MouseCode code)
return false;
}
bool e2d::Input::isPress(MouseCode code)
{
if ((_mouseState.rgbButtons[static_cast<int>(code)] & 0x80) &&
!(_mouseRecordState.rgbButtons[static_cast<int>(code)] & 0x80))
return true;
return false;
}
bool e2d::Input::isRelease(MouseCode code)
{
if (!(_mouseState.rgbButtons[static_cast<int>(code)] & 0x80) &&
(_mouseRecordState.rgbButtons[static_cast<int>(code)] & 0x80))
return true;
return false;
}
float e2d::Input::getMouseX()
{
return getMousePos().x;
@ -196,14 +160,14 @@ float e2d::Input::getMouseY()
e2d::Point e2d::Input::getMousePos()
{
HWND hWnd = Window::getInstance()->getHWnd();
auto window = Window::getInstance();
POINT mousePos;
GetCursorPos(&mousePos);
ScreenToClient(hWnd, &mousePos);
::GetCursorPos(&mousePos);
::ScreenToClient(window->getHWnd(), &mousePos);
UINT ret = ::GetDpiForWindow(hWnd);
return Point(mousePos.x * 96.f / ret, mousePos.y * 96.f / ret);
float dpi = window->getDpi();
return Point(mousePos.x * 96.f / dpi, mousePos.y * 96.f / dpi);
}
float e2d::Input::getMouseDeltaX()

View File

@ -11,6 +11,7 @@ e2d::Window::Window()
, _size(640, 480)
, _title(L"Easy2D Game")
, _iconID(0)
, _dpi(0.f)
{
}
@ -164,6 +165,8 @@ HWND e2d::Window::__create()
HMENU hmenu = ::GetSystemMenu(consoleHWnd, FALSE);
::RemoveMenu(hmenu, SC_CLOSE, MF_BYCOMMAND);
}
// »ñÈ¡ DPI
_dpi = static_cast<float>(::GetDpiForWindow(hWnd));
}
else
{
@ -196,6 +199,11 @@ e2d::Size e2d::Window::getSize()
return _size;
}
float e2d::Window::getDpi()
{
return _dpi;
}
e2d::String e2d::Window::getTitle()
{
return _title;
@ -410,7 +418,7 @@ LRESULT e2d::Window::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPar
case WM_MOUSEMOVE:
case WM_MOUSEWHEEL:
{
SceneManager::getInstance()->dispatch(MouseEvent(message, wParam, lParam));
SceneManager::getInstance()->dispatch(MouseEvent(hWnd, message, wParam, lParam));
}
result = 0;
hasHandled = true;
@ -420,7 +428,7 @@ LRESULT e2d::Window::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPar
case WM_KEYDOWN:
case WM_KEYUP:
{
SceneManager::getInstance()->dispatch(KeyEvent(message, wParam, lParam));
SceneManager::getInstance()->dispatch(KeyEvent(hWnd, message, wParam, lParam));
}
result = 0;
hasHandled = true;
@ -434,8 +442,8 @@ LRESULT e2d::Window::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPar
if (wParam == SIZE_RESTORED)
{
UINT dpi = ::GetDpiForWindow(hWnd);
_instance->_size = Size(width * 96.f / dpi, height * 96.f / dpi);
_instance->_size.width = width * 96.f / _instance->_dpi;
_instance->_size.height = height * 96.f / _instance->_dpi;
}
// 如果程序接收到一个 WM_SIZE 消息,这个方法将调整渲染

View File

@ -37,14 +37,14 @@ void e2d::Scene::update()
{
if (_autoUpdate)
{
this->onUpdate();
onUpdate();
}
_root->_update();
}
void e2d::Scene::dispatch(const MouseEvent & e)
{
if (this->onMouseEvent(e))
if (onMouseEvent(e))
{
_root->dispatch(e);
}
@ -52,7 +52,7 @@ void e2d::Scene::dispatch(const MouseEvent & e)
void e2d::Scene::dispatch(const KeyEvent & e)
{
if (this->onKeyEvent(e))
if (onKeyEvent(e))
{
_root->dispatch(e);
}

View File

@ -1,7 +1,7 @@
#include "..\e2dcommon.h"
e2d::KeyEvent::KeyEvent(UINT message, WPARAM wParam, LPARAM lParam)
e2d::KeyEvent::KeyEvent(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
: _code(KeyCode(wParam))
, _type(Type(message))
, _count(static_cast<int>((DWORD)lParam & 0x0000FFFF))

View File

@ -1,13 +1,15 @@
#include "..\e2dcommon.h"
#include "..\e2dbase.h"
e2d::MouseEvent::MouseEvent(UINT message, WPARAM wParam, LPARAM lParam)
: _pos(LOWORD(lParam), HIWORD(lParam))
, _shiftDown(GET_KEYSTATE_WPARAM(wParam) == MK_SHIFT)
, _ctrlDown(GET_KEYSTATE_WPARAM(wParam) == MK_CONTROL)
, _wheelDelta(GET_WHEEL_DELTA_WPARAM(wParam))
e2d::MouseEvent::MouseEvent(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
: _message(message)
, _wParam(wParam)
, _lParam(lParam)
, _type(Type(message))
{
float dpi = Window::getInstance()->getDpi();
_pos.x = ((float)(short)LOWORD(lParam)) * 96.f / dpi;
_pos.y = ((float)(short)HIWORD(lParam)) * 96.f / dpi;
}
float e2d::MouseEvent::getX() const
@ -27,17 +29,32 @@ e2d::Point e2d::MouseEvent::getPos() const
bool e2d::MouseEvent::isShiftDown() const
{
return _shiftDown;
return GET_KEYSTATE_WPARAM(_wParam) == MK_SHIFT;
}
bool e2d::MouseEvent::isCtrlDown() const
{
return _ctrlDown;
return GET_KEYSTATE_WPARAM(_wParam) == MK_CONTROL;
}
float e2d::MouseEvent::getWheelDelta() const
{
return _wheelDelta;
return static_cast<float>(GET_WHEEL_DELTA_WPARAM(_wParam));
}
bool e2d::MouseEvent::isLButtonDown() const
{
return GET_KEYSTATE_WPARAM(_wParam) == MK_LBUTTON;
}
bool e2d::MouseEvent::isRButtonDown() const
{
return GET_KEYSTATE_WPARAM(_wParam) == MK_RBUTTON;
}
bool e2d::MouseEvent::isMButtonDown() const
{
return GET_KEYSTATE_WPARAM(_wParam) == MK_MBUTTON;
}
e2d::MouseEvent::Type e2d::MouseEvent::getType() const

View File

@ -6,7 +6,7 @@
e2d::Button::Button()
: _func(nullptr)
, _state(ButtonState::Normal)
, _status(Status::Normal)
, _enabled(true)
, _isSelected(false)
, _normal(nullptr)
@ -18,7 +18,7 @@ e2d::Button::Button()
e2d::Button::Button(Node * normal, const Function& func)
: _func(nullptr)
, _state(ButtonState::Normal)
, _status(Status::Normal)
, _enabled(true)
, _isSelected(false)
, _normal(nullptr)
@ -32,7 +32,7 @@ e2d::Button::Button(Node * normal, const Function& func)
e2d::Button::Button(Node * normal, Node * selected, const Function& func)
: _func(nullptr)
, _state(ButtonState::Normal)
, _status(Status::Normal)
, _enabled(true)
, _isSelected(false)
, _normal(nullptr)
@ -47,7 +47,7 @@ e2d::Button::Button(Node * normal, Node * selected, const Function& func)
e2d::Button::Button(Node * normal, Node * mouseover, Node * selected, const Function& func)
: _func(nullptr)
, _state(ButtonState::Normal)
, _status(Status::Normal)
, _enabled(true)
, _isSelected(false)
, _normal(nullptr)
@ -63,7 +63,7 @@ e2d::Button::Button(Node * normal, Node * mouseover, Node * selected, const Func
e2d::Button::Button(Node * normal, Node * mouseover, Node * selected, Node * disabled, const Function& func)
: _func(nullptr)
, _state(ButtonState::Normal)
, _status(Status::Normal)
, _enabled(true)
, _isSelected(false)
, _normal(nullptr)
@ -188,69 +188,65 @@ void e2d::Button::setPivot(float pivotX, float pivotY)
SAFE_SET(_disabled, setPivot, pivotX, pivotY);
}
void e2d::Button::_update()
void e2d::Button::dispatch(const MouseEvent & e)
{
Node::_update();
if (SceneManager::getInstance()->isTransitioning())
return;
auto input = Input::getInstance();
auto window = Window::getInstance();
if (_enabled && _visible && _normal)
{
if (input->isRelease(MouseCode::Left))
{
// 鼠标左键抬起时,判断鼠标坐标是否在按钮内部
if (_isSelected &&
_normal->containsPoint(input->getMousePos()))
bool contains = _normal->containsPoint(e.getPos());
if (e.getType() == MouseEvent::Type::LeftUp && _isSelected && contains)
{
_isSelected = false;
_runCallback();
_setStatus(Status::Normal);
}
else if (e.getType() == MouseEvent::Type::LeftDown)
{
_isSelected = contains;
_setStatus(contains ? Status::Selected : Status::Normal);
}
else if (e.getType() == MouseEvent::Type::LeftUp)
{
_isSelected = false;
}
else if (e.getType() == MouseEvent::Type::Move && _isSelected && contains)
{
_setStatus(Status::Selected);
}
else
{
if (!e.isLButtonDown() && _isSelected)
{
_isSelected = false;
}
_setStatus(contains ? Status::Mouseover : Status::Normal);
}
}
if (input->isPress(MouseCode::Left))
{
if (_normal->containsPoint(input->getMousePos()))
{
// 鼠标左键按下,且位于按钮内时,标记 _isSelected 为 true
_isSelected = true;
return;
}
}
Node::dispatch(e);
}
if (_isSelected && input->isDown(MouseCode::Left))
{
if (_normal->containsPoint(input->getMousePos()))
{
_setState(ButtonState::Selected);
window->setCursor(Window::Cursor::Hand);
return;
}
}
else if (_normal->containsPoint(input->getMousePos()))
{
_setState(ButtonState::Mouseover);
window->setCursor(Window::Cursor::Hand);
return;
}
void e2d::Button::_render()
{
Node::_render();
_setState(ButtonState::Normal);
}
if (_visible && !_enabled && _normal && _normal->containsPoint(input->getMousePos()))
if (_visible &&
!_enabled &&
_normal &&
_normal->containsPoint(Input::getInstance()->getMousePos()))
{
window->setCursor(Window::Cursor::No);
Window::getInstance()->setCursor(Window::Cursor::No);
}
else if (_status == Status::Mouseover || _status == Status::Selected)
{
Window::getInstance()->setCursor(Window::Cursor::Hand);
}
}
void e2d::Button::_setState(ButtonState state)
void e2d::Button::_setStatus(Status status)
{
if (_state != state)
if (_status != status)
{
_state = state;
_status = status;
_updateVisible();
}
}
@ -264,11 +260,11 @@ void e2d::Button::_updateVisible()
if (_enabled)
{
if (_state == ButtonState::Selected && _selected)
if (_status == Status::Selected && _selected)
{
_selected->setVisible(true);
}
else if (_state == ButtonState::Mouseover && _mouseover)
else if (_status == Status::Mouseover && _mouseover)
{
_mouseover->setVisible(true);
}

View File

@ -304,79 +304,31 @@ void e2d::Node::updateTransform()
}
}
bool e2d::Node::dispatch(const MouseEvent & e)
void e2d::Node::dispatch(const MouseEvent & e)
{
if (_children.empty())
{
return onMouseEvent(e);
}
else
{
size_t i;
for (i = 0; i < _children.size(); ++i)
{
auto child = _children[i];
if (child->getOrder() < 0)
{
if (!child->dispatch(e))
{
return false;
}
}
else
{
break;
}
}
if (!onMouseEvent(e))
return;
if (!_children.empty())
{
return false;
for (auto child : _children)
{
child->dispatch(e);
}
for (; i < _children.size(); ++i)
if (!_children[i]->dispatch(e))
return false;
return true;
}
}
bool e2d::Node::dispatch(const KeyEvent & e)
void e2d::Node::dispatch(const KeyEvent & e)
{
if (_children.empty())
{
return onKeyEvent(e);
}
else
{
size_t i;
for (i = 0; i < _children.size(); ++i)
{
auto child = _children[i];
if (child->getOrder() < 0)
{
if (!child->dispatch(e))
{
return false;
}
}
else
{
break;
}
}
if (!onKeyEvent(e))
return;
if (!_children.empty())
{
return false;
for (auto child : _children)
{
child->dispatch(e);
}
for (; i < _children.size(); ++i)
if (!_children[i]->dispatch(e))
return false;
return true;
}
}

View File

@ -12,7 +12,7 @@
this->addChild(New); \
} \
Old = New; \
_updateState(); \
_updateStatus(); \
_updateVisible(); \
} \
@ -117,7 +117,7 @@ void e2d::ToggleButton::setChecked(bool checked)
if (_checked != checked)
{
_checked = checked;
_updateState();
_updateStatus();
_updateVisible();
}
}
@ -176,7 +176,7 @@ void e2d::ToggleButton::setPivot(float pivotX, float pivotY)
SAFE_SET(_disabledOff, setPivot, pivotX, pivotY);
}
void e2d::ToggleButton::_updateState()
void e2d::ToggleButton::_updateStatus()
{
if (_checked)
{
@ -207,7 +207,7 @@ void e2d::ToggleButton::_updateState()
void e2d::ToggleButton::_runCallback()
{
_checked = !_checked;
_updateState();
_updateStatus();
if (_func)
{

View File

@ -230,6 +230,9 @@ public:
// 获取窗体大小
Size getSize();
// »ñÈ¡´°¿Ú DPI
float getDpi();
// 获取窗口句柄
HWND getHWnd();
@ -279,6 +282,7 @@ private:
Size _size;
String _title;
int _iconID;
float _dpi;
static Window * _instance;
};
@ -299,31 +303,11 @@ public:
KeyCode key
);
// 检测键盘某按键是否被点击
bool isPress(
KeyCode key
);
// 检测键盘某按键是否正在松开
bool isRelease(
KeyCode key
);
// 检测鼠标按键是否正被按下
bool isDown(
MouseCode code
);
// 检测鼠标按键是否被点击
bool isPress(
MouseCode code
);
// 检测鼠标按键是否正在松开
bool isRelease(
MouseCode code
);
// 获得鼠标X轴坐标值
float getMouseX();
@ -357,9 +341,7 @@ private:
IDirectInputDevice8W* _keyboardDevice;
IDirectInputDevice8W* _mouseDevice;
DIMOUSESTATE _mouseState;
DIMOUSESTATE _mouseRecordState;
char _keyBuffer[256];
char _keyRecordBuffer[256];
static Input * _instance;
};

View File

@ -586,6 +586,7 @@ public:
public:
explicit KeyEvent(
HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam
@ -634,15 +635,19 @@ public:
public:
explicit MouseEvent(
HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam
);
// 获取鼠标横坐标
float getX() const;
// 获取鼠标纵坐标
float getY() const;
// 获取鼠标坐标
Point getPos() const;
// 获取事件类型
@ -650,6 +655,15 @@ public:
float getWheelDelta() const;
// 鼠标左键是否按下
bool isLButtonDown() const;
// 鼠标右键是否按下
bool isRButtonDown() const;
// 鼠标中键是否按下
bool isMButtonDown() const;
// Shift 键是否按下
bool isShiftDown() const;
@ -657,9 +671,9 @@ public:
bool isCtrlDown() const;
protected:
bool _shiftDown;
bool _ctrlDown;
float _wheelDelta;
UINT _message;
WPARAM _wParam;
LPARAM _lParam;
Point _pos;
MouseEvent::Type _type;
};

View File

@ -402,12 +402,12 @@ public:
void updateTransform();
// 分发鼠标消息
bool dispatch(
virtual void dispatch(
const MouseEvent& e
);
// 分发按键消息
bool dispatch(
virtual void dispatch(
const KeyEvent& e
);
@ -827,17 +827,22 @@ public:
float pivotY
) override;
// 分发鼠标消息
virtual void dispatch(
const MouseEvent& e
) override;
protected:
E2D_DISABLE_COPY(Button);
// 按钮状态枚举
enum class ButtonState { Normal, Mouseover, Selected };
enum class Status { Normal, Mouseover, Selected };
// 更新节点
virtual void _update() override;
// 渲染节点
virtual void _render() override;
// 设置按钮状态
virtual void _setState(ButtonState state);
virtual void _setStatus(Status status);
// 刷新按钮显示
virtual void _updateVisible();
@ -852,7 +857,7 @@ protected:
Node * _disabled;
bool _enabled;
bool _isSelected;
ButtonState _state;
Status _status;
Function _func;
};
@ -958,7 +963,7 @@ protected:
E2D_DISABLE_COPY(ToggleButton);
// 刷新按钮开关
virtual void _updateState();
virtual void _updateStatus();
// 执行按钮函数对象
virtual void _runCallback() override;