危险的两个函数GetCurrentDirectory和GetParent
最近这段时间用vc做了一个客户端程序,好长时间不做这种程序了,很是生疏,由于接手的别人的二手项目,大部分代码都已经完成了,只是跑起来问题很大,很多意料之中和意料之外的问题让人又爱又恨。其中遇到了两个函数造成的奇怪问题,好好分析找到了原因,都是一些平时不注意,对一些函数错误的使用造成的。下面说说这两个函数。
1、GetCurrentDirectory
DWORD WINAPI GetCurrentDirectory( __in DWORD nBufferLength, __out LPTSTR lpBuffer );
这个是函数原型,他是主要是作用是获取程序的当前目录,大部分指的是当前运行程序所在的运行目录。记得这个地方说的是大部分情况,不是所有,有些特殊的情况会返回时其他的路径。我们的程序在运行中需要有监护程序来引导,当我写完监护程序让他引导进入主程序的时候发现了奇怪的问题,程序整个界面打乱,一张图片都没有,去目录下查找图片存在,而且直接运行主程序没有这个问题。我们在主程序里面跟踪也没有头绪,每个函数都运行的正常的出奇,没有一点不妥的。可是就是在监护程序引导的情况下出现异常。经过判断感觉是路径发面出现问题,导致找不到图片。我们查看获取路径的函数,发现使用了GetCurrentDirectory,这个获取当前目录的函数按照常理应该没有问题,细想我们是在监护程序里面使用的shell把主程序调用起来的,应该是忘记了设置工作目录造成的吧,于是修改监护程序,设置工作目录,依旧无果,特殊调试发现这个函数获得的路径是监护程序的位置,看来这个GetCurrentDirectory函数本身应该是出了问题,我们使用的错误。后来查看了一些资料,微软也承认这个函数有时候不是那么恰当,他的这个获取的值收到很多的影响,所以如果只是为了获取当前程序运行路径,建议使用GetModuleFileName这个函数来处理,这个比较准,因为他获得是当前运行程序的存储路径。我们的程序也是使用这个之后恢复正常的。
2、GetParent
这个函数就本身使用来说是没有什么问题,只是我们有些时候在开发桌面应用程序的时候需要用的某个窗口置顶的问题,通常解决方法就那几个setforegroud之类的,可是这些问题都受制于如果你的父窗口不直前你也别想在最前面,所以通常会用SetParent(NULL)函数来搞掉父窗口。当搞掉父窗口之后GetParent函数也就废掉了,获取的值是NULL的。很多时候在vc里面操作父类的界面都需要拿到父类的句柄,然后再获取父类里面的某些控件的值,例如子窗口获取父类列表当前选中的值。当窗口不值钱,用GetParent一切ok,后来为了置前弄了SetParent(NULL),编译无措,运行时候系统告诉你无效句柄,呵呵,这个问题好调出来,但是如果bug夺得焦头烂额的时候也是很难被发现的。对于这个的建议我们还是建议在基类里面默认设置一个包含父类句柄的变量,这样直接用就ok了。
上面的这些问题都是一些不良的编程习惯或者随意猜测函数弄出来的问题,总结上面的问题以后我再开始一个大型的c++项目之前一定要做好前期的设计,基础框架要做好,充分的用好几个好的设计模式,集中管理一些资源,界面等容易出现泄露问题的。等这个项目结束之后总结一些在大型C++项目里面基础框架必须包含的东西来分享一下。
posted on 2010-06-10 09:11 JesseZhao 阅读(13699) 评论(14) 编辑 收藏 举报