您的位置:首页 > 编程语言 > PHP开发

危险的两个函数GetCurrentDirectory和GetParent

2013-02-25 18:03 477 查看
/article/4754089.html

危险的两个函数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++项目里面基础框架必须包含的东西来分享一下。

VC中使用GetModuleFileName获取应用程序路径

.\\与API函数GetModuleFileName获取应用程序目录有何不一样?

采用.\\也能获得应用程序目录,采用GetModuleFileName也能获得,二者有何不同?

一样!

一个是相对路径,一个是绝对路径

.\\是的到应用程序的当前目录,但当前目录不一定等于应用程序执行文件的所在目录,一个应用程序被启动时,当前目录是可以被任意设置的。

GetModuleFileName()得到模块的完整路径名,例如,你载入c:\windows\system32\a.dll,得到模块句柄h,则你可以用GetModuleFileName()得到h模块的完整路径名。

.\\一般用在包含头文件的语句中。

另一个是程序编译后起作用的,例如,打开自定义的配置文件等。

如何去取得这个Hanlde?

如果你直接用LoadLibrary()或AfxLoadLibrary()载入dll,该函数返回值就是handle;

如果你隐式载入dll, 用GetModuleHandle("dll文件名")也可以得到handle;

MFC程序得到本身路径

在开发工程中,往往需要知道当前程序本身所在目录。

一种方法是在程序安装的时候利用安装程序把文件路径写入注册表。在较大的程序中,这种方法比较常用

另一种,就是在程序得到路径。这样,程序随便移动到哪里,都可以得到正确的路径。这也是本文介绍的方法。

方法一:

//得到帮助文件的路径

CString strFullName = AfxGetApp()->m_pszHelpFilePath;

//得到的是:X:\XXXX\XXX.hlp

//解析路径,得到当前运行程序所在目录

char drive[_MAX_DRIVE];

char dir[_MAX_DIR];

_splitpath(strAppName, drive, dir, NULL,NULL);

CString strPath;

strPath.Format("%s%s", drive, dir);

//strPath即为得到的当前运行程序所在目录


另外,AfxGetApp()->m_pszAppName 得到应用程序名称

AfxGetApp()->m_pszExeName 得到程序文件名,不包括扩展名

方法二:

得到全路径

TCHAR exeFullPath[MAX_PATH]; // MAX_PATH

GetModuleFileName(NULL,exeFullPath,MAX_PATH);//得到程序模块名称,全路径

也就是当前运行程序的全路径

利用方法一的解析路径的方法,即可得到程序所在路径。

GetModuleFileName函数原型

DWORD GetModuleFileName(

HMODULE hModule, // handle to module。将要得到的模块的句柄。如果是当前模块,NULL

LPTSTR lpFilename, // path buffer 得到的文件名。

DWORD nSize // size of buffer 一般MAX_PATH就可以了

);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐