NO

Author Topic: nanoCAD test  (Read 5658 times)

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 2091
nanoCAD test
« on: June 16, 2016, 02:18:20 AM »
Quote
nanoCAD
The best free CAD ever. Most common drafting features.
Example for nanoCAD 5.0, download it from here
Code: [Select]
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
//#define INITGUID
#include <ole2.h>

#define COBJMACROS
#include "OdaX.h" // from OdaX.tlb
#include "NCAuto.h" // from ncauto.dll

#pragma comment(lib, "ole32.lib")
#pragma comment(lib, "oleaut32.lib")

char *szAppName = "nanoCadTest";

#ifndef INITGUID
GUID const CLSID_Application={0x449354E9,0xCDD8,0x4A11,0xBD,0x82,0x0D,0x4A,0x3C,0x21,0xE7,0xD2};
GUID const IID_InanoCADApplication={0xAFAB189D,0x226A,0x4047,0xB9,0x8F,0xCD,0x75,0xCE,0x56,0xDD,0xE4};
#endif

HRESULT CadCreateUtilityPoint(InanoCADUtility *pUtility, VARIANT *vpt1, double x, double y, double z);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
{
HRESULT hr;
CLSID clsid;
IUnknown *pUnk = NULL;
InanoCADApplication *pCad = NULL;
InanoCADDocument *pCadDoc = NULL;

CoInitialize(NULL);
hr = CLSIDFromProgID(L"nanoCAD.Application", &clsid);
hr = GetActiveObject(&clsid, NULL, &pUnk);
if (pUnk) hr = pUnk->lpVtbl->QueryInterface(pUnk, &IID_InanoCADApplication, (void **)&pCad);
if (!pCad) hr = CoCreateInstance(&clsid, NULL, CLSCTX_ALL, &IID_InanoCADApplication, (void **)&pCad);
if (pCad) {
InanoCADApplication_put_Visible(pCad, -1);
InanoCADApplication_get_ActiveDocument(pCad, &pCadDoc);
if (pCadDoc) {
InanoCADUtility* pUtility = NULL;
IAcadDatabase *pDataBase = NULL;
InanoCADDocument_get_Utility(pCadDoc, &pUtility);
InanoCADDocument_get_Database(pCadDoc, &pDataBase);
if (pDataBase) {
IAcadModelSpace *pModelSpace = NULL;
IAcadDatabase_get_ModelSpace(pDataBase, &pModelSpace);
if (pModelSpace) {
IAcadLine *pLine;
VARIANT vpt1, vpt2; // for points
CadCreateUtilityPoint(pUtility, &vpt1, 0.0, 0.0, 0.0);
CadCreateUtilityPoint(pUtility, &vpt2, 100.0, 100.0, 0.0);
IAcadModelSpace_AddLine(pModelSpace, vpt1, vpt2, &pLine);
if (pLine) {
//MessageBox(0,"Line",0,0);
} else MessageBox(0,"No Line",0,0);
}
}
}
InanoCADApplication_Release(pCad);
} else
MessageBox(0, "No nanoCAD.Application ?", szAppName, MB_OK);
CoUninitialize();
return 0;
}

HRESULT CadCreateUtilityPoint(InanoCADUtility *pUtility, VARIANT *vpt1, double x, double y, double z)
{
SAFEARRAY sarray1; // for arrays
SAFEARRAYBOUND sab1[1];

if (!pUtility || !vpt1) return 1; // missing params
sab1[0].lLbound = 0; sab1[0].cElements = 3;

VARIANT parm1[3];
parm1[0].vt = VT_R8; parm1[0].dblVal = x; // X
parm1[1].vt = VT_R8; parm1[1].dblVal = y; // Y
parm1[2].vt = VT_R8; parm1[2].dblVal = z; // Z

sarray1.cDims = 1;
sarray1.fFeatures = FADF_VARIANT | FADF_HAVEVARTYPE | FADF_FIXEDSIZE | FADF_STATIC;
sarray1.cbElements = sizeof(VARIANT);
sarray1.cLocks = 0;
sarray1.pvData = &parm1;
sarray1.rgsabound[0].lLbound = 0;
sarray1.rgsabound[0].cElements = 3;

return InanoCADUtility_CreateTypedArray(pUtility, vpt1, VT_R8, &sarray1);
}
Code: [Select]
int CadGetPoint(InanoCADUtility* pUtility, WCHAR *wcPromt, double pt[3])
{
HRESULT hr;
VARIANT var1, var2, var3;
VariantInit(&var1);
var2.vt = VT_BSTR;
var2.bstrVal = SysAllocString(wcPromt);
hr = InanoCADUtility_GetPoint(pUtility, var1, var2, &var3);
if (!hr) {
if (var3.vt == (VT_ARRAY | VT_R8)) {
pt[0] = ((double*)var3.parray->pvData)[0];
pt[1] = ((double*)var3.parray->pvData)[1];
pt[2] = ((double*)var3.parray->pvData)[2];
SafeArrayDestroy(var3.parray);
}
}
SysFreeString(var2.bstrVal);
return hr;
}
If this used, have to VariantClear(&vpt1); after using.
Code: [Select]
HRESULT CadCreateUtilityPoint(InanoCADUtility *pUtility, VARIANT *vpt1, double x, double y, double z)
{
HRESULT hr;
SAFEARRAY* psarr = SafeArrayCreateVector(VT_VARIANT, 0, 3);
((VARIANT*)psarr->pvData)[0].vt = VT_R8;
((VARIANT*)psarr->pvData)[0].dblVal = x;
((VARIANT*)psarr->pvData)[1].vt = VT_R8;
((VARIANT*)psarr->pvData)[1].dblVal = y;
((VARIANT*)psarr->pvData)[2].vt = VT_R8;
((VARIANT*)psarr->pvData)[2].dblVal = z;
hr = InanoCADUtility_CreateTypedArray(pUtility, vpt1, VT_R8, psarr);
// SafeArrayDestroy(psarr); // free array later
return hr;
}
C# example too
Code: [Select]
using System;
using nanoCAD;
using OdaX;

class HelloNanoCAD
{
    static nanoCAD.Application oApp;
    static void Main()
    {
        oApp = new nanoCAD.ApplicationClass();
        oApp.Visible = true;
        Console.WriteLine("Value: {0}", oApp.Version);
        InanoCADDocument oDoc = oApp.ActiveDocument;
        Console.WriteLine("Value: {0}", oDoc.Name);
        DrawLine2D(0, 0, 100, 100);
    }
    public static void DrawLine2D(double x1, double y1, double x2, double y2)
    {
        AcadLine oLine;
        Object pt1, pt2;
        oApp.ActiveDocument.Utility.CreateTypedArray(out pt1, 5, new object[] { x1, y1, 0 });
        oApp.ActiveDocument.Utility.CreateTypedArray(out pt2, 5, new object[] { x2, y2, 0 });
        oLine = oApp.ActiveDocument.ModelSpace.AddLine(pt1, pt2);
    }
}
EDIT 2016-06-19 headers updated in zip nCadTestUtility1.zip ALIASes removed.
« Last Edit: July 18, 2022, 07:02:11 PM by TimoVJL »
May the source be with you

sergey

  • Guest
Re: nanoCAD test
« Reply #1 on: June 17, 2016, 06:57:38 PM »
My humble opinion:
In this CAD many .Net Framework (v.3.5 VB C#)
The names of some of the structures/facilities authors forgot to remove 'AutoCAD'.
So do not exclude the ancestor of the disease.
And these little things are alarming.
Example C# would be good to put on 'codeproject' - where he will see the .Net fans.
Write program by .Net Framework course simpler/easier.
But where is the guarantee that he will not repeat the fate of the VBA-AutoCAD.
ProgeCAD (from C) likely to be more reliable choice.
[[Nochmals: INHO]]

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 2091
Re: nanoCAD test
« Reply #2 on: June 20, 2016, 01:30:27 AM »
 ;)
Code: [Select]
...
IAcadEntity *pEntity = NULL;
double pt[3];
hr = CadGetEntity(pUtility, &pEntity, &pt[0], L"Pick Entity");
if (pEntity) {
BSTR bstr = NULL;
hr = IAcadEntity_get_EntityName(pEntity, &bstr);
InanoCADUtility_Prompt(pUtility, bstr);
if (bstr) SysFreeString(bstr);
IAcadEntity_Release(pEntity);
}
...
Code: [Select]
int CadGetEntity(InanoCADUtility* pUtility, IAcadEntity **pEntity, double pt[3], WCHAR *wcPromt)
{ // STDMETHOD(GetEntity)(THIS,VARIANT*,VARIANT*,VARIANT);
HRESULT hr;
VARIANT var1, var2, var3;
VariantInit(&var1);
VariantInit(&var2);
var3.vt = VT_BSTR;
var3.bstrVal = SysAllocString(wcPromt);
hr = InanoCADUtility_GetEntity(pUtility, &var1, &var2, var3);
if (!hr) {
if (var1.vt == VT_DISPATCH) {
IDispatch *pDisp = NULL;
pDisp = var1.pdispVal;
pDisp->lpVtbl->QueryInterface(pDisp, &IID_IAcadEntity, (void**)pEntity);
}
if (var2.vt == (VT_ARRAY | VT_R8)) {
pt[0] = ((double*)var2.parray->pvData)[0];
pt[1] = ((double*)var2.parray->pvData)[1];
pt[2] = ((double*)var2.parray->pvData)[2];
SafeArrayDestroy(var2.parray);
}
}
SysFreeString(var3.bstrVal);
return hr;
}
AddLightWeightPolyline
Code: [Select]
IAcadLWPolyline *pLWPL;
VARIANT vpt1; // for points
double pts[] = {0.0,0.0, 100.0,0.0, 100.0,100.0};
hr = CadCreateUtilityPoints(pUtility, &vpt1, 6, pts);
if (!hr) {
hr = IAcadModelSpace_AddLightWeightPolyline(pModelSpace, vpt1, &pLWPL);
}
VariantClear(&vpt1);
Code: [Select]
HRESULT CadCreateUtilityPoints(InanoCADUtility *pUtility, VARIANT *vpt1, int nCount, double  dblPoints[])
{
HRESULT hr;
SAFEARRAY* psarr = SafeArrayCreateVector(VT_VARIANT, 0, nCount);
for (int i = 0; i < nCount; i++) {
((VARIANT*)psarr->pvData)[i].vt = VT_R8;
((VARIANT*)psarr->pvData)[i].dblVal = dblPoints[i];
}
hr = InanoCADUtility_CreateTypedArray(pUtility, vpt1, VT_R8, psarr);
// SafeArrayDestroy(psarr); // free array later
if (hr) ErrorString(hr);
return hr;
}
« Last Edit: August 25, 2016, 01:10:33 PM by TimoVJL »
May the source be with you

sergey

  • Guest
Re: nanoCAD test
« Reply #3 on: June 20, 2016, 09:36:07 PM »
This small difference in the arguments of the function:
nanoCAD: InanoCADUtility_GetEntity (pUtility, & var1, & var2, var3);
autoCAD: IAcadUtility_GetEntity (IAcadUtility * This, IDispatch ** Object, VARIANT * PickedPoint, VARIANT Prompt);
It has a large (unpleasant) consequences for working with AutoCAD.
I can call this function like this:
IAcadUtility_GetEntity (pUtility, (IDispatch **) & pEntity, & vpnt, Prompt);
and then get the coordinates 'vpnt' (picked-point), and even something like 'pEntity', but I have serious doubts that this is 'acadEntuty'.

I do not know how from 'IDispatch **' to get the object 'Entity'
And I would like in 1 or 2 steps ...

sergey

  • Guest
Re: nanoCAD test
« Reply #4 on: June 29, 2016, 07:23:22 PM »
LiteCAD v. 3.0.90
I think it deserves attention:
http://www.kolbasoft.com/