在使用MFC中经常碰到一些细小的比较有用或者需要注意的地方.在这里备忘下.
1.等待光标的使用
当某个操作比较耗时的话最好的方法是使用进度条.但如果是虽耗时但也不会太久,那可以让光标处于等待状态.这样的目的无他,只是使用户界面友好.
BeginWaitCursor();
//Do something will take much time.
EndWaitCursor();
2.String Table使用
假如字符只是用来做为提示,描述信息.(像典型的例子是错误提示信息).此时把一长串字符直接放代码里一来影响布局,降低代码的可读性.另一个也不利于维护,要修改起来还得一个个的去搜索~有时相同的字符出现在多个地方更要主流同时改动.
一个比较好的方法是使用string table.用法在简单在里面添加一行,填写ID和Caption.使用的时候利于ID获取Caption里面的内容
CString strTitle;
strTitle.LoadString( ID_TITLE);
如果软件产品支持多语言设置,String Table的作用就更加明显了啊.
3.ASSERT使用
c++的指针用起来非常灵活,但经常碰到的情况是由于存在bug,在一些地方指针为空,结果执行到那里就crash了,这样找起来也比较麻烦.如果用个ASSERT断言下,就可以直接定位到出错的地方.ASSERT只在Debug模式下执行,是为了方便调试代码而出现的机制.当然了除了常用来断言空指针,还可以断言其他一些条件是否满足.
ASSERT( m_pData);
此时如果m_pData为空,也就是ASSERT中为FALSE就会有一个断言错误.
4.释放内存时指针赋NULL值
当我们通过new动态分配内存,然后释放时通过delete释放.但是delete只是告诉操作系统标志这块内存失效.原来指向这块内存的指针的值仍然不为空,当使用该指针时就会出现未定义的错误.所以比较好的方式为delete后同时把指针赋值为NULL.
CMyData* pData;
pData = new CMyData;
//do some operation
delete pData;
pData = NULL;
5.对话框初始化
一个类的成员的初始化我们一般是放在构造函数中.而对话框CDialog的很多页面相关的初始化一般放到virtual BOOL OnInitDialog();函数中
OnInitDialog在调用DoModal创建模式对话框或调用Create创建无模式对话框时被调用.
动态Create CWnd的初始化操作一般放到virtual BOOL OnCreate(LPCREATESTRUCT lpCreateStruct);
6.RECT
我们指定一个控件的位置时经常用到结构体RECT.
看着那4个变量经常容易搞混.其实想下数学中在一个平面坐标上确定一个矩形只需要定义对角的两个点的坐标就可以了.
在这里指定控件位置也只需要控件左上方的点和右下方的点即可.这是习惯用法,实际上用右上角和左下角的点同样可以确定.
typedef struct tagRECT { LONG left; LONG top; LONG right; LONG bottom; } RECT;
left :Specifies the x-coordinate of the upper-left corner of a rectangle.
top :Specifies the y-coordinate of the upper-left corner of a rectangle.
7.计算按钮上字的长度
假如button上要动态的显示不同的字,而且可能draw不同字体和大小的字上去.此时怎么去调整button的大小呢.那首先自然要知道字的长度.
int GetStringWidth(CString strInfo){
if(strInfo.IsEmpty())
return0;
CDC* pDC = GetDC();
pDC->SelectObject(GetFont());
returnpDC->GetTextExtent(strInfo).cx;
}