● 补充小知识:枚举类型的使用
每个控件(比如列表)都对应一个自己的唯一的变量
使用枚举类型可以将变量名与编号进行绑定,以后程序需要扩展的时候,只需要在定义枚举变量的位置重新修改编号就可以了,这样全局的所有变量的编号就都跟着修改了
由于列表这个数据结构在本项目中十分重要,所有需要放在一个每一个文件都能访问到的文件当中,比如"pcb.h"
示例1:默认是0 1 2 3 4 5这样和数组一样递增的
enum Day {
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
};
int main() {
// 使用枚举类型
Day today = Wednesday;
// 输出枚举常量的值
std::cout << "Today is: " << today << std::endl;
return 0;
}
示例2:也可以是乱序使用的
enum Color {
Red = 1,
Green = 2,
Blue = 6
};
6、为列表控件添加条目
写代码的时候找不到对话框,如何转到资源视图?
为列表控件添加初始化函数,如果代码都写在OnInitDlg()函数里面,显得太过于臃肿了,于是我们考虑在CPCRemoteDlg类里面添加一个成员函数initList()用来初始化列表
在initList()函数中实现为列表添加条目
// 初始化对话框中的列表
int CPCRemoteDlg::initList()
{
// TODO: 在此处添加实现代码.
//为Online_List添加条目
for (int i = 0; i < ONLINELIST_LEN; i++) {
m_CList_Online.InsertColumn(i, g_Column_Data_Onlie[i].title, LVCFMT_CENTER, g_Column_Data_Onlie[i].nWidth);
}
//为MessageList添加条目
for (int i = 0; i < MESSAGELIST_LEN; i++) {
m_CList_Message.InsertColumn(i, g_Column_Data_Message[i].title, LVCFMT_CENTER, g_Column_Data_Message[i].nWidth);
}
return 0;
}
数据结构的定义:
2个枚举类型的列表定义在"pcb.h"文件当中:
enum
{
ONLINELIST_IP = 0, //IP的列顺序
ONLINELIST_ADDR, //地址
ONLINELIST_COMPUTER_NAME, //计算机名/备注
ONLINELIST_OS, //操作系统
ONLINELIST_CPU, //CPU
ONLINELIST_VIDEO, //摄像头
ONLINELIST_PING, //PING
ONLINELIST_LEN //OnlineList的总长度
};
enum
{
MESSAGELIST_TYPE, //信息类型
MESSAGELIST_TIME, //时间
MESSAGELIST_INFO, //信息
MESSAGELIST_LEN //MessageList的总长度
};
列表项定义在PCRemoteDlg.cpp文件当中:
typedef struct
{
char* title; //列表的名称
int nWidth; //列表的宽度
}COLUMNSTRUCT;
COLUMNSTRUCT g_Column_Data_Onlie[] =
{
{"IP", 148 },
{"区域", 150 },
{"计算机名/备注", 160 },
{"操作系统", 128 },
{"CPU", 80 },
{"摄像头", 81 },
{"PING", 81 }
};
COLUMNSTRUCT g_Column_Data_Message[] =
{
{"信息类型", 148 },
{"时间", 100 },
{"信息内容", 660 }
};
此时运行项目还是显示不出来条目,我们需要将2个列表的属性》视图:ICon 改为 Report:
然后运行起来就OK了:
注意:不要忘记在CPCRemoteDlg的initDlg函数里面调用😂😂😂
结果报C005错误
经排查是因为m_CList_Online错误地写成了m_CList_Message导致数组越界引发报错
修改为:
//为Online_List添加条目
for (int i = 0; i < ONLINELIST_LEN; i++) {
m_CList_Online.InsertColumn(i, g_Column_Data_Message[i].title, LVCFMT_CENTER, g_Column_Data_Message[i].nWidth);
}
最终运行结果截图:
但是对窗口进行放大缩小,列表的条目大小不随着变化,如何解决?
想不到使用什么函数,首先要知道这个函数一定是CList的成员函数,然后去查MSDN,或者可以再具体到你想改变列的大小,就在CList里面再查和Column相关的内容/SetXXX之类的
只有当前列表条目宽度需要设置为double类型,这个自行体会
1)定义两个列表初始宽度为全局变量
int g_Online_List_InitWidth = 0;
int g_Message_List_InitWidth = 0;
2)在initList当中分别计算出两个列表的初始宽度
// 初始化对话框中的列表
int CPCRemoteDlg::initList()
{
// TODO: 在此处添加实现代码.
//为Online_List添加条目
for (int i = 0; i < ONLINELIST_LEN; i++) {
m_CList_Online.InsertColumn(i, g_Column_Data_Onlie[i].title, LVCFMT_CENTER, g_Column_Data_Onlie[i].nWidth);
g_Online_List_InitWidth += g_Column_Data_Onlie[i].nWidth;
}
//为MessageList添加条目
for (int i = 0; i < MESSAGELIST_LEN; i++) {
m_CList_Message.InsertColumn(i, g_Column_Data_Message[i].title, LVCFMT_CENTER, g_Column_Data_Message[i].nWidth);
g_Message_List_InitWidth += g_Column_Data_Message[i].nWidth;
}
return 0;
}
3)在OnSize函数当中实现列表的条目随着窗体的大小自由伸缩
void CPCRemoteDlg::OnSize(UINT nType, int cx, int cy)
{
CDialogEx::OnSize(nType, cx, cy);
// TODO: 在此处添加消息处理程序代码
//使列表的位置随窗口自动变化
double wndCurWidth = cx; //使用double类型来重新表示当前窗口大小
double dTmp = 0;
if (m_CList_Online.m_hWnd != NULL)
{
CRect rc;
rc.left = 1; //列表的左坐标
rc.top = 80; //列表的上坐标
rc.right = cx - 1; //列表的右坐标
rc.bottom = cy - 160; //列表的下坐标
m_CList_Online.MoveWindow(rc);
//使列表条目的大小也适应窗口的变化
for (int i = 0; i < ONLINELIST_LEN; i++) {
dTmp = g_Column_Data_Onlie[i].nWidth * wndCurWidth;
dTmp /= g_Online_List_InitWidth;
int nCurWidth = (int)dTmp;
m_CList_Online.SetColumnWidth(i, nCurWidth);
}
}
//使列表的位置随窗口自动变化
if (m_CList_Message.m_hWnd != NULL)
{
CRect rc;
rc.left = 1; //列表的左坐标
rc.top = cy - 156; //列表的上坐标
rc.right = cx - 1; //列表的右坐标
rc.bottom = cy - 6; //列表的下坐标
m_CList_Message.MoveWindow(rc);
//使列表条目的大小也适应窗口的变化
for (int i = 0; i < MESSAGELIST_LEN; i++) {
dTmp = g_Column_Data_Message[i].nWidth * wndCurWidth;
dTmp /= g_Message_List_InitWidth;
int nCurWidth = (int)dTmp;
m_CList_Message.SetColumnWidth(i, nCurWidth);
}
}
}
运行效果截图:
补充编程小技巧:
在类视图下无法直接删除成员函数,想要删除成员函数需要手动转到它的定义和引用处删除
运行程序发现功能没有体现,程序没有什么变化,需要考虑是否调用了该函数