考虑codeguru中的COpenGLControl类。我已经在这里为您上传了最后一个类,但您可以在网页底部下载它在MFC控件中设置OpenGL。如果您感兴趣,文件名为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
函数中使用的算法是什么
或者,事件处理程序的工作方式与其他函数有何不同?
使用未初始化的变量不是错误。它将给出一个不确定的结果,这可能导致逻辑/算术错误。
现在,在本例中,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;
}
或者,在构造函数中,可以使用GetCursorPos (...)
的值初始化m_fLastX
和m_fLastY
无论如何,我都不会太担心。这只会在OpenGL控件第一次接收到鼠标移动事件时影响软件。之后,它将始终具有一个初始化值,用于计算鼠标增量。
它使用的算法通过存储上次通知控件光标移动时的鼠标位置,并计算其与当前鼠标位置之间的差来工作。然后,它会缩放此比例,并根据按下的按钮应用变换。它应用旋转(左按钮)、缩放(右按钮)或平移(中按钮)。
至于MFC事件处理程序,它们只是面向对象的回调。MFC隐藏内部窗口消息泵,并使用已安装的事件处理程序将事件发送到各个控件。