乐筑天下

搜索
欢迎各位开发者和用户入驻本平台 尊重版权,从我做起,拒绝盗版,拒绝倒卖 签到、发布资源、邀请好友注册,可以获得银币 请注意保管好自己的密码,避免账户资金被盗
查看: 72|回复: 5

获取ARX文件路径

[复制链接]

19

主题

154

帖子

5

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
230
发表于 2014-11-11 22:45:00 | 显示全部楼层 |阅读模式
使用ObjectARX开发的,可能并不只有ARX文件,还会有其他的一些数据库文件、图片等资源文件,通常这些文件会和ARX文件放在同一个目录下,但是在加载了ARX文件之后,如何定位获取这些文件的路径呢?如果是dll文件,在DllMain函数的第一个参数就是其模块句柄,而ARX的入口函数AcRxEntryPoint中并没有带这个参数,只能自己想办法了。这里提供了几种获取ARX文件路径的方法:
  1. void GetMyPath()
  2. {
  3.     ACHAR path[MAX_PATH]=L"";
  4.     HMODULE hMe;
  5.     //ARX文件的名称
  6.     hMe=GetModuleHandle(L"ArxHello.arx");
  7.     if(hMe==NULL)
  8.     {
  9.         acutPrintf(L"\n获取模块句柄失败\n");
  10.         return;
  11.     }
  12.     GetModuleFileName(hMe,path,MAX_PATH);
  13.     //文件的绝对路径
  14.     acutPrintf(L"\n%s\n",path);
  15.     //文件所在文件夹
  16.     ACHAR* pt=wcsrchr(path,L'\\');
  17.     *(pt+1)='\0';
  18.     acutPrintf(L"\n%s\n",path);
  19. }

这个函数需要windows.h头文件的支持,实际上是调用了系统API,但是这个函数有个小问题,就是GetModuleHandle函数中的参数,必须是我们的ARX文件名,一旦ARX文件被重命名,这个函数就回调用失败,出现“获取模块句柄失败”的提示。另一个根号的方法是,使用增强版的获取模块句柄函数,这个系统API就是GetModuleHandleEx,可以在无需知道ARX文件名的情况下获取文件路径,但是使用时要格外小心,先贴一个出来给大家看看:
  1. void GetMyPath()
  2. {
  3. ACHAR path[MAX_PATH]=L"";
  4. HMODULE hMe;
  5. GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,(ACHAR*)GetMyPath,&hMe);
  6. if(hMe==NULL)
  7. {
  8. acutPrintf(L"\n获取模块句柄失败\n");
  9. return;
  10. }
  11. GetModuleFileName(hMe,path,MAX_PATH);
  12. //文件的绝对路径
  13. acutPrintf(L"\n%s\n",path);
  14. //文件所在文件夹
  15. ACHAR* pt=wcsrchr(path,L'\\');
  16. *(pt+1)='\0';
  17. acutPrintf(L"\n%s\n",path);
  18. }

这个函数运行之后也能获取路径,而且无论我们的ARX改成什么名字,放在哪里,都能正确显示路径。但是有个问题就是,运行过该函数之后,再使用命令将ARX卸载,虽然AutoCAD提示是成功卸载了,但是ARX文件还是被AutoCAD打开,似乎有内存没有被释放,试图删除ARX文件会失败,不知道是怎么回事吧?因为GetModuleHandleEx中出现了问题。仔细阅读了MSDN中的相关条款,GetModuleHandleEx在调用的时候,会让引用计数器加1,所以第一个参数才有GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,就是不让引用计数器加1,因此,如果不带该标志位的话,虽然AutoCAD看似卸载了该动态链接库文件,但是该动态链接库的引用计数还是1,所以,确实删不掉。找到了问题之后,解决起来就方便多了,这里有两种方式可供选择:A. 将GetModuleHandleEx的第一个参数改为6(也就是GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS|GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT)B. GetModuleHandleEx的参数保持不变,在GetModuleFileName函数之后,加一句“FreeLibrary(hMe);”,也就是释放库函数。
最后,借个宝地做做广告,本人的博客: ,不定期发布一些个人学习二次开发和Windows编程相关的文章,和大家共同交流讨论,也请大家不吝赐教,共同进步。

本帖以下内容被隐藏保护;需要你回复后,才能看到!

游客,如果您要查看本帖隐藏内容请回复
回复

使用道具 举报

5

主题

15

帖子

2

银币

初来乍到

Rank: 1

铜币
35
发表于 2014-12-31 20:14:00 | 显示全部楼层
写的不错,赞一个!
回复

使用道具 举报

0

主题

6

帖子

1

银币

初来乍到

Rank: 1

铜币
6
发表于 2015-1-1 10:32:00 | 显示全部楼层
恩,不错,赞一个
回复

使用道具 举报

0

主题

1

帖子

1

银币

初来乍到

Rank: 1

铜币
1
发表于 2015-1-3 18:16:00 | 显示全部楼层
太棒了,解决了大问题,谢谢楼主。
回复

使用道具 举报

4

主题

19

帖子

4

银币

初来乍到

Rank: 1

铜币
35
发表于 2015-1-4 13:37:00 | 显示全部楼层
太好了,针对问题能够找到本质。
回复

使用道具 举报

39

主题

1451

帖子

19

银币

顶梁支柱

Rank: 50Rank: 50

铜币
1598
发表于 2015-1-4 14:57:00 | 显示全部楼层
CString ArxPath = acedGetAppName();
或者:
ACHAR modulePath[512];
DWORD pathLength = GetModuleFileName(_hdllInstance, modulePath, 512);
CString ArxPath=modulePath;
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

QQ|关于我们|小黑屋|乐筑天下 繁体中文

GMT+8, 2025-2-5 04:01 , Processed in 0.223197 second(s), 64 queries .

© 2020-2025 乐筑天下

联系客服 关注微信 帮助中心 下载APP 返回顶部 返回列表