最近编译了OSG3.7的源码,通过MFC对话框集成显示。使用过程中,自定义的按键消息无法正常响应(控制台窗口通过openGL的设备上下文环境可以正常响应,所以不是输入法的问题)。网上搜了一下,发现相关文章很少,有一个人反馈的问题http://bbs.osgchina.org/forum.php?mod=viewthread&tid=9747和我遇到的问题一致,但是没说怎么解决的。osg官方集成MFC的demo是基于多文档视图,而且貌似无法正常运行,坑。
简单跟踪了一下源码,原来是MFC默认对话框的KEY_DOWN/KEY_UP消息被界面上的其他控件捕获了,所以基于窗体的m_hWnd绘制的OSG场景无法捕获键盘消息。测试了一下,果真如此。解决办法有两个。
删除界面上的所有控件,
只保留原声窗体(默认的确定/取消按钮也不行,也需要删掉)。
{
。。。。。
mOSG = new cOSG(m_hWnd);
// Init the osg class
mOSG->InitOSG("dumptruck.osg");
}
第二种方法是,新增一个控件,利用控件的m_hWnd绘制osg场景。
{
.....
mOSG = new cOSG(GetDlgItem(IDC_STATIC)->m_hWnd);
// Init the osg class
mOSG->InitOSG("dumptruck.osg");
}
然后自己重载osgGA::GUIEventHandler的虚函数handle,简单测试胆码如下
class KeyBoardCtrlMgr : public osgGA::GUIEventHandler
{
public:
KeyBoardCtrlMgr(){}
~KeyBoardCtrlMgr() {}
bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{
bool bRet(false);
osgViewer::Viewer* viewer = dynamic_cast<osgViewer::Viewer*>(&aa);
if (viewer == NULL) return bRet;
static int _s = 0;
switch (ea.getEventType())
{
case osgGA::GUIEventAdapter::KEYDOWN:
case osgGA::GUIEventAdapter::KEYUP:
if (ea.getKey() == osgGA::GUIEventAdapter::KEY_0)
{
osg::notify(osg::NOTICE) << "Saved model to file 'saved_model.osgt'" << std::endl;
bRet = true;
}
else if (ea.getKey() == osgGA::GUIEventAdapter::KEY_1)
{
osg::notify(osg::NOTICE) << "Saved model to file 'saved_model.osgt'" << std::endl;
bRet = true;
}
break;
case osgGA::GUIEventAdapter::PUSH:
case osgGA::GUIEventAdapter::MOVE:
{
osg::notify(osg::NOTICE) << "Saved model to file 'saved_model.osgt'" << std::endl;
bRet = true;
break;
}
default:
break;
}
return bRet;
}
};
效果都正常,简单记录一下。