让VC在编译ARX项目时自动通知AutoCAD卸载ARX程序,编译完成后自动加载新编译的ARX程序
付祺 20110603
说明:以下内容编写时运行环境为AutoCAD2010+ObjectARX2010+VS2008
在编写ARX程序时,一个比较麻烦的地方在于,每次重新编译ARX项目时,需要先手动的卸载此前加载调试的ARX程序,然后编译,最后再加载新生成的程序,虽然过程不算复杂,但经常这样做会让人感到厌烦。有没有办法使VC在启动编译前,自动通知AutoCAD卸载此插件(即旧版本的ARX程序),然后开始编译,编译完成后,再自动通知AutoCAD加载此新生成的ARX插件呢?
经过不懈努力,我终于找到一种可行的方案。这个方案包括如下几个部分:
1.添加两个自定义命令,分别用于加载和卸载ARX程序AutoCAD自带几个命令,如APPLOAD, ARX等,可用于ARX程序的加载和卸载,但都是基于GUI的操作,无法完全通过命令行的方式实现ARX的加载和卸载。因此,需要我们自己编写两个命令来分别实现通过命令行加载,卸载ARX程序。这个容易实现,过程如下:新建一个叫做ArxLoader的ARX项目,添加两个命令ArxLoad, ArxUnload,分别用于加载和卸载通过路径指定的ARX程序:
// ArxLoader.cpp : 定义DLL 应用程序的导出函数。
//
#include"stdafx.h"
#include
#include
#include
staticvoidwdArxLoader_ARXLOAD(void)
{
ACHARarxPath[134];
acedGetString(1,NULL,arxPath);
AcRxDynamicLinker* pLinker = acrxDynamicLinker;
#ifdefNDEBUG// release version
pLinker->loadModule(arxPath,false);
#else// debug version
acedPrompt(arxPath);
pLinker->loadModule(arxPath,true);
#endif
}
staticvoidwdArxLoader_ARXUNLOAD(void)
{
ACHARarxPath[134];
acedGetString(1,NULL,arxPath);
AcRxDynamicLinker* pLinker = acrxDynamicLinker;
#ifdefNDEBUG// release version
pLinker->unloadModule(arxPath);
#else// debug version
acedPrompt(arxPath);
pLinker->unloadModule(arxPath);
#endif
}
voidinitApp()
{
acedRegCmds->addCommand(_T("ARXLOAD_COMMANDS"), _T("ARXLOAD"), _T("ARXLOAD"), ACRX_CMD_TRANSPARENT, wdArxLoader_ARXLOAD);
acedRegCmds->addCommand(_T("ARXLOAD_COMMANDS"), _T("ARXUNLOAD"), _T("ARXUNLOAD"), ACRX_CMD_TRANSPARENT, wdArxLoader_ARXUNLOAD);
}
voidunloadApp()
{
acedRegCmds->removeGroup(_T("ARXLOAD_COMMANDS"));
}
extern"C"AcRx::AppRetCode
acrxEntryPoint(AcRx::AppMsgCodemsg, void* pkt)
{
switch(msg)
{
caseAcRx::kInitAppMsg:
acrxDynamicLinker->unlockApplication(pkt);
acrxRegisterAppMDIAware(pkt);
initApp();
break;
caseAcRx::kUnloadAppMsg:
unloadApp();
break;
default:
break;
}
returnAcRx::kRetOK;
}
其余设置按照普通ARX程序设置即可。
这个项目会生成一个名为wdArxLoader.arx的插件,其中包含ArxLoad和ArxUnload命令。2.实现外部程序向AutoCAD主程序发送AutoCAD命令这一步比较关键,实现从我们自己的外部程序向AutoCAD发送Ansys命令。新建一个win32控制台项目,SendCmdToAcad.cpp,代码如下:// SendCmdToAcad.cpp : 定义控制台应用程序的入口点。
//
#include"stdafx.h"
#include
#include
#include
BOOLCALLBACKEnumWindowsProc(HWNDhwnd, LPARAMlParam)
{
COPYDATASTRUCT* pCmdMsg = (COPYDATASTRUCT*)lParam;
constintMAX_LEN = 256;
TCHARcaption[MAX_LEN];
assert(hwnd!=NULL);
::GetWindowText(hwnd,caption,MAX_LEN);
std::wstringcaptionStr(caption);
if (captionStr.substr(0,12)==_T("AutoCAD 2010"))
{
::SendMessage(hwnd, WM_COPYDATA, NULL, (LPARAM)pCmdMsg);
}
returnTRUE;
}
voidSendCmdToAcad(LPCTSTRcmd)
{
COPYDATASTRUCTcmdMsg;
cmdMsg.dwData = (DWORD)1;
cmdMsg.cbData = (DWORD)(_tcslen(cmd) + 1) * sizeof(TCHAR);
cmdMsg.lpData = (PVOID)cmd;
::EnumDesktopWindows(NULL,EnumWindowsProc,(LPARAM)&cmdMsg);
}
int_tmain(intargc, TCHAR* argv[])
{
if (argc>1)
{
std::wstringunloadCmd(argv[1]);
unloadCmd += _T("\r");
SendCmdToAcad(unloadCmd.c_str());
}
return 0;
}
这个项目会生成一个名为SendCmdToAcad.exe的文件。3.设置我们自己所要编译的ARX项目项目右键-属性-配置选择所有配置-配置属性生成事件-预生成事件-命令行输入D:\MyWork\VisualStudio2008\Projects\couple\Release\SendCmdToAcad.exe "arxunload $(TargetPath)"。其中D:\MyWork\VisualStudio2008\Projects\couple\Release\SendCmdToAcad.exe为SendCmdToAcad.exe文件的所在目录,"arxunload $(TargetPath)"用来发送给AutoCAD执行的命令,用于通知AutoCAD卸载我们所要重新编译生成的ARX程序。
项目右键-属性-配置选择所有配置-配置属性生成事件-生成后事件-命令行输入D:\MyWork\VisualStudio2008\Projects\couple\Release\SendCmdToAcad.exe "arxload $(TargetPath)"。其中D:\MyWork\VisualStudio2008\Projects\couple\Release\SendCmdToAcad.exe为SendCmdToAcad.exe文件的所在目录,"arxload $(TargetPath)"用来发送给AutoCAD执行的命令,用于通知AutoCAD加载我们重新编译生成的ARX程序。
注意:SendCmdToAcad.exe文件的所在目录不能出现空格,否则VS2008会报错。
4.使用方法在AutoCAD中输入APPLOAD手动加载第1步中准备好的wdArxLoader.arx,此后,就不再需要在重新编译我们的ARX项目时手动的加载卸载ARX程序了,这一过程会由VC自动通知AutoCAD帮我们完成,我们要做的就是简单重现编译下就可以了。
注意:在VS中对项目重新编译时,选择“生成”,不要选择“重新生成”等会删除arx文件后再生成arx文件的操作。这是因为“生成”方法执行顺序为执行预生成事件-……-执行生成后事件,而“重新生成”方法执行顺序为删除arx文件-执行预生成事件-……-执行生成后事件。此时arx文件在AutoCAD文件中正在使用,是不能删除的,程序会报错。切记!切记!
(下面提供两个版本的配置实例,可参考。另附VS2008源项目,本人已测试通过,完全没有问题,如果报错,请修改个人设置,或自己编写。)
中文版配置实例:
英文版配置实例如下:
本文来源:https://www.2haoxitong.net/k/doc/b4c192196bd97f192279e9ce.html
文档为doc格式