考虑COpenGLControl class here in codeguru。我已经为您上传了最后一堂课here,但如果您有兴趣,可以下载at the bottom of the webpage Setting Up OpenGL in an MFC Control. the name of the file is BF_oglMFCDialog_Part2.zip。
我的问题是,您在课程标题中定义了m_fLastX
和m_fLastY
:
OpenGLControl.h
class COpenGLControl : public CWnd
{
public:
/******************/
/* Public Members */
/******************/
UINT_PTR m_unpTimer;
// View information variables
float m_fLastX;
float m_fLastY;
float m_fPosX;
但是它们没有在类的构造函数中初始化而在其他任何地方都没有初始化,但是在OnMouseMove
事件处理程序中没有初始化时使用它们:
OpenGLControl.cpp
COpenGLControl::COpenGLControl(void)
{
m_fPosX = 0.0f; // X position of model in camera view
m_fPosY = 0.0f; // Y position of model in camera view
m_fZoom = 10.0f; // Zoom on model in camera view
m_fRotX = 0.0f; // Rotation on model in camera view
m_fRotY = 0.0f; // Rotation on model in camera view
m_bIsMaximized = false;
}
void COpenGLControl::OnMouseMove(UINT nFlags, CPoint point)
{
int diffX = (int)(point.x - m_fLastX);
int diffY = (int)(point.y - m_fLastY);
m_fLastX = (float)point.x;
m_fLastY = (float)point.y;
// Left mouse button
if (nFlags & MK_LBUTTON)
{
m_fRotX += (float)0.5f * diffY;
if ((m_fRotX > 360.0f) || (m_fRotX < -360.0f))
{
m_fRotX = 0.0f;
}
m_fRotY += (float)0.5f * diffX;
if ((m_fRotY > 360.0f) || (m_fRotY < -360.0f))
{
m_fRotY = 0.0f;
}
}
// Right mouse button
else if (nFlags & MK_RBUTTON)
{
m_fZoom -= (float)0.1f * diffY;
}
// Middle mouse button
else if (nFlags & MK_MBUTTON)
{
m_fPosX += (float)0.05f * diffX;
m_fPosY -= (float)0.05f * diffY;
}
OnDraw(NULL);
CWnd::OnMouseMove(nFlags, point);
}
你能解释一下如何使用这些未初始化的变量而不会出现任何错误吗?
实际上OnMouseMove
函数中使用的算法是什么?
或者事件处理程序如何与其他函数不同?
答案 0 :(得分:1)
使用未初始化的变量不是错误。它会给出一个不确定的结果,这可能导致逻辑/算术错误。
现在,在这个例子中,大多数时候m_fLastX
或m_fLastY
没有初始值可能无关紧要,因为MFC应用程序第一次收到一个初始值的情况很少。鼠标移动事件,用户也按下鼠标按钮。
无论如何,你应该继续纠正这个问题。我将这两个变量初始化为-1.0f(因为CPoint永远不会包含负值),然后在OnMouseMove(...)的顶部添加一些额外的逻辑:
if (m_fLastX < 0.0f && m_fLastY < 0.0f) {
m_fLastX = (float)point.x;
m_fLastY = (float)point.y;
}
或者,在构造函数中,您可以使用m_fLastX
m_fLastY
和GetCursorPos (...)
无论如何,我不会太担心。这只会在OpenGL控件第一次收到鼠标移动事件时影响软件。之后,它将始终具有用于计算鼠标增量的初始化值。
它采用的算法通过在上次通知控件被光标移动并计算它与当前鼠标位置之间的差异时存储鼠标的位置来工作。然后根据按下的按钮对其进行缩放并应用转换。它应用旋转(左按钮),缩放(右按钮)或平移(中间按钮)。
至于MFC事件处理程序,它们只是面向对象的回调。 MFC隐藏内部窗口消息泵,并使用已安装的事件处理程序将事件发送到各个控件。