MFC小记
这两周写了几个MFC小工具,准备给后续开发和测试用的。这其中有些收获,有些感悟
界面设计很重要
自己设计的界面真是丑爆了。
当初设计的时候用的嵌入窗口,根据鼠标点击不同的对象,在同一位置打开不同的属性显示窗口。然后就要考虑属性窗口和主窗口的从属关系,还有拖动同步问题。但是如果界面线程卡住了,属性窗口就不动了。
类设计也很重要
非界面的数据成员的初始化和访问问题。因为解耦的需要所以数据和界面是分离的,遇到数据改变需要操纵界面的时候,就出现了数据类引用界面类的问题。又因为界面对象没有提供外部引用,只能在外部声明一个指针,初始化界面对象的时候给指针复制,数据类使用这个指针对象。这是一个丑陋的设计。
Tips
基于VS2005
Item Data
用到的CTreeCtrl、CComboBox、CListBox都有SetItemData和GetItemData方法,可以将数据绑定到元素上面,这样选择了某个元素后,方便直接对元素对应的对象进行操作,而不需要再去根据选择项去查找对象。当然,用到指针的地方就要注意指针的有效性和内存泄露问题。
CTreeCtrl
DeleteAllItems清除所有元素。
没有方法可以直接展开树,需要自行逐级展开。
CComboBox
Type选择Dropdown时
ON_CBN_SELCHANGE事件中获得的字符串值不正确,index是正确的。
ResetContent清除所有元素。
声明了值对象时,如果后续操作中调用UpdateData,务必仅修改值对象。没有值对象时才修改索引改变显示。
窗口同步
重写CDialog::OnMove
void MainDialog::OnMove(int x, int y)
{
CDialog::OnMove(x, y);
setSubDialogPos();
}
void MainDialog::setSubDialogPos()
{
RECT reArchor, reSubDialog;
archor.GetWindowRect(&reArchor);
subDlg.GetWindowRect(&reSubDialog);
subDlg.SetWindowPos(this, reArchor.left, reArchor.top, reSubDialog.right - reSubDialog.left,
reSubDialog.bottom - reSubDialog.top, SWP_SHOWWINDOW);
}
MainDialog::setSubDialogPos中使用了一个小技巧,在主窗口中放置一个不显示的控件作为对齐锚点
窗口显示与隐藏
CWnd::IsWindowVisible 窗口是否可见
CWnd::ShowWindow(SW_HIDE) 隐藏窗口
后记
类设计很重要 *3,重要的问题说3遍
界面设计需要好好设计。如果高大上的炫酷界面到后面才发现实现不了或者做出来的东西土到渣,将就一下到头来闪瞎自己还是推倒重来?
界面与数据必须解耦。因为生成的界面响应代码会因为控件的事件增多,控件之间的关联而多到不行,因此界面代码只调用数据接口会让界面逻辑清晰很多。
对于复杂控件,或者有复杂数据的控件,单独的数据载入很有必要。想象一下3个下拉控件,分别可以选择省、市、区,省的数据是固定的,市根据省的选择变化,区又根据市的选择变化。
这里就可以用到CComboBox控件的Item Data了,省的ItemData中包含市信息,就可以在选择省后将市信息直接导入到市的下拉控件中,区同理。
数据必须同界面解耦合,只需要为界面提供足够多的接口
对于数据改变影响界面的操作,应该建立中间层,一面存放数据,另一面改变界面。