代码组织

  • 代码: 写在 View
  • 数据: 写在 Doc
  • 变量: 在 View.h 中申明, 在 View.cpp 的构造函数中初始化, 在 View.cpp 的析构函数中释放

添加消息函数

Class View视图 > 右击View类 > Properties > 点击Messages图标 > 找相应的

注册函数 ON_COMMAND

Class View视图 > 右击View类 > Properties > 点击Events图标 > 找相应的 (注: 比如menu设置N选1型(menu 中选择其中之一会打钩$\checkmark$), 类似操作, 在每个项目的第二个点击添加, 然后代码类似如下:

void COpenGLView::OnUpdateButtonLighton(CCmdUI *pCmdUI)
{
    // TODO: Add your command update UI handler code here
    pCmdUI->SetCheck(m_nLightState == LIGHT_ON);
}

添加状态栏提示信息

  • MainFrm.cpp中添加文字占位符, 粗体为新添加

    static UINT indicators[] =
    {
        ID_SEPARATOR, // status line indicator
        ID_SEPARATOR, // for 2D & 3D DT/VD
        ID_SEPARATOR, // for CGAL 2D & 3D DT/VD
        ID_INDICATOR_CAPS,
        ID_INDICATOR_NUM,
        ID_INDICATOR_SCRL,
    };
    
  • int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) 中设置所添加的占位符的宽度, 不设的话为默认值; 最后一个值是宽度值.

    m_wndStatusBar.SetPaneInfo(1,ID_SEPARATOR,0,150);
    m_wndStatusBar.SetPaneInfo(2,ID_SEPARATOR,0,150);
    
  • 在想显示提示信息的地方添加如下代码即可:

    CStatusBar * pStatus=(CStatusBar*) AfxGetApp()->m_pMainWnd->GetDescendantWindow(AFX_IDW_STATUS_BAR );
    pStatus->SetPaneText(1, "xxxxxx"); // set first
    pStatus->SetPaneText(2, "xxxxxx"); // set second
    

可以先增加Toolbar, 再增加Menu, 使得两者的ID一样就OK.

Warning提示信息

方式可以

MessageBox("Could not delete RC");

键盘处理

bool keyDown[256];
void COpenGLView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
    // TODO: Add your message handler code here and/or call default
    char nChar2=nChar;
    if (!GetAsyncKeyState(VK_LSHIFT) && nChar2<='Z' && nChar2>='A')
    {
        nChar2+='a'-'A';
    }
    keyDown[nChar2] = true;
    InvalidateRect(NULL,FALSE);
    CView::OnKeyDown(nChar, nRepCnt, nFlags);
}

void COpenGLView::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
{
    char nChar2=nChar;
    if (!GetAsyncKeyState(VK_LSHIFT) && nChar2<='Z'&&nChar2>='A')
    {
        nChar2+='a'-'A';
    }
    keyDown[nChar2] = false;
}

再在画的函数中进行真正处理:

void COpenGLView::RenderScene ()
{
    ... ...
    if (keyDown['w'])
    {
        // handling here...
    }    
    ... ...
}

鼠标处理

  • 左键处理: (中键 – 右键 类似)

    int buttonState;
    void COpenGLView::OnLButtonDown(UINT nFlags, CPoint point)
    {
        // TODO: Add your message handler code here and/or call default
        m_MouseDownPoint=point;
        SetCapture();
        buttonState = GLUT_LEFT_BUTTON;
        CView::OnLButtonDown(nFlags, point);
    }
    
    void COpenGLView::OnLButtonUp(UINT nFlags, CPoint point)
    {
        // TODO: Add your message handler code here and/or call default
        m_MouseDownPoint=CPoint(0,0);
        ReleaseCapture();
        buttonState = -1;
        CView::OnLButtonUp(nFlags, point);
    }
    
  • 真正的处理在 OnMouseMove() 函数中:

    void COpenGLView::OnMouseMove(UINT nFlags, CPoint point)
    {
        // TODO: Add your message handler code here and/or call default
        // Check if we have captured the mouse
        if (GetCapture()==this)
        {
            float dx, dy;
            dx = point.x - m_MouseDownPoint.x;
            dy = point.y - m_MouseDownPoint.y;
        }
        if (buttonState == GLUT_LEFT_BUTTON)
        {
            //
        }
        if (buttonState == GLUT_MIDDLE_BUTTON)
        {
            //
        }
        if (buttonState == GLUT_RIGHT_BUTTON)
        {
            //
        }
        m_MouseDownPoint=point;
        InvalidateRect(NULL,FALSE);
        CView::OnMouseMove(nFlags, point);
    }
    

打开文件对话框

添加方法如下:

CFileDialog fOpenDlg(TRUE, "wrl", "", OFN_HIDEREADONLY|OFN_FILEMUSTEXIST, "Mesh Files (*.wrl)|*.wrl|", this);
fOpenDlg.m_ofn.lpstrTitle="Open Mesh Files";
fOpenDlg.m_ofn.lpstrInitialDir=".\\data\\";
if(fOpenDlg.DoModal()==IDOK)
{
    CString meshPath= fOpenDlg.GetPathName();
    ... ...
}

注: 若想能同时打开多个文件, 同时可以设置同时打开的上限, 默认20个, 方法如下(同样包含如何挨个获得每个文件的Path):

CFileDialog fOpenDlg(TRUE, "wrl", "", OFN_HIDEREADONLY|OFN_FILEMUSTEXIST|OFN_ALLOWMULTISELECT|OFN_EXPLORER|OFN_ENABLEHOOK, "Mesh Files (*.wrl)|*.wrl|", this);
fOpenDlg.m_ofn.lpstrTitle="Open Mesh Files";
fOpenDlg.m_ofn.lpstrInitialDir=".\\data\\";
//extend to be able to open 100 files at a time, default only 20
fOpenDlg.m_ofn.nMaxFile=100*MAX_PATH;
fOpenDlg.m_ofn.lpstrFile=new TCHAR[fOpenDlg.m_ofn.nMaxFile];
ZeroMemory(fOpenDlg.m_ofn.lpstrFile, sizeof(TCHAR)*fOpenDlg.m_ofn.nMaxFile);
if(fOpenDlg.DoModal()==IDOK)
{
    // Retrieve file name(s).
    vector<CString> meshPath;
    POSITION fileNamesPosition = fOpenDlg.GetStartPosition();
    while(fileNamesPosition != NULL)
    {
        CString stub = fOpenDlg.GetNextPathName(fileNamesPosition);
        meshPath.push_back((CString)stub);
    }
    ... ...
}