Author Topic: C# custom object [just for fun]  (Read 4661 times)

0 Members and 1 Guest are viewing this topic.

MickD

  • King Gator
  • Posts: 3619
  • (x-in)->[process]->(y-out) ... simples!
C# custom object [just for fun]
« on: November 15, 2007, 05:49:50 PM »
I dug up this bit of code I was working on some time back (on acad 2005) when I was exploring the idea of custom objects with C#, I'm sure I had some more complete code but this is a start.
There is a reference to some of the ARX functions I wrapped required to register the CO but I think PInvoking them would be a better option (mine have a DCS prefix).

In theory I think it's quite possible, the only problem is registering the callbacks acad needs to get the object/entity's description and such so it may  be a good exercise in marshaling if nothing else.

The CO is quite simple as I derived from an existing object and simply pass the required calls back to the base object to handle the db work, I did it this way just to get a proof of concept object up and registered, once this is done I can't see a problem with starting from scratch with a Entity base class if you wanted.

For study on what's required you need to dig into the doc's and look under 'Runtime class identification', 'class declaration macros', 'class implementation macros' and 'class initialization function' under the custom objects heading.

This code was written for ac2005 so things like the editor and prompt code will need changing but it's more of an 'layout' than workable code.
If I can dig out the more advanced one I post it as well.

the object-
Code: [Select]
using System;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Interop.Common;
using Autodesk.AutoCAD.Interop;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.GraphicsInterface;
//using DCSRxFuncs;//******* you can get rid of this and PInvoke probably***********//

namespace ArxTest
{
/// <summary>
///
/// </summary>
public class DCS3dSolid : Solid3d

{
public DCS3dSolid()
{
//
// TODO: Add constructor logic here
//
}
//File writting overrides
public override void DwgInFields(DwgFiler filer)
{
base.DwgInFields(filer);
}
public override void DwgOutFields(DwgFiler filer)
{
base.DwgOutFields(filer);
}
public override void DxfInFields(DxfFiler filer)
{
base.DxfInFields(filer);
}
public override void DxfOutFields(DxfFiler filer)
{
base.DxfOutFields(filer);
}

public override Boolean WorldDraw(WorldDraw wd)
{
Boolean retcode = base.WorldDraw(wd);
return retcode;
}
public override void Extrude(Region region, double height, double taperangle)
{
base.Extrude(region, height, taperangle);
}
//class initialisation and description functions
public static IntPtr gpDesc;
public static RXClass desc()
{
Dictionary D;
D = SystemObjects.ClassDictionary;
return (RXClass)D.At("DCS3dSolid");
}
public static RXClass isA()
{
return desc();
}

public static void rxInit()
{
gpDesc = DCSRxObj.RegisterClass("DCS3dSolid","AcDb3dSolid",0,"DCS3DOBJ","AutoCAD");
return;
}

}
}

the init section at loading -
Code: [Select]
using System;
using System.IO;
using System.Diagnostics;
using System.Reflection;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Interop;
using Autodesk.AutoCAD.ApplicationServices;
//using DCSRxFuncs;//*****USE PINVOKE INSTEAD*******//


[assembly:ExtensionApplication(typeof(ArxTest.DCSApp))]
[assembly:CommandClass(typeof(ArxTest.Commands))]

namespace ArxTest
{
/// <summary>
/// The entry point for autocad, here is where I will (try to) register
/// my custom object with autocad's class hierachy
/// </summary>
public class DCSApp : IExtensionApplication
{
public void
Initialize()
{
AcadApplication app = (AcadApplication)Autodesk.AutoCAD.ApplicationServices.Application.AcadApplication;
app.ActiveDocument.Utility.Prompt(string.Format("\nLoading DCSApp..."));

DCS3dSolid.rxInit();
app.ActiveDocument.Utility.Prompt(string.Format("\n...made it past rxInit()"));

DCSRxObj.BuildClassHierarchy();
app.ActiveDocument.Utility.Prompt(string.Format("\nLoaded successfully!..."));

}

public void
Terminate()
{
//No point, can not unload .net apps from editor...
//....unloads on close of Autocad!

}
}
}
"Short cuts make long delays,' argued Pippin.”
J.R.R. Tolkien

LE

  • Guest
Re: C# custom object [just for fun]
« Reply #1 on: November 15, 2007, 06:35:34 PM »
I remember trying to derived from an Entity and never works - in my early coding with C#.... your sample looks very easy and simple to follow... will see

Now, if these smarties guys at adesk, have not exposed or wrapped for christmas the co's or the pertinent arx classes - but well, they do not know everything....  :-P

csharpbird

  • Newt
  • Posts: 64
Re: C# custom object [just for fun]
« Reply #2 on: November 19, 2007, 10:12:37 AM »
There are no source codes for the RegisterClass and BuildClassHierarchy functions.

MickD

  • King Gator
  • Posts: 3619
  • (x-in)->[process]->(y-out) ... simples!
Re: C# custom object [just for fun]
« Reply #3 on: November 19, 2007, 02:50:56 PM »
I'll see if I can dig them up, they are just C/C++ managed wrappers that could be PInvoke'd in C# anyway to save ref'ing in another dll.
"Short cuts make long delays,' argued Pippin.”
J.R.R. Tolkien

MickD

  • King Gator
  • Posts: 3619
  • (x-in)->[process]->(y-out) ... simples!
Re: C# custom object [just for fun]
« Reply #4 on: November 19, 2007, 03:16:45 PM »
Here's the managed cpp source (written for VS2002 so it may need some work) -

Code: [Select]
// DCSRxFuncs.h
// Author: Mick Duprez 22 Jan. 2005
// Description: Basic managed wrapper for methods required
// to register custom objects with AutoCAD using .net

#pragma once

using namespace System;
using namespace Autodesk::AutoCAD::Runtime;

namespace DCSRxFuncs
{
public __gc class DCSRxObj
{
// TODO: Add your methods for this class here.
public:
static void BuildClassHierarchy(void);
static IntPtr RegisterClass(String* className, String* parentName, int proxyflags, String* dxfName, String* appName);

};
}

Code: [Select]
// DCSRxFuncs.cpp
// Author: Mick Duprez 22 Jan. 2005
// Description: Basic managed wrapper for methods required
// to register custom objects with AutoCAD using .net

#include "stdafx.h"

#include "DCSRxFuncs.h"
using System::Runtime::InteropServices::Marshal;


void DCSRxFuncs::DCSRxObj::BuildClassHierarchy(void)
{
acrxBuildClassHierarchy();
}

IntPtr DCSRxFuncs::DCSRxObj::RegisterClass(String* className, String* parentName, int proxyflags, String* dxfName, String* appName)
{
long* retClass;
const char __nogc* pStr1 = static_cast<char*>(Marshal::StringToHGlobalAnsi(className).ToPointer());
const char __nogc* pStr2 = static_cast<char*>(Marshal::StringToHGlobalAnsi(parentName).ToPointer());
const char __nogc* pStr3 = static_cast<char*>(Marshal::StringToHGlobalAnsi(dxfName).ToPointer());
const char __nogc* pStr4 = static_cast<char*>(Marshal::StringToHGlobalAnsi(appName).ToPointer());
retClass = (long*)newAcRxClass(pStr1,pStr2,AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,proxyflags,NULL,pStr3,pStr4);
return retClass;
}
"Short cuts make long delays,' argued Pippin.”
J.R.R. Tolkien