完整流程:
1、 构建新类,在对话框中使用这个类。
2、 画表格
3、 填充
4、 标号
第一步:构建新类
新建一个对话框项目。设ID为IDC_CLASSTEST,假设我们新建的类为CTableCtrl;那么在ClassTestDlg.h中定义一个成员变量:TableCtrl m_table;然后在ClassTestDlg.cpp中找到
void CClassTestDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_TABLE, m_table); // 这句是添加上去的。
}
这样就可以使用这个类了。
1、如果需要改变类的参数以便重绘应该怎么办?
我们需要定义一个类的成员函数,例如ResetRowAndColumn(int nRow, int nColumn);
函数体:
{
// 添加代码
Invalidate();// 重绘
}
2、如何将编辑框中的数据与函数连接起来?
使用函数:GetDlgItemInt(nID)来获得整型数据,其他函数参见MSDN;然后通过类对象m_table调用类的成员函数来使用:m_table.ResetRowAndColumn(GetDlgItemInt(IDC_EDIT1), GetDlgItemInt(IDC_EDIT2));
画图过程最好使用双缓冲画图:
CPaintDC dc(this);
CDC dcMemory;
dcMemory.CreateCompatibleDC(&dc);
CRect rect;
GetClientRect(&rect);
// 贴图必须先创建一个bmp对象,否则不能使用BitBlt来进行拷贝(画布)
CBitmap bmp;
bmp.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height());
CBitmap *pOldBmp = dcMemory.SelectObject(&bmp);
ASSERT(pOldBmp != NULL);
// 如果不进行填充,背景是黑色的
dcMemory.FillSolidRect(&rect, RGB(255, 255, 255));
然后就可以创建画笔,进行绘图了。最后要记得返回旧的设备对象,释放dc等。
第二步:画表格
因为画表格和填充/标号并没有太多的关联,我们完全可以不画表格而进行填充和标号,所以这一步可以与其他两步一起进行。在标号时,在第一个for画横线,在嵌套的for循环中进行一次循环,画竖线。表格完成。
第三步:填充
这一步需要注意的是,假如一次填充一行,那么会覆盖掉之前画的表格。所以只能一次填充一个单元格,使用奇偶行控制填充颜色。
第四步:标号
使用函数:DrawText()
但此函数只能显示字符串,所以需要使用格式化函数sz.Format(“%d”,Num);
要使标号背景透明,需要使用函数:SetBkMode(TRANSPARENT);
要使在按回车键时与点击按钮的效果相同,则须重载OnOK函数,并在发送消息处修改:
ON_BN_CLICKED(IDC_OK, &CClassTestDlg::OnOK)
在函数体内编写步骤。
关键步骤至此完成。
编写过程中代码规范遇到的问题:
1、 变量需要放在最有用的地方,如果不需要用到变量,那就不要定义。
2、 注意命名规范,最好打开着文档,需要用到的时候打开看看。注意几个特殊情形,成员变量/静态变量/全局变量等。
3、 同一个控件或其他模块,不要get多次,定义一个变量即可解决。
4、 函数中要考虑到多种非正常情况,酌情使用断言。例如指针使用时,不能为NULL等。
5、 一个结构体内,如果只有基本的数据类型,在初始化的时候可以直接赋予0,不需要使用memset();
6、 整个程序应该只使用英文,中间不要使用中文。
7、 基本的数据类型可以使用复合前缀,如psz,pn等,派生类类型则不需要复合前缀。注意下划线后不能直接大写。
8、 关于代码重用,能够重复使用代码就不要新编写代码。尽量使用已经编好的代码。如在对话框中,初始化的时候,不要重新调用ResetRowAndColumn(),而应该调用本程序的OnOK()函数,这样可以减少代码量。