Author Topic: Creating custom grips with AcDbGripOverrule  (Read 3101 times)

0 Members and 1 Guest are viewing this topic.

ahojko

  • Guest
Creating custom grips with AcDbGripOverrule
« on: May 14, 2011, 10:53:04 AM »
First thing: hello to all of you

Now, my question is whether I can create additional grip points for an entity with Grip overrules. The documentation says "It is intended as a base class for clients who want to alter some or all behavior of a given AcDbEntity-derived class.", so I've taken it that I can.

My code so far - GripOverrule.h:
Code: [Select]
#include "dbentityoverrule.h"
#pragma once

class GripOverrule : public AcDbGripOverrule
{
public:
GripOverrule(void);
virtual ~GripOverrule(void);
virtual ACDB_PORT Acad::ErrorStatus getGripPoints(
const AcDbEntity* pSubject,
AcDbGripDataPtrArray& grips,
const double curViewUnitSize,
const int gripSize,
const AcGeVector3d& curViewDir,
const int bitflags
);
virtual bool isApplicable(const AcRxObject *pOverruledSubject) const;
};

GripOverrule.cpp
Code: [Select]
#include "StdAfx.h"
#include "GripOverrule.h"

GripOverrule::GripOverrule(void)
{
}
GripOverrule::~GripOverrule(void)
{
}

ACDB_PORT Acad::ErrorStatus GripOverrule::getGripPoints(
const AcDbEntity* pSubject,
AcDbGripDataPtrArray& grips,
const double curViewUnitSize,
const int gripSize,
const AcGeVector3d& curViewDir,
const int bitflags
)
{
if (pSubject == NULL) return Acad::eOk;

AcDbGripData* g1 = new AcDbGripData();
AcGePoint3d* point = new AcGePoint3d(50, 50, 0);
g1->setGripPoint(*point);

AcDbGripOverrule::getGripPoints(pSubject, grips, curViewUnitSize, gripSize, curViewDir, bitflags);

g1->setAppData((void*)123);

grips.append(g1);

return Acad::eOk;
}

bool GripOverrule::isApplicable(const AcRxObject *pOverruledSubject) const
{
if (!pOverruledSubject->isKindOf(AcDbPolyline::desc())) return false;
AcDbPolyline* pline = AcDbPolyline::cast(pOverruledSubject);
if (pline == NULL) return false;
if (pline->objectId().isNull()) return false;
if (!pline->objectId().isValid()) return false;
if (!pline->objectId().isResident()) return false;
if (!pline->isReadEnabled()) return false;
if (pline->isErased()) return false;

return true;
}

and main
Code: [Select]
static GripOverrule* gripOverrule = NULL;
//-----------------------------------------------------------------------------
//----- ObjectARX EntryPoint
class CArxResizeApp : public AcRxArxApp {

public:
CArxResizeApp () : AcRxArxApp () {}

virtual AcRx::AppRetCode On_kInitAppMsg (void *pkt) {
// TODO: Load dependencies here

// You *must* call On_kInitAppMsg here
AcRx::AppRetCode retCode =AcRxArxApp::On_kInitAppMsg (pkt) ;

// TODO: Add your initialization code here
gripOverrule = new GripOverrule();

return (retCode) ;
}

virtual AcRx::AppRetCode On_kUnloadAppMsg (void *pkt) {
// TODO: Add your code here

// You *must* call On_kUnloadAppMsg here
AcRx::AppRetCode retCode =AcRxArxApp::On_kUnloadAppMsg (pkt) ;

// TODO: Unload dependencies here
delete gripOverrule;

return (retCode) ;
}

virtual void RegisterServerComponents () {
}

static void ArxResize_doit(void)
{
MessageBox(NULL, (LPCWSTR)L"doit", (LPCWSTR)"", MB_OK);
GripOverrule::setIsOverruling(Adesk::kTrue);
GripOverrule::addOverrule(AcDbPolyline::desc(), gripOverrule, false);

}

static void ArxResize_undoit(void)
{
MessageBox(NULL, (LPCWSTR)L"undoit", (LPCWSTR)"", MB_OK);
GripOverrule::setIsOverruling(false);
GripOverrule::removeOverrule(AcDbPolyline::desc(), gripOverrule);
}

} ;

//-----------------------------------------------------------------------------
IMPLEMENT_ARX_ENTRYPOINT(CArxResizeApp)

ACED_ARXCOMMAND_ENTRY_AUTO(CArxResizeApp, ArxResize, _doit, doit, ACRX_CMD_TRANSPARENT, NULL);
ACED_ARXCOMMAND_ENTRY_AUTO(CArxResizeApp, ArxResize, _undoit, undoit, ACRX_CMD_TRANSPARENT, NULL);

The grip point is displayed, but when I try to move it, I immediately get access violation exception. The address being tried to read is same as the value stored via AcDbGripData::setAppData(void*), so I thought I only messed up with pointers, but examples I found regarding AcDbGripData used the same way (however these were all using AcDbEntity::getGripPoints(), not overrules). Same result when I used class insted of single value:
Code: [Select]
MyAppData* mad = new MyAppData();
mad->val = 123456;
g1->setAppData((void*)mad);

Could this be samohow caused because of not setting AcDbGripData::m_pAppDataClass?
Is there difference when using AcDbGripOverrule::getGripPoints() and AcDbEntity::getGripPoints()?
Or the easiest would be - does any have some example where Grip overrule is used?
Or what am I doing wrong? :-D

Thanks.