编程日记(44) 梁肇新 2001年 44期 2000年2月17日 星期四 阴   计划:在目录树上实现右键系统菜单,且支持改名   程序代码的初期编写工作已经进行了一段时间,前期工作比较顺利,没有出现什么问题。一切都按照进度计划在实施,这一点我很满意。   今天,××部的小林在编写鼠标右键消息处理的相关代码时,遇到了难题。一般说来,在程序的某个区域点击鼠标右键都会产生WM_CONTEXTMENU消息,在这个消息中可以做弹出右键菜单的处理。但是我们发现按照常规的代码,在树列表中点击鼠标右键却没有这个消息,必须双击右键才产生消息让我们奇怪了很久。   经过仔细检查,发现在列表窗中有一个LVS_SINGLESEL标志,而在目录树上查看却没有发现这个标志。由此我们判断LVS_SINGLESEL可能与单/双击右键无关。接下来,我们查看资源管理器目录树的右键(通过SPY++程序来查看),同样没有NM_CONTEXTMENU消息。经分析发现,在WM_RBUTTO NUP中处理鼠标右键菜单与ListView不同,目录树取不到WM_RBUTTONUP消息,从而不产生WM_CONTEXTMENU消息。但是移动一下鼠标却可以取到消息,查看代码后发现这是由于目录树中有一个消息循环会把WM_RBUTTONUP取走,所以没有收到这个消息(系统发送的NOTIFY的NM_RCLICK消息)。找到原因了,问题也就好办了。这样,大眼睛就能够产生一个可以符合Windows用户习惯并且拥有很规范代码的鼠标右键菜单。   第二个问题出现在对列表窗中的图标下面的文字进行改名。这就用到列表窗支持的改名处理,然而代码编写完毕后发现改名时在目录树上改变了一个名称,这个名称在列表中还在显示,而此时列表中的文字也应该跟着变才对。因此判断需要一种机制能及时反映出变化来,即必须取出新的名字,然后成功返回原号码以便刷新这一次显示。由于刷新时只显示和刷新有字的区域,如果更改以后的文字比改名前的文字短,那么就会因为没有清除而出现残余线条。通过先清除原有字区域的方法来解决这个问题。   通过检查代码,终于发现原因,这是因为一些同事在开发代码时将程序中变量的声明与代码混杂在一起而造成的。虽然C++允许在任意地方声明变量,看起来编写时是很方便的,实际上却导致代码很零乱,一般变量的类型并不是编程中很重要的部分,但是算法代码是核心部分,一段清晰的代码只有将算法非常明白地表达出来才比较利于阅读,也不会有声明类型来干扰阅读。把变量区和代码区分开是十分有益的。除了类对象变量应该在使用时声明之外,其他基本类型的变量应该在函数的开头处声明,这些变量在程序运行时都会启用相同大小的空间,不会有前后顺序,但类对象是有顺序的。   总结:   1.虽然WM_RBUTTONUP消息也可以处理右键菜单,但是使用不是很普遍,所以右键菜单必须在使用很广泛的NM_RCLICK中进行,即不在WM_CONTEXTMENU中,这是TreeView的特点。   2.初学编程的人往往不了解代码区和数据区的区别,教科书也以为变量和代码混杂在一起是正常的。实践证明,变量区和代码区分开是代码规范化的一个重要组成部分。这样对一个开发团体编写的程序来说,很多人写的代码就能很好地结合在一起而成为一个产品了。当然,也是一种可以提高编程人员水平的捷径。