0

考虑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事件处理程序中使用:

OpenGL控制.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函数中使用的算法是什么?
或者事件处理程序与其他函数的工作方式有何不同?

4

1 回答 1

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_fLastXm_fLastY使用GetCursorPos (...)

无论如何,我不会太担心它。这只会在 OpenGL 控件第一次收到鼠标移动事件时影响软件。之后,它将始终具有用于计算鼠标增量的初始化值。

它采用的算法通过存储上次通知控件光标移动时鼠标的位置并计算它与当前鼠标位置之间的差异来工作。然后它会根据按下的按钮对其进行缩放并应用转换。它适用于旋转(左键)、缩放(右键)或平移(中键)。

至于 MFC 事件处理程序,它们只是面向对象的回调。MFC 隐藏内部窗口消息泵并使用已安装的事件处理程序将事件发送到各个控件。

于 2013-08-25T22:50:05.170 回答