MFC程序设计(三)常用复杂控件的使用
预备工作
继上一节课实现的控件以后,现在我们实现上图中新的控件
设置宏#define HOTKEY_USER_MSG 12138
IP添加控件变量m_IP
树控件添加控件类型变量m_Tree
右上角列表绑定控件变量m_FileList ,注意一行为一项,行列交叉的项属于子项
添加右键菜单
Tab页绑定控件变量m_Tab
热键
首先我们新建一个热键:进入对话框类向导,进入OnInitDialog添加初始化代码,注册热键
RegisterHotKey(m_hWnd, HOTKEY_USER_MSG, MOD_SHIFT, VK_F1); //1.窗口句柄,2.热键消息码 3.辅助键(组合键)
进入类向导,添加OnHotKey消息
void CDemo02Dlg::OnBnClickedButton8()//输入IP地址,点击设置按钮弹窗
{//一个IP地址:192.168.31.118,每个部分都是byte类型变量BYTE cIPA, cIPB, cIPC, cIPD;if (m_IP.IsBlank())//判断IP字段是否为空{AfxMessageBox(L"IP地址不能为空");return;}m_IP.GetAddress(cIPA, cIPB, cIPC, cIPD);//控件获取IP地址CString csIP;csIP.Format(L"%d.%d.%d.%d", cIPA, cIPB, cIPC, cIPD);//存储IP地址AfxMessageBox(csIP);//弹窗IP地址
}
IP控件
设置IP
void CDemo02Dlg::OnBnClickedButton8()//输入IP地址,点击设置按钮弹窗
{//一个IP地址:192.168.31.118,每个部分都是byte类型变量BYTE cIPA, cIPB, cIPC, cIPD;if (m_IP.IsBlank())//判断IP字段是否为空{AfxMessageBox(L"IP地址不能为空");return;}m_IP.GetAddress(cIPA, cIPB, cIPC, cIPD);//控件获取IP地址CString csIP;csIP.Format(L"%d.%d.%d.%d", cIPA, cIPB, cIPC, cIPD);//存储IP地址AfxMessageBox(csIP);//弹窗IP地址
}
清空IP
void CDemo02Dlg::OnBnClickedButton9()//点击清除按钮,IP地址清空
{m_IP.ClearAddress();//清空IP地址
}
获取IP
void CDemo02Dlg::OnBnClickedButton10()//点击获取按钮,将获取到的IP填入IP控件
{char ip[] = "192.168.0.1";//我们获取到的IPDWORD dwIP = htonl(inet_addr(ip));//将IPV4字符串转换为inet_addr结构再转换为网络字节序的长整型m_IP.SetAddress(dwIP);//设置IP控件上的地址
}//注意此处需要通过程序提示添加预处理器
树
在OnInitDialog中进行初始化
HTREEITEM hRoot = m_Tree.InsertItem(L"Root", TVI_ROOT, TVI_LAST);//设置根节点。HTREEITEM hSubNode1 = m_Tree.InsertItem(L"hSubNode1", hRoot, TVI_LAST);HTREEITEM hSubNode1Sub1 = m_Tree.InsertItem(L"hSubNode1Sub1", hSubNode1, TVI_LAST);HTREEITEM hSubNode1Sub2 = m_Tree.InsertItem(L"hSubNode1Sub2", hSubNode1, TVI_LAST);HTREEITEM hSubNode1Sub3 = m_Tree.InsertItem(L"hSubNode1Sub3", hSubNode1, TVI_LAST);HTREEITEM hSubNode1Sub4 = m_Tree.InsertItem(L"hSubNode1Sub4", hSubNode1, TVI_LAST);HTREEITEM hSubNode2 = m_Tree.InsertItem(L"hSubNode2", hRoot, TVI_LAST);
获取并修改树节点
void CDemo02Dlg::OnBnClickedButton11()//点击当前选中按钮,获取并修改选中树结点的文本
{HTREEITEM hCurNode = m_Tree.GetSelectedItem();//获取当前选中项CString csText = m_Tree.GetItemText(hCurNode);//获取选中项文本AfxMessageBox(csText);//弹窗选中项文本CString csSetBuffer = L"rkvir";m_Tree.SetItemText(hCurNode,csSetBuffer);//设置选中项新文本
}
删除树节点
void CDemo02Dlg::OnBnClickedButton12()//点击删除选中,删除选中的树节点
{HTREEITEM hCurNode = m_Tree.GetSelectedItem();//获取当前选中项m_Tree.DeleteItem(hCurNode);//删除选中项
}
删除所有树节点
void CDemo02Dlg::OnBnClickedButton13()//点击全部删除,删除所有树节点
{m_Tree.DeleteAllItems();
}
列表
在OnInitDialog中进行初始化列表风格
m_FileList.SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);//设置风格m_FileList.InsertColumn(0, L"Name", 0, 100);//插入列头m_FileList.InsertColumn(1, L"Path", 0, 260);m_FileList.InsertColumn(2, L"Title", 0, 100);DWORD dwIndex = 0;//列表行索引CFileFind finder;//创建一个文件类BOOL bRet = finder.FindFile(L"D:\\symbols(Win7x64)\\*.*");//读取目标目录下文件while (bRet)//遍历目标目录下文件{bRet = finder.FindNextFileW();//读取目标目录下下一个文件m_FileList.InsertItem(dwIndex, finder.GetFileName(), 0);//在目标行第0列插入文件名。注意第0列需要使用该函数m_FileList.SetItemText(dwIndex, 1, finder.GetFilePath());//第目标行1列插入文件路径m_FileList.SetItemText(dwIndex, 2, finder.GetFileTitle());//第目标行2列插入文件类型dwIndex++;//指向下一行}
右键菜单应用
在列表中添加右键消息
void CDemo02Dlg::OnRclickList2(NMHDR *pNMHDR, LRESULT *pResult)
{LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);// TODO: 在此添加控件通知处理程序代码POINT pt = { 0 };//获取点击位置GetCursorPos(&pt);//存储点击位置HMENU hMenu = LoadMenu((HINSTANCE)GetWindowLongPtr(m_hWnd, GWLP_HINSTANCE), MAKEINTRESOURCE(IDR_MENU3));//加载IDR_MENU3菜单HMENU hSubMenu = GetSubMenu(hMenu, NULL);//获取菜单句柄TrackPopupMenu(hSubMenu, TPM_CENTERALIGN, pt.x, pt.y, 0, m_hWnd, NULL);//鼠标点击位置弹出菜单*pResult = 0;
}
删除列表一行数据
void CDemo02Dlg::On32780()//点击删除一行消息
{int nPos = (int)m_FileList.GetFirstSelectedItemPosition();//获取选中行位置,MFC该函数从1开始计算nPos -= 1;/位置减1,获取实际下标索引m_FileList.DeleteItem(nPos);//删除选中行
}
删除全部数据
void CDemo02Dlg::On32781()//删除全部消息
{m_FileList.DeleteAllItems();
}
获取选中文本并修改
void CDemo02Dlg::On32779()//获取选中行文本,并进行修改
{int nPos = (int)m_FileList.GetFirstSelectedItemPosition();nPos -= 1;CString csResBuffer = m_FileList.GetItemText(nPos, 0);//接收选中行0列文本//AfxMessageBox(csResBuffer);//弹窗文本m_FileList.SetItemText(nPos, 0, L"rkvir");//修改选中行0列文本
}
Tab
此处我们需要额外创建三个对话框并分别添加类命名为CPAGE123,在主对话框中添加这三个对话框头文件。在主对话框头文件中代码增加三个对话框类对象。注意对话框外观Border修改none,style修改为child
在OnInitDialog中进行初始化
m_Tab.InsertItem(0, L"page0");
m_Tab.InsertItem(1, L"page1");
m_Tab.InsertItem(2, L"page2");//插入页名
page1.Create(IDD_DIALOG1, &m_Tab);
page2.Create(IDD_DIALOG2, &m_Tab);
page3.Create(IDD_DIALOG3, &m_Tab);//创建三个页
CRect rs;
m_Tab.GetClientRect(rs);//获取页客户区,即显示内容的区域
rs.top += 20;//用户区顶部下移20单位距离
page1.MoveWindow(rs);
page2.MoveWindow(rs);
page3.MoveWindow(rs);//移动三个对话框移动到目标客户去使之不遮挡页名
page1.ShowWindow(SW_SHOW);//显示第一个页
Tab页切换
void CDemo02Dlg::OnTcnSelchangeTab1(NMHDR *pNMHDR, LRESULT *pResult)
{int nCurSel = m_Tab.GetCurSel();//获取点击页的页码switch (nCurSel){case 0:page1.ShowWindow(SW_SHOW);//显示选中页page2.ShowWindow(SW_HIDE);page3.ShowWindow(SW_HIDE);//隐藏另外两个页break;case 1:page1.ShowWindow(SW_HIDE);page2.ShowWindow(SW_SHOW);page3.ShowWindow(SW_HIDE);break;case 2:page1.ShowWindow(SW_HIDE);page2.ShowWindow(SW_HIDE);page3.ShowWindow(SW_SHOW);break;default:break;}*pResult = 0;
拓展库使用
接下来我们试一试网上一些前辈写的资源库,此处我们使用EditListCtrl库进行一个演示
1.将资源库放入目标项目文件夹
2.在该项目源文件头文件中添加该库即可。
3.主对话框添加头文件include<EditListCtrl.h>
4.在主对话框头文件中修改m_FileList类型为CEditListCtrl
5.在EditListCtrl.h中添加头文件pch.h
6.修改EditListCtrl.cpp中stdafx.h为pch.h
完成以上操作后,我们运行程序,双击列表便可以正常编写文本了
作业
01.使用MFC搜索D盘获取指定文件并且读取到程序内,显示在列表上
02.自己随便写点什么,练习树控件的使用
03.模仿任务管理器,实现一个多Tab的程序