开发环境:
客户端: visual stdio2010
服务端: visual C++ 6.0 +platform SDK February2003
第一课、
1.新建一个工程,看操作 我们必须给工程起一个响亮的名字:-D 就叫PCRemote吧
2.添加最大化窗口,最小化窗口的属性
3.更改对话框到适当大小
4.添加服务端连接后显示的列表控件IDC_ONLINE,日志列表控件IDC_MESSAGE,设置上线列表控件的属性“view”为:Report(报表样式)
5.演示伸缩窗口,最大化时列表不能伸缩
6.添加列表控件变量m_CList_Online,m_CList_Message
7.相应对话框改变大小的消息WM_SIZE就是向对话框抛出这个消息对话框就会改变大小,我们先相应这个消息,然后再把这个消息
向下传递 看演示
8.在响应WM_SIZE函数OnSize中添加更改列表大小的代码
//*******界面自适应大小处理函数*************//
voidCVeryEvilDlg::OnSize(UINT nType, int cx, int cy)
{//cx代表改变大小后的整个界面的宽度,cy代表改变大小后的整个界面的高度
CDialogEx::OnSize(nType, cx, cy);
if (m_CList_Online.m_hWnd!=NULL)
{//判断控件变量是否和一个窗口句柄发生关联(如果关联则说明控件已经正确显示),避免出错
CRect rc;
rc.left=1; //列表的左上角的X坐标
rc.top=80; //列表的左上角的Y坐标
rc.right=cx-1; //列表的右下角的X坐标
rc.bottom=cy-160; //列表的右下角的Y坐标
m_CList_Online.MoveWindow(rc);//移动控件窗口到新位置
}
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);
}
// TODO: 在此处添加消息处理程序代码
}
9.示范伸缩
10.在上面的WM_ONSIZE函数中我们处理了当界面发生改变时调整控件到指定位置,
但是,界面一开始显示的时候如果不和我们在WM_SIZE设定的位置一样时就会有不同的表现,为了不让用户看到这个差异我们可以在界面初始化函数(OnInitDialog)中让界面改变一次大小,这样有会产生一个WM_SIZE消息了,这样就巧妙的解决了这个问题了。
BOOLCVeryEvilDlg::OnInitDialog()
{
......................
// TODO: 在此添加额外的初始化代码
/*******使界面具有自适应大小功能,初始化的时候移动窗口一边产生一条WM_SIZE消息*******/
/*******,在消息函数中调整界面位置**********************************************/
CRect rect;
GetWindowRect(&rect);
rect.bottom+=20;
MoveWindow(rect);
/******************/
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
第二课、
1.参考gh0st的列表中的列名:
0IP 1所在区域 2计算机名/备注 3操作系统 4CPU 5摄像头 6Ping
2.上一节我们为列表控件添加变量,我们来查看变量的类型:
CListCtrl 类 查看MSDN 找到int InsertColumn(
int nCol, //列的索引(位置)
LPCTSTR lpszColumnHeading, //列的名字
int nFormat = LVCFMT_LEFT, //列对齐的方式 LVCFMT_LEFT, LVCFMT_RIGHT,LVCFMT_CENTER
int nWidth = -1, //列的宽度
int nSubItem = -1 //与之联系的子条目 默认为-1 我们不用写
);
3.有了这些我们可以现在就写入代码了,但请等一下我们来考虑一下以后的扩展问题,假如我们要加入新的列那会不会很麻烦,我们每一个
列都写入了固定的
顺序(0--6)没有考虑扩展,比如在CPU列的后面加入显示内存大小,那么加入的就是第5列,而第5列恰好是摄头,这样显示的数据就会混乱
(其实这个正是我写
PCRat时犯的错误),解决这个问题的方式就是用枚举enum写入列的顺序时不写入硬编码(0----6)而是写入枚举成员这样我们只需很小的
改动就能达到目的。
(唠叨一下) 很多知识都是这个样,学习到的知识只有到实践中才体会到用处很大,枚举变量就是一个例子,我开始学习时感觉这个一点用
处都没有,但在实践中感觉用
枚举解决问题更简单。
4.因为这个列表比较重要所以要放到一个每一个文件都能访问到的文件很自然的就是stdafx.h
enum
{
ONLINELIST_IP=0, //IP的列顺序
ONLINELIST_ADDR, //地址
ONLINELIST_COMPUTER_NAME, //计算机名/备注
ONLINELIST_OS, //操作系统
ONLINELIST_CPU, //CPU
ONLINELIST_VIDEO, //摄像头
ONLINELIST_PING //PING
};
5.处理列表的代码应该统一放在一处,添加列表处理的代码InitList()
6.写入加入列表列名的代码:
列表的名字与列表的宽度是同一一对应的关系,以后为了以后修改方便建立这样的一个结构体:
typedef struct
{
char *title; //列表的名称
int nWidth; //列表的宽度
}COLUMNSTRUCT;
然后建立这个结构体变量的数组
添加全局变量
intg_Column_Count_Online=7; //列表的个数
COLUMNSTRUCT g_Column_Data_Online[] =
{
{"IP", 148 },
{"区域", 150 },
{"计算机名/备注", 160 },
{"操作系统", 128 },
{"CPU", 80 },
{"摄像头", 81 },
{"PING", 81 }
};
intg_Column_Count_Message=3; //列表的个数
COLUMNSTRUCTg_Column_Data_Message[] =
{
{"信息类型", 68 },
{"时间", 100 },
{"信息内容", 660 }
};
7.在对话框类中添加InitList()函数,在initList中写入加入列表列名称的代码并解释:
int CVeryEvilDlg::InitList(void)
{
//初始化上线列表控件
for (inti = 0; i < g_Column_Count_Online; i++)
{
m_CList_Online.InsertColumn(i,g_Column_Data[i].title,
LVCFMT_CENTER,g_Column_Data[i].nWidth);
}
//初始化日志列表控件
for (inti = 0; i < g_Column_Count_Message; i++)
{
m_CList_Message.InsertColumn(i,g_Column_Data_Message[i].title,
LVCFMT_CENTER,g_Column_Data_Message[i].nWidth);
}
return 0;
}
8在OninitDlg中调用InitList()