Highflybird 发表于 2013-5-7 00:05:54

ARX的综合运用--反应器,IPM,JIG,acedDragGen,自定义实体及与LISP的通信机制

本帖最后由 Highflybird 于 2013-10-31 16:51 编辑

此贴起源于:

http://bbs.xdcad.net/thread-667838-1-1.html

这些天做了个程序给LISP调用,其中综合运用了arx的 JIG类,AcEdInputPointMonitor类,反应器,和自定义实体,以及对acedDragGen函数和回调函数做了一些研究。有些部分牵涉到了简单的事务处理。后面我还加了一些定时器,和钩子等。虽然是给LISP的,但其中有许多东西,还是可以利用的。
这个东西花费我一些时间,希望的是能跟大家一起讨论研究,虽然我开源给大家,但是我还是收取了一定数量D豆,那些真心学习研讨的人应该不会在乎这点吧。所以此贴非诚勿扰。如果你相信此贴的价值超过它收取的D豆,就下载吧。
一些有用的建议和bug指出,我会给他们加分。
欢迎大家多提意见。

**** Hidden Message *****
版本更新到2013年10月。

Gdlprfcu 发表于 2013-5-7 12:20:56

{:soso_e102:},可惜还不够权限,我得努力。

守仁格竹GM 发表于 2013-5-7 13:12:26

积分也差太多了

XDSoft 发表于 2013-5-13 13:39:23

守仁格竹GM 发表于 2013-5-7 13:12
积分也差太多了

静下心,多交流,会够的。

传下你的代码,给你加分,一个贡献10个积分,一个威望15个积分。

守仁格竹GM 发表于 2013-5-13 13:46:25

积极努力中,现在快到了:lol

cxjzxf 发表于 2013-5-21 00:25:20

高大师的贴子一定要顶

Gdlprfcu 发表于 2013-5-23 11:19:08

给点小小建议:我觉得既然是给lisp调用的,钩子和定时器应该做成文档级的,不应该是全局性的。

yxpxa 发表于 2013-7-26 16:07:49

偶像的帖子,一定要顶

Highflybird 发表于 2013-7-26 17:11:08

Gdlprfcu 发表于 2013-5-23 11:19
给点小小建议:我觉得既然是给lisp调用的,钩子和定时器应该做成文档级的,不应该是全局性的。

现在看来,因为钩子和定时器牵涉到的arx函数都是全局级的,看来无法做到文档级别的了。

zhangq_cai1 发表于 2013-7-26 17:30:38

权限不够,努力中~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~·

Gdlprfcu 发表于 2013-7-28 01:30:35

Highflybird 发表于 2013-7-26 17:11
现在看来,因为钩子和定时器牵涉到的arx函数都是全局级的,看来无法做到文档级别的了。
应该可以吧,我是这样做的,把定时器做成类结构,再在DOC类中定义一个map容器保存当前文档的定时器类,文档被释构时同时释放已实例化的定时器类,这样做还可以同时在同一文档定义多个定时器。具体代码如下:
#include "StdAfx.h"
#include "Timer.h"
class Timer
{
public:
Timer(HWND CurHandle,UINT nElapse,const ACHAR * CallbackFunction);
static void CALLBACK TimerProc(HWND hWnd,UINT nMsg,UINT nTimerid,DWORD dwTime);
static int LispTimer(void);
static int KillLispTimer(void);
public:
~Timer(void);
private:
ACHAR *m_CallbackFunction;
UINT m_nElapse;
static UINT TimerID;
AcApDocument *m_doc;
HWND m_CurHandle;
UINT_PTR uIDEvent;
};
UINT Timer::TimerID = 1000;
Timer::Timer(HWND CurHandle,UINT nElapse,const ACHAR * CallbackFunction):m_CurHandle(CurHandle)
{
if (nElapse > 0)
{
    m_nElapse = nElapse;
}
else
{
    m_nElapse = 500;
}
TimerID++;
m_doc = acDocManager->curDocument();
m_CallbackFunction = new ACHAR;
wcscpy(m_CallbackFunction,CallbackFunction);
//m_CurHandle = CurHandle;\\adsw_acadDocWnd();
uIDEvent = SetTimer(m_CurHandle,TimerID,nElapse,(TIMERPROC)Timer::TimerProc);
if (uIDEvent == 0)
{
--TimerID;
}
}
Timer::~Timer(void)
{
if (m_CallbackFunction != NULL)
{
    delete[] m_CallbackFunction;
    m_CallbackFunction = NULL;
}
}
void Timer::TimerProc(HWND hWnd,UINT nMsg,UINT nTimerid,DWORD dwTime)
{
AcApDocument *curdoc = acDocManager->curDocument();
Timer *curtimer = DocVars.docData().mapTimers;
if (curtimer->m_doc != curdoc)
{
    return;
}
struct resbuf *in_rb=NULL,*out_rb=NULL;
in_rb = acutBuildList(RTSTR,curtimer->m_CallbackFunction,RTSHORT,hWnd,RTSHORT,nMsg,RTSHORT,nTimerid,RTSHORT,dwTime,0);
if (in_rb == NULL)
{
    return;
}
if (acedInvoke(in_rb,&out_rb) != RTNORM )
{
    return;
}
acutRelRb(in_rb);
in_rb = NULL;
if (out_rb != NULL)
{
    acutRelRb(out_rb);
    out_rb = NULL;
}
return;
}

int Timer::LispTimer()
{
struct resbuf *m_rb = acedGetArgs();
if (m_rb == NULL || m_rb->rbnext == NULL || m_rb->restype != RTSHORT ||(m_rb->rbnext->restype != RTSHORT && m_rb->rbnext->restype != RTSTR))
{
    return RTERROR;
}
HWND CurHandle ;
if (m_rb->restype == RTSHORT && m_rb->rbnext->restype == RTSHORT)
{
    if (m_rb->rbnext->rbnext == NULL || m_rb->rbnext->rbnext->restype != RTSTR)
    {
      return RTERROR;
    }
    CurHandle =(HWND) m_rb->resval.rint;
    m_rb = m_rb->rbnext;
}
else
{
   CurHandle = adsw_acadDocWnd();
}
Timer *myTime = new Timer(CurHandle,m_rb->resval.rint,m_rb->rbnext->resval.rstring);
if (myTime->uIDEvent == 0)
{
    delete myTime;
    myTime = NULL;
    acedRetNil();
}
else
{
    DocVars.docData().mapTimers = myTime;
    acedRetInt(myTime->uIDEvent);
}
return RSRSLT;
}
int Timer::KillLispTimer(void)
{
struct resbuf *m_rb = acedGetArgs();
if (NULL == m_rb || m_rb->restype != RTSHORT)
{
    acutPrintf(_T("\n参数类型错误。"));
return RTERROR;
}
map<UINT,Timer*>::iterator iter;
iter = DocVars.docData().mapTimers.find((UINT)m_rb->resval.rint);
if (iter == DocVars.docData().mapTimers.end())
{
    acedRetNil();
    return RSRSLT;
}
Timer *m_timer = DocVars.docData().mapTimers;
bool isok;
isok = KillTimer(m_timer->m_CurHandle,m_timer->uIDEvent);
if (isok)
{
    DocVars.docData().mapTimers.erase(m_rb->resval.rint);
    delete m_timer;
    m_timer = NULL;
    acedRetT();
}
else
{
    acutPrintf(_T("\n删除定时器时出错。"));
return RTERROR;
}
return RSRSLT;
}



Highflybird 发表于 2013-7-28 09:39:11

Gdlprfcu 发表于 2013-7-28 01:30
应该可以吧,我是这样做的,把定时器做成类结构,再在DOC类中定义一个map容器保存当前文档的定时器类,文 ...

嗯,好方法。
但是那个钩子是全局级别的函数,似乎没办法改。

Gdlprfcu 发表于 2013-7-28 11:07:52

Highflybird 发表于 2013-7-28 09:39
嗯,好方法。
但是那个钩子是全局级别的函数,似乎没办法改。

钩子我没试过,不过钩子有一个也够了,只要把回调函数字符串做成文档级的,在ARX里判断一下就可以了,这样就不会在没有加载LISP回调数的文档里出现“xxxx函数没定义"这样的提示了。然后再做一个获取当前回调函数字符串的函数,就像设置系统变量一样,使用完再恢复。

pengfei2010 发表于 2013-8-5 14:20:16

100积分是什么概念啊?我多少积分了?

aeo 发表于 2013-10-31 15:14:31

看看,要50豆呀,我一共才105豆
页: [1] 2 3
查看完整版本: ARX的综合运用--反应器,IPM,JIG,acedDragGen,自定义实体及与LISP的通信机制