如何让VC在编译ARX项目时自动通知AutoCAD卸载ARX程序,并在编译完成后自动加载新编译的ARX程序
在编写ARX程序时,一个比较麻烦的地方在于,每次重新编译ARX项目时,需要先手动的卸载此前加载调试的ARX程序,然后编译,最后再加载新生成的程序,虽然过程不算复杂,但经常这样做会让人感到厌烦。有没有办法使VC在启动编译前,自动通知AutoCAD卸载此插件(即旧版本的ARX程序),然后开始编译,编译完成后,再自动通知AutoCAD加载此新生成的ARX插件呢?
我在查看了QQ群里一些朋友的讨论之后,结合他们给出的一些思路,经过一番摸索,终于找到一种可行的方案。这个方案包括如下几个部分:
1.添加两个自定义命令,分别用于加载和卸载ARX程序
AutoCAD自带几个命令,如APPLOAD, ARX等,可用于ARX程序的加载和卸载,但都是基于GUI的操作,无法完全通过命令行的方式实现ARX的加载和卸载。因此,需要我们自己编写两个命令来分别实现通过命令行加载,卸载ARX程序。这个容易实现:
新建一个叫做ArxLoader的ARX项目,添加两个命令ArxLoad, ArxUnload,分别用于加载和卸载通过路径指定的ARX程序:
static void wdArxLoader_ARXLOAD(void)
{
ACHAR arxPath[134];
acedGetString(1,NULL,arxPath);
AcRxDynamicLinker* pLinker = acrxDynamicLinker;
#ifdef NDEBUG // release version
pLinker->loadModule(arxPath,false);
#else // debug version
acedPrompt(arxPath);
pLinker->loadModule(arxPath,true);
#endif
}
static void wdArxLoader_ARXUNLOAD(void)
{
ACHAR arxPath[134];
acedGetString(1,NULL,arxPath);
AcRxDynamicLinker* pLinker = acrxDynamicLinker;
#ifdef NDEBUG // release version
pLinker->unloadModule(arxPath);
#else // debug version
acedPrompt(arxPath);
pLinker->unloadModule(arxPath);
#endif
}
这个项目会生成一个名为wdArxLoader.arx的插件,其中包含ArxLoad和ArxUnload命令,备用。
2.实现外部程序向AutoCAD主程序发送AutoCAD命令
这一步比较关键,实现方法也比较“古怪”。这里有篇文章讲述如何通过各种方式向AutoCAD发送命令:
Techniques for calling AutoCAD commands programmatically
我采用了这篇文章中所介绍的方式来实现从我们自己的外部程序向AutoCAD发送Ansys命令。
新建一个win32控制台项目,添加如下代码:
#include <string>
#include <cassert>
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
COPYDATASTRUCT* pCmdMsg = (COPYDATASTRUCT*)lParam;
const int MAX_LEN = 256;
TCHAR caption[MAX_LEN];
assert(hwnd!=NULL);
::GetWindowText(hwnd,caption,MAX_LEN);
std::wstring captionStr(caption);
if (captionStr.substr(0,12)==_T("AutoCAD 2008"))
{
::SendMessage(hwnd, WM_COPYDATA, NULL, (LPARAM)pCmdMsg);
}
return TRUE;
}
void SendCmdToAcad(LPCTSTR cmd)
{
COPYDATASTRUCT cmdMsg;
cmdMsg.dwData = (DWORD)1;
cmdMsg.cbData = (DWORD)(_tcslen(cmd) + 1) * sizeof(TCHAR);
cmdMsg.lpData = (PVOID)cmd;
::EnumDesktopWindows(NULL,EnumWindowsProc,(LPARAM)&cmdMsg);
}
int _tmain(int argc, TCHAR* argv[])
{
if (argc>1)
{
std::wstring unloadCmd(argv[1]);
unloadCmd += _T("\r");
SendCmdToAcad(unloadCmd.c_str());
}
return 0;
}
这里向AutoCAD主窗口发送消息的代码与参考文献的类似,只是获取AutoCAD主窗口的句柄的方式不一样,原文中adsw_acadMainWnd()函数只能用于从ARX插件内部获取主窗口句柄,而不能用于“外部独立程序”中,因此只能采取其他间接的方法获取,比如我这里使用的枚举所有顶级窗口的方式。
这个项目会生成一个名为SendCmdToAcad.exe的命令行小工具,备用。
3.设置我们自己所要编译的ARX项目
在项目的属性页对话框中,在“All Configuration”配置下,选择”Build Events>>Pre-build Event”,然后在”Command line”中输入:
D:\Cpp\ObjectArx\AcadToAnsys\Release\SendCmdToAcad.exe "arxunload $(TargetPath)"
其中,”D:\Cpp\ObjectArx\AcadToAnsys\Release\SendCmdToAcad.exe”是我们前面第2步准备的命令行小工具的完整路径,”arxunload $(TargetPath) ”是要发送给AutoCAD执行的命令,用于通知AutoCAD卸载我们所要重新编译生成的ARX程序。
选择”Build Events>>Pre-build Event”,然后在”Command line”中输入:
D:\Cpp\ObjectArx\AcadToAnsys\Release\SendCmdToAcad.exe "arxload $(TargetPath)"
其中,”D:\Cpp\ObjectArx\AcadToAnsys\Release\SendCmdToAcad.exe”是我们前面第2步准备的命令行小工具的完整路径,”arxload $(TargetPath) ”是要发送给AutoCAD执行的命令,用于通知AutoCAD加载我们刚重新编译生成的ARX程序。
4.使用方法
在AutoCAD中输入APPLOAD手动加载第1步中准备好的wdArxLoader.arx,此后,就不再需要在重新编译我们的ARX项目时,手动的加载卸载ARX程序了,这一过程会由VC自动通知AutoCAD帮我们完成,我们要做的就是简单重现编译下就可以了,![]()


浙公网安备 33010602011771号