还是先来谈一谈主界面技术:
真是一个丰富的主界面啊! MFC经典的矩形式控件让我的艺术创作都规规矩矩的了!
先来看一看这个MFC菜单式按钮。
它实际上就是类向导下面“添加类”---“添加MFC类”同样的效果。 MFC类:CMFCMenuButton
首先在OnInitDialog函数中设置菜单
//Init the 'Add' MFC Menu Button
CMenu* m_menu = new CMenu;//AfxGetMainWnd()->GetMenu();
m_menu->LoadMenu(IDR_CTRLMENU_POPUP);
m_ctlButtonAdd.m_hMenu = m_menu->GetSubMenu(0)->GetSafeHmenu();
然后映射消息ON_BN_CLICKED
ON_BN_CLICKED(IDC_MFCMENUBUTTON1, &CStudentManagerSystemDlg::OnBnClickedMfcmenubutton1)
接着处理事件
void CStudentManagerSystemDlg::OnBnClickedMfcmenubutton1()
{
// TODO: 在此添加控件通知处理程序代码
switch (m_ctlButtonAdd.m_nMenuResult)
{
case ID_POPUP_ADD_GRADE:
{
AddGrade();
break;
}
case ID_POPUP_ADD_CLASS:
{
AddClass();
break;
}
case ID_POPUP_ADD_TEACHER:
{
AddTeacher();
break;
}
case ID_POPUP_ADD_GROUP:
{
AddGroup();
break;
}
case ID_POPUP_ADD_STUDENT:
{
AddStudent();
break;
}
}
}
最后大功告成!
再来谈一谈这个记录管理空间(List控件报表Report模式)
这个表格最“高级”的地方在于,你可以直接在上面编辑。
原理其实很简单,就是动态创建一个编辑控件,读取再写入。
void CStudentManagerSystemDlg::OnNMClickDataList(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码
NM_LISTVIEW* pEditCtrl = (NM_LISTVIEW*)pNMHDR;
if (pEditCtrl->iItem == -1)
{
if (HaveEditCreate == true)
{
ListDistroyEdit(&m_ctlDataList, &m_Edit, e_Item, e_SubItem);//销毁单元格编辑框对象
HaveEditCreate = false;
}
if (HaveComboboxCreate == true)//如果之前创建了下拉列表框就销毁掉
{
ListDistroyCombobox(&m_ctlDataList, &m_comBox, e_Item, e_SubItem);
HaveComboboxCreate = false;
}
}
else if (pEditCtrl->iSubItem == 0 || pEditCtrl->iSubItem == 1)//如果不是点评老师选项
{
m_ctlDataList.SetFocus();
}
else if (pEditCtrl->iSubItem != 2)//如果不是点评老师选项
{
if (HaveComboboxCreate == true)//如果之前创建了编辑框就销毁掉
{
ListDistroyCombobox(&m_ctlDataList, &m_comBox, e_Item, e_SubItem);
HaveComboboxCreate = false;
}
if (HaveEditCreate == true)
{
if (!(e_Item == pEditCtrl->iItem && e_SubItem == pEditCtrl->iSubItem))//如果点中的单元格不是之前创建好的
{
ListDistroyEdit(&m_ctlDataList, &m_Edit, e_Item, e_SubItem);
HaveEditCreate = false;
ListCreateEdit(pEditCtrl, &m_Edit, e_Item, e_SubItem, HaveEditCreate);//创建编辑框
}
else//点中的单元格是之前创建好的
{
m_Edit.SetFocus();//设置为焦点
}
}
else
{
e_Item = pEditCtrl->iItem;//将点中的单元格的行赋值给“刚编辑过的行”以便后期处理
e_SubItem = pEditCtrl->iSubItem;//将点中的单元格的行赋值给“刚编辑过的行”以便后期处理
ListCreateEdit(pEditCtrl, &m_Edit, e_Item, e_SubItem, HaveEditCreate);//创建编辑框
}
}
else//如果是点评老师选项,在单元格处生成下拉列表项
{
if (HaveEditCreate == true)//如果之前创建了编辑框就销毁掉
{
ListDistroyEdit(&m_ctlDataList, &m_Edit, e_Item, e_SubItem);
HaveEditCreate = false;
}
if (HaveComboboxCreate == true)
{
if (!(e_Item == pEditCtrl->iItem && e_SubItem == pEditCtrl->iSubItem))//如果点中的单元格不是之前创建好的
{
ListDistroyCombobox(&m_ctlDataList, &m_comBox, e_Item, e_SubItem);
HaveComboboxCreate = false;
ListCreateCombobox(pEditCtrl, &m_comBox, e_Item, e_SubItem, HaveComboboxCreate);//创建编辑框
m_comBox.AddString(L"班主任");
m_comBox.AddString(L"语文老师");
m_comBox.AddString(L"数学老师");
m_comBox.AddString(L"英语老师");
m_comBox.AddString(L"体育老师");
m_comBox.AddString(L"信息老师");
m_comBox.AddString(L"生物老师");
m_comBox.AddString(L"地理老师");
m_comBox.AddString(L"政治老师");
m_comBox.AddString(L"历史老师");
m_comBox.AddString(L"心理老师");
m_comBox.AddString(L"选修老师");
m_comBox.AddString(L"年级主任");
m_comBox.AddString(L"教导处主任");
m_comBox.AddString(L"校长");
m_comBox.ShowDropDown();//自动下拉
}
else//点中的单元格是之前创建好的
{
m_comBox.SetFocus();//设置为焦点
}
}
else
{
e_Item = pEditCtrl->iItem;//将点中的单元格的行赋值给“刚编辑过的行”以便后期处理
e_SubItem = pEditCtrl->iSubItem;//将点中的单元格的行赋值给“刚编辑过的行”以便后期处理
ListCreateCombobox(pEditCtrl, &m_comBox, e_Item, e_SubItem, HaveComboboxCreate);//创建编辑框
m_comBox.AddString(L"班主任");
m_comBox.AddString(L"语文老师");
m_comBox.AddString(L"数学老师");
m_comBox.AddString(L"英语老师");
m_comBox.AddString(L"体育老师");
m_comBox.AddString(L"信息老师");
m_comBox.AddString(L"生物老师");
m_comBox.AddString(L"地理老师");
m_comBox.AddString(L"政治老师");
m_comBox.AddString(L"历史老师");
m_comBox.AddString(L"心理老师");
m_comBox.AddString(L"选修老师");
m_comBox.AddString(L"年级主任");
m_comBox.AddString(L"教导处主任");
m_comBox.AddString(L"校长");
m_comBox.ShowDropDown();//自动下拉
}
}
*pResult = 0;
}
void CStudentManagerSystemDlg::ListCreateEdit(NM_LISTVIEW* pEditCtrl, CEdit* createdit, int& Item, int& SubItem, bool& havecreat)
{
Item = pEditCtrl->iItem;//将点中的单元格的行赋值给“刚编辑过的行”以便后期处理
SubItem = pEditCtrl->iSubItem;//将点中的单元格的行赋值给“刚编辑过的行”以便后期处理
createdit->Create(ES_AUTOHSCROLL | WS_CHILD | ES_LEFT | ES_WANTRETURN,
CRect(0, 0, 0, 0), this, IDC_EDIT_CREATEID);//创建编辑框对象,IDC_EDIT_CREATEID为控件ID号3000,在文章开头定义
havecreat = true;
createdit->SetFont(this->GetFont(), FALSE);//设置字体,不设置这里的话上面的字会很突兀的感觉
createdit->SetParent(&m_ctlDataList);//将list control设置为父窗口,生成的Edit才能正确定位,这个也很重要
CRect EditRect;
m_ctlDataList.GetSubItemRect(e_Item, e_SubItem, LVIR_LABEL, EditRect);//获取单元格的空间位置信息
EditRect.SetRect(EditRect.left + 1, EditRect.top + 1, EditRect.left + m_ctlDataList.GetColumnWidth(e_SubItem) - 1, EditRect.bottom - 1);//+1和-1可以让编辑框不至于挡住列表框中的网格线
CString strItem = m_ctlDataList.GetItemText(e_Item, e_SubItem);//获得相应单元格字符
createdit->SetWindowText(strItem);//将单元格字符显示在编辑框上
createdit->MoveWindow(&EditRect);//将编辑框位置放在相应单元格上
createdit->ShowWindow(SW_SHOW);//显示编辑框在单元格上面
createdit->SetFocus();//设置为焦点
createdit->SetSel(-1);//设置光标在文本框文字的最后
}
void CStudentManagerSystemDlg::ListDistroyEdit(CListCtrl* list, CEdit* distroyedit, int& Item, int& SubItem)
{
CString meditdata;
distroyedit->GetWindowTextW(meditdata);
list->SetItemText(Item, SubItem, meditdata);//获得相应单元格字符
distroyedit->DestroyWindow();//销毁对象,有创建就要有销毁,不然会报错
}
时间不早了,我们下期《实践:MFC学生管理系统(三)-- 趣谈主界面(下)》再见!