我有一个使用Ogre3D创建多个渲染窗口的应用程序,并且我使用发布的解决方案here来支持对这些窗口的非独占鼠标输入。但是,我发现在重新获得焦点之前,我必须物理地点击一个渲染窗口,而我真的很喜欢渲染窗口关注于鼠标悬停事件。是否有可能在Ogre3D/OIS中未聚焦的渲染窗口上捕获鼠标悬停事件,然后为渲染窗口设置焦点?使用Ogre3D专注于Windows中的MouseOver
1
A
回答
0
为了在Windows中使用Ogre3D来支持这种功能,我必须实现一个单例对象,它保存了所有实例化显示的集合。
class InputProcessor
{
/// @name Types
/// @{
public:
/// @}
/// @name InputProcessor implementation
/// @{
public:
void addDisplay(Display* _pDisplay);
bool processMouseMoved(int _x, int _y, int _z, int _keyModifier);
bool processMousePressed(int _keyModifier, int _id);
bool processMouseReleased(int _keyModifier, int _id);
static InputProcessor& getSingleton();
/// @}
/// @name 'Structors
/// @{
private:
InputProcessor();
~InputProcessor();
/// @}
/// @name Member Variables
/// @{
private:
typedef std::set<Display*> Displays_type;
Displays_type m_displays;
/// @}
}; // class InputProcessor
然后,在我的UIFrameListener(从OGRE3D的ExampleFrameListener派生),我改变鼠标的窗口坐标全球屏幕坐标。如果鼠标恰好位于窗口区域之外,我将相对鼠标移动应用到最后记录的鼠标位置;否则,我简单地应用窗口内的绝对鼠标位置:
bool
UIFrameListener::mouseMoved(const OIS::MouseEvent& e)
{
int keyModifierState = GetKeyModifierState();
int windowLeft = m_display.getLeft();
int windowTop = m_display.getTop();
int windowWidth = m_display.m_pWindow->getWidth();
int windowHeight = m_display.m_pWindow->getHeight();
if (e.state.X.abs != 0 && e.state.X.abs != windowWidth)
{
m_lastX = e.state.X.abs;
}
else
{
m_lastX += e.state.X.rel;
}
int x = windowLeft + (m_display.m_width * m_lastX)/windowWidth;
if (e.state.Y.abs != 0 && e.state.Y.abs != windowHeight)
{
m_lastY = e.state.Y.abs;
}
else
{
m_lastY += e.state.Y.rel;
}
int y = windowTop + (m_display.m_height * m_lastY)/windowHeight;
int z = 0;
if (e.state.Z.rel != 0)
{
z = e.state.Z.rel/-120;
}
return InputProcessor::getSingleton().processMouseMoved(x, y, z, keyModifierState);
}
而在InputProcessor::processMouseMoved()
,我确定鼠标光标是在其中窗口(如果有的话),然后适当地设定焦点,即
bool
InputProcessor::processMouseMoved(int _x,
int _y,
int _z,
int _keyModifier)
{
bool found = false;
Displays_type::iterator iter = m_displays.begin();
while (iter != m_displays.end() && !found)
{
int left = (*iter)->getLeft();
int top = (*iter)->getTop();
int width = (*iter)->m_pWindow->getWidth();
int height = (*iter)->m_pWindow->getHeight();
if (left <= _x && left + width > _x &&
top <= _y && top + height > _y)
{
found = true;
}
else
{
iter++;
}
}
if (iter != m_displays.end())
{
int left = (*iter)->getLeft();
int top = (*iter)->getTop();
(*iter)->m_pContext->ProcessMouseMove(
_x - left, _y - top, _keyModifier
);
(*iter)->m_pContext->ProcessMouseWheel(_z, _keyModifier);
if (!(*iter)->hasFocus())
{
(*iter)->setFocus(true);
}
}
return true;
}
而且在Display
实施,我有一个方法Display::setFocus()
将焦点设置适当的窗口:
void
Display::setFocus(bool _hasFocus)
{
if (m_handle != NULL && _hasFocus)
{
SetFocus(m_handle);
}
}
相关问题
- 1. jquery:专注于windows(浏览器页面)
- 2. 专注于DataTemplate中的TextBox
- 3. 专注于NSTextView
- 4. 专注于C#中的用户控件
- 5. 使用.focus()专注于span标记()
- 6. 专注于滚动
- 7. zxing专注于iOS
- 8. UWP专注于AutoSuggestBox
- 9. 如何专注于Windows中的新Emacs框架
- 10. 我不想专注于如果用户专注于特定的div
- 11. 专注于上部分和禁用下部分专注
- 12. 无法专注于使用Silverlight的ListBox中的TextBox
- 13. 专注于禁用的MenuItem。 WPF
- 14. 专注于Opera中的跨域Ajax
- 15. Angularjs,专注于表格中的输入
- 16. 专注于angularjs中的错误提交
- 17. 试图专注于$ mdSideNav中的元素
- 18. 专注于div字段
- 19. 专注于坦克(CSS,JS)
- 20. 专注于文本框
- 21. 如何专注于EditText
- 22. ASP.NET C#GridView - 专注于RowEditing
- 23. Jdialog没有专注于IE9
- 24. 专注于文本框
- 25. Kinect-WPF专注于悬停
- 26. 专注于输入字段
- 27. Chrome和IE专注于iframe
- 28. WebView专注于Google TV
- 29. MS CRM - 专注于SubGrig
- 30. android:listview专注于第一项
注意,在许多风管理者,获得关注也意味着将窗口带入字体。对于习惯了窗口管理器的用户来说,这种行为可能非常不寻常。 – 2012-03-06 23:19:08
正式指出 - 在我的特殊应用中,窗户是平铺的,并且具有静态位置,并且您建议的行为实际上是需要的... – hatboyzero 2012-03-07 02:39:47
如果这是真的,那么他们为什么是窗户?你不能只渲染单独的平铺视口吗? – 2012-03-07 02:47:37