前言
- 各位师傅大家好,我是qmx_07,今天讲解剩下的复杂控件知识点
IP地址栏
- 绘图准备 :
- 调整windows窗口大小、设置 ip address control
- 设置 Button按钮,修改名称
- 添加IP栏 变量:m_IP
获取IP栏内容
cpp
void CMFCApplication3Dlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
BYTE cIPA, cIPB, cIPC, cIPD;
if (m_IP.IsBlank())
{
AfxMessageBox(L"IP地址栏不能为空");
return;
}
m_IP.GetAddress(cIPA, cIPB, cIPC, cIPD);
CString csIP;
csIP.Format(L"%d.%d.%d.%d", cIPA, cIPB, cIPC, cIPD);
MessageBox(csIP);
}
- BYTE 0-255 符合ip的习惯
- IsBlank()判断是否为空
- GetAddress()获取IP栏的内容
- 检查IP栏是否为空,将IP栏内容输出到cIPA, cIPB, cIPC, cIPD进行弹窗
清空IP栏内容
cpp
void CMFCApplication3Dlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
m_IP.ClearAddress();
}
- ClearAddress()清空IP栏内容
设置IP栏内容
cpp
void CMFCApplication3Dlg::OnBnClickedButton3()
{
// TODO: 在此添加控件通知处理程序代码
char ip[] = "192.168.0.1";
DWORD dwIP = htonl(inet_addr(ip));
m_IP.SetAddress(dwIP);
}
- inet_addr将 IP 地址字符串转换为一个以网络字节序表示的 32 位整数
- htonl 函数将这个整数转换为主机字节序到网络字节序
- SetAddress()设置ip地址
- 将ip地址 进行转换,设置到ip栏里
知识点讲解
- 网络字节序是指在网络传输中规定的统一的字节顺序,互联网中,通常采用大端字节序,也就是高位字节存储在低地址,低位字节存储在高地址
- 主机字节序则是因不同的计算机体系结构而有所不同,主要分为大端字节序和小端字节序,Intel x86 系列的 CPU 采用小端字节序,而一些其他的处理器架构可能采用大端字节序
- 在网络编程中,为了确保不同主机之间能够正确地传输和解析数据,需要进行字节序的转换。
画面演示
树控件
-
绘图准备 :
-
调整windows窗口大小,设置Tree control控件,设置属性Has Lines、Has Buttons 为True
-
设置Button按钮
-
设置变量:m_Tree
-
通过类向导,进入OninitDialog
cpp
HTREEITEM hRoot = m_Tree.InsertItem(L"Root", TVI_ROOT, TVI_LAST);
HTREEITEM hSubNode = m_Tree.InsertItem(L"SubNode",hRoot, TVI_LAST);
HTREEITEM hSubNode_Sub1 = m_Tree.InsertItem(L"SubNode1", hSubNode, TVI_LAST);
HTREEITEM hSubNode_Sub2 = m_Tree.InsertItem(L"SubNode2", hSubNode, TVI_LAST);
HTREEITEM hSubNode_Sub3 = m_Tree.InsertItem(L"SubNode3", hSubNode, TVI_LAST);
HTREEITEM hSubNode_Sub4 = m_Tree.InsertItem(L"SubNode4", hSubNode, TVI_LAST);
- TVI_ROOT 为root节点
- InsertItem插入节点
- TVI_LAST 向后插入
画面演示:
当前选中
cpp
void CMFCApplication3Dlg::OnBnClickedButton4()
{
// TODO: 在此添加控件通知处理程序代码
HTREEITEM hCurNode = m_Tree.GetSelectedItem();
CString Text = m_Tree.GetItemText(hCurNode);
AfxMessageBox(Text);
}
- GetSelectedItem()获取当前的对象
- GetItemText()获取文本信息
删除选中
cpp
void CMFCApplication3Dlg::OnBnClickedButton5()
{
// TODO: 在此添加控件通知处理程序代码
HTREEITEM hCurNode = m_Tree.GetSelectedItem();
m_Tree.DeleteItem(hCurNode);
}
- DeleteItem()删除当前的对象
删除全部
cpp
void CMFCApplication3Dlg::OnBnClickedButton6()
{
// TODO: 在此添加控件通知处理程序代码
m_Tree.DeleteAllItems();
}
- DeleteAllItems()删除全部对象
画面演示
列表
- 绘图准备 :
- 调整windows窗口大小,设置 List control 列表,设置属性:View 为report报表
- 通过类向导,进入OnInitDialog
cpp
m_File_List.SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);
m_File_List.InsertColumn(0, L"Name", 0, 100);
m_File_List.InsertColumn(1, L"Path", 0, 100);
m_File_List.InsertColumn(2, L"Title", 0, 100);
- LVS_EX_GRIDLINES 使用网线格
- LVS_EX_FULLROWSELECT整行选中
- InsertColumn() :
- 第一个参数 为 索引列
- 第二个参数为 名称
- 第三个参数为 对齐方式
- 第四个参数为 宽度
画面演示:
模拟windows文件夹
cpp
m_File_List.SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);
m_File_List.InsertColumn(0, L"Name", 0, 100);
m_File_List.InsertColumn(1, L"Path", 0, 200);
m_File_List.InsertColumn(2, L"Title", 0, 100);
DWORD Index = 0;
CFileFind finder;
BOOL Ret = finder.FindFile(L"G:\\MFC_Demo\\*.*");
while (Ret)
{
Ret = finder.FindNextFileW();
m_File_List.InsertItem(Index, finder.GetFileName(), 0);
m_File_List.SetItemText(Index, 1, finder.GetFilePath());
m_File_List.SetItemText(Index, 2, finder.GetFileTitle());
Index++;
}
- 利用之前学习的文件类 CFileFind 进行文件遍历插入
- InsertItem(): 第一个参数是列,第二个参数是内容,第三个不使用特定图标
- SetItemText():第一个是列,第二个是行,第三个是内容
文件素材:
画面演示:
为windows文件夹 设置右键菜单功能
- 添加菜单
- 类向导创建右键命令 NM_BCLICK
cpp
void CMFCApplication3Dlg::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_MENU1));//加载IDR_MENU1菜单
HMENU hSubMenu = GetSubMenu(hMenu, NULL);//加载子菜单
TrackPopupMenu(hSubMenu, TPM_CENTERALIGN, pt.x, pt.y, 0, m_hWnd, NULL);//弹出菜单
*pResult = 0;
}
-
设置显示右键菜单,具体上一节有相关说明
-
为三个选项添加 事件处理程序
获取文本
cpp
void CMFCApplication3Dlg::On32771()
{
// TODO: 在此添加命令处理程序代码
//获取文本
int nPos = (int)m_File_List.GetFirstSelectedItemPosition();
nPos -= 1;
CString Buffer = m_File_List.GetItemText(nPos , 0);
AfxMessageBox(Buffer);
}
- GetFirstSelectedItemPosition() 这个函数 获取到的索引值 偏差值为1,所以需要-=1
- GetItemText()第一个参数为获取的列,第二个参数为获取的行
删除一行
cpp
void CMFCApplication3Dlg::On32772()
{
// TODO: 在此添加命令处理程序代码
//删除一行
int nPos = (int)m_File_List.GetFirstSelectedItemPosition();
nPos -= 1;
m_File_List.DeleteItem(nPos);
}
- DeleteItem() 删除对象,由于LVS_EX_FULLROWSELECT ,可以直接删除一行数据
删除全部
cpp
void CMFCApplication3Dlg::On32773()
{
// TODO: 在此添加命令处理程序代码
//删除全部
m_File_List.DeleteAllItems();
}
- DeleteAllItems() 删除全部对象
画面演示
表格
- 绘图准备 :
- 调整windows窗口大小,设置Tab control
- 为表格添加变量: m_Tab
- 进入OnInitDiaglog
cpp
m_Tab.InsertItem(0, L"Page0");
m_Tab.InsertItem(1, L"Page1");
m_Tab.InsertItem(2, L"Page2");
画面演示:
- 有了画面效果,还需要创建对话框
- 点击创建Dialog对话框
- 将Border 设置为NULL,Style设置为Child,创建三个对话框
- 为每个对话框 创建类
- 在主程序头文件,引用
- 创建类变量
- 在OnInitDialog里写下面程序:
cpp
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;
page1.MoveWindow(rs);
page2.MoveWindow(rs);
page3.MoveWindow(rs);
- 创建三个对话框,但是会产生覆盖效果,看不到其他的标签页
- 所以要进行移动
- 为表格设置 事件处理程序
cpp
void CMFCApplication3Dlg::OnTcnSelchangeTab1(NMHDR *pNMHDR, LRESULT *pResult)
{
// TODO: 在此添加控件通知处理程序代码
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;
}
- 获取所点击的标签页,让其他页面隐藏
画面效果:
总结
- 我们学习了IP地址栏,树控件,列表,表格等复杂控件的基本使用,以及对话框的创建与绑定