MFC sumup

代码组织

  • 代码: 写在 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$), 类似操作, 在每个项目的第二个点击添加, 然后代码类似如下:

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

添加状态栏提示信息

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    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) 中设置所添加的占位符的宽度, 不设的话为默认值; 最后一个值是宽度值.

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

    1
    2
    3
    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提示信息

方式可以

1
MessageBox("Could not delete RC");

键盘处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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;
}

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

1
2
3
4
5
6
7
8
9
void COpenGLView::RenderScene ()
{
... ...
if (keyDown['w'])
{
// handling here...
}
... ...
}

鼠标处理

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    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() 函数中:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    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);
    }

打开文件对话框

添加方法如下:

1
2
3
4
5
6
7
8
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):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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);
}
... ...
}