ZWSoft ZRX for ZWCAD: Developer Guide: Modules

ZWSoft ZRX for ZWCAD: Developer Guide 2023
Modules
Here is a list of all modules:
[detail level 12345]
▼ ZRX Introductory Concepts
▼ Overview of ZRX
System Requirement
ZRX Directory Tree
▶ Setting up a ZRX Project Using Microsoft Visual Studio
Create a ZRX Project by Using Wizard
Create a ZRX Project Manually
Migrate an ARX Application to ZRX of ZWCAD
▼ Database Primer
Database Overview
▶ Creating Objects in ZRX
Creating Entities
Creating a New Layer
Adding a Group to the Group Dictionary
Adding a Dimesion Style to the Symbol Table
Opening and Closing ZRX Objects
▼ ZRX Application Basic
▶ Creating an ZRX Application
Create a ZRX Project
Responding to ZWCAD Messages
Registering new commands
Loading a ZRX application
Unloading a ZRX application
▶ ZRX Commands
? --List
Load
UnLoad
Commands
▼ Database Operations
Getting Current Database
Saving a Database
ReadIn and Populating a Database
Creating a New Database By Wblock
Inserting a Database
Long Transactions
▼ Database Objects
Opening and Closing Database Objects
Deleting Objects
Database Ownership of Objects
▶ Adding Object-Specific Data
Extended Data
Extension Dictionary
Erasing Objects
Object Filing
Embedded and Encapsulating Objects
▼ Entities
▶ Simple Entity
Draw a Line
Draw a Polyline
Create a Text
▶ Complex Entity
Create Regions
Create a Hatch
▶ Create a Simple Block
Create a Simple Block Table Record
Create a Simple Block Table Record with Attribute Definitions
Creating a Block Reference with Attributes
▶ Modifiy Entity
Entity Visibility
Entity Highlight
Entity Layer
Entity Color
Entity Transform
▼ Container Objects
▶ Symbol Tables
Modifying a Layer Table Record
Iterating over Tables
▶ Dictionaries
Creating a Dictionary
Groups and the Group Dictionary
Iterating over Dictionary Entries
▶ Xrecords
Xrecord Examples
▼ Basic Interaction with ZWCAD
▼ MFC Support in ZRX
MFC model dialog
Resource Solution
Using CAD UI Class
▼ Selection Set, Entity, and Symbol Table Functions
▶ Selection Set
Getting Selection Set
Filter with Wild Card
Filter with Compare condition
Entities information
Symbol Table
▼ Plot API
Plot to a File
▼ Global Functions for Interacting with ZWCAD
▶ General Access
Using acedCmd()
Pausing for User Input
Passing Pick Points to ZWCAD Commands
System Variables
AutoLISP Symbols
File Search
Object Snap
Viewport Descriptors
Geometric Utilities
The Text Box Utility Function
▶ Getting User Input
User-Input Functions
▶ Control of User-Input Function Conditions
Input Options for User-Input Functions
Keyword Specifications
Graphically Dragging Selection Sets.
User Breaks.
Returning Values to AutoLISP Functions.
▶ Conversions
String Conversions
Real-World Units
Character Type Handling
Coordinate System Transformations
▶ Display Control
Interactive Output
Control of Graphics and Text Screens
Control of Low-Level Graphics and User Input
Tablet Calibration
Wild-Card Matching
▼ ZRX Global Utility Functions
▶ Common Characteristics of ZRX Library Functions
▶ ZRX Global Function Calls Compared to AutoLISP Calls
Argument Lists in AutoLISP and C
Memory Management
Function Return Values versus Function Results
▶ External Functions
Defining External Functions
Evaluating External Functions
Error Handling Functions
▶ Communication Between Applications
Handling Errors from Invoked Functions
Handling External Applications
▶ Variables, Types, and Values Defined in ObjectARX
▶ General Types and Definitions
Real Numbers And Points
Transformation Matrices
Entity and Selection Set Names
Useful Values
▶ Result Buffers and Type Codes
Result Buffers
Result Type Codes Defined by ObjectARX
DXF Group Codes
ZARX Function Result Type Codes
User-Input Control Bit Codes
▶ Lists and Other Dynamically Allocated Data
▶ Result-Buffer Memory Management
List Creation and Deletion
AutoLISP Lists
Entity Lists with DXF Codes in ObjectARX
Command and Function Invocation Lists
▼ ZWCAD Command Prompt Standard
▶ CommandLine Interface
General Format
Format for the Current Value Line
▶ Format for the Command Line Prompt
Current Instruction
Descriptive Information
List of Options
Default Option
Context Menu Population
▼ Custom Objects
▼ Deriving from AcDbobject
Header File
Source File
▼ Deriving from AcDbEntity
▶ Custom Entity Data Base
Header File
▶ Source File
ZsdkSign
ZsdkDB
Custom Entity UI
▼ Using AcEdJig
Header File
Source File
▼ Advanced Topics
▼ Table Linking
Data Links
Table Content
▼ Notification
Creating an Editor Reactor
Creating a Database Reactor
Creating an Object Reactor
Using a Reactor
The Multiple Document Interface
Transaction Management
Deep Cloning
Protocol Extension
▼ Input Point Processing
▶ Custom Object Snap Modes
Header File
Source File
▶ Input Point Filters and Monitors
Point Filters
Input Point Monitors
Input Context Events
Application Configuration
zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: ZRX Introductory Concepts

Modules
ZRX Introductory Concepts

Modules

Overview of ZRX
Database Primer
ZRX Application Basic
Database Operations
Database Objects
Entities
Container Objects

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: Overview of ZRX

Modules
Overview of ZRX
ZRX Introductory Concepts

Modules

System Requirement
ZRX Directory Tree
Setting up a ZRX Project Using Microsoft Visual Studio

Detailed Description

This section is the overview of ZRX programming.


ZWSoft ZRX for ZWCAD: Developer Guide: System Requirement

System Requirement
ZRX Introductory Concepts » Overview of ZRX

1. Developing environment: Visual Studio 2017 Version 15.9 or above.

2. ZWCAD Version: ZWCAD 2022

3. SDK: ZRXSDK


ZWSoft ZRX for ZWCAD: Developer Guide: ZRX Directory Tree

ZRX Directory Tree
ZRX Introductory Concepts » Overview of ZRX

Introduces the directory structure of the SDK package.

arxport
The arxport directory contains the header files. The header files contains macro conversion, in order to be compatible with ObjectARX.
Doc
The Doc directory contains the help documentation about ZRX.
inc
The inc directory contains the ZRX header files.
lib-Win32
The lib-Win32 directory contains the library files for 32bit operating systems.
lib-x64
The lib-x64 directory contains the library files for 64bit operating systems.
samples
The samples directory contains some examples of ZRX application.
Tools
The Tools directory contains a ZRX wizard.
utils
The utils directory constains a library that extend ZRX.


ZWSoft ZRX for ZWCAD: Developer Guide: Setting up a ZRX Project Using Microsoft Visual Studio

Modules
Setting up a ZRX Project Using Microsoft Visual Studio
ZRX Introductory Concepts » Overview of ZRX

Modules

Create a ZRX Project by Using Wizard
Create a ZRX Project Manually
Migrate an ARX Application to ZRX of ZWCAD

Detailed Description

This section introduces how to setup a ZRX project using Miscrosoft Visual Studio 2017.


ZWSoft ZRX for ZWCAD: Developer Guide: Create a ZRX Project by Using Wizard

Create a ZRX Project by Using Wizard
ZRX Introductory Concepts » Overview of ZRX » Setting up a ZRX Project Using Microsoft Visual Studio

This section introduces how to create a ZRX project by template.

Note
You need to install ZRX Application Template.

a) Just one step. Select a ZRX project template to create a new project in Visual Studio 2017.


ZWSoft ZRX for ZWCAD: Developer Guide: Create a ZRX Project Manually

Create a ZRX Project Manually
ZRX Introductory Concepts » Overview of ZRX » Setting up a ZRX Project Using Microsoft Visual Studio

This section introduces how to create a ZRX project manually. Follow the steps below to set the project properties.

a) If you use MBCS in your project, please change to "Use Unicode Character Set" as below.

For Windows XP Edition, please change the Platform Toolset to "Visual Studio 2017 - Windows XP (v141_xp)" as below.

b) Add the path of "ZRXSDK\arxport". For example, the path is "C:\ZWCAD_ZRXSDK\arxport". It is shown as the figure below.

For Windows XP Edition, please change the Preprocessor Definitions, add "WINVER=0x0501;_WIN32_WINNT=0x0501;" as below.

c) Change [Treat wchart_t as Built-in Type] and [Force Conformance in For Loop Scope] to "Yes" as below.

d) Add the path of "ZRXSDK\lib", for example, "C:\ZWCAD_ZRXSDK\lib-$(Platform)". It's shown as the figure below.

e) Add follow dependency libraries: "ZwdUI.lib;ZwAuto.lib;ZWCAD.lib;ZwDatabase.lib;ZwDatabaseMgd.lib;ZwGeometry.lib;ZwRx.lib;ZwUI.lib;ZwZrx.lib;ZwPAL.lib;". Add the path of Module Definition File, for example, "ZrxProject". About the contents of the file, see the example.

An example of ZrxProject.def

LIBRARY ""
EXPORTS
zcrxEntryPoint PRIVATE
zcrxGetApiVersion PRIVATE


ZWSoft ZRX for ZWCAD: Developer Guide: Migrate an ARX Application to ZRX of ZWCAD

Migrate an ARX Application to ZRX of ZWCAD
ZRX Introductory Concepts » Overview of ZRX » Setting up a ZRX Project Using Microsoft Visual Studio

This section introduces how to migrate an ARX application to ZRX fo ZWCAD.


ZWSoft ZRX for ZWCAD: Developer Guide: Database Primer

Modules
Database Primer
ZRX Introductory Concepts

Modules

Database Overview
Creating Objects in ZRX

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: Database Overview

Database Overview
ZRX Introductory Concepts » Database Primer

The database structure of ZRX can be divided into four parts: Block Table, Layer Table, Other Symbol Tables and Named Object Dictionary.

Block Table
Define a pointer to a AcDbBlockTable object:

AcDbBlockTable *pBlockTable;

Obtain the Block Table for current drawing:

acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlockTable,AcDb::kForRead);

Define a pointer to a AcDbBlockTableRecord Object�?

AcDbBlockTableRecord *pBlockTableRecord;

Layer Table
Define a pointer to a AcDbLayerTable object:

AcDbLayerTable *pLayerTable;

Other Symbol Tables
Define a pointer to AcDbDimStyleTable object:

AcDbDimStyleTable *pDimStyleTable;

Named Object Dictronary
Define a pointer to AcDbGroup object:

AcDbGroup pGroup;

Note
You can call the following function to abtain the database for current drawing:
acdbHostApplicationServices()->workingDatabase()

When you are done using database objects, you must close them, for example:
pBlockTable->close();
pBlockTableRecord->close();


ZWSoft ZRX for ZWCAD: Developer Guide: Creating Objects in ZRX

Modules
Creating Objects in ZRX
ZRX Introductory Concepts » Database Primer

Modules

Creating Entities
Creating a New Layer
Adding a Group to the Group Dictionary
Adding a Dimesion Style to the Symbol Table
Opening and Closing ZRX Objects

Detailed Description

The sample code creates objects in Block Table,Layer Table,Symbol Table and Named Object Dictionary, respectively.


ZWSoft ZRX for ZWCAD: Developer Guide: Creating Entities

Creating Entities
ZRX Introductory Concepts » Database Primer » Creating Objects in ZRX

The following code creates a line.

AcDbObjectId DBPrimer::CreateLine()
{
AcGePoint3d ptStart(0,0,0);
AcGePoint3d ptEnd(100,100,0);
AcDbLine *pLine = new AcDbLine(ptStart,ptEnd);
AcDbBlockTable *pBlockTable;
acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlockTable,AcDb::kForRead);
AcDbBlockTableRecord *pBlockTableRecord;
pBlockTable->getAt(ACDB_MODEL_SPACE,pBlockTableRecord,AcDb::kForWrite);
AcDbObjectId lineId;
pBlockTableRecord->appendAcDbEntity(lineId,pLine);
pLine->close();
pBlockTableRecord->close();
pBlockTable->close();
return lineId;
}

The following code creates an arc.

AcDbObjectId DBPrimer::CreateArc()
{
AcGePoint3d ptCenter(0,0,0);
AcGeVector3d vec(0,0,1);
double radius = 100;
double startAngle = 10;
double endAngle = 20;
AcDbArc *pArc = new AcDbArc(ptCenter,vec,radius,startAngle,endAngle);
AcDbBlockTable *pBlockTable;
acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlockTable,AcDb::kForRead);
AcDbBlockTableRecord *pBlockTableRecord;
pBlockTable->getAt(ACDB_MODEL_SPACE,pBlockTableRecord,AcDb::kForWrite);
AcDbObjectId arcId;
pBlockTableRecord->appendZcDbEntity(arcId,pArc);
pArc->close();
pBlockTableRecord->close();
pBlockTable->close();
return arcId;
}


ZWSoft ZRX for ZWCAD: Developer Guide: Creating a New Layer

Creating a New Layer
ZRX Introductory Concepts » Database Primer » Creating Objects in ZRX

The following code creates a new layer.

AcDbObjectId DBPrimer::CreateLayer()
{
AcDbLayerTable *pLayerTable;
acdbHostApplicationServices()->workingDatabase()->getLayerTable(pLayerTable,AcDb::kForWrite);
AcDbLayerTableRecord *pLayerTableRecord = new AcDbLayerTableRecord();
pLayerTableRecord->setName(_T("NewLayer"));
AcDbObjectId layerTableRecordId;
pLayerTable->add(layerTableRecordId,pLayerTableRecord);
pLayerTableRecord->close();
pLayerTable->close();
return layerTableRecordId;
}


ZWSoft ZRX for ZWCAD: Developer Guide: Adding a Group to the Group Dictionary

Adding a Group to the Group Dictionary
ZRX Introductory Concepts » Database Primer » Creating Objects in ZRX

The following code creates a group and then add it into the Group Dictionary.

void DBPrimer::CreateGroup(AcDbObjectId objId)
{
AcDbGroup *pGroup = new AcDbGroup();
pGroup->setName(_T("NewGroup"));
pGroup->append(objId);
AcDbDictionary *pGroupDict;
acdbHostApplicationServices()->workingDatabase()->getGroupDictionary(pGroupDict,AcDb::kForWrite);
AcDbObjectId pGroupId;
pGroupDict->setAt(_T("NewGroup"),pGroup,pGroupId);
pGroupDict->close();
pGroup->close();
}


ZWSoft ZRX for ZWCAD: Developer Guide: Adding a Dimesion Style to the Symbol Table

Adding a Dimesion Style to the Symbol Table
ZRX Introductory Concepts » Database Primer » Creating Objects in ZRX

The following code creates a dimesion style and then add it into the Symbol Table.

void DBPrimer::CreateDimStyle()
{
AcDbDimStyleTable *pDimStyleTable;
acdbHostApplicationServices()->workingDatabase()->getDimStyleTable(pDimStyleTable,AcDb::kForWrite);
AcDbDimStyleTableRecord *pDimStyleTableRecord;
pDimStyleTableRecord = new AcDbDimStyleTableRecord();
pDimStyleTableRecord->setName(_T("NewDimStyle"));
pDimStyleTableRecord->setDimasz(5);
pDimStyleTableRecord->setDimexe(3);
pDimStyleTableRecord->setDimtxt(2);
pDimStyleTable->add(pDimStyleTableRecord);
pDimStyleTableRecord->close();
pDimStyleTable->close();
}


ZWSoft ZRX for ZWCAD: Developer Guide: Opening and Closing ZRX Objects

Opening and Closing ZRX Objects
ZRX Introductory Concepts » Database Primer » Creating Objects in ZRX

The following code shows how to open a object, then modify and close.

Acad::ErrorStatus DBPrimer::ChangeColor(AcDbObjectId entId)
{
AcDbEntity *pEnt;
acdbOpenAcDbEntity(pEnt,entId,AcDb::kForWrite);
pEnt->setColorIndex(1);
pEnt->close();
return Acad::eOk;
}


ZWSoft ZRX for ZWCAD: Developer Guide: ZRX Application Basic

Modules
ZRX Application Basic
ZRX Introductory Concepts

Modules

Creating an ZRX Application
Registering new commands
Loading a ZRX application
Unloading a ZRX application
ZRX Commands

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: Creating an ZRX Application

Modules
Creating an ZRX Application
ZRX Introductory Concepts » ZRX Application Basic

Modules

Create a ZRX Project
Responding to ZWCAD Messages

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: Create a ZRX Project

Create a ZRX Project
ZRX Introductory Concepts » ZRX Application Basic » Creating an ZRX Application

Initialize the ZRX application by calling the function:

void initApp()
{
acedRegCmds->addCommand(_T("HELLOWORLD"),
_T("Hello"),
_T("Helo"),
ACRX_CMD_MODAL,
HelloWorld);
}

Unload the ZRX application by calling the function:

void unloadApp()
{
acedRegCmds->removeGroup(_T("HELLOWORLD"));
}

An entrypoint function:

extern "C" AcRx::AppRetCode
acrxEntryPoint(AcRx::AppMsgCode msg, void *p)
{
switch(msg)
{
case AcRx::kInitAppMsg:
acrxDynamicLinker->unlockApplication(p);
acrxRegisterAppMDIAware(p);
initApp();
break;
}
case AcRx::kUnloadAppMsg:
unlocadApp();
break;
default:
break;
}
return AcRx::kRetOK;

A custom function:

void HelloWorld()
{
acutPrintf("Hello World");
}


ZWSoft ZRX for ZWCAD: Developer Guide: Responding to ZWCAD Messages

Responding to ZWCAD Messages
ZRX Introductory Concepts » ZRX Application Basic » Creating an ZRX Application

Messa
kInitAppMsg | Sent when the ZRX application is loaded.
kUnloadAppMsg | Sent when the ZRX application is unloaded.
kInitDialogMsg | Initialize application's system resources.
switch( msg )
{
case AcRx::kInitAppMsg:
acrxDynamicLinker->unlockApplication(appId);
acrxDynamicLinker->registerAppMDIAware(appId);
initApp();
break;
case AcRx::kUnloadAppMsg:
unloadApp();
break;
case AcRx::kInitDialogMsg:
break;
default:
break;
}


ZWSoft ZRX for ZWCAD: Developer Guide: Registering new commands

Registering new commands
ZRX Introductory Concepts » ZRX Application Basic

Register a new command by calling function:

Zcad::ErrorStatus addCommand(const ZTCHAR * cmdGroupName,
const ZTCHAR * cmdGlobalName,
const ZTCHAR * cmdLocalName,
ZSoft::Int32 commandFlags,
ZcRxFunctionPtr FunctionAddr,
ZcEdUIContext *UIContext=NULL,
int fcode=-1,
HINSTANCE hResourceHandle=NULL,
ZcEdCommand** cmdPtrRet=NULL)

You must register a command in function:

void initApp();

see Create a ZRX Project


ZWSoft ZRX for ZWCAD: Developer Guide: Loading a ZRX application

Loading a ZRX application
ZRX Introductory Concepts » ZRX Application Basic

Using command APPLOAD, you can load or unload applications and define the applications to be loaded at the startup.
Another way, you can use the command options of ZRX command.
For more information, see Load


ZWSoft ZRX for ZWCAD: Developer Guide: Unloading a ZRX application

Unloading a ZRX application
ZRX Introductory Concepts » ZRX Application Basic

You can unload ZRX applications by using command APPLOAD or using the command options of ZRX command.
For more information, see UnLoad


ZWSoft ZRX for ZWCAD: Developer Guide: ZRX Commands

Modules
ZRX Commands
ZRX Introductory Concepts » ZRX Application Basic

Modules

? --List
Load
UnLoad
Commands

Detailed Description

The ZRX command has four options: [?/Load/UnLoad/Commands]


ZWSoft ZRX for ZWCAD: Developer Guide: ? --List

? --List
ZRX Introductory Concepts » ZRX Application Basic » ZRX Commands

List the already loaded runtime extension files.


ZWSoft ZRX for ZWCAD: Developer Guide: Load

Load
ZRX Introductory Concepts » ZRX Application Basic » ZRX Commands

Open runtime extension files.


ZWSoft ZRX for ZWCAD: Developer Guide: UnLoad

UnLoad
ZRX Introductory Concepts » ZRX Application Basic » ZRX Commands

Unload a runtime extension file.


ZWSoft ZRX for ZWCAD: Developer Guide: Commands

Commands
ZRX Introductory Concepts » ZRX Application Basic » ZRX Commands

Show all commands registered from ZRX programs.


ZWSoft ZRX for ZWCAD: Developer Guide: Database Operations

Modules
Database Operations
ZRX Introductory Concepts

Modules

Getting Current Database
Saving a Database
ReadIn and Populating a Database
Creating a New Database By Wblock
Inserting a Database
Long Transactions

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: Getting Current Database

Getting Current Database
ZRX Introductory Concepts » Database Operations

ZRX Application can get the current database pointer by using acdbHostApplicationServices()->workingDatabase().
Through the database pointer, ZRX Application can accesses the block table, linetype table, text style table, layer table, and so on.
This example shows how to add a text to the current database.

void CdatabaseOperations::workingDatabase()
{
AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase();
if (pDb != NULL)
{
AcDbBlockTable* pBlockTable=NULL;
AcDbObjectId entId=AcDbObjectId::kNull;
Acad::ErrorStatus es=Acad::eOk;
es=pDb->getBlockTable(pBlockTable, AcDb::kForRead);
if (es==Acad::eOk)
{
AcDbBlockTableRecord* pBlockTableRecord=NULL;
es=pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite);
pBlockTable->close();
if (es==Acad::eOk)
{
AcDbMText* pText=new AcDbMText();
AcString text=_T("HelloWorld!");
double height=5;
double width=60;
AcGePoint3d position(30, 20, 0);
pText->setContents(text.kTCharPtr());
pText->setLocation(position);
pText->setTextHeight(height);
pText->setWidth(width);
es=pBlockTableRecord->appendZcDbEntity(entId, pText);
if (es==Acad::eOk)
{
pText->close();
}
pBlockTableRecord->close();
}
}
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: Saving a Database

Saving a Database
ZRX Introductory Concepts » Database Operations

ZRX Application uses the saveAs function of AcDbDatabase to save information into the filename.
This example shows how to save the current database in the editor.

void CdatabaseOperations::saveDatabase()
{
AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase();
if (pDb != NULL)
{
pDb->saveAs(_T("Drawing1.dwg"));
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: ReadIn and Populating a Database

ReadIn and Populating a Database
ZRX Introductory Concepts » Database Operations

Using readDwgFile function of AcDbDatabase to load a exiting dwg file into database.
This example shows: load "Drawing1.dwg" file into a new database, then add a poly line with 3 points into database, fanally save the database information back to "Drawing1.dwg" file.

void CdatabaseOperations::readDwgFile()
{
AcDbDatabase *pDb = new AcDbDatabase(Adesk::kFalse);
if(Acad::eOk != pDb->readDwgFile(_T("Drawing1.dwg")))
{
acedAlert(_T("Readin the file fail."));
return ;
}
AcDbBlockTable* pBlockTable=NULL;
AcDbObjectId entId=AcDbObjectId::kNull;
Acad::ErrorStatus es=Acad::eOk;
es=pDb->getBlockTable(pBlockTable, AcDb::kForRead);
if (es==Acad::eOk)
{
AcDbBlockTableRecord* pBlockTableRecord=NULL;
es=pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite);
pBlockTable->close();
if (es==Acad::eOk)
{
AcGePoint2d pt0(5, 5), pt1(50, 10), pt2(150, 70);
AcDbPolyline* pPLine=new AcDbPolyline(3);
double width = 1;
pPLine->addVertexAt(0, pt0, 0, width, width);
pPLine->addVertexAt(1, pt1, 0, width, width);
pPLine->addVertexAt(2, pt2, 0, width, width);
es=pBlockTableRecord->appendZcDbEntity(entId, pPLine);
if (es==Acad::eOk)
{
pPLine->close();
}
pBlockTableRecord->close();
}
}
es = pDb->saveAs(_T("Drawing1.dwg"));
delete pDb;
}


ZWSoft ZRX for ZWCAD: Developer Guide: Creating a New Database By Wblock

Creating a New Database By Wblock
ZRX Introductory Concepts » Database Operations

ZRX Application uses the wblock function of AcDbDatabase to transfer entire contents from current database to another new database.

void CdatabaseOperations::wblockDB()
{
AcDbDatabase *pSourceDb = new AcDbDatabase(Adesk::kFalse);
AcDbDatabase *pDestDb = new AcDbDatabase(Adesk::kFalse);
Acad::ErrorStatus es = Acad::eOk;
if(Acad::eOk != pSourceDb->readDwgFile(_T("Drawing1.dwg")))
{
acedAlert(_T("Readin the file fail."));
return ;
}
es = pSourceDb->wblock(pDestDb);
es = pDestDb->saveAs(_T("Drawing2.dwg"));
delete pDestDb;
delete pSourceDb;
}


ZWSoft ZRX for ZWCAD: Developer Guide: Inserting a Database

Inserting a Database
ZRX Introductory Concepts » Database Operations

Using the insert function of AcDbDatabase to copy all the entities from the model space of a database(Drawing1.dwg) to current database.

void CdatabaseOperations::insertDB()
{
AcDbDatabase *pSourceDb = new AcDbDatabase(Adesk::kFalse);
Acad::ErrorStatus es = Acad::eOk;
if(Acad::eOk != pSourceDb->readDwgFile(_T("Drawing1.dwg")))
{
acedAlert(_T("Readin the file fail."));
return ;
}
if (Acad::eOk != acdbHostApplicationServices()->workingDatabase()->insert(AcGeMatrix3d::kIdentity, pSourceDb))
acedAlert(_T("insert operation fail!"));
delete pSourceDb;
}


ZWSoft ZRX for ZWCAD: Developer Guide: Long Transactions

Long Transactions
ZRX Introductory Concepts » Database Operations

Long Transactions provide a way for ZRX Appplications to check out entities from a database and modify them in current database, then check them back.
The original database's objects are updated to what have be changed.
This example shows: how to change the color of the entities.

void CdatabaseOperations::longTrans()
{
AcDbDatabase *pSourceDb = new AcDbDatabase(Adesk::kFalse);
Acad::ErrorStatus es = Acad::eOk;
if(Acad::eOk != pSourceDb->readDwgFile(_T("Drawing1.dwg")))
{
acedAlert(_T("Readin the file fail."));
return ;
}
AcDbBlockTable* pBlockTable=NULL;
AcDbObjectId entId=AcDbObjectId::kNull;
AcDbBlockTableRecordIterator* blkIer;
AcDbObjectIdArray objectArr;
AcDbEntity* ent;
es=pSourceDb->getBlockTable(pBlockTable, AcDb::kForRead);
if (es==Acad::eOk)
{
AcDbBlockTableRecord* pBlockTableRecord=NULL;
es=pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite);
pBlockTable->close();
if (es==Acad::eOk)
{
es=pBlockTableRecord->newIterator(blkIer);
if (es==Acad::eOk)
{
for (blkIer->start(); !blkIer->done(); blkIer->step())
{
if (blkIer->getEntity(ent, AcDb::kForRead)==Acad::eOk)
{
objectArr.append(ent->objectId());
}
ent->close();
}
}
delete blkIer;
}
pBlockTableRecord->close();
}
if (objectArr.isEmpty())
{
acedAlert(_T("Drawing1.dwg is empty."));
return ;
}
AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase();
if (pDb != NULL)
{
AcDbBlockTable* pBlockTable=NULL;
AcDbObjectId entId=AcDbObjectId::kNull;
Acad::ErrorStatus es=Acad::eOk;
es=pDb->getBlockTable(pBlockTable, AcDb::kForRead);
if (es==Acad::eOk)
{
AcDbBlockTableRecord* pBlockTableRecord=NULL;
es=pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForRead);
pBlockTable->close();
if (es==Acad::eOk)
{
entId=pBlockTableRecord->objectId();
pBlockTableRecord->close();
AcDbIdMapping err;
AcDbObjectId checkoutId;
acapLongTransactionManagerPtr()->checkOut(checkoutId, objectArr, entId, err);
int cIndex;
if (acedGetInt(_T("Set Entity color Index :"), &cIndex)==RTNORM)
{
AcDbObject* pcheck;
if (acdbOpenObject(pcheck, checkoutId, AcDb::kForRead)==Acad::eOk)
{
AcDbLongTransaction* pLong=AcDbLongTransaction::cast(pcheck);
if (pLong!=NULL)
{
AcDbLongTransWorkSetIterator* pIter;
es=pLong->newWorkSetIterator(pIter);
if (es==Acad::eOk)
{
for (pIter->start(); !pIter->done(); pIter->step())
{
AcDbEntity* pEnt;
acdbOpenAcDbEntity(pEnt, pIter->objectId(), AcDb::kForWrite);
pEnt->setColorIndex(cIndex);
pEnt->close();
}
delete pIter;
}
}
pcheck->close();
}
}
acapLongTransactionManagerPtr()->checkIn(checkoutId, err);
pSourceDb->saveAs(_T("Drawing1.dwg"));
delete pSourceDb;
acedAlert(_T("check Drawing1.dwg file."));
}
}
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: Database Objects

Modules
Database Objects
ZRX Introductory Concepts

Modules

Opening and Closing Database Objects
Deleting Objects
Database Ownership of Objects
Adding Object-Specific Data
Erasing Objects
Object Filing
Embedded and Encapsulating Objects

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: Opening and Closing Database Objects

Opening and Closing Database Objects
ZRX Introductory Concepts » Database Objects

You can use acdbOpenObject() to open an object.
You have three ways to open an object.
- kForRead.As long as the object is not already open for write or for notify,the obeject can be opened or read by up to 256 readers.
- kForWrite.If the object is not already open,you can open it for write.
- kForNotify.if the object is already closed,open for read,or open for write ,but not already open for notify,you can open it for notify.

AcDbEntity * DBObjects::UserOpenObject(AcDbObjectId objID,AcDb::OpenMode openMode)
{
AcDbEntity *pEnt;
Acad::ErrorStatus eStat=acdbOpenObject(pEnt,objID,openMode);
switch(eStat)
{
case Acad::eOk:
acutPrintf(_T("Succeeds."));
break;
case Acad::eAtMaxReaders:
acutPrintf(_T("ReadCount=256."));
break;
case Acad::eWasOpenForRead:
acutPrintf(_T("The Object is already open for read."));
break;
case Acad::eWasOpenForNotify:
acutPrintf(_T("The Object is open for notify."));
break;
}
return pEnt;
}

When you open an object, you should close it as early as possible.

pEnt->close();

If there is only one reader of the object,you can upgrade the open status to write.
Similarly, if your object is open for notify,you can use upgradeFromNotify to upgrade its open status to write

Use downgradeOpen() to downgrade its status to read.
Similarly,Use downgradeToNotify() to downgrade status to notify.

pEnt->upgradeOpen();
pEnt->setColorIndex(2);//Change a Entity Object Data
pEnt->downgradeOpen();

You can refer an AcDbObject object by handle,object ID or c++ instance pointer.

void DBObjects::userSelectEntity()
{
ads_name objName;
ads_point pt;
//It is returned in ads_name form ads_name is equivalent to AcDbObjectId.
acedEntSel(_T("\n User select an entity:"),objName,pt);
AcDbObjectId objID;
//Exchange ads_name to Object ID
//You can exchange Object ID to ads_name by use acdbGetAdsName(ads_name& objName,AcDbObjectId objId).
acdbGetObjectId(objID,objName);
AcDbEntity *pEnt;
AcDb::OpenMode openMode=AcDb::OpenMode::kForRead;
pEnt=UserOpenObject(objID,openMode);
if (pEnt!=NULL)
{
pEnt->upgradeOpen();
pEnt->setColorIndex(2);
pEnt->downgradeOpen();
pEnt->close();//Close the database object.
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: Deleting Objects

Deleting Objects
ZRX Introductory Concepts » Database Objects

Use the AcDbObject :: new () function when you create an instance of an AcDbObject object to attach it to the database.
once an object is added to the database, it can not be deleted;
ZWCAD manages the deletion of all database resident objects.
So,object can be deleted only it is first created, and has not yet been added to the database.

AcDbObjectId DBObjects::CreateLine()
{
AcGePoint3d pStart(0,0,0);
AcGePoint3d pEnd(100,100,0);
AcDbLine *pLine=new AcDbLine(pStart,pEnd);
AcDbBlockTable *pBlockTable;
acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlockTable, AcDb::kForRead);
AcDbBlockTableRecord *pBlockTableRecord;
pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite);
AcDbObjectId lineId;
Acad::ErrorStatus es=pBlockTableRecord->appendAcDbEntity(lineId, pLine);
if(es!=Acad::eOk)
{
pBlockTableRecord->close();
delete pLine;//Add failed, you can delete it.
pLine=NULL;
return AcDbObjectId::kNull;
}
pBlockTableRecord->close();
pLine->close();
return lineId;
}


ZWSoft ZRX for ZWCAD: Developer Guide: Database Ownership of Objects

Database Ownership of Objects
ZRX Introductory Concepts » Database Objects


ZWSoft ZRX for ZWCAD: Developer Guide: Adding Object-Specific Data

Modules
Adding Object-Specific Data
ZRX Introductory Concepts » Database Objects

Modules

Extended Data
Extension Dictionary

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: Extended Data

Extended Data
ZRX Introductory Concepts » Database Objects » Adding Object-Specific Data

The setXData function of the AcDbObject class is used to set the extension data for an object

virtual Acad::ErrorStatus AcDbObject::setXData(const resbuf* xdata);

The xData function of the AcDbObject class is used to get extended data for an object

virtual resbuf* AcDbObject::xData(const char* regappName = NULL) const;

The following example uses the setXdata() function to set the xdata of the selected object.

void DBObjects::AddXData()
{
ads_name en;
ads_point pt;
if(acedEntSel(_T("\nSelect the entity you want to add extended data:"),en,pt) != RTNORM)
{
return;
}
AcDbObjectId entId;
Acad::ErrorStatus es = acdbGetObjectId(entId,en);
struct resbuf* pRb;
acdbRegApp(_T("XData"));
CString strAppName(_T("XData"));;
CString str(_T("hello"));
pRb = acutBuildList(AcDb::kDxfRegAppName,strAppName,
AcDb::kDxfXdAsciiString,str,
AcDb::kDxfXdInteger32,2,
AcDb::kDxfXdReal,3.14,
AcDb::kDxfXdWorldXCoord,pt,
RTNONE);
AcDbEntity* pEnt;
acdbOpenAcDbEntity(pEnt,entId,AcDb::kForWrite);
struct resbuf* pTemp;
pTemp = pEnt->xData(_T("XData"));
if(pTemp != NULL)
{
acutRelRb(pTemp);
acutPrintf(_T("It already contains extended data"));
}
else
{
pEnt->setXData(pRb);
acutPrintf(_T("\n Extended data added successfully"));
}
pEnt->close();
acutRelRb(pRb);
}

The following example uses the xData () function to get the xdata of the selected object, and then print the xdata to the screen

void DBObjects::PrintXData()
{
ads_name en;
ads_point pt;
if(acedEntSel(_T("\nSelect the extended data entity to view:"),en,pt) != RTNORM)
{
return;
}
AcDbObjectId entId;
Acad::ErrorStatus es = acdbGetObjectId(entId,en);
//Open the entity to check if the data is contains an extension
AcDbEntity* pEnt;
acdbOpenAcDbEntity(pEnt,entId,AcDb::kForRead);
struct resbuf* pRb;
pRb = pEnt->xData(_T("XData"));
pEnt->close();
if(pRb != NULL)
{
struct resbuf* pTemp;
pTemp = pRb;
pTemp = pTemp->rbnext;
acutPrintf(_T("\n String type data extension�?s"),pTemp->resval.rstring);
pTemp = pTemp->rbnext;
acutPrintf(_T("\n Integer type data extension�?d"),pTemp->resval.rint);
pTemp = pTemp->rbnext;
acutPrintf(_T("\n Real number type data extension�?.2f"),pTemp->resval.rreal);
pTemp = pTemp->rbnext;
acutPrintf(_T("\n Point type data extension�?.2f,%.2f,%.2f"),pTemp->resval.rpoint[X],pTemp->resval.rpoint[Y],pTemp->resval.rpoint[Z]);
acutRelRb(pRb);
}
else
{
acutPrintf(_T("\n The entity does not contain any extension data"));
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: Extension Dictionary

Extension Dictionary
ZRX Introductory Concepts » Database Objects » Adding Object-Specific Data

The extension dictionary is associated with a specific entity, but an entity does not contain an extension dictionary by default. If you want to use the extension dictionary to hold the data associated with the entity, you can use the createExtensionDictionary function to create an extension dictionary for the entity, if the entity already contains an extension dictionary Function calls do not have any effect.

After creating the extension dictionary, you can use the extensionDictionary() function to get the entity's extension dictionary. The setAt function of the AcDbDictionary object can add an element to the dictionary, either AcDbXrecord or other type of object. If you add AcDbXrecord, you can use the acutBuildList() function to build a result buffer list that holds the data, and then use the setFromRbChain() function to add the resulting buffer list to the extension and record.

void DBObjects::AddXRecord()
{
ads_name en;
ads_point pt;
if(acedEntSel(_T("\nSelect the entity you want to add XRecord data"),en,pt) != RTNORM)
{
return;
}
AcDbObjectId entId;
Acad::ErrorStatus es = acdbGetObjectId(entId,en);
AcDbXrecord* pXrec = new AcDbXrecord;
AcDbObject* pObj;
AcDbObjectId dictObjId,xRecObjId;
AcDbDictionary* pDict;
struct resbuf* pRb;
acdbOpenObject(pObj,entId,AcDb::kForWrite);
pObj->createExtensionDictionary();
dictObjId = pObj->extensionDictionary();
pObj->close();
acdbOpenObject(pDict,dictObjId,AcDb::kForWrite);
pDict->setAt(_T("XRecord"),pXrec,xRecObjId);
pDict->close();
pRb = acutBuildList(AcDb::kDxfText,_T("\n Line"),
AcDb::kDxfInt32,12,
AcDb::kDxfReal,3.14,
AcDb::kDxfXCoord,pt,
RTNONE);
pXrec->setFromRbChain(*pRb);
pXrec->close();
acutRelRb(pRb);
}

If you want to access the extension records saved in the entity extension dictionary, you can use the extensionDictionary () function to get the entity's extension dictionary, and then get the specified element (extension record) through the getAt () function, using AcDbXrecord :: rbChain () to get The result of the data buffer list.

void DBObjects::PrintXRecord ()
{
ads_name en;
ads_point pt;
if(acedEntSel(_T("\nSelect the XRecord data entity to view:"),en,pt) != RTNORM)
return;
AcDbObjectId entId;
Acad::ErrorStatus es = acdbGetObjectId(entId,en);
AcDbEntity* pEnt;
acdbOpenAcDbEntity(pEnt,entId,AcDb::kForRead);
AcDbObjectId dictObjId = pEnt->extensionDictionary();
pEnt->close();
if(dictObjId == AcDbObjectId::kNull)
{
acutPrintf(_T("\n The selected entity does not contain an extension dictionary."));
return;
}
AcDbDictionary* pDict;
AcDbXrecord* pXrec;
acdbOpenObject(pDict,dictObjId,AcDb::kForRead);
pDict->getAt(_T("XRecord"),(AcDbObject* &)pXrec,AcDb::kForRead);
pDict->close();
struct resbuf* pRb;
pXrec->rbChain(&pRb);
pXrec->close();
if(pRb != NULL)
{
struct resbuf* pTemp;
pTemp = pRb;
acutPrintf(_T("\n String type data extension�?s"),pTemp->resval.rstring);
pTemp = pTemp->rbnext;
acutPrintf(_T("\n Integer type data extension�?d"),pTemp->resval.rint);
pTemp = pTemp->rbnext;
acutPrintf(_T("\n Real number type data extension�?.2f"),pTemp->resval.rreal);
pTemp = pTemp->rbnext;
acutPrintf(_T("\n Point type data extension�?.2f,%.2f,%.2f"),pTemp->resval.rpoint[X],pTemp->resval.rpoint[Y],pTemp->resval.rpoint[Z]);
acutRelRb(pRb);
}
else
{
acutPrintf(_T("\n Did not find its extended data"));
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: Erasing Objects

Erasing Objects
ZRX Introductory Concepts » Database Objects

The erase() function does not delete the entity immediately, and the deleted entity can use erase (kfalse) to undo the deletion.
The following code uses the erase() function to delete the entity selected by the user.

void DBObjects::EraseObject()
{
ads_name en;
ads_point pt;
if(acedEntSel(_T("\nSelect the entity you want to erase:"),en,pt) != RTNORM)
{
return;
}
AcDbObjectId entId;
Acad::ErrorStatus es = acdbGetObjectId(entId,en);
if (es==Acad::eOk)
{
AcDbEntity* pEnt;
acdbOpenAcDbEntity(pEnt,entId,AcDb::kForWrite);
pEnt->erase();
pEnt->close();
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: Object Filing

Object Filing
ZRX Introductory Concepts » Database Objects


ZWSoft ZRX for ZWCAD: Developer Guide: Embedded and Encapsulating Objects

Embedded and Encapsulating Objects
ZRX Introductory Concepts » Database Objects


ZWSoft ZRX for ZWCAD: Developer Guide: Entities

Modules
Entities
ZRX Introductory Concepts

Modules

Simple Entity
Complex Entity
Modifiy Entity

Detailed Description

This part introduce entity that has a min graphical representation in database.
Like the Line, Circle, Polyline, Regions, Hatch, Block, and so on is derived from entity.
We will then focus on how to create some simple entities and complex entities in the form of code examples.


ZWSoft ZRX for ZWCAD: Developer Guide: Simple Entity

Modules
Simple Entity
ZRX Introductory Concepts » Entities

Modules

Draw a Line
Draw a Polyline
Create a Text

Detailed Description

This summary describes creating the Simple Entity like Line,Polyline,Text and through the example we learn how to create a Simple Entity and add it to the model space.


ZWSoft ZRX for ZWCAD: Developer Guide: Draw a Line

Draw a Line
ZRX Introductory Concepts » Entities » Simple Entity

The following example demonstrates creating a line from point(4.0, 2.0, 0.0) to point(10.0, 7.0, 0.0) and appending it to the model space block table record.

void drawLine()
{
AcGePoint3d startPt(4.0, 2.0, 0.0);
AcGePoint3d endPt(10.0, 7.0, 0.0);
AcDbLine *pLine = new AcDbLine(startPt, endPt);
AcDbBlockTable *pBlockTable;
acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBlockTable, AcDb::kForRead);
AcDbBlockTableRecord *pBlockTableRecord;
pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite);
pBlockTable->close();
AcDbObjectId lineId;
pBlockTableRecord->appendAcDbEntity(lineId, pLine);
pBlockTableRecord->close();
pLine->close();
}


ZWSoft ZRX for ZWCAD: Developer Guide: Draw a Polyline

Draw a Polyline
ZRX Introductory Concepts » Entities » Simple Entity

The following example demonstrates creating a Polyline and appending it to the model space block table record.

void drawPolyline()
{
AcGePoint2d ptStart(0, 0), ptMiddle(50, 0), ptEnd(100, 100);
AcGePoint2dArray points;
points.append(ptStart);
points.append(ptMiddle);
points.append(ptEnd);
int numVertices = points.length();
AcDbPolyline *pPoly = new AcDbPolyline(numVertices);
for (int i = 0; i < numVertices; i++)
{
pPoly->addVertexAt(i, points.at(i));
}
AcDbBlockTable *pBlockTable;
acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBlockTable, AcDb::kForRead);
AcDbBlockTableRecord *pBlockTableRecord;
pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite);
pBlockTable->close();
AcDbObjectId lineId;
pBlockTableRecord->appendAcDbEntity(lineId, pPoly);
pBlockTableRecord->close();
pPoly->close();
}


ZWSoft ZRX for ZWCAD: Developer Guide: Create a Text

Create a Text
ZRX Introductory Concepts » Entities » Simple Entity

The following example demonstrates creating a Text:"Hello World" and appending it to the model space block table record.

void addText()
{
AcGePoint3d ptInsert(6, 19, 0);
const ZTCHAR* text = _T("Hello World");
AcDbObjectId style = AcDbObjectId::kNull;
double height = 2.5;
double rotation = 0;
AcDbText *pText = new AcDbText(ptInsert, text, style, height, rotation);
AcDbBlockTable *pBlockTable;
acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBlockTable, AcDb::kForRead);
AcDbBlockTableRecord *pBlockTableRecord;
pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite);
pBlockTable->close();
AcDbObjectId lineId;
pBlockTableRecord->appendAcDbEntity(lineId, pText);
pBlockTableRecord->close();
pText->close();
}


ZWSoft ZRX for ZWCAD: Developer Guide: Complex Entity

Modules
Complex Entity
ZRX Introductory Concepts » Entities

Modules

Create Regions
Create a Hatch
Create a Simple Block

Detailed Description

This summary describes creating the Complex Entity like Regions,Hatch,Simple Block and through the example we learn how to create a Complex Entity and add it to the model space.


ZWSoft ZRX for ZWCAD: Developer Guide: Create Regions

Create Regions
ZRX Introductory Concepts » Entities » Complex Entity

The following example demonstrates creating some createRegions and appending it to the model space block table record.Tips：select some entity must closed.

AcDbObjectIdArray createRegions( const AcDbObjectIdArray& curveIds )
{
AcDbObjectIdArray regionIds;
AcDbVoidPtrArray curves;
AcDbVoidPtrArray regions;
AcDbEntity *pEnt = NULL;
AcDbRegion *pRegion = NULL;
for (int i = 0; i < curveIds.length(); i++)
{
acdbOpenAcDbEntity(pEnt, curveIds.at(i), AcDb::kForRead);
if (pEnt->isKindOf(AcDbCurve::desc()))
{
curves.append(static_cast<void*>(pEnt));
}
}
Acad::ErrorStatus es = AcDbRegion::createFromCurves(curves, regions);
if (es == Acad::eOk)
{
for (int i = 0; i < regions.length(); i++)
{
pRegion = static_cast<AcDbRegion*>(regions[i]);
pRegion->setDatabaseDefaults();
AcDbBlockTable *pBlockTable;
acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBlockTable, AcDb::kForRead);
AcDbBlockTableRecord *pBlockTableRecord;
pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite);
pBlockTable->close();
AcDbObjectId regionId;
pBlockTableRecord->appendAcDbEntity(regionId, pRegion);
pBlockTableRecord->close();
pRegion->close();
regionIds.append(regionId);
}
}
else
{
for (int i = 0; i < regions.length(); i++)
{
delete (AcRxObject*)regions[i];
}
}
for (int i = 0; i < curves.length(); i++)
{
pEnt = static_cast<AcDbEntity*>(curves[i]);
pEnt->close();
}
return regionIds;
}
void AddRegion()
{
ads_name ss;
int rt = acedSSGet(NULL, NULL, NULL, NULL, ss);
AcDbObjectIdArray objIds;
if (rt == RTNORM)
{
long length;
acedSSLength(ss, &length);
for (int i = 0; i < length; i++)
{
ads_name ent;
acedSSName(ss, i, ent);
AcDbObjectId objId;
acdbGetObjectId(objId, ent);
objIds.append(objId);
}
}
acedSSFree(ss);
AcDbObjectIdArray regionIds;
regionIds = createRegions(objIds);
int number = regionIds.length();
acutPrintf(_T("\n Create %d Regions."), number);
}


ZWSoft ZRX for ZWCAD: Developer Guide: Create a Hatch

Create a Hatch
ZRX Introductory Concepts » Entities » Complex Entity

The following example demonstrates creating a Hatch and appending it to the model space block table record.

void AddHatch()
{
ads_name ss;
int rt = acedSSGet(NULL, NULL, NULL, NULL, ss);
AcDbObjectIdArray objIds;
if (rt == RTNORM)
{
long length;
acedSSLength(ss, &length);
for (int i = 0; i < length; i++)
{
ads_name ent;
acedSSName(ss, i, ent);
AcDbObjectId objId;
acdbGetObjectId(objId, ent);
objIds.append(objId);
}
}
acedSSFree(ss);
Acad::ErrorStatus es;
AcDbHatch *pHatch = new AcDbHatch();
AcGeVector3d normal(0, 0, 1);
pHatch->setNormal(normal);
pHatch->setElevation(0);
pHatch->setAssociative(true);
pHatch->setPattern(AcDbHatch::kPreDefined, TEXT("SOLID"));
es = pHatch->appendLoop(AcDbHatch::kDefault, objIds);
es = pHatch->evaluateHatch();
AcDbBlockTable *pBlockTable;
acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBlockTable, AcDb::kForRead);
AcDbBlockTableRecord *pBlockTableRecord;
pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite);
pBlockTable->close();
AcDbObjectId hatchId;
pBlockTableRecord->appendAcDbEntity(hatchId, pHatch);
pBlockTableRecord->close();
pHatch->close();
if (acdbOpenObject(pHatch, hatchId, AcDb::kForRead) == Acad::eOk)
{
AcDbObjectIdArray assocEntIds;
pHatch->getAssocObjIds(assocEntIds);
for (int i = 0; i < assocEntIds.length(); i++)
{
AcDbEntity *pEnt = NULL;
if (acdbOpenObject(pEnt, assocEntIds[i], AcDb::kForWrite) == Acad::eOk)
{
pEnt->addPersistentReactor(hatchId);
pEnt->close();
}
}
pHatch->close();
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: Create a Simple Block

Modules
Create a Simple Block
ZRX Introductory Concepts » Entities » Complex Entity

Modules

Create a Simple Block Table Record
Create a Simple Block Table Record with Attribute Definitions
Creating a Block Reference with Attributes

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: Create a Simple Block Table Record

Create a Simple Block Table Record
ZRX Introductory Concepts » Entities » Complex Entity » Create a Simple Block

The following example demonstrates creating a BlockRecord and appending it to the Database block table record,then you can use "insert" command to insert this block to the model space.

void creatBlockRecord()
{
AcDbBlockTableRecord *pBlockRecord = new AcDbBlockTableRecord();
pBlockRecord->setName(_T("block_test"));
AcDbBlockTable *pBlkTbl = NULL;
acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlkTbl, AcDb::kForWrite);
AcDbObjectId blockTableRecordId;
pBlkTbl->add(blockTableRecordId, pBlockRecord);
pBlkTbl->close();
AcGePoint3d startPt(4.0, 2.0, 0.0);
AcGePoint3d endPt(10.0, 7.0, 0.0);
AcDbLine *pLine = new AcDbLine(startPt, endPt);
AcDbObjectId lineId;
pBlockRecord->appendAcDbEntity(lineId,pLine);
pLine->close();
pBlockRecord->close();
}


ZWSoft ZRX for ZWCAD: Developer Guide: Create a Simple Block Table Record with Attribute Definitions

Create a Simple Block Table Record with Attribute Definitions
ZRX Introductory Concepts » Entities » Complex Entity » Create a Simple Block

The following example demonstrates creating a BlockRecord with Attribute and appending it to the Database block table record,then you can use "insert" command to insert this block to the model space.

AcDbObjectId creatAttBlockRecord()
{
AcDbBlockTableRecord *pBlockRecord = new AcDbBlockTableRecord();
pBlockRecord->setName(_T("block_Att"));
AcDbBlockTable *pBlkTbl = NULL;
acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlkTbl, AcDb::kForWrite);
AcDbObjectId blockTableRecordId;
pBlkTbl->add(blockTableRecordId, pBlockRecord);
pBlkTbl->close();
AcGePoint3d startPt(4.0, 2.0, 0.0);
AcGePoint3d endPt(10.0, 7.0, 0.0);
AcDbLine *pLine = new AcDbLine(startPt, endPt);
AcDbObjectId lineId;
pBlockRecord->appendAcDbEntity(lineId,pLine);
pLine->close();
AcDbAttributeDefinition *pAttdef = new AcDbAttributeDefinition(endPt,_T("line"),_T("Entity type"),_T("input Entity type"));
AcDbObjectId AttdefId;
pBlockRecord->appendAcDbEntity(AttdefId,pAttdef);
pAttdef->close();
pBlockRecord->close();
return blockTableRecordId;
}


ZWSoft ZRX for ZWCAD: Developer Guide: Creating a Block Reference with Attributes

Creating a Block Reference with Attributes
ZRX Introductory Concepts » Entities » Complex Entity » Create a Simple Block

The following example demonstrates creating a block with Attribute Tag:"Entity type" and String:"line" ,and appending it to the model space block table record.

void creatAttReference()
{
AcDbObjectId blockId = creatAttBlockRecord();
AcDbBlockReference *pBlkRef = new AcDbBlockReference;
pBlkRef->setBlockTableRecord(blockId);
struct resbuf to, from;
from.restype = RTSHORT;
from.resval.rint = 1; // UCS
to.restype = RTSHORT;
to.resval.rint = 0; // WCS
AcGePoint3d basePoint(0,0,0);
AcGeVector3d normal(0.0, 0.0, 1.0);
acedTrans(&(normal.x), &from, &to, Adesk::kTrue,
&(normal.x));
pBlkRef->setPosition(basePoint);
pBlkRef->setRotation(0.0);
pBlkRef->setNormal(normal);
AcDbBlockTable *pBlockTable;
acdbHostApplicationServices()->workingDatabase()
->getSymbolTable(pBlockTable, AcDb::kForRead);
AcDbBlockTableRecord *pBlockTableRecord;
pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord,
AcDb::kForWrite);
pBlockTable->close();
AcDbObjectId newEntId;
pBlockTableRecord->appendAcDbEntity(newEntId, pBlkRef);
pBlockTableRecord->close();
AcDbBlockTableRecord *pBlockDef;
acdbOpenObject(pBlockDef, blockId, AcDb::kForRead);
AcDbBlockTableRecordIterator *pIterator;
pBlockDef->newIterator(pIterator);
AcDbEntity *pEnt;
AcDbAttributeDefinition *pAttdef;
for (pIterator->start(); !pIterator->done();
pIterator->step())
{
pIterator->getEntity(pEnt, AcDb::kForRead);
pAttdef = AcDbAttributeDefinition::cast(pEnt);
if (pAttdef != NULL && !pAttdef->isConstant()) {
AcDbAttribute *pAtt = new AcDbAttribute();
pAtt->setPropertiesFrom(pAttdef);
pAtt->setInvisible(pAttdef->isInvisible());
basePoint = pAttdef->position();
basePoint += pBlkRef->position().asVector();
pAtt->setPosition(basePoint);
pAtt->setHeight(pAttdef->height());
pAtt->setRotation(pAttdef->rotation());
pAtt->setTag(_T("Entity type"));
pAtt->setFieldLength(25);
ZTCHAR *pStr = pAttdef->tag();
pAtt->setTag(pStr);
free(pStr);
pAtt->setFieldLength(pAttdef->fieldLength());
pAtt->setTextString(TEXT("line"));
AcDbObjectId attId;
pBlkRef->appendAttribute(attId, pAtt);
pAtt->close();
}
pEnt->close();
}
delete pIterator;
pBlockDef->close();
pBlkRef->close();
}


ZWSoft ZRX for ZWCAD: Developer Guide: Modifiy Entity

Modules
Modifiy Entity
ZRX Introductory Concepts » Entities

Modules

Entity Visibility
Entity Highlight
Entity Layer
Entity Color
Entity Transform

Detailed Description

All entities have a number of common properties and include member functions for setting and getting their values. through some example we learn how change these values.


ZWSoft ZRX for ZWCAD: Developer Guide: Entity Visibility

Entity Visibility
ZRX Introductory Concepts » Entities » Modifiy Entity

The following example demonstrates an entity Visibility or unVisibility use function "setVisibility";

void EntityVisibility(AcDbObjectId entId , Visibility isVisibility)
{
AcDbEntity* pEnt;
if (acdbOpenObject(pEnt,entId,AcDb::kForWrite) == Acad::eOk)
{
pEnt->setVisibility(isVisibility);
pEnt->close();
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: Entity Highlight

Entity Highlight
ZRX Introductory Concepts » Entities » Modifiy Entity

The following example demonstrates an entity Highlight or Highlight use function "highlight" or "unhighlight";

void HighlightEntity(AcDbObjectId entId , BOOL isHighlight)
{
AcDbEntity* pEnt;
if (acdbOpenObject(pEnt,entId,AcDb::kForWrite) == Acad::eOk)
{
if (isHighlight)
{
pEnt->highlight();
}
else
{
pEnt->unhighlight();
}
pEnt->close();
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: Entity Layer

Entity Layer
ZRX Introductory Concepts » Entities » Modifiy Entity

The following example demonstrates change an entity layer,if an entity not set layer it will be in layer "0";

void setEntityLayer(AcDbObjectId entId , const ZTCHAR* layername)
{
AcDbEntity* pEnt;
if (acdbOpenObject(pEnt,entId,AcDb::kForWrite) == Acad::eOk)
{
pEnt->setLayer(layername);
pEnt->close();
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: Entity Color

Entity Color
ZRX Introductory Concepts » Entities » Modifiy Entity

The following example demonstrates change an entity Color. tips: colorIndex value is 0 Specifies BYBLOCK,265 Specifies BYLAYER,if colorIndex between 0 and 265 means different color.

void setEntityColor(AcDbObjectId entId , int colorIndex)
{
AcDbEntity* pEnt;
if (acdbOpenObject(pEnt,entId,AcDb::kForWrite) == Acad::eOk)
{
pEnt->setColorIndex(colorIndex);
pEnt->close();
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: Entity Transform

Entity Transform
ZRX Introductory Concepts » Entities » Modifiy Entity

The following example demonstrates modifies the entity using the specified matrix by transformBy function.

void TransformEntity(AcDbObjectId entId)
{
AcDbEntity* pEnt;
if (acdbOpenObject(pEnt,entId,AcDb::kForWrite) == Acad::eOk)
{
AcGeVector3d vecMove = AcGePoint3d( 10, 10, 0.0 ) - AcGePoint3d::kOrigin;
AcGeMatrix3d mat3d;
mat3d.setTranslation(vecMove);
pEnt->transformBy(vecMove);
pEnt->close();
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: Container Objects

Modules
Container Objects
ZRX Introductory Concepts

Modules

Symbol Tables
Dictionaries
Xrecords

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: Symbol Tables

Modules
Symbol Tables
ZRX Introductory Concepts » Container Objects

Modules

Modifying a Layer Table Record
Iterating over Tables

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: Modifying a Layer Table Record

Modifying a Layer Table Record
ZRX Introductory Concepts » Container Objects » Symbol Tables

The following codes gets the Layer Table Record from Layer Table by name, then changes the name of the Layer Table Record.

void ContainerObj::ModifyLayerTable( ACHAR *layerName )
{
AcDbLayerTable *pLayerTable;
acdbHostApplicationServices()->workingDatabase()->getLayerTable(pLayerTable,AcDb::kForRead);
if(!pLayerTable->has(layerName))
{
pLayerTable->close();
return;
}
AcDbLayerTableRecord *pLayerTableRecord;
pLayerTable->getAt(layerName,pLayerTableRecord,AcDb::kForWrite);
pLayerTableRecord->setName(_T("NewLayerName"));
pLayerTableRecord->close();
pLayerTable->close();
}


ZWSoft ZRX for ZWCAD: Developer Guide: Iterating over Tables

Iterating over Tables
ZRX Introductory Concepts » Container Objects » Symbol Tables

The following code iterates through the dimension table.

void ContainerObj::IterateDimStyle()
{
AcDbDimStyleTable *pDimStyleTable;
acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pDimStyleTable,AcDb::kForRead);
AcDbDimStyleTableIterator *pDimIterator;
pDimStyleTable->newIterator(pDimIterator);
AcDbDimStyleTableRecord *pDimStyleTableRecord;
AcDbObjectIdArray objIds;
AcDbObjectId objId;
for(;!pDimIterator->done();pDimIterator->step())
{
pDimIterator->getRecord(pDimStyleTableRecord,AcDb::kForRead);
objId=pDimStyleTableRecord->objectId();
objIds.append(objId);
pDimStyleTableRecord->close();
}
delete pDimIterator;
pDimStyleTable->close();
}


ZWSoft ZRX for ZWCAD: Developer Guide: Dictionaries

Modules
Dictionaries
ZRX Introductory Concepts » Container Objects

Modules

Creating a Dictionary
Groups and the Group Dictionary
Iterating over Dictionary Entries

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: Creating a Dictionary

Creating a Dictionary
ZRX Introductory Concepts » Container Objects » Dictionaries

The following codes creates a dictionary and add it into the Named Object Dictionary.

void ContainerObj::CreateDict()
{
AcDbDictionary *pNamedObjDict;
acdbHostApplicationServices()->workingDatabase()->getNamedObjectsDictionary(pNamedObjDict,AcDb::kForWrite);
AcDbDictionary *pDict = new AcDbDictionary();
AcDbObjectId dictId;
pNamedObjDict->setAt(_T("NewDictionary"),pDict,dictId);
pDict->close();
pNamedObjDict->close();
}


ZWSoft ZRX for ZWCAD: Developer Guide: Groups and the Group Dictionary

Groups and the Group Dictionary
ZRX Introductory Concepts » Container Objects » Dictionaries

The following codes shows how to add objects into group dictionary.

void ContainerObj::AddtoGroup(AcDbObjectIdArray& objIds, ACHAR *groupName)
{
AcDbDictionary *pDictionary;
acdbHostApplicationServices()->workingDatabase()->getGroupDictionary(pDictionary,AcDb::kForRead);
AcDbGroup *pGroup;
pDictionary->getAt(groupName,(AcDbObject* &)pGroup,AcDb::kForWrite);
for(int i=0;i<objIds.length();i++)
{
pGroup->append(objIds[i]);
}
pGroup->close();
pDictionary->close();
}
//The following codes removes a group by name.
void ContainerObj::RemoveGroup()
{
AcDbDictionary *pDictionary;
acdbHostApplicationServices()->workingDatabase()->getGroupDictionary(pDictionary,AcDb::kForWrite);
if(pDictionary->has(_T("TheGroup")))
{
pDictionary->remove(_T("TheGroup"));
}
pDictionary->close();
}


ZWSoft ZRX for ZWCAD: Developer Guide: Iterating over Dictionary Entries

Iterating over Dictionary Entries
ZRX Introductory Concepts » Container Objects » Dictionaries

The following codes uses a iterator to step through the objects in Named Object Dictionary, and then add objectids into a AcDbObjectIdArray.

void ContainerObj::IterDict()
{
AcDbDictionary *pNamedObjDict;
acdbHostApplicationServices()->workingDatabase()->getNamedObjectsDictionary(pNamedObjDict,AcDb::kForRead);
AcDbDictionary *pDict;
pNamedObjDict->getAt(_T("NewDictionary"),(AcDbObject* &)pDict,AcDb::kForRead);
AcDbDictionaryIterator *pDictIter = pDict->newIterator();
AcDbObject *obj;
AcDbObjectIdArray objIds;
for(;!pDictIter->done();pDictIter->next())
{
pDictIter->getObject(obj,AcDb::kForRead);
objIds.append(obj->id());
}
delete pDictIter;
pDict->close();
pNamedObjDict->close();
}


ZWSoft ZRX for ZWCAD: Developer Guide: Xrecords

Modules
Xrecords
ZRX Introductory Concepts » Container Objects

Modules

Xrecord Examples

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: Xrecord Examples

Xrecord Examples
ZRX Introductory Concepts » Container Objects » Xrecords

The following code adds a xrecord into a dictionary.

void ContainerObj::AddXrecord(AcDbObjectId dictId)
{
AcDbDictionary *pDict;
acdbOpenObject(pDict,dictId,AcDb::kForWrite);
AcDbObjectId xrecordId;
AcDbXrecord *pXrecord = new AcDbXrecord();
pDict->setAt(_T("Xrecord"),pXrecord,xrecordId);
struct resbuf *pRb;
pRb = acutBuildList(AcDb::kDxfText,
_T("Xrecord List"),
AcDb::kDxfInt32,10,
AcDb::kDxfReal,3.14,
RTNONE);
pXrecord->setFromRbChain(*pRb);
pXrecord->close();
pDict->close();
acutRelRb(pRb);
}
/**

The following codes shows how to view the Xrecord;

void ContainerObj::ViewXrecord(AcDbObjectId dictId)
{
AcDbDictionary *pDict;
acdbOpenObject(pDict,dictId,AcDb::kForRead);
AcDbXrecord *pXrecord;
pDict->getAt(_T("Xrecord"),(AcDbObject* &)pXrecord,AcDb::kForRead);
struct resbuf *pRb;
pXrecord->rbChain(&pRb);
if(pRb!=NULL)
{
struct resbuf *pTemp;
pTemp = pRb;
acutPrintf(_T("\n %s"),pTemp->resval.rstring);
pTemp = pTemp->rbnext;
acutPrintf(_T("\n %d"),pTemp->resval.rint);
pTemp = pTemp->rbnext;
acutPrintf(_T("\n %f"),pTemp->resval.rreal);
}
pXrecord->close();
pDict->close();
acutRelRb(pRb);
}


ZWSoft ZRX for ZWCAD: Developer Guide: Basic Interaction with ZWCAD

Modules
Basic Interaction with ZWCAD

Modules

MFC Support in ZRX
Selection Set, Entity, and Symbol Table Functions
Plot API
Global Functions for Interacting with ZWCAD
ZRX Global Utility Functions
ZWCAD Command Prompt Standard

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: MFC Support in ZRX

Modules
MFC Support in ZRX
Basic Interaction with ZWCAD

Modules

MFC model dialog
Resource Solution
Using CAD UI Class

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: MFC model dialog

MFC model dialog
Basic Interaction with ZWCAD » MFC Support in ZRX

ZRX Application can directly use The Microsoft Foundation Class(MFC) libary. Developer can use MFC implement design standard user interfaces easily.
This example shows: how to build up a standard dialog. Click OK or Cancel button to close, and click "Button1" to show a welcome message.

class MFCDlg : public CDialog
{
public:
MFCDlg(CWnd* pParent = NULL);
enum { IDD = IDD_DIALOG1 };
protected:
virtual void DoDataExchange(CDataExchange* pDX);
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedButton1();
};
MFCDlg::MFCDlg(CWnd* pParent )
: CDialog(MFCDlg::IDD, pParent)
{
}
void MFCDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(MFCDlg, CDialog)
ON_BN_CLICKED(IDC_BUTTON1, &MFCDlg::OnBnClickedButton1)
END_MESSAGE_MAP()
void MFCDlg::OnBnClickedButton1()
{
MessageBox(_T("HelloWorld!"), _T("DlgSample"), MB_OK);
}
void CMFCSupport::MFCDialog()
{
MFCDlg mydialog;
mydialog.DoModal();
}


ZWSoft ZRX for ZWCAD: Developer Guide: Resource Solution

Resource Solution
Basic Interaction with ZWCAD » MFC Support in ZRX

Resources are important for the user interface. The ZRX program can use a macro AC_IMPLEMENT_EXTENSION_MODULE to manage the resources used by the user interface.
When the DLL dynamic library is loaded, using "AttachInstance" to initialize the define resources; and when the DLL is uninstalled, using "DetachInstance" to restore the default resources.
The resource instance using "ModuleResourceInstance" is loaded as a parameter, when registering a command.

AC_IMPLEMENT_EXTENSION_MODULE(theArxDLL);
static void initApp()
{
acedRegCmds->addCommand(_T("ZRX_DLG_SAMPLE"),
_T("ZRXDLGSAMPLE"),
_T("DLGSAMPLE"),
ACRX_CMD_MODAL,
dialogCreate,
NULL,
-1,
theArxDLL.ModuleResourceInstance());
}
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
// Remove this if you use lpReserved
UNREFERENCED_PARAMETER(lpReserved);
if (dwReason == DLL_PROCESS_ATTACH)
{
theArxDLL.AttachInstance(hInstance);
}
else if (dwReason == DLL_PROCESS_DETACH)
{
theArxDLL.DetachInstance();
}
return 1; // ok
}


ZWSoft ZRX for ZWCAD: Developer Guide: Using CAD UI Class

Using CAD UI Class
Basic Interaction with ZWCAD » MFC Support in ZRX

CAD platform has a series of classes similar to the MFC user interface that allows users to quickly create the desired interface.
The interface features and displays are consistent with the CAD platform.
This example shows: how to use platform class to create a tool pallete which can be docked into the CAD.

1.Add a new class "CADDlg" which derived from CAcUiDialog for the dialog.
This is a "BUTTON2" button in the dialog. Click the button, then wait for user to get a piont and print the piont information.

class CADDlg : public CAcUiDialog
{
public:
CADDlg(CWnd* pParent = NULL);
enum { IDD = IDD_DIALOG2 };
protected:
virtual void DoDataExchange(CDataExchange* pDX);
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedButton2();
};
CADDlg::CADDlg(CWnd* pParent ) : CAcUiDialog(CADDlg::IDD, pParent)
{
}
void CADDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CADDlg, CAcUiDialog)
ON_BN_CLICKED(IDC_BUTTON2, &CADDlg::OnBnClickedButton2)
END_MESSAGE_MAP()
void CADDlg::OnBnClickedButton2()
{
ads_point point;
if (acedGetPoint(NULL, _T("Get a point: \n"), point) == RTNORM)
{
acutPrintf(_T("Point(%g, %g, %g)\n"), point[X], point[Y], point[Z]);
}
}

2.Add a new class "CADPalette" which derived from CAdUiPalette.
Add a CADDlg variable to the CADPalette class definition, in order to show the custom dialog box in the palette.
Create the dialog box and set the size when the palette is created at "OnCreate".
When resizing the palette, resize the dialog box at the same time at "OnSize".

class CADPalette : public CAdUiPalette
{
DECLARE_DYNAMIC (CADPalette)
public:
CADPalette (HINSTANCE hInstance =NULL) ;
virtual ~CADPalette () ;
protected:
afx_msg int OnCreate (LPCREATESTRUCT lpCreateStruct) ;
afx_msg void OnSize (UINT nType, int cx, int cy);
DECLARE_MESSAGE_MAP()
private:
CADDlg PDlg;
} ;
IMPLEMENT_DYNAMIC (CADPalette, CAdUiPalette)
BEGIN_MESSAGE_MAP(CADPalette, CAdUiPalette)
ON_WM_CREATE()
ON_WM_SIZE()
END_MESSAGE_MAP()
CADPalette::CADPalette (HINSTANCE hInstance) : CAdUiPalette (), PDlg(NULL)
{
}
CADPalette::~CADPalette ()
{
}
int CADPalette::OnCreate (LPCREATESTRUCT lpCreateStruct)
{
if ( CAdUiPalette::OnCreate (lpCreateStruct) == -1 )
return (-1) ;
PDlg.Create (IDD_DIALOG2, this) ;
CRect rect ;
GetClientRect (&rect) ;
PDlg.ShowWindow(SW_SHOW);
PDlg.MoveWindow (0, 0, rect.Width (), rect.Height (), TRUE) ;
return 0 ;
}
void CADPalette::OnSize (UINT nType, int cx, int cy)
{
CWnd::OnSize(nType, cx, cy);
CRect rect;
GetClientRect(&rect);
PDlg.MoveWindow(&rect);
}

3.In the implementation function of the "CADPaletteSet" command, add and display the paletteset.
Add a new palette to the paletteset to show the custom dialog.
Finally create a function "DelPaletteSet" to delete the paletteset, when the program is exit.

CAdUiPaletteSet* pPaletteSet = NULL;
CAdUiPalette* pPalette = NULL;
void CMFCSupport::CADPaletteSet()
{
if (!pPaletteSet)
{
pPaletteSet = new CAdUiPaletteSet;
CRect rect(0, 0, 200, 200);
pPaletteSet->Create(_T("DRAW TOOL"), WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN, rect, acedGetAcadFrame());
pPalette = new CADPalette();
pPaletteSet->AddPalette(pPalette);
pPaletteSet->EnableDocking(CBRS_ALIGN_LEFT|CBRS_FLOATING);
pPaletteSet->RestoreControlBar();
}
acedGetAcadFrame()->ShowControlBar(pPaletteSet, TRUE, FALSE);
}
void CMFCSupport::DelPaletteSet()
{
if (pPaletteSet != NULL)
{
pPaletteSet->DestroyWindow();
delete pPaletteSet;
pPaletteSet = NULL;
}
if (pPalette != NULL)
{
pPalette->DestroyWindow();
delete pPalette;
pPalette = NULL;
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: Selection Set, Entity, and Symbol Table Functions

Modules
Selection Set, Entity, and Symbol Table Functions
Basic Interaction with ZWCAD

Modules

Selection Set
Entities information
Symbol Table

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: Selection Set

Modules
Selection Set
Basic Interaction with ZWCAD » Selection Set, Entity, and Symbol Table Functions

Modules

Getting Selection Set
Filter with Wild Card
Filter with Compare condition

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: Getting Selection Set

Getting Selection Set
Basic Interaction with ZWCAD » Selection Set, Entity, and Symbol Table Functions » Selection Set

The selection set is an important means for CAD to interact with the user.
The selection set allows the user to select one or more graphic objects, while providing a wealth of means to select entities that meet certain condition.
The operation of selection object is implemented by the "acedSSGet" function.

int acedSSGet (const char *str, const void *pt1, const void *pt2, const struct resbuf *filter, ads_name ss)

This example shows: how to select all the entities in current database using "A" for the str param.
Then print the number of the entities.

void CSelEntSy::SelectEnt()
{
ads_name name;
acedSSGet(_T("A"), NULL, NULL, NULL, name);
long entCount;
acedSSLength(name, &entCount);
acutPrintf(_T("\n Entities: %d."), entCount);
acedSSFree(name);
}

This example shows: how to select the polyline entities in current database.
Using "X" for the str param to set up the filter condition, and using the resbuf with "LWPOLYLINE" string for the filter condition to filt.
Then print the number of the polyline entities.

void CSelEntSy::SelectPL()
{
struct resbuf rb;
TCHAR sbuf[20]={0};
ads_name ssname;
rb.restype=0;
_tcscpy(sbuf, _T("LWPOLYLINE"));
rb.resval.rstring = sbuf;
rb.rbnext = NULL;
acedSSGet(_T("X"), NULL, NULL, &rb, ssname);
long length;
acedSSLength(ssname, &length);
acutPrintf(_T("\n POLYLINE: %d"), length);
acedSSFree(ssname);
}

This example shows: how to select the entities which is in the define rectangular region in current database.
Using "W" for the str param to set up the rectangular region selection, and using the pt1, pt2 param to define the rectangular region.
Then print the number of the entities in the rectangular region.

void CSelEntSy::SelectRect()
{
ads_name ssname;
ads_point point1, point2;
point1[X]=0;point1[Y]=0;point1[Z]=0;
point2[X]=250;point2[Y]=230;point2[Z]=0;
acedSSGet(_T("W"), &point1, &point2, NULL, ssname);
long length;
acedSSLength(ssname, &length);
acutPrintf(_T("\n Entities in rectangle: %d"), length);
acedSSFree(ssname);
}


ZWSoft ZRX for ZWCAD: Developer Guide: Filter with Wild Card

Filter with Wild Card
Basic Interaction with ZWCAD » Selection Set, Entity, and Symbol Table Functions » Selection Set

"acedSSGet" function can use wild card in the filter param.
This example shows: how to select the blocks whose name have five character start with "door".
Then print the number of the blocks.

void CSelEntSy::SelectWild()
{
struct resbuf rb;
TCHAR sbuf[20]={0};
ads_name ssname;
rb.restype=2;
_tcscpy(sbuf, _T("door?"));
rb.resval.rstring = sbuf;
rb.rbnext = NULL;
acedSSGet(_T("X"), NULL, NULL, &rb, ssname);
long length;
acedSSLength(ssname, &length);
acutPrintf(_T("\n blocks: %d"), length);
acedSSFree(ssname);
}


ZWSoft ZRX for ZWCAD: Developer Guide: Filter with Compare condition

Filter with Compare condition
Basic Interaction with ZWCAD » Selection Set, Entity, and Symbol Table Functions » Selection Set

"acedSSGet" function can use relational operators in the filter param.
This example shows: how to select the "ARC" entities whose radius is greater than 15.
Then print the number of the blocks.

void CSelEntSy::SelectCompare()
{
struct resbuf* rb;
ads_name ssname;
ads_real radius=15;
rb = acutBuildList(RTDXF0, _T("ARC"), -4, _T(">"), 40, radius, RTNONE);
acedSSGet(_T("X"), NULL, NULL, rb, ssname);
long length;
acedSSLength(ssname, &length);
acutPrintf(_T("\n ARC: %d"), length);
acedSSFree(ssname);
}


ZWSoft ZRX for ZWCAD: Developer Guide: Entities information

Entities information
Basic Interaction with ZWCAD » Selection Set, Entity, and Symbol Table Functions

Getting the entity code information.
This example shows: use the "acedEntSel" function to prompt the user to select a entity and saves the selected result in a "ads_name" variable.
The global function "acdbEntGet" returns a result buffer list that holds the entity defined data.
According to "restype" to determine the current result, the buffer saves the data type, and uses the "GetResvalTypeFromDxftype" function to parse and print the entity's information.
Finally, you need to use the "auctRelRb" function to release the storage space of the result buffer list.

int GetResvalTypeFromDxftype(int restype)
{
int nType=0;
if (restype > -6 && restype < 2000)
{
if (restype < 0)
{
if (restype == -1 || restype == -2)
{
nType = RTENAME;
}
else if (restype == -3)
{
nType = RTNONE;
}
else if (restype == -4)
{
nType = RTSTR;
}
else
{
nType = RTENAME;
}
}
else if (restype < 10)
{
nType = RTSTR;
}
else
{
int nRange=restype/10;
switch(nRange)
{
case 1:
case 11:
case 21:
nType = RT3DPOINT;
break;
case 2:
case 3:
case 4:
case 5:
case 12:
case 13:
case 14:
nType = RTREAL;
break;
case 6:
case 7:
case 17:
case 27:
case 28:
case 29:
case 37:
case 38:
case 40:
nType = RTSHORT;
break;
case 9:
nType = RTLONG;
break;
case 10:
case 30:
case 32:
case 41:
nType = RTSTR;
break;
case 16:
nType = RTINT64;
break;
case 33:
case 34:
case 35:
case 36:
case 39:
nType = RTENAME;
break;
default:
nType = RTERROR;
break;
}
}
}
else
{
nType = RTNONE;
}
return nType;
}
void CSelEntSy::EntityInfo()
{
struct resbuf* rbEnt;
struct resbuf* rb;
ads_name entName;
ads_point point;
if (acedEntSel(_T("Select a Entity: "), entName, point) != RTNORM)
{
return;
}
rbEnt=acdbEntGet(entName);
rb=rbEnt;
int valType=0;
acutPrintf(_T("\n"));
for(rb=rbEnt; rb!=NULL; rb=rb->rbnext)
{
valType = GetResvalTypeFromDxftype(rb->restype);
switch(valType)
{
case RTENAME:
acutPrintf(_T("(%d . <ENTITY NAME: %8lx>) "), rb->restype, rb->resval.rlname[0]);
break;
case RTSHORT:
acutPrintf(_T("(%d . %d) "), rb->restype, rb->resval.rint);
break;
case RTLONG:
acutPrintf(_T("(%d . %ld) "), rb->restype, rb->resval.rlong);
break;
case RTINT64:
acutPrintf(_T("(%d . %I64d) "), rb->restype, rb->resval.mnInt64);
break;
case RTREAL:
acutPrintf(_T("(%d . %0.3f) "), rb->restype, rb->resval.rreal);
break;
case RTSTR:
acutPrintf(_T("(%d . \"%s\") "), rb->restype, rb->resval.rstring);
break;
case RT3DPOINT:
acutPrintf(_T("(%d %0.3f %0.3f %0.3f) "), rb->restype, rb->resval.rpoint[X], rb->resval.rpoint[Y], rb->resval.rpoint[Z]);
break;
}
}
acutPrintf(_T("\n"));
acutRelRb(rbEnt);
}

This example shows: how to use result buffer list to build the entity.
Using the "acutBuildList" function with the group code information to create a list of result buffers which have the same format as returned by "acdbEntGet".
Then creating a new entity based on the content of the result buffer list by using "acdbEntMake" function.

void CSelEntSy::MakeEntity()
{
struct resbuf* rbEnt;
ads_point point1, point2;
ads_real radius=50;
int rc=RTNORM;
point1[X]=100;point1[Y]=100;point1[Z]=0;
point2[X]=20;point2[Y]=50;point2[Z]=0;
rbEnt = acutBuildList(RTDXF0, _T("Line"), 10, point1, 11, point2, RTNONE);
if (rbEnt == NULL)
{
acedAlert(_T("acutBuildList fail."));
return;
}
rc=acdbEntMake(rbEnt);
acutRelRb(rbEnt);
if (rc != RTNORM)
{
acedAlert(_T("acdbEntMake fail."));
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: Symbol Table

Symbol Table
Basic Interaction with ZWCAD » Selection Set, Entity, and Symbol Table Functions

Global function "acdbTblNext" provides a way to obtain symbolic table from the current database.
This example shows: how to use "acdbTblNext" to return the first entry in the "LAYER" table which is specified by the string param.
Then uses the "GetResvalTypeFromDxftype" function to parse and print the layer's information.

void CSelEntSy::TableInfo()
{
struct resbuf* rbEnt;
struct resbuf* rb;
rbEnt = acdbTblNext(_T("LAYER"), 1);
rb=rbEnt;
int valType=0;
acutPrintf(_T("\n"));
for(rb=rbEnt; rb!=NULL; rb=rb->rbnext)
{
valType = GetResvalTypeFromDxftype(rb->restype);
switch(valType)
{
case RTENAME:
acutPrintf(_T("(%d . <ENTITY NAME: %8lx>) "), rb->restype, rb->resval.rlname[0]);
break;
case RTSHORT:
acutPrintf(_T("(%d . %d) "), rb->restype, rb->resval.rint);
break;
case RTLONG:
acutPrintf(_T("(%d . %ld) "), rb->restype, rb->resval.rlong);
break;
case RTINT64:
acutPrintf(_T("(%d . %I64d) "), rb->restype, rb->resval.mnInt64);
break;
case RTREAL:
acutPrintf(_T("(%d . %0.3f) "), rb->restype, rb->resval.rreal);
break;
case RTSTR:
acutPrintf(_T("(%d . \"%s\") "), rb->restype, rb->resval.rstring);
break;
case RT3DPOINT:
acutPrintf(_T("(%d %0.3f %0.3f %0.3f) "), rb->restype, rb->resval.rpoint[X], rb->resval.rpoint[Y], rb->resval.rpoint[Z]);
break;
}
}
acutRelRb(rbEnt);
}


ZWSoft ZRX for ZWCAD: Developer Guide: Plot API

Modules
Plot API
Basic Interaction with ZWCAD

Modules

Plot to a File

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: Plot to a File

Plot to a File
Basic Interaction with ZWCAD » Plot API

ZRX Application provide the plot method to outpout the image file.
By using the series of "plot" functons, user can set what to plot, such as which layer; and use which print device to plot.
This example shows: how to plot the image of current database to a pdf file.
1. Using "createPublishEngine" to create a engine for plotting.
2. Getting the actived layer of current database.
3. Using "plotSettingsValidator" to get the pointer of plotsetting.
4. Using "setPlotCfgName" to select "DWG To PDF.pc5" as the printer to output the pdf file. And user can change other printer device in system.
5. Using "setCanonicalMediaName" to select "ISO_A4_(210.00_x_297.00_MM)" as the A4 media.
6. Using "setPlotCentered" to print the image in the center of the media.
7. Using "beginPlot" to send command to the plot engine for plotting.

void CPlotFile::PlotToPdf()
{
AcPlPlotEngine* PlotEngine = NULL;
AcDbPlotSettingsValidator* PlotSettingsValidator = NULL;
Acad::ErrorStatus es = Acad::eOk;
AcDbObjectId ObjectId=AcDbObjectId::kNull;
es = AcPlPlotFactory::createPublishEngine(PlotEngine);
if(Acad::eOk == es && PlotEngine)
{
AcPlPlotPageInfo PlotPageInfo;
AcPlPlotInfo PlotInfo;
AcDbLayout* Layout = NULL;
AcDbPlotSettings* PlotSettings=NULL;
AcDbLayoutManager* LayoutManager = acdbHostApplicationServices()->layoutManager();
AcDbObjectId ObjectId = LayoutManager->getActiveLayoutBTRId();
AcDbBlockTableRecord* BlockTableRecord;
es = acdbOpenObject(BlockTableRecord, ObjectId, AcDb::kForRead);
ObjectId = BlockTableRecord->getLayoutId();
es = acdbOpenObject(Layout, ObjectId, AcDb::kForWrite);
PlotSettings=new AcDbPlotSettings(Layout->modelType());
PlotSettings->copyFrom(Layout);
Layout->close();
BlockTableRecord->close();
PlotSettingsValidator = (AcDbPlotSettingsValidator*)acdbHostApplicationServices()->plotSettingsValidator();
PlotSettingsValidator->setPlotCfgName(PlotSettings, _T("DWG To PDF.pc5"));
PlotSettingsValidator->refreshLists(PlotSettings);
PlotSettingsValidator->setCanonicalMediaName(PlotSettings, _T("ISO_A4_(210.00_x_297.00_MM)"));
PlotSettingsValidator->setUseStandardScale(PlotSettings, Adesk::kTrue);
PlotSettingsValidator->setStdScaleType(PlotSettings, AcDbPlotSettings::kScaleToFit);
PlotSettingsValidator->setPlotType(PlotSettings, AcDbPlotSettings::kExtents);
PlotSettingsValidator->setPlotCentered(PlotSettings, true);
PlotInfo.setLayout(ObjectId);
PlotInfo.setOverrideSettings(PlotSettings);
AcPlPlotInfoValidator validator;
validator.setMediaMatchingPolicy(AcPlPlotInfoValidator::MatchingPolicy::kMatchEnabled);
es = validator.validate(PlotInfo);
if (es == Acad::eOk)
{
const ACHAR* fileName=acDocManager->curDocument()->fileName();
PlotEngine->beginPlot(NULL);
PlotEngine->beginDocument(PlotInfo, fileName, NULL, 1, true, _T("Drawing1.pdf"));
PlotEngine->beginPage(PlotPageInfo, PlotInfo, true);
PlotEngine->beginGenerateGraphics();
PlotEngine->endGenerateGraphics();
PlotEngine->endPage();
PlotEngine->endDocument();
PlotEngine->endPlot();
}
PlotEngine->destroy();
PlotEngine = NULL;
}
else
{
acedAlert(_T("createPublishEngine fail"));
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: Global Functions for Interacting with ZWCAD

Modules
Global Functions for Interacting with ZWCAD
Basic Interaction with ZWCAD

Modules

General Access
Getting User Input
Conversions
Character Type Handling
Coordinate System Transformations
Display Control
Tablet Calibration
Wild-Card Matching

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: General Access

Modules
General Access
Basic Interaction with ZWCAD » Global Functions for Interacting with ZWCAD

Modules

Using acedCmd()
Pausing for User Input
Passing Pick Points to ZWCAD Commands
System Variables
AutoLISP Symbols
File Search
Object Snap
Viewport Descriptors
Geometric Utilities
The Text Box Utility Function

Detailed Description

You can use the acedCommand or acedCmd function to execute an internal command, which is the same as the direct execution of the corresponding command in ZWCAD

The number of parameters of the function is variable, and the parameters are paired. The first parameter in the parameter pair indicates the type of the parameter, and the second represents its actual data. The last parameter of the parameter table must be 0 or RTNONE.

int acedCommand(int rtype, ... unnamed);

The argument to this function is a pointer to a resbuf type

int acedCmd(const struct resbuf * rbp);

The following code Use the acedCommand function to create a circle.And then user Choose an entity to do the rotation operation.
(RTPOINT, ptCenter) and (RTSTR, "10,10,0") are the same for specifying a point coordinate

void InteractGlobalFunction::UseCmd()
{
ads_point ptCenter = {10, 10, 0};
ads_real radius = 10.0;
acedCommand(RTSTR, _T("circle"),
RT3DPOINT, ptCenter,
RTREAL, radius,
RTNONE);
ads_name entres;
ads_point ptres;
acedEntSel(NULL, entres, ptres);
int iRet = 0;
ads_point ptBase = {0, 0, 0};
ads_point ptEnd = {1, 1, 0};
acedCommand(RTSTR, _T("rotate3d"), RTENAME, entres, RTSTR, _T(""), RTPOINT, ptBase, RTPOINT, ptEnd, RTREAL, 90.0, 0);
}


ZWSoft ZRX for ZWCAD: Developer Guide: Using acedCmd()

Using acedCmd()
Basic Interaction with ZWCAD » Global Functions for Interacting with ZWCAD » General Access

The argument to the acedCmd function is a pointer to a resbuf type, and the result buffers needed here can be generated by the acutBuildList function.

struct resbuf {
struct resbuf *rbnext;
short restype;
union ads_u_val resval;
};

The acedCommand function is actually a resbuf structure for the command to be executed. So the acedCmd function and the acedCommand function are equivalent.

void InteractGlobalFunction::UseCmd2()
{
struct resbuf *rb;
ads_point ptCenter = {10, 0, 0};
ads_real radius = 10;
rb = acutBuildList(RTSTR,_T("circle"),
RTPOINT, ptCenter,
RTREAL, radius,
RTNONE);
if (rb != NULL)
{
acedCmd(rb);
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: Pausing for User Input

Pausing for User Input
Basic Interaction with ZWCAD » Global Functions for Interacting with ZWCAD » General Access

By acedCommand () or acedCmd () command is invoked, if there PAUSE symbol in the sequence of parameters, ZWCAD command encounters this symbol in the implementation process will pause and wait for user input information (including drag).
Pause symbol PAUSE consists of a string that contains a backslash

#define PAUSE ZCRX_T("\\")

The following code call the Rotate command to wait for the user to enter the base point and the rotation angle.
[RTSTR, ""] on behalf of the input carriage return.
[RTSTR, PAUSE] stands for pause and waiting for user input.

void InteractGlobalFunction::CmdPAUSE()
{
ads_name entres;
ads_point ptres;
acedEntSel(NULL, entres, ptres);
acedCommand(RTSTR, _T("rotate"), RTENAME, entres, RTSTR,"", RTSTR, PAUSE, RTREAL, 90.0, 0);
}


ZWSoft ZRX for ZWCAD: Developer Guide: Passing Pick Points to ZWCAD Commands

Passing Pick Points to ZWCAD Commands
Basic Interaction with ZWCAD » Global Functions for Interacting with ZWCAD » General Access

For some commands such as Trim, Extend, and Fillet, they require the user to specify the pick point and the entity for the command. To pass such entity and point data through the function acedCommand (), the user can place the entity and the point on the result Type code between RTLB and RTLE.

void InteractGlobalFunction::CmdPassPickPoint()
{
ads_point p1={8,0,0};
ads_point p2={20,10,0};
ads_name entres;
acedCommand(RTSTR,"LINE",RTSTR,"1,0",RTSTR,"30,0",RTSTR,"",0);
acdbEntNext(NULL,entres);
acedCommand(RTSTR,_T("break"),
RTLB,RTENAME,entres,RT3DPOINT,p1,RTLE,
RT3DPOINT,p2,
0);
}


ZWSoft ZRX for ZWCAD: Developer Guide: System Variables

System Variables
Basic Interaction with ZWCAD » Global Functions for Interacting with ZWCAD » General Access

Use the acedGetVar() and acedSetVar() functions to get and set the value of the zwcad system variable.
The following code use acedGetVar() get the text height Variable.

void InteractGlobalFunction::GetSystemVariables()
{
struct resbuf rb1,rb2;
acedGetVar(_T("TEXTSIZE"), &rb1);
CString str;
str.Format(_T("\n%f\n"),rb1.resval.rreal);
acutPrintf(str);
acedGetVar(_T("TEXTSTYLE"), &rb2);
if (rb2.resval.rstring != NULL)
{
acutPrintf(rb2.resval.rstring);
// Release memory acquired for string
free(rb2.resval.rstring);
}
}

The following code use acedSetVar() get the text height Variable.

void InteractGlobalFunction::SetSystemVariables()
{
struct resbuf rb;
rb.restype = RTREAL;
rb.resval.rreal = 5;
if(acedSetVar(_T("TEXTSIZE"), &rb)==RTNORM)
{
acutPrintf(_T("Set textsize success."));
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: AutoLISP Symbols

AutoLISP Symbols
Basic Interaction with ZWCAD » Global Functions for Interacting with ZWCAD » General Access

Use acedGetSym() and acedPutSym() functions to get and set the value of the AutoLISP variable.
The following code is equivalent to lsp expressions:

(setq mystr "ZWCAD.com")
!mystr
void InteractGlobalFunction::GetAndSetLispSymbols()
{
struct resbuf *rb1;
int rc;
rb1 = acutBuildList(RTSTR, _T("ZWCAD.com"),0);
rc = acedPutSym(_T("mystr"), rb1);
if (rc==RTNORM)
{
acutPrintf(_T("PutSym mystr is %s\n"), rb1->resval.rstring);
}
acutRelRb(rb1);
struct resbuf *rb2;
rc = acedGetSym(_T("mystr"), &rb2);
if (rc == RTNORM && rb2->restype == RTSTR)
acutPrintf(_T("GetSym mystr is %s\n"), rb2->resval.rstring);
acutRelRb(rb2);
}


ZWSoft ZRX for ZWCAD: Developer Guide: File Search

File Search
Basic Interaction with ZWCAD » Global Functions for Interacting with ZWCAD » General Access

The following code uses acedFindFile () function to search for a file.

void InteractGlobalFunction::FileSearch()
{
const ZTCHAR *refname = _T("zwcad.dwg");
ZTCHAR fullpath[100];
if (acedFindFile(refname, fullpath) == RTNORM)
{
acutPrintf(_T("Find file: %s.\n"), fullpath);
}
}

The acedGetFileD() function uses the standard ZWCAD file dialog box to prompt the user to enter a file name.

int acedGetFileD(const char * title,
const char * default,
const char * ext,
int flags,
struct resbuf * result);

title: the title of the dialog box.
default: the default file name.
ext: the default file extension.
flags: The parameter controls the style of the dialog with a bit value.
result: The path selected by the user.

The following code uses acedFindFileD() function to call the file dialog boxs to earch for a file.

void InteractGlobalFunction::FileSearchD()
{
struct resbuf *result;
int rc, flags;
result = acutNewRb(RTSTR);
result->resval.rstring=NULL;
flags = 2;
rc = acedGetFileD(_T("Select file"),
_T("D:\\"),
_T("dwg;dxf"),
flags,
result);
if (rc == RTNORM)
acedAlert(result->resval.rstring);
acutRelRb(result);
}


ZWSoft ZRX for ZWCAD: Developer Guide: Object Snap

Object Snap
Basic Interaction with ZWCAD » Global Functions for Interacting with ZWCAD » General Access

Use the acedOsnap () function to specify a snap pattern to capture a point

The following code uses the acedOsnap () function to capture a circle's center.

The result is the circle's center(10.000000,10.000000,0.000000)

void InteractGlobalFunction::ObjectSnap()
{
ads_point ptCenter = {10, 10, 0};
ads_real radius = 10.0;
acedCommand(RTSTR, _T("circle"),
RT3DPOINT, ptCenter,
RTREAL, radius,
RTNONE);
ads_point pt1={0, 10, 0};//A point on the circle
ads_point pt2;
acedOsnap(pt1,_T("center"),pt2);
acutPrintf(_T("%f,%f,%f"),pt2[0],pt2[1],pt2[2]);
}


ZWSoft ZRX for ZWCAD: Developer Guide: Viewport Descriptors

Viewport Descriptors
Basic Interaction with ZWCAD » Global Functions for Interacting with ZWCAD » General Access

The acedVports() function gets a list of descriptors of the current viewports and their locations.

void InteractGlobalFunction::GetViewport()
{
struct resbuf *rb;
int rc;
rc = acedVports(&rb);
if (rc==RTNORM)
{
acedRetList(rb);
}
acutRelRb(rb);
}


ZWSoft ZRX for ZWCAD: Developer Guide: Geometric Utilities

Geometric Utilities
Basic Interaction with ZWCAD » Global Functions for Interacting with ZWCAD » General Access

The following sample code shows some simple calls to the geometric utility functions.
acutPolar()function finds a point by means of polar coordinates.

void InteractGlobalFunction::GeometricUtl()
{
ads_point pt1={10,10,0};
ads_point pt2={0,10,0};
ads_point endpt;
ads_real rads, length;
rads = acutAngle(pt1, pt2);
acutPrintf(_T("The Angle in the XY plane of the current UCS, in radians:%f\n"),rads);
length = acutDistance(pt1, pt2);
acutPrintf(_T("The Distance:%f\n"),length);
acutPolar(pt1, rads, length, endpt);
acutPrintf(_T("The Polar point:(%f,%f,%f)\n"),endpt[X],endpt[Y],endpt[Z]);
}


ZWSoft ZRX for ZWCAD: Developer Guide: The Text Box Utility Function

The Text Box Utility Function
Basic Interaction with ZWCAD » Global Functions for Interacting with ZWCAD » General Access

The following code use acedTextBox() function to find the coordinates of the box that contains the text entity. You can get the lower-left and upper-right coordinates of the box.The coordinates are expressed in the ECS of entity.

void InteractGlobalFunction::TextBox()
{
ads_name tname;
struct resbuf *textent, *tent;
ads_point origin, lowleft, upright, p1, p2, p3, p4;
ads_real rotatn;
ZTCHAR rotatstr[15];
if (acedEntSel(_T("\nSelect text: "), tname, p1) == RTNORM)
{
textent = acdbEntGet(tname);
if (textent != NULL)
{
if (acedTextBox(textent, lowleft, upright) == RTNORM)
{
acutPrintf(_T("Lowleft:(%f,%f,%f)\n"),lowleft[X],lowleft[Y],lowleft[Z]);
acutPrintf(_T("Upright:(%f,%f,%f)\n"),upright[X],upright[Y],upright[Z]);
}
acutRelRb(textent);
}
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: Getting User Input

Modules
Getting User Input
Basic Interaction with ZWCAD » Global Functions for Interacting with ZWCAD

Modules

User-Input Functions
Control of User-Input Function Conditions
Graphically Dragging Selection Sets.
User Breaks.
Returning Values to AutoLISP Functions.

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: User-Input Functions

User-Input Functions
Basic Interaction with ZWCAD » Global Functions for Interacting with ZWCAD » Getting User Input

ZWCAD provides a number of global functions that prompt user input, including acedGetString, acedGetPoint, acedGetInt, acedGetKword, and acedGetReal, etc.
- acedGetInt: pauses the program execution, waiting for the user to enter an integer.
- acedGetReal: pauses the program execution, waiting for the user to enter a real number.
- acedGetString: suspend the program execution, waiting for the user to enter a string, the function is defined as:

int acedGetString (int cronly, cons t char * prompt, char * result);

The argument cronly shows whether the string contains a space.0 means that the string is not allowed to contain spaces, and 1 means that the string can contain spaces.
- acedGetDist: pause the program execution, waiting for the user to enter a straight line distance.
- acedGetCorner: pause the program execution, waiting for the user to enter the diagonal point of the rectangular box of the graphics window.
- acedGetAngle: pauses the program, waiting for the user to enter an angle relative to the current value set by the ANGBASE system variable.
acedInitGet, acedGetKword, and acedGetInput are used to prompt the user to enter a keyword and perform different actions based on the keywords entered by the user.
The following code prompts the user to enter a point and enter a distance after successful execution

void InteractGlobalFunction::UserInput()
{
ads_point pt;
int nReturn=acedGetPoint(NULL,_T("please select a point:\n "),pt);
switch(nReturn)
{
case RTNORM:
acutPrintf(_T("Point:(%f,%f,%f)\n"),pt[X],pt[Y],pt[Z]);
acutPrintf(_T("User entered a valid value\n"));
ads_real fDist;
if (acedGetDist(pt,_T("please put distance\n"),&fDist)==RTNORM)
{
acutPrintf(_T("RealNumber:%f\n"),fDist);
}
break;
case RTERROR:
acutPrintf(_T("The function call failed\n"));
break;
case RTCAN:
acutPrintf(_T("User entered ESC\n"));
break;
case RTNONE:
acutPrintf(_T("User entered only ENTER\n"));
break;
case RTREJ:
acutPrintf(_T("Rejected the request as invalid\n"));
break;
case RTKWORD:
acutPrintf(_T("User entered a keyword or arbitrary text\n"));
break;
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: Control of User-Input Function Conditions

Modules
Control of User-Input Function Conditions
Basic Interaction with ZWCAD » Global Functions for Interacting with ZWCAD » Getting User Input

Modules

Input Options for User-Input Functions
Keyword Specifications

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: Input Options for User-Input Functions

Input Options for User-Input Functions
Basic Interaction with ZWCAD » Global Functions for Interacting with ZWCAD » Getting User Input » Control of User-Input Function Conditions

In the interaction with the user to obtain data, sometimes need to add some restrictions. Such as prompting the user to enter the radius of the circle, it must be limited to the input data can not be negative. This can be done by calling the acedInitGet () function. The function will control the user input followed by a acedGetXXX () function behind it.

int acedInitGet(int val,const ACHAR *kwl);

Input options set by acedInitGet:

  • 1 RSG_NONULL Disallow null input
  • 2 RSG_NOZERO Disallow zero values
  • 4 RSG_NONEG Disallow negative values
  • 8 RSG_NOLIM Do not check drawing limits, even if LIMCHECK is on
  • 32 RSG_DASH Use dashed lines when drawing rubber-band line or box
  • 64 RSG_2D Ignore Z coordinate of 3D points (acedGetDist() only)
  • 128 RSG_OTHER Allow arbitrary input–whatever the user types
  • 256 RSG_DDISTFIRST Force direct distance input to have precedence over arbitrary input
  • 512 RSG_TRACKUCS Allow UCS tracking for faces
  • 1024 RSG_NOORTHOZ Disables polar/otrack/ortho tracking in the Z direction
  • 2048 RSG_NOOSNAP Disables object snaps
void InteractGlobalFunction::UserInputInitGet()
{
int num = 0;
acedInitGet(RSG_NONULL | RSG_NOZERO | RSG_NONEG,NULL);
int rc=acedGetInt(_T("Input int Number:\n"), &num);
if ( rc== RTNORM)
{
acutPrintf(_T("Input Number:%f\n"),num);
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: Keyword Specifications

Keyword Specifications
Basic Interaction with ZWCAD » Global Functions for Interacting with ZWCAD » Getting User Input » Control of User-Input Function Conditions

Use the acedGetKword () function to get the user input keywords.
After calling a user input function, the acedGetInput () function retrieves the keyword entered by the user.The retrieved keywords are stored in a string.
The acedGetInput () function is called after the call to the user's input function,Otherwise it is meaningless and will not succeed. Even so, the call will only succeed if the user enters a function that returns the RTKWORD value.

void InteractGlobalFunction::UserInputKWord()
{
ads_real num = 0;
acedInitGet(NULL,TEXT("Z W"));
int rc=acedGetReal(_T("Input Real Number [Or put Z / W]:\n"), &num);
if ( rc== RTNORM)
{
acutPrintf(_T("Real Number:%f\n"),num);
}
else if (rc==RTKWORD)
{
TCHAR kwork[20];
if (acedGetInput(kwork)==RTNORM)
{
acutPrintf(_T("Text:%s\n"),kwork);
}
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: Graphically Dragging Selection Sets.

Graphically Dragging Selection Sets.
Basic Interaction with ZWCAD » Global Functions for Interacting with ZWCAD » Getting User Input

The following code uses the acedDragGen() function to prompt the user to drag a set of selected objects

ads_name ss;
ads_point bp;
void ident_init(ads_matrix id)
{
int i, j;
for (i = 0; i <= 3; i ++)
for (j = 0; j <= 3; j ++)
id[i][j] = 0.0;
for (i = 0; i <= 3; i ++)
id[i][i] = 1.0;
}
void ucs2wcs(ads_point pt)
{
struct resbuf fromrb, torb;
fromrb.restype = RTSHORT;
fromrb.resval.rint = 1; // UCS
torb.restype = RTSHORT;
torb.resval.rint = 0; //WCS
acedTrans(pt, &fromrb, &torb, FALSE, pt);
return;
}
int dragfunc(ads_point usrpt, ads_matrix matrix)
{
ucs2wcs(usrpt);
matrix[0][T] = usrpt[X] - bp[X];
matrix[1][T] = usrpt[Y] - bp[Y];
matrix[2][T] = usrpt[Z] - bp[Z];
return RTNORM;
}
static void MyDragGen(void)
{
ads_point rpt;
acedSSGet(NULL,NULL,NULL,NULL, ss);
acedGetPoint(NULL,_T("\n Select the base point:"),bp);
ucs2wcs(bp);
int rt = acedDragGen(ss, _T("\n Select the insertion point:"), 0, dragfunc, rpt);
if(rt==RTNORM||rt==RTCAN)
{
ucs2wcs(rpt);
ads_matrix mat;
ident_init(mat);
mat[0][T] = rpt[X] - bp[X];
mat[1][T] = rpt[Y] - bp[Y];
mat[2][T] = rpt[Z] - bp[Z];
acedXformSS(ss,mat);
}
acedSSFree(ss);
}


ZWSoft ZRX for ZWCAD: Developer Guide: User Breaks.

User Breaks.
Basic Interaction with ZWCAD » Global Functions for Interacting with ZWCAD » Getting User Input

Usually the application does not need to call acedUsrBrk ().Functions acedCommand (), acedCmd (), acedEntSel (), acedNEntSelP (), acedNEntSel (), acedDragGen (), and acedSSGet () etc. returns the RTCAN by pressing ESC.


ZWSoft ZRX for ZWCAD: Developer Guide: Returning Values to AutoLISP Functions.

Returning Values to AutoLISP Functions.
Basic Interaction with ZWCAD » Global Functions for Interacting with ZWCAD » Getting User Input

Functions acedRetXXX returns value to AutoLISP.

void InteractGlobalFunction::ValueToLisp()
{
ads_point ptCenter = {10, 10, 0};
acedRetPoint(ptCenter);
}


ZWSoft ZRX for ZWCAD: Developer Guide: Conversions

Modules
Conversions
Basic Interaction with ZWCAD » Global Functions for Interacting with ZWCAD

Modules

String Conversions
Real-World Units

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: String Conversions

String Conversions
Basic Interaction with ZWCAD » Global Functions for Interacting with ZWCAD » Conversions

- acdbRToS () Converts the value of the ads_real type to a string

int acdbRToS(
ads_real val,
int unit,
int prec,
ACHAR * str);

Where val is realvalue to be converted; unit specifies the unit to use, and if set to -1, the value of the LUNITS system variable in the ZWCAD drawing is used as the unit of use. precstr is number of decimal places of precision to include in the string; if set to -1, uses the current value of the ZWCAD LUPREC system variable .str Returns the conversion result.

- acdbAngToS () Converts the angle to a string by format.
- acdbDisToF() Converts a real number stored in a string into a real number based on the specified unit.

int acdbDisToF(
const char * str,
int unit,
ads_real * v);

Where str holds the string to be converted; unit specifies the unit to use, and if set to -1, the value of the LUNITS system variable in the ZWCAD drawing is used as the unit of use. v Returns the conversion result.

- acdbAngToF() Converts a angle stored in a string into a real number based on the specified unit.

void InteractGlobalFunction::StringConversions()
{
ads_real f = 100.5;
ZTCHAR strf[12];
acdbRToS(f, -1, 4, strf);
acutPrintf(_T("real value to string: %s\n"), strf);
ads_real v;
acdbDisToF(strf,-1,&v);
acutPrintf(_T("string value to real : %f\n"), v);
ads_real ang = 3.14159;
acdbAngToS(ang, -1, 0, strf);
acutPrintf(_T("agle value to string: %s\n"), strf);
acdbDisToF(strf,-1,&v);
acutPrintf(_T("string value to angle: %f\n"), v);
}


ZWSoft ZRX for ZWCAD: Developer Guide: Real-World Units

Real-World Units
Basic Interaction with ZWCAD » Global Functions for Interacting with ZWCAD » Conversions

The function acutCvUnit () is used to convert the value of a unit into another unit value. The unit is represented by a string, and the string used must be the same as defined in the file acad.unt.
Note: You can not use the function acutCvUnit () to convert unmatched units, for example, you can not convert inches into years.
The following procedure converts the specified distance into meters.

void InteractGlobalFunction::RealWorldUnits()
{
ads_real ilen=100;
ads_real mlen;
acutCvUnit (ilen, _T("inches"), _T("meters"), & mlen);
acutPrintf(_T("inches to meters : %f\n"), mlen);
}


ZWSoft ZRX for ZWCAD: Developer Guide: Character Type Handling

Character Type Handling
Basic Interaction with ZWCAD » Global Functions for Interacting with ZWCAD

Provides a set of character handling functions can be applied to the current language configuration of ZWCAD acutIsAlpha: Verifies that the character is alphabetic

acutIsUpper: Verifies that the character is uppercase

acutIsLower: Verifies that the character is lowercase

acutIsDigit: Verifies that the character is a digit

acutIsXDigit: Verifies that the character is a hexadecimal digit

acutIsSpace: Verifies that the character is a white-space character

acutIsPunct: Verifies that the character is a punctuation character

acutIsAlNum: Verifies that the character is alphanumeric

acutIsPrint: Verifies that the character is printable

acutIsGraph: Verifies that the character is graphical

acutIsCntrl: Verifies that the character is a control character

acutToUpper: Converts the character to uppercase

acutToLower: Converts the character to lowercase

void InteractGlobalFunction::CharacterHandle()
{
char chars[]={'A',0x09,'Z'};
int i;
int nSize=sizeof(chars)/sizeof(char);
for(i=0;i<nSize;i++)
{
acutPrintf(_T("Char %c is %s a Controlcharacter\n"), chars[i],(acutIsCntrl(chars[i]))?_T(""):_T("not"));
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: Coordinate System Transformations

Coordinate System Transformations
Basic Interaction with ZWCAD » Global Functions for Interacting with ZWCAD

Use the acedTrans() function to convert coordinate points or displacement from one coordinate system to another coordinate system.

void InteractGlobalFunction::TranCoorSystem()
{
ads_point pt;
if(acedGetPoint(NULL,_T("please select a point:\n "),pt)==RTNORM)
{
acutPrintf(_T("Point UCS:(%f,%f,%f)\n"),pt[X],pt[Y],pt[Z]);
ads_point result;
struct resbuf fromrb, torb;
fromrb.restype = RTSHORT;
fromrb.resval.rint = 1; // UCS
torb.restype = RTSHORT;
torb.resval.rint = 0; // WCS
acedTrans(pt, &fromrb, &torb, FALSE, result);
acutPrintf(_T("Point WCS:(%f,%f,%f)\n"),result[X],result[Y],result[Z]);
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: Display Control

Modules
Display Control
Basic Interaction with ZWCAD » Global Functions for Interacting with ZWCAD

Modules

Interactive Output
Control of Graphics and Text Screens
Control of Low-Level Graphics and User Input

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: Interactive Output

Interactive Output
Basic Interaction with ZWCAD » Global Functions for Interacting with ZWCAD » Display Control

The acutPrompt() function displays a piece of information at the command line. Returns the RTNORM if the acutPrompt() function call succeeds, otherwise returns an error code. The function argument is a pointer to a string constant, and the function can not change the contents of the string.

The acutPrintf() function is equivalent to the standard C library function printf(), except that the acutPrintf() function displays the output on the text screen. The acutPrintf() function saves the string to be output in an internal buffer before sending the string to ZWCAD. The buffer contains 133 bytes, so calling the acutPrintf() function displays no more than 132 characters.

void InteractGlobalFunction::InteractOutput()
{
acedPrompt(_T("Prompt user message\n"));
acutPrintf(_T("Print user message\n"));
}


ZWSoft ZRX for ZWCAD: Developer Guide: Control of Graphics and Text Screens

Control of Graphics and Text Screens
Basic Interaction with ZWCAD » Global Functions for Interacting with ZWCAD » Display Control


ZWSoft ZRX for ZWCAD: Developer Guide: Control of Low-Level Graphics and User Input

Control of Low-Level Graphics and User Input
Basic Interaction with ZWCAD » Global Functions for Interacting with ZWCAD » Display Control

The following code uses the acedGrRead() function to change the center point of the circle.

void InteractGlobalFunction::UserMoveText()
{
ads_name tname;
ads_point pt;
if (acedEntSel(_T("Select circle: \n"), tname, pt) == RTNORM)
{
AcDbObjectId objid;
Acad::ErrorStatus es=acdbGetObjectId(objid,tname);
if(es==Acad::eOk)
{
AcDbEntity *pEnt;
if(acdbOpenAcDbEntity(pEnt,objid,AcDb::kForWrite)==Acad::eOk)
{
AcGePoint3d ptT;
int track=1;
int type;
struct resbuf result;
if (pEnt->isKindOf(AcDbCircle::desc()))
{
AcDbCircle *pCircle;
pCircle=AcDbCircle::cast(pEnt);
while(track>0)
{
acedGrRead(track,&type,&result);
ptT[X]=result.resval.rpoint[X];
ptT[Y]=result.resval.rpoint[Y];
if (pCircle!=NULL)
{
pCircle->setCenter(ptT);
}
if (type==3)
{
track=0;
}
}
}
pEnt->close();
}
}
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: Tablet Calibration

Tablet Calibration
Basic Interaction with ZWCAD » Global Functions for Interacting with ZWCAD


ZWSoft ZRX for ZWCAD: Developer Guide: Wild-Card Matching

Wild-Card Matching
Basic Interaction with ZWCAD » Global Functions for Interacting with ZWCAD

The following code uses the acutWcMatch() function for string wildcard comparison.

The acutWcMatchEx() function has an additional argument to allow it to ignore case.

void InteractGlobalFunction::WildCardMatch()
{
if (acutWcMatch(_T("allofxzsdf"), _T("allof*")) == RTNORM)
{
acutPrintf(_T("Match success,use acutWcMatch\n"));
}
if (acutWcMatchEx(_T("ALLofxzsdf"), _T("allof*"),true))
{
acutPrintf(_T("Match success,use acutWcMatchEx\n"));
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: ZRX Global Utility Functions

Modules
ZRX Global Utility Functions
Basic Interaction with ZWCAD

Modules

Common Characteristics of ZRX Library Functions
Variables, Types, and Values Defined in ObjectARX
Lists and Other Dynamically Allocated Data

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: Common Characteristics of ZRX Library Functions

Modules
Common Characteristics of ZRX Library Functions
Basic Interaction with ZWCAD » ZRX Global Utility Functions

Modules

ZRX Global Function Calls Compared to AutoLISP Calls
Function Return Values versus Function Results
External Functions
Error Handling Functions
Communication Between Applications
Handling External Applications

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: ZRX Global Function Calls Compared to AutoLISP Calls

Modules
ZRX Global Function Calls Compared to AutoLISP Calls
Basic Interaction with ZWCAD » ZRX Global Utility Functions » Common Characteristics of ZRX Library Functions

Modules

Argument Lists in AutoLISP and C
Memory Management

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: Argument Lists in AutoLISP and C

Argument Lists in AutoLISP and C
Basic Interaction with ZWCAD » ZRX Global Utility Functions » Common Characteristics of ZRX Library Functions » ZRX Global Function Calls Compared to AutoLISP Calls

The following code uses the acdbEntMake() function to receive a list of variable parameters. Simulation of AutoLisp entmake function can be any input variable parameters of the function.
The acutPrintf () function is similar to the standard C library printf () function.

void GlobalUtilityFunction::ArgumentLists()
{
struct resbuf* rbEnt;
ads_point point1={10,0,0};
ads_point point2={30,00,0};
rbEnt = acutBuildList(RTDXF0, _T("Line"), 10, point1, 11, point2, RTNONE);
if (rbEnt != NULL)
{
if (acdbEntMake(rbEnt) == RTNORM)
{
acutPrintf(_T("Line:(%.2f,%.2f,%.2f),(%.2f,%.2f,%.2f)\n"),point1[X],point1[Y],point1[Z],point2[X],point2[Y],point2[Z]);
}
acutRelRb(rbEnt);
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: Memory Management

Memory Management
Basic Interaction with ZWCAD » ZRX Global Utility Functions » Common Characteristics of ZRX Library Functions » ZRX Global Function Calls Compared to AutoLISP Calls

Unlike AutoLisp, ZRX does not have automatic garbage collection. In addition to some global functions, in most cases, users need to explicitly free memory.

The following code demonstrates that the iterator must be released manually after use.

void GlobalUtilityFunction::MemoryManage()
{
AcDbBlockTable *pBlockTable;
acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlockTable,AcDb::kForRead);
AcDbBlockTableRecord *pBlockRecord;
pBlockTable->getAt(ACDB_MODEL_SPACE,pBlockRecord,AcDb::kForRead);
pBlockTable->close();
AcDbBlockTableRecordIterator *pIter;
pBlockRecord->newIterator(pIter);
AcDbEntity *pEnt;
for (pIter->start();!pIter->done();pIter->step())
{
pIter->getEntity(pEnt,AcDb::kForRead);
AcDbHandle entHandle;
pEnt->getZcDbHandle(entHandle);
acutPrintf(_T("%s:%d\n"),pEnt->isA()->name(),entHandle);
pEnt->close();
}
delete pIter;
pBlockRecord->close();
}


ZWSoft ZRX for ZWCAD: Developer Guide: Function Return Values versus Function Results

Function Return Values versus Function Results
Basic Interaction with ZWCAD » ZRX Global Utility Functions » Common Characteristics of ZRX Library Functions

The following code shows the return value of the acedGetPoint () function and prints the result value if a point is successfully selected.

void GlobalUtilityFunction::ReturnValues()
{
ads_point pt;
int nReturn=acedGetPoint(NULL,_T("please select a point:\n "),pt);
switch(nReturn)
{
case RTNORM:
acutPrintf(_T("Point:(%f,%f,%f)\n"),pt[X],pt[Y],pt[Z]);
acutPrintf(_T("User entered a valid value\n"));
break;
case RTERROR:
acutPrintf(_T("The function call failed\n"));
break;
case RTCAN:
acutPrintf(_T("User entered ESC\n"));
break;
case RTNONE:
acutPrintf(_T("User entered only ENTER\n"));
break;
case RTREJ:
acutPrintf(_T("Rejected the request as invalid\n"));
break;
case RTKWORD:
acutPrintf(_T("User entered a keyword or arbitrary text\n"));
break;
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: External Functions

Modules
External Functions
Basic Interaction with ZWCAD » ZRX Global Utility Functions » Common Characteristics of ZRX Library Functions

Modules

Defining External Functions
Evaluating External Functions

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: Defining External Functions

Defining External Functions
Basic Interaction with ZWCAD » ZRX Global Utility Functions » Common Characteristics of ZRX Library Functions » External Functions


ZWSoft ZRX for ZWCAD: Developer Guide: Evaluating External Functions

Evaluating External Functions
Basic Interaction with ZWCAD » ZRX Global Utility Functions » Common Characteristics of ZRX Library Functions » External Functions


ZWSoft ZRX for ZWCAD: Developer Guide: Error Handling Functions

Error Handling Functions
Basic Interaction with ZWCAD » ZRX Global Utility Functions » Common Characteristics of ZRX Library Functions

You can use the acdbFail (), acedAlert (), and acrx_abort () functions to let the application notify the user of an error message

void GlobalUtilityFunction::SelectCircle()
{
ads_name tname;
ads_point pt;
if (acedEntSel(_T("Select circle: \n"), tname, pt) == RTNORM)
{
AcDbObjectId objid;
Acad::ErrorStatus es=acdbGetObjectId(objid,tname);
if(es==Acad::eOk)
{
AcDbEntity *pEnt;
if(acdbOpenAcDbEntity(pEnt,objid,AcDb::kForWrite)==Acad::eOk)
{
AcGePoint3d ptT;
int track=1;
int type;
struct resbuf result;
if (pEnt->isKindOf(AcDbCircle::desc()))
{
acedAlert(_T("This is a circle"));
}
else
{
acdbFail(_T("The Entity is not a circle"));
}
pEnt->close();
}
}
else
{
acdbFail(_T("The pick operation failed"));
}
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: Communication Between Applications

Modules
Communication Between Applications
Basic Interaction with ZWCAD » ZRX Global Utility Functions » Common Characteristics of ZRX Library Functions

Modules

Handling Errors from Invoked Functions

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: Handling Errors from Invoked Functions

Handling Errors from Invoked Functions
Basic Interaction with ZWCAD » ZRX Global Utility Functions » Common Characteristics of ZRX Library Functions » Communication Between Applications


ZWSoft ZRX for ZWCAD: Developer Guide: Handling External Applications

Handling External Applications
Basic Interaction with ZWCAD » ZRX Global Utility Functions » Common Characteristics of ZRX Library Functions

The following print the names of all currently loaded applications.
And show how to Load or Unload an application:

void GlobalUtilityFunction::HandleExternal()
{
struct resbuf *rb1, *rb2;
for (rb2 = rb1 = acedArxLoaded(); rb2 != NULL; rb2 = rb2->rbnext) {
if (rb2->restype == RTSTR)
acutPrintf(_T("%s\n"), rb2->resval.rstring);
}
if (acedArxUnload(_T("myappname")) != RTERROR) {
acutPrintf(_T("unLoaded successfully\n"));
}
if (acedArxLoad(_T("myappname")) != RTERROR) {
acutPrintf(_T("Loaded successfully\n"));
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: Variables, Types, and Values Defined in ObjectARX

Modules
Variables, Types, and Values Defined in ObjectARX
Basic Interaction with ZWCAD » ZRX Global Utility Functions

Modules

General Types and Definitions
Useful Values
Result Buffers and Type Codes
ZARX Function Result Type Codes
User-Input Control Bit Codes

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: General Types and Definitions

Modules
General Types and Definitions
Basic Interaction with ZWCAD » ZRX Global Utility Functions » Variables, Types, and Values Defined in ObjectARX

Modules

Real Numbers And Points
Transformation Matrices
Entity and Selection Set Names

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: Real Numbers And Points

Real Numbers And Points
Basic Interaction with ZWCAD » ZRX Global Utility Functions » Variables, Types, and Values Defined in ObjectARX » General Types and Definitions

ZWCAD real values are defined as the following double type:

typedef double ads_real;

ZWCAD points are defined as the following array type:

typedef ads_real ads_point[3];

The following code show how to use ads_point;

void GlobalUtilityFunction::use_ads_point()
{
ads_point pt1={10,10,0};
ads_point pt2={10.23,6.88,0};
acutPrintf(_T("pt1 point:(%f,%f,%f)\n"),pt1[X],pt1[Y],pt1[Z]);
pt1[X]=pt2[X];
pt1[Y]=pt2[Y];
pt1[Z]=pt2[Z];
acutPrintf(_T("pt1 copies the value of pt2:(%f,%f,%f)\n"),pt1[X],pt1[Y],pt1[Z]);
ads_point pt3;
ads_point_set(pt2, pt3);
acutPrintf(_T("pt3 copies the value of pt2:(%f,%f,%f)\n"),pt3[X],pt3[Y],pt3[Z]);
}


ZWSoft ZRX for ZWCAD: Developer Guide: Transformation Matrices

Transformation Matrices
Basic Interaction with ZWCAD » ZRX Global Utility Functions » Variables, Types, and Values Defined in ObjectARX » General Types and Definitions

The following code show how to use transformation matrix to scale the entities;
The ident_init function initializes the transformation matrix.
The transformation matrix is a 4 × 4 order array with the ads_real data type. The first three columns of the matrix determine the ratio and the rotation, and the fourth column is a translation vector. The last line of the matrix is defined as [0 0 0 1].
With the acedXformSS() function, the selection set can use the transformation matrix. Using a transformation matrix, you can change the ratio, move, rotate, or mirror the selection of the entity.

void GlobalUtilityFunction::ident_init(ads_matrix id)
{
int i, j;
for (i = 0; i <= 3; i ++)
for (j = 0; j <= 3; j ++)
id[i][j] = 0.0;
for (i = 0; i <= 3; i ++)
id[i][i] = 1.0;
}
void GlobalUtilityFunction::Transmatrices(void)
{
ads_name ss;
int rt=acedSSGet(NULL,NULL,NULL,NULL, ss);
if (rt == RTNORM)
{
long length;
acedSSLength(ss, &length);
if (length>0)
{
ads_matrix mat;
ident_init(mat);
mat[0][X] =2;
mat[1][Y] =2;
mat[2][Z] =2;
acedXformSS(ss,mat);
}
}
acedSSFree(ss);
}


ZWSoft ZRX for ZWCAD: Developer Guide: Entity and Selection Set Names

Entity and Selection Set Names
Basic Interaction with ZWCAD » ZRX Global Utility Functions » Variables, Types, and Values Defined in ObjectARX » General Types and Definitions

ZWCAD the names of entities and selection sets are defined as the following array type:

typedef __w64 long zds_name[2];

The following code copy an selection set name by calling the ads_name_set() function;

void GlobalUtilityFunction::adsName(void)
{
ads_name ss;
ads_name snew;
ads_point rpt;
int rt=acedSSGet(NULL,NULL,NULL,NULL, ss);
if (rt == RTNORM)
{
acutPrintf(_T("\n ss:%lx"), ss[0]);
ads_name_set(ss, snew);
if (!ads_name_nil(snew))
{
acutPrintf(_T("\n snew copies the value of ss:%lx"), ss[0]);
ads_name_clear(ss);
acutPrintf(_T("\n clear ss:%lx"), ss[0]);
}
}
acedSSFree(ss);
}


ZWSoft ZRX for ZWCAD: Developer Guide: Useful Values

Useful Values
Basic Interaction with ZWCAD » ZRX Global Utility Functions » Variables, Types, and Values Defined in ObjectARX

Pause symbol PAUSE consists of a string that contains a backslash
EOS symbol is String termination character

#define PAUSE ZCRX_T("\\")
#define TRUE 1
#define FALSE 0
#define EOS ZCRX_T('\0')

The following code use Pause symbol;

void GlobalUtilityFunction::UsefulValues()
{
ads_name entres;
ads_point ptres;
acedEntSel(NULL, entres, ptres);
acedCommand(RTSTR, _T("rotate"), RTENAME, entres, RTSTR,"", RTSTR, PAUSE, RTREAL, 90.0, 0);
}


ZWSoft ZRX for ZWCAD: Developer Guide: Result Buffers and Type Codes

Modules
Result Buffers and Type Codes
Basic Interaction with ZWCAD » ZRX Global Utility Functions » Variables, Types, and Values Defined in ObjectARX

Modules

Result Buffers
Result Type Codes Defined by ObjectARX
DXF Group Codes

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: Result Buffers

Result Buffers
Basic Interaction with ZWCAD » ZRX Global Utility Functions » Variables, Types, and Values Defined in ObjectARX » Result Buffers and Type Codes

The resulting buffer (resbuf) is a structure, which is defined as

struct resbuf {
struct resbuf *rbnext;
short restype;
union zds_u_val resval;
};

The restype variable is used to specify the type of variable saved in the union ads_u_val.
Two global functions associated with the result buffer: �?br /> - acutRelRb: Releases the storage space of the resulting buffer list. �?br /> - acutNewRb: Creates a new result buffer and allocates storage space for it. Use the assigned function, The storage space must be manually released.

void GlobalUtilityFunction::ReBuf()
{
struct resbuf *result;
result = acutNewRb(RTSTR);
result->resval.rstring=NULL;
int rc = acedGetFileD(_T("Select file"),
NULL,
_T("dwg;dxf"),
0,
result);
if (rc == RTNORM)
acedAlert(result->resval.rstring);
acutRelRb(result);
}


ZWSoft ZRX for ZWCAD: Developer Guide: Result Type Codes Defined by ObjectARX

Result Type Codes Defined by ObjectARX
Basic Interaction with ZWCAD » ZRX Global Utility Functions » Variables, Types, and Values Defined in ObjectARX » Result Buffers and Type Codes


ZWSoft ZRX for ZWCAD: Developer Guide: DXF Group Codes

DXF Group Codes
Basic Interaction with ZWCAD » ZRX Global Utility Functions » Variables, Types, and Values Defined in ObjectARX » Result Buffers and Type Codes

You can type in the command line: (entget (car (entsel))) To get the entity code information.

Command: (entget (car (entsel)))
Select object: ((-1 . <ENTITY NAME: 1f5a51f8>) (0 . "CIRCLE") (5 . "262") (330 . <ENTITY NAME: 1f5a1bb0>) (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (100 . "AcDbCircle") (10 -13.1413 0.481785 0.0) (40 . 30809.6) (210 0.0 0.0 1.0))

Group code and its corresponding parameter values appear in pairs, such as (GroupGode. ParameterValues) format. E.g:
The object type group code 0 (0. "CIRCLE").
Layer group code f 8 (8. "0") .
Round group code 10 (10 -13.1413 0.481785 0.0).
Radius of the code group 40 (40.30809.6).


ZWSoft ZRX for ZWCAD: Developer Guide: ZARX Function Result Type Codes

ZARX Function Result Type Codes
Basic Interaction with ZWCAD » ZRX Global Utility Functions » Variables, Types, and Values Defined in ObjectARX

The following code shows the return value after the user selects a point operation

void GlobalUtilityFunction::ResultTypeCode()
{
ads_point pt;
int nReturn=acedGetPoint(NULL,_T("please select a point:\n "),pt);
switch(nReturn)
{
case RTNORM:
acutPrintf(_T("Point:(%f,%f,%f)\n"),pt[X],pt[Y],pt[Z]);
acutPrintf(_T("User entered a valid value\n"));
break;
case RTERROR:
acutPrintf(_T("The function call failed\n"));
break;
case RTCAN:
acutPrintf(_T("User entered ESC\n"));
break;
case RTNONE:
acutPrintf(_T("User entered only ENTER\n"));
break;
case RTREJ:
acutPrintf(_T("Rejected the request as invalid\n"));
break;
case RTKWORD:
acutPrintf(_T("User entered a keyword or arbitrary text\n"));
break;
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: User-Input Control Bit Codes

User-Input Control Bit Codes
Basic Interaction with ZWCAD » ZRX Global Utility Functions » Variables, Types, and Values Defined in ObjectARX

In the interaction with the user to obtain data, sometimes need to add some restrictions. Such as prompting the user to enter the radius of the circle, it must be limited to the input data can not be negative. This can be done by calling the acedInitGet () function. The function will control the user input followed by a acedGetXXX () function behind it.

Input options set by acedInitGet:

  • 1 RSG_NONULL Disallow null input
  • 2 RSG_NOZERO Disallow zero values
  • 4 RSG_NONEG Disallow negative values
  • 8 RSG_NOLIM Do not check drawing limits, even if LIMCHECK is on
  • 32 RSG_DASH Use dashed lines when drawing rubber-band line or box
  • 64 RSG_2D Ignore Z coordinate of 3D points (acedGetDist() only)
  • 128 RSG_OTHER Allow arbitrary input–whatever the user types
  • 256 RSG_DDISTFIRST Force direct distance input to have precedence over arbitrary input
  • 512 RSG_TRACKUCS Allow UCS tracking for faces
  • 1024 RSG_NOORTHOZ Disables polar/otrack/ortho tracking in the Z direction
  • 2048 RSG_NOOSNAP Disables object snaps
void GlobalUtilityFunction::UserInputControl()
{
ads_point pt;
acedInitGet(RSG_NONULL,NULL);
int rc=acedGetPoint(NULL,_T("Input an Point:\n"),pt);
if ( rc== RTNORM)
{
acutPrintf(_T("Input Point:(%.2f,%.2f,%.2f)\n"),pt[X],pt[Y],pt[Z]);
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: Lists and Other Dynamically Allocated Data

Modules
Lists and Other Dynamically Allocated Data
Basic Interaction with ZWCAD » ZRX Global Utility Functions

Modules

Result-Buffer Memory Management

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: Result-Buffer Memory Management

Modules
Result-Buffer Memory Management
Basic Interaction with ZWCAD » ZRX Global Utility Functions » Lists and Other Dynamically Allocated Data

Modules

List Creation and Deletion
AutoLISP Lists
Entity Lists with DXF Codes in ObjectARX
Command and Function Invocation Lists

Detailed Description

You must explicitly manage the result-buffer list it creates and uses. Regardless of whether the application creates a list or passes it.
The following code shows the layer of the user selected entity, which needs to explicitly release the return result-buffer memory.

void GlobalUtilityFunction::MemoryManagement()
{
struct resbuf* rbEnt;
struct resbuf* rb;
ads_name entName;
ads_point point;
if (acedEntSel(_T("Select a Entity: \n"), entName, point) == RTNORM)
{
rbEnt=acdbEntGet(entName);
rb=rbEnt;
for(rb=rbEnt; rb!=NULL; rb=rb->rbnext)
{
if(rb->restype==8)
{
acutPrintf(_T("Ent layer:%s\n"),rb->resval.rstring);
break;
}
}
if (rbEnt!=NULL)
{
acutRelRb(rbEnt);
}
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: List Creation and Deletion

List Creation and Deletion
Basic Interaction with ZWCAD » ZRX Global Utility Functions » Lists and Other Dynamically Allocated Data » Result-Buffer Memory Management

The acutNewRb() function can reates a new result buffer and allocates storage space for it.
The acutBuildList() function constructs a result buffer and automatically allocates memory.
Whether using acutNewRb or using acutBuildList, you need to use the acutRelRb function to release the allocated memory

void GlobalUtilityFunction::ReBuf2()
{
ads_name ss;
struct resbuf *rb1;
rb1 = acutBuildList(RTDXF0,_T("CIRCLE"),8,_T("0"),RTNONE);
int rt=acedSSGet(_T("X"),NULL,NULL,rb1, ss);
if (rt == RTNORM)
{
long length;
acedSSLength(ss, &length);
if (length>0)
{
acutPrintf(_T("select %d entities.\n"),length);
}
}
acedSSFree(ss);
}


ZWSoft ZRX for ZWCAD: Developer Guide: AutoLISP Lists

AutoLISP Lists
Basic Interaction with ZWCAD » ZRX Global Utility Functions » Lists and Other Dynamically Allocated Data » Result-Buffer Memory Management


ZWSoft ZRX for ZWCAD: Developer Guide: Entity Lists with DXF Codes in ObjectARX

Entity Lists with DXF Codes in ObjectARX
Basic Interaction with ZWCAD » ZRX Global Utility Functions » Lists and Other Dynamically Allocated Data » Result-Buffer Memory Management

Use acutBuildList to construct an entity DXF list, and then use the acdbEntMake function to create an entity.

void GlobalUtilityFunction::EntMake()
{
struct resbuf* rbEnt;
ads_point point1={10,0,0};
ads_point point2={10,20,0};
rbEnt = acutBuildList(RTDXF0, _T("Line"), 10, point1, 11, point2,62, 1, RTNONE);
if (rbEnt != NULL)
{
if (acdbEntMake(rbEnt) != RTNORM)
{
acdbFail(_T("acdbEntMake fail."));
}
acutRelRb(rbEnt);
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: Command and Function Invocation Lists

Command and Function Invocation Lists
Basic Interaction with ZWCAD » ZRX Global Utility Functions » Lists and Other Dynamically Allocated Data » Result-Buffer Memory Management

The following code use acutBuildList and acedCmd function to create an circle.

void GlobalUtilityFunction::UseCmd()
{
struct resbuf *rb;
ads_point ptCenter = {10, 0, 0};
ads_real radius = 10;
rb = acutBuildList(RTSTR,_T("circle"),
RTPOINT, ptCenter,
RTREAL, radius,
RTNONE);
if (rb != NULL)
{
acedCmd(rb);
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: ZWCAD Command Prompt Standard

Modules
ZWCAD Command Prompt Standard
Basic Interaction with ZWCAD

Modules

CommandLine Interface

Detailed Description

Each command is performed by different functions, the input method is not the same, the command contains the parameters and subcommands vary widely, the following zwcad various orders for the implementation of a brief introduction.


ZWSoft ZRX for ZWCAD: Developer Guide: CommandLine Interface

Modules
CommandLine Interface
Basic Interaction with ZWCAD » ZWCAD Command Prompt Standard

Modules

General Format
Format for the Current Value Line
Format for the Command Line Prompt
Context Menu Population

Detailed Description

Users can use the command line to perform functional operations.
For example: Enter "Line" on the command line. Create a line through the prompts given at the command line

Command: LINE
Specify the first point: 0,0,0
Specify the next point or [Angle/Length/Undo]: 10,0,0
Specify the next point or [Angle/Length/Undo]:


ZWSoft ZRX for ZWCAD: Developer Guide: General Format

General Format
Basic Interaction with ZWCAD » ZWCAD Command Prompt Standard » CommandLine Interface

Commands can be entered using the cursor, mouse, digitizer, and keyboard. When the user executes a command, the system will prompt a further prompt, then, the user can follow the command line prompts, according to the steps to operate, you can complete the command.
Consensus of various symbols:
1. "/": Separate symbols, separate the different options in the command, each of the capital letters that abbreviation, you can directly type this letter to perform this option.
2. "<>": square brackets, this parentheses is the system default or the current option to be executed, if you do not meet the user's drawing requirements, enter the new value.
3. Press the [esc] key directly to exit the command.
4. After executing a command, use the Enter key


ZWSoft ZRX for ZWCAD: Developer Guide: Format for the Current Value Line

Format for the Current Value Line
Basic Interaction with ZWCAD » ZWCAD Command Prompt Standard » CommandLine Interface

The example shows the current value obtained from the system.

Command: TRIM
Current settings: ProjMode = UCS, EdgeMode = No extend
Select entities for cutting edge or <Select all>:
1 found
Select entities for cutting edge or <Select all>:
Select entity to trim, or press Shift and select entity to extend, or [Edge mode/Fence/Crossing/Projection/eRase/Undo]: Specify opposite corner:
Select entity to trim, or press Shift and select entity to extend, or [Edge mode/Fence/Crossing/Projection/eRase/Undo]: *cancel*


ZWSoft ZRX for ZWCAD: Developer Guide: Format for the Command Line Prompt

Modules
Format for the Command Line Prompt
Basic Interaction with ZWCAD » ZWCAD Command Prompt Standard » CommandLine Interface

Modules

Current Instruction
Descriptive Information
List of Options
Default Option

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: Current Instruction

Current Instruction
Basic Interaction with ZWCAD » ZWCAD Command Prompt Standard » CommandLine Interface » Format for the Command Line Prompt

The following example shows that the current instruction prompts the user for input radius information.

Command: CIRCLE
Specify the center point of circle or [3P/2P/Ttr (tangency tangency radius)]:
Specify circle radius or [Diameter]:10


ZWSoft ZRX for ZWCAD: Developer Guide: Descriptive Information

Descriptive Information
Basic Interaction with ZWCAD » ZWCAD Command Prompt Standard » CommandLine Interface » Format for the Command Line Prompt

The following example shows the Descriptive Information prompts like "(0.0 mm-2.11 mm)".

Command: -LAYER
Current layer: 0
Enter an option [?/New/Make/Set/Color/Ltype/LWeight/Print/ON/OFF/Freeze/Thaw/LOck/Unlock]: lw
Enter line weight (0.0 mm-2.11 mm) or [?] <Default>:?
Available Lineweights:
BYLAYER BYBLOCK Default
0.00 mm 0.05 mm 0.09 mm 0.13 mm 0.15 mm 0.18 mm
0.20 mm 0.25 mm 0.30 mm 0.35 mm 0.40 mm 0.50 mm
0.53 mm 0.60 mm 0.70 mm 0.80 mm 0.90 mm 1.00 mm
1.06 mm 1.20 mm 1.40 mm 1.58 mm 2.00 mm 2.11 mm
Enter line weight (0.0 mm-2.11 mm) or [?] <Default>:0.05


ZWSoft ZRX for ZWCAD: Developer Guide: List of Options

List of Options
Basic Interaction with ZWCAD » ZWCAD Command Prompt Standard » CommandLine Interface » Format for the Command Line Prompt

The following example shows list of options.
The format for options is as follows:

[Option1/oPtion2/opTion3...]

Command: -COLOR
Enter a default color [Truecolor/COlorbook] <yellow>: t
Please input Red, Green, Blue: 100,200,0


ZWSoft ZRX for ZWCAD: Developer Guide: Default Option

Default Option
Basic Interaction with ZWCAD » ZWCAD Command Prompt Standard » CommandLine Interface » Format for the Command Line Prompt

The following example shows Default Option.
"<>": square brackets, this parentheses is the system default or the current option to be executed, if you do not meet the user's drawing requirements, enter the new value.

Command: UCS
Currently in World UCS.
Specify origin of UCS or [?/Face/3point/Delete/OBject/Origin/Previous/Restore/Save/View/X/Y/Z/ZAxis/World] <World>: 3
Specify the new origin <0,0,0>:
Specify the point on positive X axis <1,0,0>: 10,10,0
Specify the point in X-Y plane with positive Y value <0,1,0>:


ZWSoft ZRX for ZWCAD: Developer Guide: Context Menu Population

Context Menu Population
Basic Interaction with ZWCAD » ZWCAD Command Prompt Standard » CommandLine Interface

The context (or right-click) menus can display candidate operation options.The user can operate via the context menu.


ZWSoft ZRX for ZWCAD: Developer Guide: Custom Objects

Modules
Custom Objects

Modules

Deriving from AcDbobject
Deriving from AcDbEntity
Using AcEdJig

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: Deriving from AcDbobject

Modules
Deriving from AcDbobject
Custom Objects

Modules

Header File
Source File

Detailed Description

This part introduce how to derive a custom class from AcDbObject.
if a custom class derive from AcDbObject it is a invisible object and In normal conditions uses for
store some information,finally we save the custom object in AcDbDictionary.
The following is sample code for store dwg Author name in dwg file.


ZWSoft ZRX for ZWCAD: Developer Guide: Header File

Header File
Custom Objects » Deriving from AcDbobject

The following code shows the class declaration for the new class DwgAuthor derived from AcDbObject: A custom class must override the following functions:
virtual Acad::ErrorStatus dxfOutFields(AcDbDxfFiler* pFiler) const;
virtual Acad::ErrorStatus dxfInFields(AcDbDxfFiler* pFiler);
virtual Acad::ErrorStatus dwgOutFields(AcDbDwgFiler* pFiler) const;
virtual Acad::ErrorStatus dwgInFields(AcDbDwgFiler* pFiler);
which are used for persistent storage of objects as well as for copying and undo operations.
GetDwgAuthor and SetDwgAuthor functions are provided for this data member "m_DwgAuthor" for store file Author name.

class DwgAuthor : public AcDbObject
{
public:
ACRX_DECLARE_MEMBERS(DwgAuthor);
DwgAuthor();
virtual ~DwgAuthor();
virtual Acad::ErrorStatus dxfOutFields(AcDbDxfFiler* pFiler) const;
virtual Acad::ErrorStatus dxfInFields(AcDbDxfFiler* pFiler);
virtual Acad::ErrorStatus dwgOutFields(AcDbDwgFiler* pFiler) const;
virtual Acad::ErrorStatus dwgInFields(AcDbDwgFiler* pFiler);
void SetDwgAuthor(AcString DwgAuthor);
AcString GetDwgAuthor() const;
private:
AcString m_DwgAuthor;
};


ZWSoft ZRX for ZWCAD: Developer Guide: Source File

Source File
Custom Objects » Deriving from AcDbobject

The following code shows the implementation for the new class DwgAuthor:

#define VERSION_DWGAUTHOR 1
ACRX_DXF_DEFINE_MEMBERS(DwgAuthor, AcDbObject,
AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
AcDbProxyObject::kNoOperation,
DWGAUTHOR, DWGAUTHOR);
DwgAuthor::DwgAuthor()
{
m_DwgAuthor = "";
}
DwgAuthor::~DwgAuthor()
{
}
Acad::ErrorStatus DwgAuthor::dwgInFields(AcDbDwgFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es;
// Call dwgInFields from AcDbObject
if ((es = AcDbObject::dwgInFields(pFiler)) != Acad::eOk) {
return es;
}
// Read version number.
Adesk::UInt16 version;
pFiler->readItem(&version);
if (version > VERSION_DWGAUTHOR)
return Acad::eMakeMeProxy;
// Read the data members.
switch (version)
{
case (1):
// TODO: here you can file datamembers not
ACHAR* pszBuf = NULL;
pFiler->readString(&pszBuf);
m_DwgAuthor = AcString(pszBuf);
delString(pszBuf);
break;
}
return pFiler->filerStatus();
}
Acad::ErrorStatus DwgAuthor::dwgOutFields(AcDbDwgFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es;
// Call dwgOutFields from AcDbObject
if ((es = AcDbObject::dwgOutFields(pFiler)) != Acad::eOk) {
return es;
}
// Write version number.
pFiler->writeItem((Adesk::UInt16) VERSION_DWGAUTHOR);
// Write the data members.
// TODO: here you can file datamembers not
pFiler->writeString((LPCTSTR)m_DwgAuthor);
return pFiler->filerStatus();
}
Acad::ErrorStatus DwgAuthor::dxfInFields(AcDbDxfFiler* pFiler)
{
assertWriteEnabled();
struct resbuf rb;
Acad::ErrorStatus es = AcDbObject::dxfInFields( pFiler );
if( Acad::eOk != es ) {
return es;
}
// Check that we are at the correct subclass data
if( !pFiler->atSubclassData( _T("DwgAuthor") ))
{
return Acad::eBadDxfSequence;
}
// Read version number.
pFiler->readItem(&rb);
if (rb.restype != AcDb::kDxfInt16) {
pFiler->pushBackItem();
pFiler->setError(Acad::eInvalidDxfCode,
_T("nError: expected object version group code %d"),
AcDb::kDxfInt16);
return pFiler->filerStatus();
} else {
Adesk::UInt16 version = rb.resval.rint;
if (version > VERSION_DWGAUTHOR)
return Acad::eMakeMeProxy;
}
pFiler->readItem(&rb);
if (rb.restype == AcDb::kDxfText)
{
m_DwgAuthor = AcString(rb.resval.rstring);
}
return pFiler->filerStatus();
}
Acad::ErrorStatus DwgAuthor::dxfOutFields(AcDbDxfFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es;
if ((es = AcDbObject::dxfOutFields(pFiler)) != Acad::eOk)
return es;
// Write subclass marker.
pFiler->writeItem(AcDb::kDxfSubclass, _T("DwgAuthor"));
// Write version number.
pFiler->writeItem(AcDb::kDxfInt16, (Adesk::UInt16) VERSION_DWGAUTHOR);
pFiler->writeString(AcDb::kDxfText, (LPCTSTR)m_DwgAuthor);
return es;
}
void DwgAuthor::SetDwgAuthor( AcString DwgAuthor)
{
assertWriteEnabled();
m_DwgAuthor = DwgAuthor;
}
AcString DwgAuthor::GetDwgAuthor() const
{
assertReadEnabled();
return m_DwgAuthor;
}
const CString DWG_AUTHOR_KEY = TEXT("DwgAuthor");
// This is command 'SETDwgAuthor'
void SetDwgAuthor()
{
ACHAR AuthorName[1024] = {0};
acedGetString(0,_T("input Dwg Author name�?quot;),AuthorName);
AcDbDictionary *pNameObjDict = NULL;
acdbHostApplicationServices()->workingDatabase()
->getNamedObjectsDictionary(pNameObjDict, AcDb::kForWrite);
AcDbObjectId dictObjId;
DwgAuthor *pDwgAuthor = new DwgAuthor();
pDwgAuthor->SetDwgAuthor(AuthorName);
pNameObjDict->setAt(DWG_AUTHOR_KEY, pDwgAuthor, dictObjId);
pDwgAuthor->close();
pNameObjDict->close();
}
// This is command 'GETDwgAuthor'
void GetDwgAuthor()
{
AcDbDictionary *pNameObjDict = NULL;
Acad::ErrorStatus es;
acdbHostApplicationServices()->workingDatabase()
->getNamedObjectsDictionary(pNameObjDict, AcDb::kForRead);
DwgAuthor *pDwgAuthor = NULL;
es = pNameObjDict->getAt(DWG_AUTHOR_KEY, (AcDbObject*&)pDwgAuthor, AcDb::kForRead);
pNameObjDict->close();
if (es == Acad::eKeyNotFound)
{
acutPrintf(TEXT("\nnot exist%s."), DWG_AUTHOR_KEY);
return;
}
acutPrintf(TEXT("\n Dwg Author is :"));
acutPrintf(pDwgAuthor->GetDwgAuthor());
pDwgAuthor->close();
}
void initApp()
{
// register a command with the ZWCAD command mechanism for edit this data member "m_DwgAuthor"
acedRegCmds->addCommand(_T("DwgAuthor"), _T("SetDwgAuthor"), _T("SetDwgAuthor"), ACRX_CMD_MODAL, SetDwgAuthor);
acedRegCmds->addCommand(_T("DwgAuthor"), _T("GetDwgAuthor"), _T("GetDwgAuthor"), ACRX_CMD_MODAL, GetDwgAuthor);
//Register a new custom class with the following code:
DwgAuthor::rxInit();
acrxBuildClassHierarchy();
}
void unloadApp()
{
acedRegCmds->removeGroup(_T("DwgAuthor"));
//Unregister a new custom class with the following code:
deleteAcRxClass(DwgAuthor::desc());
}


ZWSoft ZRX for ZWCAD: Developer Guide: Deriving from AcDbEntity

Modules
Deriving from AcDbEntity
Custom Objects

Modules

Custom Entity Data Base
Custom Entity UI

Detailed Description

All database objects with graphical representations are derived from AcDbEntity. If a class is derived from AcDbEntity,it is a visible object,In addition we can define it shape object ,snap points, grip points, and stretch points and so on. It is recommended that the data class and the operation be separated when building a custom entity, the advantage is that if a custom entity is present in the drawing,only need to the data class is provided and loaded to display the custom entity instead of the proxy class. If others want to operate a custom entity you can then provide and load the operation class, and if you want to create a custom drag sequence for your entity, you will implement your own AcEdJig, and we'll show you how to drag your custom entity in the next section.


ZWSoft ZRX for ZWCAD: Developer Guide: Custom Entity Data Base

Modules
Custom Entity Data Base
Custom Objects » Deriving from AcDbEntity

Modules

Header File
Source File

Detailed Description

This part introduce how to derive a custom class from Entity.


ZWSoft ZRX for ZWCAD: Developer Guide: Header File

Header File
Custom Objects » Deriving from AcDbEntity » Custom Entity Data Base

The following code shows the class declaration for the new class ZsdkSign derived from AcDbEntity.

class ZsdkSign :
public AcDbEntity
{
public:
ZsdkSign(void);
virtual ~ZsdkSign(void);
public:
ACRX_DECLARE_MEMBERS(ZsdkSign);
virtual Adesk::Boolean subWorldDraw(AcGiWorldDraw* pWd);
virtual Acad::ErrorStatus subExplode(AcDbVoidPtrArray& entitySet) const;
virtual void subList() const;
virtual Acad::ErrorStatus subGetGripPoints(
AcGePoint3dArray& gripPoints,
AcDbIntArray & osnapModes,
AcDbIntArray & geomIds) const;
virtual Acad::ErrorStatus subGetGripPoints(AcDbGripDataPtrArray& grips,
const double curViewUnitSize, const int gripSize,
const AcGeVector3d& curViewDir, const int bitflags) const;
virtual Acad::ErrorStatus subMoveGripPointsAt(const AcDbIntArray& indices,
const AcGeVector3d& offset);
virtual Acad::ErrorStatus subTransformBy(const AcGeMatrix3d& xform);
virtual Acad::ErrorStatus subGetClassID(CLSID* pClsid) const;
virtual Acad::ErrorStatus subGetGeomExtents(AcDbExtents&) const;
virtual Acad::ErrorStatus dwgInFields(AcDbDwgFiler* filer);
virtual Acad::ErrorStatus dwgOutFields(AcDbDwgFiler* filer) const;
virtual Acad::ErrorStatus dxfInFields(AcDbDxfFiler* filer);
virtual Acad::ErrorStatus dxfOutFields(AcDbDxfFiler* filer) const;
virtual AcGeVector3d normal() const;
virtual void setNormal(const AcGeVector3d v);
virtual AcGePoint3d center() const;
virtual void setCenter(const AcGePoint3d c);
virtual double radius() const;
virtual void setRadius(const double r);
virtual AcCmColor textTrueColor() const;
virtual void setTextTrueColor(const AcCmColor& color);
virtual AcString text() const;
virtual void setText(const AcString& t);
static void initCLSID();
private:
static bool s_bHasClsid;
static CLSID s_clsid; // COM wrapper's CLSID, for OPM exposure
AcGeVector3d mNormal;
AcGePoint3d mCenter;
double mRadius;
AcCmColor mTextColor;
AcString mText;
};


ZWSoft ZRX for ZWCAD: Developer Guide: Source File

Modules
Source File
Custom Objects » Deriving from AcDbEntity » Custom Entity Data Base

Modules

ZsdkSign
ZsdkDB

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: ZsdkSign

ZsdkSign
Custom Objects » Deriving from AcDbEntity » Custom Entity Data Base » Source File

The following code shows the implementation for the new class ZsdkSign:

ACRX_DXF_DEFINE_MEMBERS(ZsdkSign, AcDbEntity,
AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
AcDbProxyEntity::kTransformAllowed |
AcDbProxyEntity::kColorChangeAllowed |
AcDbProxyEntity::kLayerChangeAllowed,
ZSDKSIGN, SignDb|Product: ZRX Enabler for Sign Entity|Company: ZWSOFT|Website: www.zwcad.com
);
const double kCurrentVersionNumber = 1.0;
bool ZsdkSign::s_bHasClsid = false;
CLSID ZsdkSign::s_clsid;
ZsdkSign::ZsdkSign(void)
{
mNormal = AcGeVector3d::kZAxis;
mCenter = AcGePoint3d::kOrigin;
mRadius = 10;
mTextColor.setRGB(255, 255, 0);
mText = _T("A");
}
ZsdkSign::~ZsdkSign(void)
{
}
Acad::ErrorStatus ZsdkSign::dwgInFields(AcDbDwgFiler* filer)
{
assertWriteEnabled();
AcDbEntity::dwgInFields(filer);
// Read version number
double version;
filer->readItem(&version);
if (version > kCurrentVersionNumber)
{
return Acad::eMakeMeProxy;
}
filer->readItem(&mNormal);
filer->readItem(&mCenter);
filer->readItem(&mRadius);
Adesk::UInt32 color;
filer->readUInt32(&color);
mTextColor.setColor(color);
ACHAR* pszBuf = NULL;
filer->readString(&pszBuf);
setText(AcString(pszBuf));
delString(pszBuf);
AcGeScale3d sc;
filer->readScale3d(&sc);
filer->readItem(&sc);
return filer->filerStatus();
}
Acad::ErrorStatus ZsdkSign::dwgOutFields(AcDbDwgFiler* filer) const
{
assertReadEnabled();
AcDbEntity::dwgOutFields(filer);
filer->writeItem(kCurrentVersionNumber);
filer->writeItem(mNormal);
filer->writeItem(mCenter);
filer->writeItem(mRadius);
filer->writeItem(mTextColor.color());
filer->writeString((LPCTSTR)mText);
AcGeScale3d sc(0.5);
filer->writeScale3d(sc);
filer->writeItem(sc);
return filer->filerStatus();
}
Acad::ErrorStatus ZsdkSign::dxfInFields(AcDbDxfFiler* filer)
{
assertWriteEnabled();
struct resbuf rb;
AcGePoint3d center, mouthleftpt, mouthbottompt, mouthrightpt;
double radius;
Acad::ErrorStatus es = AcDbEntity::dxfInFields( filer );
if( Acad::eOk != es ) {
return es;
}
// Check that we are at the correct subclass data
//
if( !filer->atSubclassData( _T("ZsdkSign") ))
{
return Acad::eBadDxfSequence;
}
// First piece of data MUST be the version number
if( Acad::eOk != ( es = filer->readItem( &rb )))
{
return es;
}
if ( AcDb::kDxfReal != rb.restype )
{
return Acad::eMakeMeProxy;
}
// Check version first
if ( rb.resval.rreal > 1.0 )
{
return Acad::eMakeMeProxy;
}
// Set the normal's default value in case it's not in the
// DXF information coming in
//
mNormal = AcGeVector3d( 0, 0, 1 ); // set default value:
while( Acad::eOk == es ) {
if( Acad::eOk == ( es = filer->readItem( &rb ))) {
switch( rb.restype ) {
case AcDb::kDxfXCoord:
center.set( rb.resval.rpoint[X],
rb.resval.rpoint[Y],
rb.resval.rpoint[Z]);
setCenter( center );
break;
case AcDb::kDxfReal+1:
radius = rb.resval.rreal;
setRadius( radius );
break;
case AcDb::kDxfNormalX:
mNormal.set( rb.resval.rpoint[X],
rb.resval.rpoint[Y],
rb.resval.rpoint[Z]);
break;
case AcDb::kDxfColor:
{
filer->pushBackItem();
AcCmColor col;
col.dxfIn(filer);
setColor(col);
}
break;
case AcDb::kDxfText:
setText(AcString(rb.resval.rstring));
break;
}
}
}
return filer->filerStatus();
}
Acad::ErrorStatus ZsdkSign::dxfOutFields(AcDbDxfFiler* filer) const
{
assertReadEnabled();
AcDbEntity::dxfOutFields( filer );
filer->writeItem( AcDb::kDxfSubclass, _T("ZsdkSign") );
// Write version number
filer->writeItem( AcDb::kDxfReal, kCurrentVersionNumber );
filer->writeItem( AcDb::kDxfXCoord, center() );
filer->writeItem( AcDb::kDxfReal+1, radius() );
if( filer->includesDefaultValues()
|| mNormal != AcGeVector3d( 0, 0, 1 ))
{
filer->writeItem( AcDb::kDxfNormalX, mNormal );
}
AcCmColor col = textTrueColor();
col.dxfOut( filer );
filer->writeString( AcDb::kDxfText, (LPCTSTR)mText );
return filer->filerStatus();
}
bool funGripViewportDraw(ZcDbGripData* pThis, ZcGiViewportDraw* pWd,
const ZcDbObjectId& entId, ZcDbGripOperations::DrawType type,
ZcGePoint3d* imageGripPoint, int gripSize)
{
// Use this as a reference point to draw the custom grip
AcGePoint3d pt = pThis->gripPoint();
// Get the number of pixels per unit square
AcGePoint2d pixelArea;
pWd->viewport().getNumPixelsInUnitSquare(pt, pixelArea);
double gripWidth = 2.0 / pixelArea.x;
double offset = (gripSize * pixelArea.x) * 2.0;
// To draw the graphics use the various geometry methods
// To set attributes, acess the pVD->subEntityTraits()
//pWd->subEntityTraits().setColor(kYellow);
// Draw the grip
AcGePoint3d pts[4];
pts[0] = pt + AcGeVector3d(-1-offset,-1-offset,0);
pts[1] = pt + AcGeVector3d(1+offset,-1-offset,0);
pts[2] = pt + AcGeVector3d(1+offset,1+offset,0);
pts[3] = pt + AcGeVector3d(-1-offset,1+offset,0);
pWd->geometry().polygonEye(4,pts);
return true;
}
bool funGripWorldDraw(AcDbGripData* pThis, AcGiWorldDraw* pWd,
const AcDbObjectId& entId, AcDbGripOperations::DrawType type,
AcGePoint3d* imageGripPoint, double dGripSize)
{
AcGePoint3d pt = pThis->gripPoint();
// Draw the grip
AcGePoint3d pts[4];
pts[0] = pt + AcGeVector3d(-1,-1,0) * dGripSize;
pts[1] = pt + AcGeVector3d(1,-1,0)* dGripSize;
pts[2] = pt + AcGeVector3d(1,1,0)* dGripSize;
pts[3] = pt + AcGeVector3d(-1,1,0)* dGripSize;
pWd->geometry().polygon(4,pts);
return true;
}
Acad::ErrorStatus ZsdkSign::subGetGripPoints(AcDbGripDataPtrArray& grips,
const double curViewUnitSize, const int gripSize,
const AcGeVector3d& curViewDir, const int bitflags) const
{
AcGePoint3dArray gripPoints;
AcGePoint3d cen( center() );
AcGeVector3d xoff( radius(), 0, 0 );
AcGeVector3d yoff( 0, radius(), 0 );
gripPoints.append( cen + xoff );
gripPoints.append( cen + yoff );
gripPoints.append( cen - xoff );
gripPoints.append( cen - yoff );
for(int i = 0;i<gripPoints.length(); i++)
{
AcDbGripData* gdtemp = new AcDbGripData;
gdtemp->setGripPoint(gripPoints[i]);
gdtemp->setWorldDraw((GripWorldDrawPtr)funGripWorldDraw);
//gdtemp->setViewportDraw((GripViewportDrawPtr)funGripViewportDraw);
grips.append(gdtemp);
}
return eOk;
}
Adesk::Boolean ZsdkSign::subWorldDraw(AcGiWorldDraw* wd)
{
assertReadEnabled();
AcGiRegenType test = wd->regenType();
if (objectId().isValid())
{
acutPrintf(_T("\nWorldDraw is called."));
}
wd->subEntityTraits().setTrueColor(entityColor());
wd->subEntityTraits().setFillType(kAcGiFillNever);
wd->geometry().circle(center(), radius(), normal());
AcGePoint3dArray rectarray;
AcGePoint3d ptTemp;
double textHeight = radius() / 2;
double rectsidelen = textHeight * 1.1;
ptTemp = center();
ptTemp[X] += rectsidelen / 2;
ptTemp[Y] += rectsidelen / 2;
rectarray.append(ptTemp);
ptTemp[X] -= rectsidelen;
rectarray.append(ptTemp);
ptTemp[Y] -= rectsidelen;
rectarray.append(ptTemp);
ptTemp[X] += rectsidelen;
rectarray.append(ptTemp);
ptTemp[Y] += rectsidelen;
rectarray.append(ptTemp);
wd->geometry().polyline(5, rectarray.asArrayPtr(), &normal());
AcGePoint3dArray lineptarray;
lineptarray.append(rectarray[0]);
ptTemp = center() + (lineptarray[0] - center()).normalize() * radius();
lineptarray.append(ptTemp);
wd->geometry().polyline(2, lineptarray.asArrayPtr(), &normal());
lineptarray.removeAll();
lineptarray.append(rectarray[1]);
ptTemp = center() + (lineptarray[0] - center()).normalize() * radius();
lineptarray.append(ptTemp);
wd->geometry().polyline(2, lineptarray.asArrayPtr(), &normal());
lineptarray.removeAll();
lineptarray.append(rectarray[2]);
ptTemp = center() + (lineptarray[0] - center()).normalize() * radius();
lineptarray.append(ptTemp);
wd->geometry().polyline(2, lineptarray.asArrayPtr(), &normal());
lineptarray.removeAll();
lineptarray.append(rectarray[3]);
ptTemp = center() + (lineptarray[0] - center()).normalize() * radius();
lineptarray.append(ptTemp);
wd->geometry().polyline(2, lineptarray.asArrayPtr(), &normal());
AcDbMText* pText = new AcDbMText();
pText->setDatabaseDefaults();
pText->setNormal(normal());
pText->setContents(text());
pText->setTextHeight(textHeight);
pText->setColor(textTrueColor());
pText->setLocation(center());
pText->setAttachment(AcDbMText::kMiddleCenter);
pText->worldDraw(wd);
delete pText;
pText = NULL;
return Adesk::kTrue;
}
Acad::ErrorStatus ZsdkSign::subExplode(AcDbVoidPtrArray& entitySet) const
{
assertReadEnabled();
AcDbCircle *pCircle = new AcDbCircle( center(), normal(), radius() );
entitySet.append( pCircle );
AcDbLine *pLine = NULL;
AcGePoint3dArray rectarray;
AcGePoint3d ptTemp;
double textHeight = radius() / 2;
double rectsidelen = textHeight * 1.1;
ptTemp = center();
ptTemp[X] += rectsidelen / 2;
ptTemp[Y] += rectsidelen / 2;
rectarray.append(ptTemp);
ptTemp[X] -= rectsidelen;
rectarray.append(ptTemp);
ptTemp[Y] -= rectsidelen;
rectarray.append(ptTemp);
ptTemp[X] += rectsidelen;
rectarray.append(ptTemp);
ptTemp[Y] += rectsidelen;
rectarray.append(ptTemp);
pLine = new AcDbLine( rectarray[0], rectarray[1] );
entitySet.append( pLine );
pLine = new AcDbLine( rectarray[1], rectarray[2] );
entitySet.append( pLine );
pLine = new AcDbLine( rectarray[2], rectarray[3] );
entitySet.append( pLine );
pLine = new AcDbLine( rectarray[3], rectarray[0] );
entitySet.append( pLine );
AcGePoint3dArray lineptarray;
lineptarray.append(rectarray[0]);
ptTemp = center() + (lineptarray[0] - center()).normalize() * radius();
lineptarray.append(ptTemp);
pLine = new AcDbLine( lineptarray[0], lineptarray[1] );
entitySet.append( pLine );
lineptarray.removeAll();
lineptarray.append(rectarray[1]);
ptTemp = center() + (lineptarray[0] - center()).normalize() * radius();
lineptarray.append(ptTemp);
pLine = new AcDbLine( lineptarray[0], lineptarray[1] );
entitySet.append( pLine );
lineptarray.removeAll();
lineptarray.append(rectarray[2]);
ptTemp = center() + (lineptarray[0] - center()).normalize() * radius();
lineptarray.append(ptTemp);
pLine = new AcDbLine( lineptarray[0], lineptarray[1] );
entitySet.append( pLine );
lineptarray.removeAll();
lineptarray.append(rectarray[3]);
ptTemp = center() + (lineptarray[0] - center()).normalize() * radius();
lineptarray.append(ptTemp);
pLine = new AcDbLine( lineptarray[0], lineptarray[1] );
entitySet.append( pLine );
AcDbMText* pText = new AcDbMText();
pText->setDatabaseDefaults();
pText->setNormal(normal());
pText->setContents(text());
pText->setTextHeight(textHeight);
pText->setColor(textTrueColor());
pText->setLocation(center());
pText->setAttachment(AcDbMText::kMiddleCenter);
entitySet.append( pText );
return Acad::eOk;
}
void ZsdkSign::subList() const
{
assertReadEnabled();
AcGePoint3d cen(center());
AcDbEntity::subList();
acutPrintf(
_T("%12scenter point, X=%9.16q0 Y=%9.16q0 Z=%9.16q0\n")
_T("%11s radius %9.16q0\n"),
_T(""), cen[X], cen[Y], cen[Z],
_T(""), radius()
);
}
Acad::ErrorStatus ZsdkSign::subGetGripPoints(AcGePoint3dArray& gripPoints,
AcDbIntArray& osnapModes,
AcDbIntArray& geomIds) const
{
assertReadEnabled();
AcGePoint3d cen( center() );
gripPoints.append( cen );
AcGeVector3d xoff( radius(), 0, 0 );
AcGeVector3d yoff( 0, radius(), 0 );
gripPoints.append( cen + xoff );
gripPoints.append( cen + yoff );
gripPoints.append( cen - xoff );
gripPoints.append( cen - yoff );
return Acad::eOk;
}
Acad::ErrorStatus ZsdkSign::subMoveGripPointsAt(const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
assertWriteEnabled();
AcGePoint3dArray eyearray;
AcGePoint3d oldquad, newquad;
for( int i = 0; i < indices.length(); i++ )
{
int idx = indices[i];
switch( idx )
{
case 0:
setCenter( center() + offset );
continue;
break;
case 1:
oldquad = center() + AcGeVector3d( radius(), 0, 0 );
break;
case 2:
oldquad = center() + AcGeVector3d( 0, radius(), 0 );
break;
case 3:
oldquad = center() - AcGeVector3d( radius(), 0, 0 );
break;
case 4:
oldquad = center() - AcGeVector3d( 0, radius(), 0 );
break;
}
newquad = oldquad + offset;
setRadius( newquad.distanceTo( center() ));
}
return Acad::eOk;
}
Acad::ErrorStatus ZsdkSign::subTransformBy(const AcGeMatrix3d& xform)
{
assertWriteEnabled();
setCenter(center().transformBy(xform));
return Acad::eOk;
}
Acad::ErrorStatus ZsdkSign::subGetGeomExtents( AcDbExtents& ) const
{
return eOk;
}
Acad::ErrorStatus ZsdkSign::subGetClassID(CLSID* pClsid) const
{
assertReadEnabled();
if (s_bHasClsid)
{
*pClsid = s_clsid;
return Acad::eOk;
}
else
{
return Acad::eNotImplementedYet;
}
}
void ZsdkSign::initCLSID()
{
s_bHasClsid = SUCCEEDED(CLSIDFromProgID(L"SignDb.Entity", &s_clsid));
if (!s_bHasClsid)
{
HMODULE hModule = GetModuleHandle(_T("SignDb.zrx"));
TCHAR szBuf[MAX_PATH] = {0};
::GetModuleFileName(hModule, szBuf, MAX_PATH);
_tcscpy(szBuf + _tcslen(szBuf) - _tcslen(_T("SignDb.zrx")), _T("SignDbCom.dll"));
HMODULE hMod = ::LoadLibrary(szBuf);
if (hMod)
{
typedef HRESULT (WINAPI *SETUP)(void);
SETUP pSetUp = (SETUP)GetProcAddress(hMod, "SetUp");
if (pSetUp)
{
pSetUp();
s_bHasClsid = SUCCEEDED(CLSIDFromProgID(L"SignDb.Entity", &s_clsid));
}
::FreeLibrary(hMod);
}
}
}
//If you want to learn more about "SignDbCom.dll" you can check out the SignDbCom project in the samples/Sign example.
AcGeVector3d ZsdkSign::normal() const
{
assertReadEnabled();
return mNormal;
}
void ZsdkSign::setNormal(const AcGeVector3d v)
{
assertWriteEnabled();
mNormal = v;
recordGraphicsModified();
}
AcGePoint3d ZsdkSign::center() const
{
assertReadEnabled();
return mCenter;
}
void ZsdkSign::setCenter(const AcGePoint3d c)
{
assertWriteEnabled();
mCenter = c;
recordGraphicsModified();
}
double ZsdkSign::radius() const
{
assertReadEnabled();
return mRadius;
}
void ZsdkSign::setRadius(const double r)
{
assertWriteEnabled();
mRadius = r;
recordGraphicsModified();
}
AcCmColor ZsdkSign::textTrueColor() const
{
assertReadEnabled();
return mTextColor;
}
void ZsdkSign::setTextTrueColor(const AcCmColor& color)
{
assertWriteEnabled();
mTextColor = color;
recordGraphicsModified();
}
AcString ZsdkSign::text() const
{
assertReadEnabled();
return mText;
}
void ZsdkSign::setText(const AcString& t)
{
assertWriteEnabled();
if (t.length() > 1)
mText = t.mid(0, 1);
else
mText = t;
recordGraphicsModified();
}


ZWSoft ZRX for ZWCAD: Developer Guide: ZsdkDB

ZsdkDB
Custom Objects » Deriving from AcDbEntity » Custom Entity Data Base » Source File

The following code shows the registration and initialization of the new class ZsdkSign:

#include "stdafx.h"
#include "ZsdkSign.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#ifndef ZSDKSIGNDB_SERVICE
#define ZSDKSIGNDB_SERVICE _T("ZSDKSIGNDB_SERVICE")
#endif
void initApp();
void unloadApp();
void RegisterZrxApp();
// ZRX EntryPoint
extern "C" AcRx::AppRetCode
zcrxEntryPoint(AcRx::AppMsgCode msg, void* pkt)
{
switch (msg) {
case AcRx::kInitAppMsg:
// Comment out the following line if your
// application should be locked into memory
acrxDynamicLinker->unlockApplication(pkt);
acrxDynamicLinker->registerAppMDIAware(pkt);
initApp();
break;
case AcRx::kUnloadAppMsg:
unloadApp();
break;
}
return AcRx::kRetOK;
}
// Init this application. Register your
// reactors, custom classes...
void initApp()
{
//Register a new custom class with the following code:
ZsdkSign::rxInit();
acrxBuildClassHierarchy();
acrxRegisterService(ZSDKSIGNDB_SERVICE);
RegisterZrxApp();
ZsdkSign::initCLSID();
}
// Unload this application. Unregister all objects
// registered in initApp.
void unloadApp()
{
//Unregister a new custom class with the following code:
deleteAcRxClass(ZsdkSign::desc());
delete acrxServiceDictionary->remove(ZSDKSIGNDB_SERVICE);
}
//----- Register the Application in the ZWCAD registry (demand loading)
// This function registers this ZRX Application
// on ZWCAD for demandload and in the
// Windows Registry.
void RegisterZrxApp()
{
// Fill the AppInfo structure with our demand loading details.
AcadAppInfo appInfo;
appInfo.setAppName(_T("SignDb"));// AppName
// Get the DBX file path.
HMODULE hModule = GetModuleHandle(_T("SignDb.zrx"));
TCHAR modulePath[512];
DWORD pathLength = GetModuleFileName(hModule, modulePath, 512);
if (pathLength)
appInfo.setModuleName(modulePath); // Set the DBX file path.
appInfo.setAppDesc(_T("SignDb Sample"));// Description
appInfo.setLoadReason(
AcadApp::LoadReasons(// Specify when we want this app to load.
AcadApp::kOnProxyDetection |
AcadApp::kOnLoadRequest));
appInfo.writeToRegistry(true,true);// Write the AppInfo to the registry, include the DBX registry section.
}


ZWSoft ZRX for ZWCAD: Developer Guide: Custom Entity UI

Custom Entity UI
Custom Objects » Deriving from AcDbEntity

The following code shows the implementation for Register the command to create a custom entity.
If you want to learn more about "JigSign"command you can check out the next chapter"Using AcEdJig".

extern void JigSign();
void initApp();
void unloadApp();
void RegisterZrxApp();
// ZRX EntryPoint
extern "C" AcRx::AppRetCode
zcrxEntryPoint(AcRx::AppMsgCode msg, void* pkt)
{
AcRxDynamicLinker *pLinker = acrxDynamicLinker;
switch (msg) {
case AcRx::kInitAppMsg:
// Comment out the following line if your
// application should be locked into memory
pLinker->unlockApplication(pkt);
pLinker->registerAppMDIAware(pkt);
// check if the zrx app is loaded or not.
// if not, load it as UI so that we won't have
// proxy if this dll is unloaded by OS
if (!::acrxAppIsLoaded(_T("SignDb.zrx")))
{
if (!pLinker->loadModule(_T("SignDb.zrx"), false, true))
return AcRx::kRetError;
}
// bump the reference count
pLinker->loadModule(_T("SignDb.zrx"), false, false);
initApp();
break;
case AcRx::kUnloadAppMsg:
pLinker->unloadModule(_T("SignDb.zrx"));
unloadApp();
break;
}
return AcRx::kRetOK;
}
void sign()
{
ZsdkSign* pSign = (ZsdkSign*)ZsdkSign::desc()->create();
pSign->setDatabaseDefaults();
pSign->setCenter(AcGePoint3d::kOrigin);
pSign->setNormal(AcGeVector3d::kZAxis);
pSign->setRadius(50);
pSign->setText(_T("TEST"));
AcDbBlockTable *pBlockTable;
acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBlockTable, AcDb::kForRead);
AcDbBlockTableRecord *pBlockTableRecord;
pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite);
pBlockTable->close();
AcDbObjectId lineId;
ErrorStatus es = pBlockTableRecord->appendAcDbEntity(lineId, pSign);
pBlockTableRecord->close();
acutPrintf(_T("\nBefore close."));
pSign->close();
}
// Init this application. Register your
// commands, reactors...
void initApp()
{
acedRegCmds->addCommand(_T("JIGSIGN"), _T("JIGSIGN"), _T("JIGSIGN"), ACRX_CMD_MODAL, JigSign);
acedRegCmds->addCommand(_T("ZSDK_SIGN"), _T("ZSDK_SIGN"), _T("SIGN"), ACRX_CMD_MODAL, sign);
RegisterZrxApp();
//InitAcUiDLL();
}
// Unload this application. Unregister all objects
// registered in initApp.
void unloadApp()
{
acedRegCmds->removeGroup(_T("ZSDK_SIGN"));
}
void RegisterZrxApp()
{
// Fill the AppInfo structure with our demand loading details.
AcadAppInfo appInfo;
appInfo.setAppName(_T("SignUi"));// Application Name
appInfo.setModuleName(acedGetAppName());// ZRX File Location
appInfo.setAppDesc(_T("SignUi Sample")); // Description
appInfo.setLoadReason( // Specify when we want this to load
AcadApp::LoadReasons(
AcadApp::kOnCommandInvocation |
AcadApp::kOnLoadRequest));
appInfo.writeToRegistry(false,true);// Write the AppInfo to the registry, don't write to DBX registry section.
appInfo.writeGroupNameToRegistry(_T("ZSDK_SIGN")); // Write the Group Name
appInfo.writeCommandNameToRegistry(_T("SIGN"),_T("SIGN"));// Write our command.
}


ZWSoft ZRX for ZWCAD: Developer Guide: Using AcEdJig

Modules
Using AcEdJig
Custom Objects

Modules

Header File
Source File

Detailed Description

This part introduce how to create a custom drag sequence for your entity.


ZWSoft ZRX for ZWCAD: Developer Guide: Header File

Header File
Custom Objects » Using AcEdJig

The following code shows the class declaration for the new class SignJig derived from AcEdJig:

class SignJig :
public AcEdJig
{
public:
SignJig(const AcGePoint3d&, const AcGeVector3d&);
virtual ~SignJig(void);
public:
void start();
AcDbEntity* entity() const;
DragStatus sampler();
Adesk::Boolean update();
private:
ZsdkSign* mpSign;
double mRadius;
};


ZWSoft ZRX for ZWCAD: Developer Guide: Source File

Source File
Custom Objects » Using AcEdJig

The following code shows the implementation for the new class SignJig to create custom entity:

ACRX_DEFINE_MEMBERS(ZsdkSign);
SignJig::SignJig(const AcGePoint3d& center, const AcGeVector3d& normal)
{
mpSign = (ZsdkSign*)ZsdkSign::desc()->create();
mpSign->setDatabaseDefaults();
mpSign->setCenter(center);
mpSign->setNormal(normal);
}
SignJig::~SignJig(void)
{
if (mpSign)
{
delete mpSign;
mpSign = NULL;
}
}
void SignJig::start()
{
setDispPrompt(_T("\nRadius: "));
AcEdJig::DragStatus stat = drag();
if (kNormal == stat)
{
append();
}
else
{
delete mpSign;
}
mpSign = NULL;
}
AcEdJig::DragStatus SignJig::sampler()
{
double dist;
setUserInputControls((UserInputControls)(kAccept3dCoordinates | kGovernedByOrthoMode | kDontUpdateLastPoint));
DragStatus stat = acquireDist(dist, mpSign->center());
if (kNormal == stat)
{
if (0.0 >= dist)
{
stat = kOther;
}
else
{
// save new radius for later update of our entity
if (dist != mRadius)
mRadius = dist;
else
stat = kNoChange;
}
}
return stat;
}
Adesk::Boolean SignJig::update()
{
mpSign->setRadius(mRadius);
return Adesk::kTrue;
}
AcDbEntity * SignJig::entity() const
{
return mpSign;
}
void JigSign()
{
AcGePoint3d cen;
struct resbuf rbFrom, rbTo;
ads_getpoint(NULL, _T("\nCenter point: "), asDblArray(cen));
rbFrom.restype = RTSHORT;
rbFrom.resval.rint = 1; // from UCS
rbTo.restype = RTSHORT;
rbTo.resval.rint = 0; // to WCS
ads_trans(asDblArray(cen), &rbFrom, &rbTo, Adesk::kFalse, asDblArray(cen));
AcGeVector3d x = acdbHostApplicationServices()->workingDatabase()->ucsxdir();
AcGeVector3d y = acdbHostApplicationServices()->workingDatabase()->ucsydir();
AcGeVector3d normal = x.crossProduct(y);
normal.normalize();
SignJig jig(cen, normal);
jig.start();
}


ZWSoft ZRX for ZWCAD: Developer Guide: Advanced Topics

Modules
Advanced Topics

Modules

Table Linking
Notification
The Multiple Document Interface
Transaction Management
Deep Cloning
Protocol Extension
Input Point Processing
Application Configuration

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: Table Linking

Modules
Table Linking
Advanced Topics

Modules

Data Links
Table Content

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: Data Links

Data Links
Advanced Topics » Table Linking

The following example demonstrates to link a table data to an excel spreadsheet.
Warning : there are some related interfaces are not implemented so this feature is temporarily unavailable.

void DataLinkSample()
{
AcDbTable *pTbl = NULL;
AcDbObjectId pEntId;
ads_name en;
ads_point pt;
if (acedEntSel(_T("\nPlease select a table: "), en, pt)
!= RTNORM)
{
acutPrintf(_T("Nothing Selected\n"));
return;
}
acdbGetObjectId(pEntId, en);
acdbOpenObject(pTbl, pEntId, AcDb::kForWrite);
if(NULL == pTbl)
{
acutPrintf(_T("\n Selected entity was not a table!"));
return;
}
struct resbuf *result;
int rc;
if ( (result = acutNewRb(RTSTR)) == NULL)
{
pTbl->close();
acutPrintf(_T("\nError!"));
return;
}
result->resval.rstring=NULL;
rc = acedGetFileD(_T("Excel File"),
_T("c:/test"),
_T("xlsx;xls"),
16,
result);
if (rc != RTNORM)
{
pTbl->close();
acutPrintf(_T("\nError in selecting an EXCEL file!"));
return;
}
ACHAR fileName[MAX_PATH];
_tcscpy(fileName, result->resval.rstring);
rc = acutRelRb(result);
static ACHAR sMyDataLink[MAX_PATH] = _T("DataLinkSample");
Acad::ErrorStatus es;
AcDbDataLinkManager* pDlMan = acdbHostApplicationServices()->workingDatabase()->getDataLinkManager();
assert(pDlMan);
AcDbObjectId idDL;
AcDbDataLink *pDL = NULL;
if( pDlMan->getDataLink(sMyDataLink, pDL, AcDb::kForRead) == Acad::eOk && pDL)
{
pDL->close();
es = pDlMan->removeDataLink(sMyDataLink, idDL);
if( es != Acad::eOk )
{
pTbl->close();
acutPrintf(_T("\nError in removing the Data Link!"));
return;
}
}
es = pDlMan->createDataLink(_T("ZwExcel"), sMyDataLink, _T("data link test."), fileName, idDL);
if( es != Acad::eOk )
{
pTbl->close();
acutPrintf(_T("\nError in creating Data Link!"));
return;
}
es = acdbOpenObject<AcDbDataLink>(pDL, idDL, AcDb::kForWrite);
if ( es != Acad::eOk || !pDL )
{
pTbl->close();
acutPrintf(_T("\nError in opening the Data Link object!"));
return;
}
es = pDL->setOption(AcDb::kDataLinkOptionPersistCache);
es = pDL->setUpdateOption(pDL->updateOption() | AcDb::kUpdateOptionAllowSourceUpdate);
pDL->close();
es = pTbl->setDataLink(1, 0, idDL, true);
if( es != Acad::eOk )
{
pTbl->close();
acutPrintf(_T("\nError in setting Data Link to the selected table!"));
return;
}
es = pTbl->close();
}


ZWSoft ZRX for ZWCAD: Developer Guide: Table Content

Table Content
Advanced Topics » Table Linking

The following example demonstrates to create a table template use selected table.
Then newly created table will have the same structure, formatting, and overrides as the template.

void createTableTemplate()
{
Acad::ErrorStatus es;
AcDbTable *pTbl = NULL;
AcDbObjectId pEntId;
ads_name en;
ads_point pt;
if (acedEntSel(_T("\nPlease select a table for get table style: "), en, pt)
!= RTNORM)
{
acutPrintf(_T("Nothing Selected\n"));
return;
}
acdbGetObjectId(pEntId, en);
acdbOpenObject(pTbl, pEntId, AcDb::kForWrite);
if(NULL == pTbl)
{
acutPrintf(_T("\n Selected entity was not a table!"));
return;
}
static ACHAR sTableTemplate[MAX_PATH] = _T("TableTemplate");
static ACHAR sTableStyle[MAX_PATH] = _T("TableStyle");
AcDbTableTemplate* pTblTpl = new AcDbTableTemplate();
es = pTblTpl->capture(pTbl, AcDb::kTableCopySkipContent);
es = pTblTpl->setName(sTableTemplate);
AcDbTableStyle* pTblSty = new AcDbTableStyle();
AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase();
assert(pDb);
AcDbDictionary *pDict = NULL;
es = acdbHostApplicationServices()->workingDatabase()->getTableStyleDictionary(pDict,AcDb::kForRead);
if(pDict->has(sTableStyle))
{
es = pDict->upgradeOpen();
es = pDict->remove(sTableStyle);
}
AcDbObjectId id1;
es = pDict->upgradeOpen();
if(Acad::eOk != (es = pDict->setAt(sTableStyle,pTblSty,id1)))
{
pDict->close();
delete pTblSty;
delete pTblTpl;
es = pTbl->close();
acutPrintf(_T("\nUnable to add new Table Style"));
return;
}
es = pDict->close();
assert(es == Acad::eOk);
AcDbObjectId id2;
es = pTblSty->setTemplate(pTblTpl, AcDb::kMergeCellStyleNone, id2);
if( es != Acad::eOk )
{
delete pTblTpl;
pTblSty->close();
pTbl->close();
acutPrintf(_T("\nError in setting data table template!"));
return;
}
es = pTblSty->close();
es = pTblTpl->close();
es = pTbl->close();
}


ZWSoft ZRX for ZWCAD: Developer Guide: Notification

Modules
Notification
Advanced Topics

Modules

Creating an Editor Reactor
Creating a Database Reactor
Creating an Object Reactor
Using a Reactor

Detailed Description

create reactor


ZWSoft ZRX for ZWCAD: Developer Guide: Creating an Editor Reactor

Creating an Editor Reactor
Advanced Topics » Notification

The following code creates a reactor derived from AcEditorReactor to print the name of events.

class EditorReactor : public AcEditorReactor
{
public:
virtual void dwgFileOpened(ZcDbDatabase*, ZTCHAR* fileName)
{
acutPrintf(_T("\nAcEditorReactor: dwgFileOpened"));
}
virtual void commandWillStart(const ZTCHAR* cmdStr)
{
acutPrintf(_T("\nAcEditorReactor: commandWillStart(%s)"),cmdStr);
}
virtual void commandEnded(const ZTCHAR* cmdStr)
{
acutPrintf(_T("\nAcEditorReactor: commandEnded(%s)"),cmdStr);
}
static EditorReactor *getEditorReactor()
{
if(m_editorReactor == NULL)
{
m_editorReactor = new EditorReactor();
}
return m_editorReactor;
}
private:
EditorReactor(){};
static EditorReactor *m_editorReactor;
};
EditorReactor * EditorReactor::m_editorReactor = NULL;


ZWSoft ZRX for ZWCAD: Developer Guide: Creating a Database Reactor

Creating a Database Reactor
Advanced Topics » Notification

The following example creates a reactor derived from AcDbDatabaseReactor to counts the number of objects and print whether the object is a circle when the object was appended.

class DBReactor : public AcDbDatabaseReactor
{
public:
virtual void objectAppended(const AcDbDatabase* dwg, const AcDbObject* dbObj)
{
acutPrintf(_T("\nAcDbDatabaseReactor: objectAppended"));
m_entCount++;
if(dbObj->isKindOf(AcDbCircle::desc()))
{
acutPrintf(_T("\nIt is a circle."));
}
else
{
acutPrintf(_T("\nIt is not a circle."));
}
acutPrintf(_T("\nThe number of entities: %d"),m_entCount);
}
virtual void objectOpenedForModify(const AcDbDatabase* dwg, const AcDbObject* dbObj)
{
acutPrintf(_T("\nAcDbDatabaseReactor: objectOpenedForModify"));
}
virtual void objectErased(const ZcDbDatabase* dwg, const ZcDbObject* dbObj, ZSoft::Boolean bErased)
{
acutPrintf(_T("\nAcDbDatabaseReactor: objectErased"));
if(bErased == Adesk::kTrue)
{
m_entCount--;
acutPrintf(_T("\nThe number of entities: %d"),m_entCount);
}
else
{
m_entCount++;
acutPrintf(_T("\nThe number of entities: %d"),m_entCount);
}
}
static DBReactor *getDBReactor()
{
if(m_dbReactor == NULL)
{
m_dbReactor = new DBReactor();
}
return m_dbReactor;
}
private:
DBReactor(){};
static DBReactor *m_dbReactor;
static int m_entCount;
};
DBReactor * DBReactor::m_dbReactor = NULL;
int DBReactor::m_entCount = 0;


ZWSoft ZRX for ZWCAD: Developer Guide: Creating an Object Reactor

Creating an Object Reactor
Advanced Topics » Notification

The following code creates a reactor derived from AcDbObjectReactor to print when a object was erased or unerased.

class ObjectReactor : public AcDbObjectReactor
{
public:
virtual void erased(const ZcDbObject* dbObj, ZSoft::Boolean pErasing )
{
if(pErasing == Adesk::kTrue)
{
acutPrintf(_T("\nObjectReactor: erased"));
}
else
{
acutPrintf(_T("\nObjectReactor: unerased"));
}
}
static ObjectReactor *getObjectReactor()
{
if(m_objReactor == NULL)
{
m_objReactor = new ObjectReactor();
}
return m_objReactor;
}
private:
ObjectReactor(){};
static ObjectReactor *m_objReactor;
};
ObjectReactor * ObjectReactor::m_objReactor = NULL;


ZWSoft ZRX for ZWCAD: Developer Guide: Using a Reactor

Using a Reactor
Advanced Topics » Notification

When you want to use a reactor, you can create an instance of the custom reactor class, and then add the reactor to the database. And you can remove it when you don't want to use the reactor anymore.
The createReactor() function shows how to add the reactors. The clearReactor() removes the reactors and deletes them.

void createReactor()
{
//Using AcEditorReactor
EditorReactor *editorReactor = EditorReactor::getEditorReactor();
acedEditor->addReactor(editorReactor);
//Using AcDbDatabaseReactor
DBReactor *dbReactor = DBReactor::getDBReactor();
acdbHostApplicationServices()->workingDatabase()->addReactor(dbReactor);
//Using AcDbObjectReactor
ObjectReactor *objReactor = ObjectReactor::getObjectReactor();
AcGePoint3d ptStart(0,0,0);
AcGePoint3d ptEnd(100,100,0);
AcDbLine *pLine = new AcDbLine(ptStart,ptEnd);
AcDbBlockTable *pBlockTable;
acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlockTable,AcDb::kForRead);
AcDbBlockTableRecord *pBlockTableRecord;
pBlockTable->getAt(ACDB_MODEL_SPACE,pBlockTableRecord,AcDb::kForWrite);
pBlockTableRecord->appendAcDbEntity(lineId,pLine);
pLine->addReactor(objReactor);
pLine->close();
pBlockTableRecord->close();
pBlockTable->close();
}
void clearReactor()
{
//Clearing AcEditorReactor
EditorReactor *editorReactor = EditorReactor::getEditorReactor();
acedEditor->removeReactor(editorReactor);
delete editorReactor;
editorReactor = NULL;
//Clearing AcDbDatabaseReactor
DBReactor *dbReactor = DBReactor::getDBReactor();
acdbHostApplicationServices()->workingDatabase()->removeReactor(dbReactor);
delete dbReactor;
dbReactor = NULL;
//Clearing AcDbObjectReactor
ObjectReactor *objReactor = ObjectReactor::getObjectReactor();
AcDbLine *pLine;
acdbOpenObject(pLine,lineId,AcDb::kForWrite);
pLine->removeReactor(objReactor);
pLine->close();
delete objReactor;
objReactor = NULL;
}

Add a reactor by calling the function:

addReactor(pReactor);

Remove a reactor by calling the function:

removeReactor(pReactor);


ZWSoft ZRX for ZWCAD: Developer Guide: The Multiple Document Interface

The Multiple Document Interface
Advanced Topics

Platform support multiple document.
The graphic document is different from the graphics database.
The class corresponding to the graphics database is AcDbDatabase, and the class corresponding to the graphics document is AcApDocument.
Each open graph has an associated document object, the document object contains a lot of useful information,
such as file name, the CDocument object of MFC, the current graphics database, and the current file format.
Commands that work within the application context can create and switch documents, and commands that work within the document context can edit and modify the current document's graphics database.
This setion shows: how to have multiple drawings in a session.

When using "acedRegCmds->addCommand" to register a command, setting the parameter "ACRX_CMD_SESSION" to register commands running in the application context.

acedRegCmds->addCommand(_T("MDIDocument"),_T("CreateDraw"),_T("CreateDraw"),ACRX_CMD_SESSION, MDIDocument::CreateDraw,NULL,
-1,theArxDLL.ModuleResourceInstance());

When using "acedRegCmds->addCommand" to register a command, setting the parameter "ACRX_CMD_SESSION" to register commands running in the application context.

void MDIDocument::CreateDraw(void)
{
Acad::ErrorStatus es;
es = acDocManager->lockDocument(acDocManager->curDocument());
int count=0;
AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase();
if (pDb != NULL)
{
AcDbBlockTable* pBlockTable=NULL;
AcDbObjectId entId=AcDbObjectId::kNull;
Acad::ErrorStatus es=Acad::eOk;
es=pDb->getBlockTable(pBlockTable, AcDb::kForRead);
if (es==Acad::eOk)
{
AcDbBlockTableRecord* pBlockTableRecord=NULL;
es=pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite);
pBlockTable->close();
if (es==Acad::eOk)
{
AcDbBlockTableRecordIterator* blkIer=NULL;
AcDbEntity* ent=NULL;
es=pBlockTableRecord->newIterator(blkIer);
if (es==Acad::eOk)
{
for (blkIer->start(); !blkIer->done(); blkIer->step())
{
if (blkIer->getEntity(ent, AcDb::kForRead)==Acad::eOk)
{
count++;
}
ent->close();
}
}
delete blkIer;
pBlockTableRecord->close();
}
}
}
acDocManager->unlockDocument(acDocManager->curDocument());
es = acDocManager->appContextNewDocument(NULL);
if (es == Acad::eOk)
{
es = acDocManager->lockDocument(acDocManager->curDocument());
//add
pDb = acdbHostApplicationServices()->workingDatabase();
if (pDb != NULL)
{
AcDbBlockTable* pBlockTable=NULL;
AcDbObjectId entId=AcDbObjectId::kNull;
Acad::ErrorStatus es=Acad::eOk;
es=pDb->getBlockTable(pBlockTable, AcDb::kForRead);
if (es==Acad::eOk)
{
AcDbBlockTableRecord* pBlockTableRecord=NULL;
es=pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite);
pBlockTable->close();
if (es==Acad::eOk)
{
AcDbObjectId entId=AcDbObjectId::kNull;
for(int i=0; i<count; i++)
{
double y = i * 20;
AcGePoint3d startpoint(0, y, 0);
AcGePoint3d endpoint(100, y, 0);
AcDbLine* pLine=new AcDbLine(startpoint, endpoint);
es=pBlockTableRecord->appendZcDbEntity(entId, pLine);
if (es==Acad::eOk)
{
pLine->close();
}
}
pBlockTableRecord->close();
}
}
}
es = acDocManager->unlockDocument(acDocManager->curDocument());
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: Transaction Management

Transaction Management
Advanced Topics

This section describes the transaction model, which can be used to operate on objects.
In this model, multiple operations on multiple objects are grouped together into one atomic operation called a transaction.
Create some multiple objects and post it to the database.
Start Transaction 1: Create a line .
Start Transaction 2: Create a circle.
Start Transaction 3: Create a text.
Abort the transaction? Answer yes.
End Transaction 3.
End Transaction 2.
Note
If you abort at this point, Transactions 2 and 3 are both canceled. If you abort a containing transaction, all the nested transactions are aborted, even if they were successfully ended.
End Transaction 1.

Acad::ErrorStatus
getYOrN(TCHAR* promptStr, Adesk::Boolean defaultY, Adesk::Boolean& yes,Adesk::Boolean& interrupted)
{
TCHAR option[256];
yes = Adesk::kTrue;
acedInitGet(0, _T("Yes No"));
int as = acedGetKword(promptStr, option);
switch (as) {
case RTNORM:
if (_tcscmp(option, _T("Yes")) == 0)
yes = Adesk::kTrue;
else
yes = Adesk::kFalse;
break;
case RTNONE:
if (defaultY)
yes = Adesk::kTrue;
else
yes = Adesk::kFalse;
break;
case RTCAN:
interrupted = Adesk::kTrue;
break;
default:
break;
}
return Acad::eOk;
}
void testTransaction()
{
AcTransaction *pTrans
= actrTransactionManager->startTransaction();
assert(pTrans != NULL);
acutPrintf(_T("\n\n>>>>>> Started transaction one.")
_T(" <<<<<<\n"));
TCHAR option[256];
acedGetKword(_T("\nEnter any key to create a line."), option);
AcGePoint3d startPt(200 ,200, 0);
AcGePoint3d endPt(600, 200, 0);
AcDbLine *pLine = new AcDbLine(startPt, endPt);
AcDbBlockTable *pBlockTable1;
acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBlockTable1, AcDb::kForRead);
AcDbBlockTableRecord *pBlockTableRecord1;
pBlockTable1->getAt(ACDB_MODEL_SPACE, pBlockTableRecord1, AcDb::kForWrite);
pBlockTable1->close();
AcDbObjectId lineId;
pBlockTableRecord1->appendAcDbEntity(lineId, pLine);
pBlockTableRecord1->close();
pLine->close();
actrTransactionManager
->addNewlyCreatedDBRObject(pLine);
pLine->draw();
acutPrintf(_T("\nCreated a Line ")
_T(" the Line."));
pTrans = actrTransactionManager->startTransaction();
assert(pTrans != NULL);
acutPrintf(_T("\n\n>>>>> Started transaction two.")
_T(" <<<<<<\n"));
acedGetKword(_T("\nEnter any key to create a Circle."), option);
AcDbCircle* pCircle = new AcDbCircle(AcGePoint3d(400,200,0),AcGeVector3d(0,0,1),200);
AcDbBlockTable *pBlockTable;
acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBlockTable, AcDb::kForRead);
AcDbBlockTableRecord *pBlockTableRecord;
pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite);
pBlockTable->close();
AcDbObjectId circleId;
pBlockTableRecord->appendAcDbEntity(circleId, pCircle);
pBlockTableRecord->close();
pCircle->close();
actrTransactionManager
->addNewlyCreatedDBRObject(pCircle);
pCircle->draw();
acutPrintf(_T("\nCreated a Circle ")
_T(" the Circle."));
pTrans = actrTransactionManager->startTransaction();
assert(pTrans != NULL);
acutPrintf(_T("\n\n>>>>> Started transaction three.")
_T(" <<<<<<\n"));
acedGetKword(_T("\nEnter any key to create a text."), option);
AcGePoint3d ptInsert(220, 200, 0);
const ACHAR* text = _T("Hello World");
AcDbObjectId style = AcDbObjectId::kNull;
double height = 50;
double rotation = 0;
AcDbText *pText = new AcDbText(ptInsert, text, style, height, rotation);
AcDbBlockTable *pBlockTable2;
acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBlockTable2, AcDb::kForRead);
AcDbBlockTableRecord *pBlockTableRecord2;
pBlockTable2->getAt(ACDB_MODEL_SPACE, pBlockTableRecord2, AcDb::kForWrite);
pBlockTable2->close();
AcDbObjectId textId;
pBlockTableRecord2->appendAcDbEntity(textId, pText);
pBlockTableRecord2->close();
pText->close();
actrTransactionManager
->addNewlyCreatedDBRObject(pText);
pText->draw();
acutPrintf(_T("\nCreated a Text ")
_T(" the Text."));
Adesk::Boolean yes = Adesk::kTrue;
Adesk::Boolean interrupted;
yes = Adesk::kFalse;
if (getYOrN(_T("\nAbort transaction three? <No> : "),
Adesk::kFalse, yes,interrupted) == Acad::eOk
&& yes == Adesk::kTrue)
{
acutPrintf(_T("\n\n@@@@@ Aborting transaction")
_T(" three. @@@@@\n"));
actrTransactionManager->abortTransaction();
acutPrintf(_T("\nBack to the circle and line."));
} else {
acutPrintf(_T("\n\n&&&&& Ending transaction three.")
_T(" &&&&&\n"));
actrTransactionManager->endTransaction();
}
yes = Adesk::kFalse;
if (getYOrN(_T("\nAbort transaction two? <No> : "),
Adesk::kFalse, yes,interrupted) == Acad::eOk
&& yes == Adesk::kTrue)
{
acutPrintf(_T("\n\n@@@@@ Aborting transaction two.")
_T(" @@@@@@\n"));
actrTransactionManager->abortTransaction();
acutPrintf(_T("\nBack to circle"));
} else {
acutPrintf(_T("\n\n&&&&& Ending transaction two.")
_T(" &&&&&\n"));
actrTransactionManager->endTransaction();
}
yes = Adesk::kFalse;
if (getYOrN(_T("\nAbort transaction one? <No> : "),
Adesk::kFalse, yes,interrupted) == Acad::eOk
&& yes == Adesk::kTrue)
{
acutPrintf(_T("\n\n@@@@@ Aborting transaction one.")
_T(" @@@@@\n"));
actrTransactionManager->abortTransaction();
acutPrintf(_T("\nBack to nothing."));
} else {
actrTransactionManager->endTransaction();
acutPrintf(_T("\n\n&&&&& Ending transaction one.")
_T(" &&&&&\n"));
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: Deep Cloning

Deep Cloning
Advanced Topics

This part shows the deep clone functions, by using the deepCloneOjbects interface of AcDbDataBase.
Acad::ErrorStatus deepCloneObjects(AcDbObjectIdArray& objectIds,AcDbObjectId& owner,AcDbIdMapping& idMap,bool deferXlation = false);
ObjectIds
Enter an array of objects to be deeply cloned
Owner
Enter the object ID that is the object of the owner of the clone
IdMap
Returns an array of AcDbIdPair objects used to transform ID relations of objects
DeferXlation
Enter Boolean values to indicate whether to perform ID transformation

Clone all objects in the objectId array and add them to the container object specified by owner. IdMap stores the AcDbIdPair object, which contains the objectId entity of the original and cloned object pairs. AcDbIdPair. This array can be used to pre process objects contained in deep cloning operations. When all the objects to be cloned do not have the same host, a separate AcDbObjectIdArray entity must be established, each AcDbObjectIdArray entity containing objects with all the same host.

void DeepClone::CloneObject(void)
{
ads_name name;
acedSSGet(_T("A"), NULL, NULL, NULL, name);
long entCount;
acedSSLength(name, &entCount);
if (entCount < 1)
{
return ;
}
AcDbObjectIdArray entArr;
AcDbObjectId entID;
for (int i=0; i < entCount; i++)
{
ads_name entName;
acedSSName(name, i, entName);
acdbGetObjectId(entID, entName);
entArr.append(entID);
}
acedSSFree(name);
AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase();
if (pDb != NULL)
{
AcDbBlockTable* pBlockTable=NULL;
AcDbObjectId entId=AcDbObjectId::kNull;
Acad::ErrorStatus es=Acad::eOk;
es=pDb->getBlockTable(pBlockTable, AcDb::kForRead);
if (es==Acad::eOk)
{
AcDbObjectId pBlockTableRecord;
es=pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite);
pBlockTable->close();
if (es==Acad::eOk)
{
AcDbIdMapping entMap;
pDb->deepCloneObjects(entArr, pBlockTableRecord, entMap);
AcDbIdMappingIter entMapIt(entMap);
for (entMapIt.start(); !entMapIt.done(); entMapIt.next())
{
AcDbIdPair entPair;
entMapIt.getMap(entPair);
if (entPair.isCloned())
{
acutPrintf(_T("\nObjectID : %d"), entPair.value().asOldId());
}
}
}
}
}
}


ZWSoft ZRX for ZWCAD: Developer Guide: Protocol Extension

Protocol Extension
Advanced Topics

The following example demonstrates to create a protocol extension .
The implementation of the setcolor() function for the SETCOLOR command, which allows the user to select an entity and then set different color for that entity.
circle:set green
default:set blue
line:set red

#include <stdlib.h>
#include "rxobject.h"
#include "rxregsvc.h"
#include "rxdlinkr.h"
#include "rxditer.h"
#include "aced.h"
#include "adslib.h"
#include "dbents.h"
#include "dbregion.h"
#include "dbdict.h"
#include "dbsymtb.h"
#include "tchar.h"
void initApp();
void unloadApp();
extern "C"
AcRx::AppRetCode acrxEntryPoint(AcRx::AppMsgCode, void*);
class ZsdkEntSetColor : public AcRxObject
{
public:
ACRX_DECLARE_MEMBERS(ZsdkEntSetColor);
virtual Acad::ErrorStatus setColor(AcDbEntity*) const = 0;
};
ACRX_NO_CONS_DEFINE_MEMBERS(ZsdkEntSetColor, AcRxObject);
class ZsdkDefaultSetColor : public ZsdkEntSetColor
{
public:
virtual Acad::ErrorStatus setColor(AcDbEntity* pEnt) const;
};
Acad::ErrorStatus
ZsdkDefaultSetColor::setColor(
AcDbEntity* pEnt) const
{
acutPrintf(_T("\nDefault:set blue \n"));
return pEnt->setColorIndex(5);
}
class ZsdkLineSetColor : public ZsdkEntSetColor
//
// ZsdkEntSetColor implementation for Lines.
//
{
public:
virtual Acad::ErrorStatus setColor(AcDbEntity* pEnt) const;
};
Acad::ErrorStatus
ZsdkLineSetColor::setColor(
AcDbEntity* pEnt) const
{
AcDbLine *pLine = AcDbLine::cast(pEnt);
acutPrintf(_T("\nline:set red \n"));
return pLine->setColorIndex(1);
}
class ZsdkCircleSetColor : public ZsdkEntSetColor
//
// ZsdkEntSetColor implementation for circles.
{
public:
virtual Acad::ErrorStatus setColor(AcDbEntity* pEnt) const;
};
Acad::ErrorStatus
ZsdkCircleSetColor::setColor(
AcDbEntity* pEnt) const
{
AcDbCircle *pCircle = AcDbCircle::cast(pEnt);
acutPrintf(_T("\ncircle:set green \n"));
return pCircle->setColorIndex(3);
}
// This function has the user select an entity and then
// calls the setColor() function in the protocol
// extension class attached to that entity's class.
//
void
setcolor()
{
AcDbEntity *pEnt;
AcDbObjectId pEntId;
ads_name en;
ads_point pt;
if (acedEntSel(_T("\nSelect an Entity: "), en, pt)
!= RTNORM)
{
acutPrintf(_T("Nothing Selected\n"));
return;
}
acdbGetObjectId(pEntId, en);
acdbOpenObject(pEnt, pEntId, AcDb::kForWrite);
// call the protocol extension class's method
//
double eTemp = ACRX_X_CALL(pEnt,
ZsdkEntSetColor)->setColor(pEnt);
pEnt->close();
}
// Pointers for Protocol Extension Objects. These pointers
// are global so that they can be accessed during
// initialization *and* cleanup
//
ZsdkDefaultSetColor *pDefaultTemp;
ZsdkLineSetColor *pLineTemp;
ZsdkCircleSetColor *pCircleTemp;
void
initApp()
{
acrxRegisterService(_T("ZsdkSetColor"));
ZsdkEntSetColor::rxInit();
acrxBuildClassHierarchy();
pDefaultTemp = new ZsdkDefaultSetColor();
pLineTemp = new ZsdkLineSetColor();
pCircleTemp = new ZsdkCircleSetColor();
// Add the protocol extension objects to the appropriate
// AcRxClass objects
//
AcDbEntity::desc()->addX(ZsdkEntSetColor::desc(),
pDefaultTemp);
AcDbLine::desc()->addX(ZsdkEntSetColor::desc(),
pLineTemp);
AcDbCircle::desc()->addX(ZsdkEntSetColor::desc(),
pCircleTemp);
acedRegCmds->addCommand(_T("Zsdk_SetColor_APP"),
_T("Zsdk_SETCOLOR"), _T("setcolor"), ACRX_CMD_TRANSPARENT,
setcolor);
}
void
unloadApp()
{
delete acrxServiceDictionary->remove(_T("ZsdkSetColor"));
acedRegCmds->removeGroup(_T("Zsdk_SetColor_APP"));
AcDbEntity::desc()->delX(ZsdkEntSetColor::desc());
delete pDefaultTemp;
AcDbLine::desc()->delX(ZsdkEntSetColor::desc());
delete pLineTemp;
AcDbCircle::desc()->delX(ZsdkEntSetColor::desc());
delete pCircleTemp;
// Remove the ZsdkEntSetColor class from the ZRX
// runtime class hierarchy.
//
deleteAcRxClass(ZsdkEntSetColor::desc());
}
AcRx::AppRetCode
acrxEntryPoint(AcRx::AppMsgCode msg, void* appId)
{
switch (msg) {
case AcRx::kInitAppMsg:
acrxDynamicLinker->unlockApplication(appId);
acrxDynamicLinker->registerAppMDIAware(appId);
initApp();
break;
case AcRx::kUnloadAppMsg:
unloadApp();
}
return AcRx::kRetOK;
}


ZWSoft ZRX for ZWCAD: Developer Guide: Input Point Processing

Modules
Input Point Processing
Advanced Topics

Modules

Custom Object Snap Modes
Input Point Filters and Monitors
Input Context Events

Detailed Description

This part introduce a variety of input processing examples :Custom Object Snap Modes,Input Context Events,Input Point Filters and Input Point Monitors.


ZWSoft ZRX for ZWCAD: Developer Guide: Custom Object Snap Modes

Modules
Custom Object Snap Modes
Advanced Topics » Input Point Processing

Modules

Header File
Source File

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: Header File

Header File
Advanced Topics » Input Point Processing » Custom Object Snap Modes
class CustomOsnapInfo : public AcDbCustomOsnapInfo
{
public:
ACRX_DECLARE_MEMBERS(CustomOsnapInfo);
virtual Acad::ErrorStatus getOsnapInfo(
AcDbEntity* pickedObject,
Adesk::GsMarker gsSelectionMark,
const AcGePoint3d& pickPoint,
const AcGePoint3d& lastPoint,
const AcGeMatrix3d& viewXform,
AcArray<AcGePoint3d>& snapPoints,
AcDbIntArray & geomIdsForPts,
AcArray<AcGeCurve3d*>& snapCurves,
AcDbIntArray & geomIdsForLines);
};
class CustomOsnapForLine : public CustomOsnapInfo {
public:
virtual Acad::ErrorStatus getOsnapInfo(
AcDbEntity* pickedObject,
Adesk::GsMarker gsSelectionMark,
const AcGePoint3d& pickPoint,
const AcGePoint3d& lastPoint,
const AcGeMatrix3d& viewXform,
AcArray<AcGePoint3d>& snapPoints,
AcDbIntArray & geomIdsForPts,
AcArray<AcGeCurve3d*>& snapCurves,
AcDbIntArray & geomIdsForLines);
};
// Osnap mode glyph object
//
class CustomOsnapGlyph : public AcGiGlyph
{
public:
virtual Acad::ErrorStatus setLocation(const AcGePoint3d& dcsPoint);
#if _ZWCAD
virtual void viewportDraw(AcGiViewportDraw* vportDrawContext);
#else
virtual void subViewportDraw(AcGiViewportDraw* vportDrawContext);
#endif
private:
AcGePoint3d mCurDcsLoc;
};
CustomOsnapGlyph* pSocketGlyph = NULL;
class CustomOsnapMode : public AcDbCustomOsnapMode {
public:
virtual const ACHAR*
localModeString() const {return TEXT("line1/3");};
virtual const ACHAR*
globalModeString() const {return TEXT("line1/3");};
virtual const AcRxClass*
entityOsnapClass() const {return CustomOsnapInfo::desc();};
virtual AcGiGlyph*
glyph() const {return pSocketGlyph;};
virtual const ACHAR*
tooltipString() const {return TEXT("line1/3 point"); };
};


ZWSoft ZRX for ZWCAD: Developer Guide: Source File

Source File
Advanced Topics » Input Point Processing » Custom Object Snap Modes

The following example demonstrates creating a custom osnap mode to capture the one-third the length of a line.
Warning : There are some related interfaces are not implemented so this feature is temporarily unavailable.

ACRX_NO_CONS_DEFINE_MEMBERS(CustomOsnapInfo,AcDbCustomOsnapInfo);
Acad::ErrorStatus CustomOsnapInfo::getOsnapInfo(
AcDbEntity* pickedObject,
Adesk::GsMarker gsSelectionMark,
const AcGePoint3d& pickPoint,
const AcGePoint3d& lastPoint,
const AcGeMatrix3d& viewXform,
AcArray<AcGePoint3d>& snapPoints,
AcDbIntArray & geomIdsForPts,
AcArray<AcGeCurve3d*>& snapCurves,
AcDbIntArray & geomIdsForLines)
{
// Associate with AcDbEntity to define default behavior.
//
snapPoints.setLogicalLength(0);
geomIdsForPts.setLogicalLength(0);
snapCurves.setLogicalLength(0);
geomIdsForLines.setLogicalLength(0);
return Acad::eOk;
}
// Socket Osnap mode protocol extension object for AcDbLine.
//
Acad::ErrorStatus CustomOsnapForLine::getOsnapInfo(
AcDbEntity* pickedObject,
Adesk::GsMarker gsSelectionMark,
const AcGePoint3d& pickPoint,
const AcGePoint3d& lastPoint,
const AcGeMatrix3d& viewXform,
AcArray<AcGePoint3d>& snapPoints,
AcDbIntArray & geomIdsForPts,
AcArray<AcGeCurve3d*>& snapCurves,
AcDbIntArray & geomIdsForLines)
{
ASSERT(pickedObject->isKindOf(AcDbLine::desc()));
AcDbLine* lineEnt = (AcDbLine*)pickedObject;
AcGePoint3d point_1 = AcGePoint3d((lineEnt->endPoint().x + 2*lineEnt->startPoint().x)/3,
(lineEnt->endPoint().y + 2*lineEnt->startPoint().y)/3,0);
snapPoints.append(point_1);
AcGePoint3d point_2 = AcGePoint3d((2*lineEnt->endPoint().x + lineEnt->startPoint().x)/3,
(2*lineEnt->endPoint().y + lineEnt->startPoint().y)/3,0);
snapPoints.append(point_2);//set snap Points.
snapCurves.setLogicalLength(0);
geomIdsForLines.setLogicalLength(0);
return Acad::eOk;
}
Acad::ErrorStatus
CustomOsnapGlyph::setLocation(const AcGePoint3d& dcsPoint)
{
mCurDcsLoc = dcsPoint;
return Acad::eOk;
}
#if _ZWCAD
void
CustomOsnapGlyph::viewportDraw(AcGiViewportDraw* vportDrawContext)
#else
void
CustomOsnapGlyph::subViewportDraw(AcGiViewportDraw* vportDrawContext)
#endif
{
AcGePoint2d pixelArea;
ASSERT(!vportDrawContext->viewport().isPerspective());
vportDrawContext->viewport().getNumPixelsInUnitSquare(AcGePoint3d::kOrigin, pixelArea);
double halfGlyphSizeInDCS = acdbCustomOsnapManager()->osnapGlyphSize()/pixelArea.x ;
AcGePoint3d sSegmentPoints[2];
sSegmentPoints[0].set(
mCurDcsLoc.x-halfGlyphSizeInDCS,
mCurDcsLoc.y-halfGlyphSizeInDCS, 0.0);
sSegmentPoints[1].set(
mCurDcsLoc.x+halfGlyphSizeInDCS,
mCurDcsLoc.y+halfGlyphSizeInDCS, 0.0);
vportDrawContext->geometry().polylineDc(
2, &(sSegmentPoints[0]));
sSegmentPoints[0].set(
mCurDcsLoc.x-halfGlyphSizeInDCS,
mCurDcsLoc.y+halfGlyphSizeInDCS, 0.0);
sSegmentPoints[1].set(
mCurDcsLoc.x+halfGlyphSizeInDCS,
mCurDcsLoc.y-halfGlyphSizeInDCS, 0.0);
vportDrawContext->geometry().polylineDc(
2, &(sSegmentPoints[0]));
sSegmentPoints[0].set(
mCurDcsLoc.x-halfGlyphSizeInDCS,
mCurDcsLoc.y, 0.0);
sSegmentPoints[1].set(
mCurDcsLoc.x+halfGlyphSizeInDCS,
mCurDcsLoc.y, 0.0);
vportDrawContext->geometry().polylineDc(
2, &(sSegmentPoints[0]));
sSegmentPoints[0].set(
mCurDcsLoc.x,
mCurDcsLoc.y-halfGlyphSizeInDCS, 0.0);
sSegmentPoints[1].set(
mCurDcsLoc.x,
mCurDcsLoc.y+halfGlyphSizeInDCS, 0.0);
vportDrawContext->geometry().polylineDc(
2, &(sSegmentPoints[0]));
AcGiTextStyle style;
style.setFileName(TEXT("txt.shx"));
style.setTextSize(halfGlyphSizeInDCS*5);
style.loadStyleRec();
vportDrawContext->geometry().text(mCurDcsLoc, AcGeVector3d::kZAxis,AcGeVector3d::kXAxis ,TEXT("1/3"),3,Adesk::kFalse, style);
}
static CustomOsnapMode* pSocketMode = NULL;
static CustomOsnapInfo* pDefaultSocketInfo = NULL;
static CustomOsnapForLine* pSocketForLine = NULL;
void initApp()
{
// register a command with the ZWCAD command mechanism
// Register the class.
//
CustomOsnapInfo::rxInit();
acrxBuildClassHierarchy();
pDefaultSocketInfo = new CustomOsnapInfo;
AcDbEntity::desc()->addX(CustomOsnapInfo::desc(),
pDefaultSocketInfo);
pSocketForLine = new CustomOsnapForLine;
AcDbLine::desc()->addX(CustomOsnapInfo::desc(),
pSocketForLine);
pSocketGlyph = new CustomOsnapGlyph;
pSocketMode = new CustomOsnapMode;
acdbCustomOsnapManager()->addCustomOsnapMode(pSocketMode);
acdbCustomOsnapManager()->activateOsnapMode(TEXT("line1/3"));
}
void unloadApp()
{
acdbCustomOsnapManager()->removeCustomOsnapMode(pSocketMode);
delete pSocketMode;
// Unregister, then delete the protocol extension object.
//
AcDbEntity::desc()->delX(CustomOsnapInfo::desc());
delete pDefaultSocketInfo;
AcDbLine::desc()->delX(CustomOsnapInfo::desc());
delete pSocketForLine;
// Remove the protocol extension class definition.
//
acrxClassDictionary->remove(TEXT("CustomOsnapInfo"));
}


ZWSoft ZRX for ZWCAD: Developer Guide: Input Point Filters and Monitors

Modules
Input Point Filters and Monitors
Advanced Topics » Input Point Processing

Modules

Point Filters
Input Point Monitors

Detailed Description

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: Point Filters

Point Filters
Advanced Topics » Input Point Processing » Input Point Filters and Monitors
class ZdskInputPointFilter : public AcEdInputPointFilter {
public:
virtual Acad::ErrorStatus
processInputPoint(const AcEdInputPoint& input, AcEdInputPointFilterResult& output);
};

The following example demonstrates creating a input point filters.
Warning : There are some related interfaces are not implemented so this feature is temporarily unavailable.

Acad::ErrorStatus
ZdskInputPointFilter::processInputPoint(const AcEdInputPoint& input, AcEdInputPointFilterResult& output)
{
if (input.pointComputed() && (input.history() & Acad::eOsnapped))
{
output.setNewPoint(input.osnappedPoint() + AcGeVector3d(0.2,0.2,0.0));
input.drawContext()->geometry().circle(output.newPoint(), 0.1,
AcGeVector3d::kZAxis);
}
return Acad::eOk;
}
// // Input point filter
ZdskInputPointFilter my_InputPointFilter;
// Installs an input point filter.
//
void testipf()
{
curDoc()->inputPointManager()->registerPointFilter(&my_InputPointFilter);
}
extern "C" __declspec(dllexport)
AcRx::AppRetCode
zcrxEntryPoint(AcRx::AppMsgCode msg, void *p)
{
switch (msg)
{
case AcRx::kInitAppMsg:
acrxRegisterAppMDIAware(p);
acrxUnlockApplication(p);
acedRegCmds->addCommand(TEXT("testipf"), TEXT("testipf"), TEXT("testipf"),
ACRX_CMD_TRANSPARENT, testipf);
break;
case AcRx::kUnloadAppMsg:
acedRegCmds->removeGroup(TEXT("testipm"));
break;
}
return AcRx::kRetOK;
}


ZWSoft ZRX for ZWCAD: Developer Guide: Input Point Monitors

Input Point Monitors
Advanced Topics » Input Point Processing » Input Point Filters and Monitors
class ZsdkInputPointMonitor : public AcEdInputPointMonitor
{
public:
virtual Acad::ErrorStatus
monitorInputPoint(const AcEdInputPoint& input, AcEdInputPointMonitorResult& output);
virtual bool
excludeFromOsnapCalculation (const AcArray<AcDbObjectId>& nestedEntity,
Adesk::GsMarker gsSelectionMark);
};

The following example demonstrates creating a input point monitor.
Warning : There are some related interfaces are not implemented so this feature is temporarily unavailable.

Acad::ErrorStatus
ZsdkInputPointMonitor::monitorInputPoint(const AcEdInputPoint& input, AcEdInputPointMonitorResult& output)
{
if ( !input.pointComputed() )
{
// Points cannot be computed in the Monitor
// Forced picking may be enabled
if ( input.history() & Acad::eCyclingPt)
acutPrintf( _T("\nNo point computed, but new cycling osnap: %.2f, %.2f, %.2f\n"),
input.osnappedPoint()[X], input.osnappedPoint()[Y], input.osnappedPoint()[Z] );
return Acad::eOk;
}
// Show historical point selection information
//
#define HISTORY_CHECK(x) if (input.history() & Acad:: ## x) acutPrintf(_T("%s "), _T(#x))
acutPrintf( _T("\nHistory: %d, "), input.history() );
HISTORY_CHECK(eTablet);
HISTORY_CHECK(eNotDigitizer);
HISTORY_CHECK(eLastPt);
HISTORY_CHECK(eGripped);
HISTORY_CHECK(eCartSnapped);
HISTORY_CHECK(eOrtho);
HISTORY_CHECK(eCyclingPt);
HISTORY_CHECK(eOsnapped);
HISTORY_CHECK(ePolarAngle);
HISTORY_CHECK(eAligned);
HISTORY_CHECK(eAppFiltered);
HISTORY_CHECK(eForcedPick);
HISTORY_CHECK(ePickMask);
HISTORY_CHECK(eDidNotPick);
HISTORY_CHECK(eUsedPickBox);
HISTORY_CHECK(eUsedOsnapBox);
HISTORY_CHECK(ePickAborted);
HISTORY_CHECK(eXPending);
HISTORY_CHECK(eYPending);
HISTORY_CHECK(eZPending);
HISTORY_CHECK(eCoordPending);
#undef HISTORY_CHECK
acutPrintf( _T("\n") );
// Show more point input information
//
if ( input.history() & Acad::eLastPt )
acutPrintf( _T("Last point: %.2f, %.2f, %.2f\n"), input.lastPoint()[X], input.lastPoint()[Y], input.lastPoint()[Z] );
acutPrintf( _T("Raw point: %.2f, %.2f, %.2f\n"), input.rawPoint()[X], input.rawPoint()[Y], input.rawPoint()[Z] );
acutPrintf( _T("Computed point: %.2f, %.2f, %.2f\n"), input.computedPoint()[X], input.computedPoint()[Y], input.computedPoint()[Z] );
if ( input.history() & Acad::eGripped )
acutPrintf( _T("Gripped point: %.2f, %.2f, %.2f\n"), input.grippedPoint()[X], input.grippedPoint()[Y], input.grippedPoint()[Z] );
if ( input.history() & Acad::eCartSnapped )
acutPrintf( _T("Cartesian snapped point: %.2f, %.2f, %.2f\n"), input.cartesianSnappedPoint()[X], input.cartesianSnappedPoint()[Y], input.cartesianSnappedPoint()[Z] );
if ( input.history() & Acad::eOsnapped )
{
acutPrintf( _T("Osnapped point: %.2f, %.2f, %.2f\n"), input.osnappedPoint()[X], input.osnappedPoint()[Y], input.osnappedPoint()[Z] );
acutPrintf( _T("Object snap masks: ") );
#define OSMASK_CHECK(x) if (input.osnapMask() & AcDb:: ## x) acutPrintf(_T("%s "), _T(#x))
OSMASK_CHECK(kOsMaskEnd);
OSMASK_CHECK(kOsMaskMid);
OSMASK_CHECK(kOsMaskCen);
OSMASK_CHECK(kOsMaskNode);
OSMASK_CHECK(kOsMaskQuad);
OSMASK_CHECK(kOsMaskInt);
OSMASK_CHECK(kOsMaskIns);
OSMASK_CHECK(kOsMaskPerp);
OSMASK_CHECK(kOsMaskTan);
OSMASK_CHECK(kOsMaskNear);
OSMASK_CHECK(kOsMaskQuick);
OSMASK_CHECK(kOsMaskApint);
OSMASK_CHECK(kOsMaskImmediate);
OSMASK_CHECK(kOsMaskAllowTan);
OSMASK_CHECK(kOsMaskDisablePerp);
OSMASK_CHECK(kOsMaskRelCartesian);
OSMASK_CHECK(kOsMaskRelPolar);
#undef OSMASK_CHECK
if ( 0 == input.osnapMask() )
{
for ( int i = 0; i < input.customOsnapModes().length(); i++ )
acutPrintf( _T("%s\n"), input.customOsnapModes()[i]->globalModeString() );
}
acutPrintf( _T("\n") );
}
// Show the object snap overrides
//
if ( 0 != input.osnapOverrides() )
{
acutPrintf( _T("Object snap overrides: ") );
#define OSMASK_CHECK(x) if (input.osnapOverrides() & AcDb:: ## x) acutPrintf(_T("%s "), _T(#x))
OSMASK_CHECK(kOsMaskEnd);
OSMASK_CHECK(kOsMaskMid);
OSMASK_CHECK(kOsMaskCen);
OSMASK_CHECK(kOsMaskNode);
OSMASK_CHECK(kOsMaskQuad);
OSMASK_CHECK(kOsMaskInt);
OSMASK_CHECK(kOsMaskIns);
OSMASK_CHECK(kOsMaskPerp);
OSMASK_CHECK(kOsMaskTan);
OSMASK_CHECK(kOsMaskNear);
OSMASK_CHECK(kOsMaskQuick);
OSMASK_CHECK(kOsMaskApint);
OSMASK_CHECK(kOsMaskImmediate);
OSMASK_CHECK(kOsMaskAllowTan);
OSMASK_CHECK(kOsMaskDisablePerp);
OSMASK_CHECK(kOsMaskRelCartesian);
OSMASK_CHECK(kOsMaskRelPolar);
#undef OSMASK_CHECK
acutPrintf(_T("\n"));
}
// Show custom object snap overrides
//
if ( 0 != input.customOsnapOverrides().length() )
{
acutPrintf( _T("Custom object snap overrides: ") );
for ( int x = 0; x < input.customOsnapOverrides().length(); x++)
acutPrintf( _T("%s "), input.customOsnapOverrides()[x]->globalModeString() );
acutPrintf( _T("\n") );
}
// Show object snap or forced pick information: the entities in the aperture
acutPrintf( _T("%d apertured entities, "), input.pickedEntities().length() );
acutPrintf( _T("%d nested apertured entities\n"), input.nestedPickedEntities().length() );
// Show AutoSnap information
// Note: nestedKeyPointEntities.length() == keyPointGsSelectionMark.length()
//
acutPrintf( _T("%d key point entities, "), input.keyPointEntities().length() );
acutPrintf( _T("%d nested key point entities\n"), input.nestedKeyPointEntities().length() );
acutPrintf( _T("%d alignment paths\n"), input.alignmentPaths().length() );
// Add an additional comment to the tootip string
//
if ( NULL != input.tooltipString() )
{
output.setAdditionalTooltipString(_T(", Additional comment!"));
acutPrintf( _T("Appending \"%s\" to \"%s\"\n"), _T(", Additional comment!"), input.tooltipString() );
}
else
acutPrintf( _T("Tooltip is NULL\n") );
acedPostCommandPrompt();
return Acad::eOk;
}
bool
ZsdkInputPointMonitor::excludeFromOsnapCalculation (const AcArray<AcDbObjectId>& nestedEntity, INT_PTR gsSelectionMark)
{
acutPrintf( _T("\nExcludeFromOsnapCalculation called on monitor...\n") );
acutPrintf( _T("%d nested entities under cursor\n"), nestedEntity.length() );
return false;
}
// Input point monitor
ZsdkInputPointMonitor my_InputPointMonitor;
//
void testipm()
{
curDoc()->inputPointManager()->addPointMonitor(&my_InputPointMonitor);
}
extern "C" __declspec(dllexport)
AcRx::AppRetCode
zcrxEntryPoint(AcRx::AppMsgCode msg, void *p)
{
switch (msg)
{
case AcRx::kInitAppMsg:
acrxRegisterAppMDIAware(p);
acrxUnlockApplication(p);
acedRegCmds->addCommand(TEXT("testipm"), TEXT("testipm"), TEXT("testipm"),
ACRX_CMD_TRANSPARENT, testipm);
break;
case AcRx::kUnloadAppMsg:
acedRegCmds->removeGroup(TEXT("testipm"));
break;
}
return AcRx::kRetOK;
}


ZWSoft ZRX for ZWCAD: Developer Guide: Input Context Events

Input Context Events
Advanced Topics » Input Point Processing

The following example demonstrates creating a input context reactor.

class ZsdkContextReactor : public AcEdInputContextReactor
{
public:
virtual void
beginGetPoint(
const AcGePoint3d* pIn,
const ACHAR* promptString,
int initGetFlags,
const ACHAR* pKeywords);
virtual void
endGetPoint(
Acad::PromptStatus returnStatus,
const AcGePoint3d& pointOut,
const ACHAR*& pKeyword);
virtual void
beginGetOrientation(
const AcGePoint3d* pointIn,
const ACHAR* promptString,
int initGetFlags,
const ACHAR* pKeywords);
virtual void
endGetOrientation(
Acad::PromptStatus returnStatus,
double& angle,
const ACHAR*& pKeyword);
virtual void
beginGetCorner(
const AcGePoint3d* firstCorner,
const ACHAR* promptString,
int initGetFlags,
const ACHAR* pKeywords);
virtual void
endGetCorner(
Acad::PromptStatus returnStatus,
AcGePoint3d& secondCorner,
const ACHAR*& pKeyword);
virtual void
beginSSGet(
const ACHAR* pPrompt,
int initGetFlags,
const ACHAR* pKeywords,
const ACHAR* pSSControls,
const AcArray<AcGePoint3d>& points,
const resbuf* entMask);
virtual void
endSSGet(
Acad::PromptStatus returnStatus,
const AcArray<AcDbObjectId>& ss);
};
void
ZsdkContextReactor::beginGetPoint(
const AcGePoint3d* pointIn,
const ACHAR* promptString,
int initGetFlags,
const ACHAR* pKeywords)
{
if (pointIn == NULL) return;
acutPrintf(TEXT("beginGetPoint: pointIn = %.2f,%.2f,%.2f\n"),
(*pointIn)[0], (*pointIn)[1], (*pointIn)[2]);
}
void
ZsdkContextReactor::endGetPoint(
Acad::PromptStatus returnStatus,
const AcGePoint3d& pointOut,
const ACHAR*& pKeyword)
{
acutPrintf(TEXT("endGetPoint: pointOut =%.2f,%.2f,%.2f\n"), pointOut[0], pointOut[1],
pointOut[2]);
}
void
ZsdkContextReactor::beginGetOrientation(
const AcGePoint3d* pointIn,
const ACHAR* promptString,
int initGetFlags,
const ACHAR* pKeywords)
{
if (pointIn == NULL) return;
acutPrintf(TEXT("beginGetOrientation: %.2f, %.2f, %.2f\n"),
(*pointIn)[0], (*pointIn)[1], (*pointIn)[2]);
}
void
ZsdkContextReactor::endGetOrientation(
Acad::PromptStatus returnStatus,
double& angle,
const ACHAR*& pKeyword)
{
acutPrintf(TEXT("endGetOrientation: %.2f\n"), angle);
}
void
ZsdkContextReactor::beginGetCorner(
const AcGePoint3d* firstCorner,
const ACHAR* promptString,
int initGetFlags,
const ACHAR* pKeywords)
{
if (NULL != firstCorner)
{
acutPrintf(
TEXT("beginGetCorner: %.2f, %.2f, %.2f\n"),
(*firstCorner)[0],
(*firstCorner)[1],
(*firstCorner)[2]);
}
}
void
ZsdkContextReactor::endGetCorner(
Acad::PromptStatus returnStatus,
AcGePoint3d& secondCorner,
const ACHAR*& pKeyword)
{
acutPrintf(
TEXT("endGetCorner: %.2f, %.2f, %.2f\n"),
(secondCorner)[0],
(secondCorner)[1],
(secondCorner)[2]);
}
void
ZsdkContextReactor::beginSSGet(
const ACHAR* pPrompt,
int initGetFlags,
const ACHAR* pKeywords,
const ACHAR* pSSControls,
const AcArray<AcGePoint3d>& points,
const resbuf* entMask)
{
acutPrintf(TEXT("beginSSGet:%s\n"), NULL != pPrompt ? pPrompt : TEXT(""));
for (int i = 0; i < points.length(); i++)
acutPrintf(TEXT("%d: %.2f, %.2f, %.2f\n"), i, points[i][X],
points[i][Y], points[i][Z]);
}
void
ZsdkContextReactor::endSSGet(
Acad::PromptStatus returnStatus,
const AcArray<AcDbObjectId>& ss)
{
acutPrintf(TEXT("endSSGet\n"));
for (int i = 0; i < ss.length(); i++)
acutPrintf(TEXT("Entity %d: <%x>\n"), i, ss[i].asOldId());
}
// My context reactor object
ZsdkContextReactor* Zsdk_cr = NULL;
#if _ZWCAD
extern "C" __declspec(dllexport) AcRx::AppRetCode
zcrxEntryPoint(
#else
extern "C" __declspec(dllexport) AcRx::AppRetCode
acrxEntryPoint(
#endif
AcRx::AppMsgCode msg,
void *p)
{
switch (msg)
{
case AcRx::kInitAppMsg:
acrxUnlockApplication(p);
acrxRegisterAppMDIAware(p);
Zsdk_cr = new ZsdkContextReactor();
curDoc()->inputPointManager()->
addInputContextReactor(Zsdk_cr);
break;
case AcRx::kLoadDwgMsg:
// Attach a context reactor to the current document.
//
break;
case AcRx::kUnloadAppMsg:
// Warning! This sample attaches a context reactor,
// but it never detaches it. A real-life application
// will need to monitor to which document it attached
// the reactor, and will need to detach it.
//
curDoc()->inputPointManager()->
removeInputContextReactor(Zsdk_cr);
break;
}
return AcRx::kRetOK;
}


ZWSoft ZRX for ZWCAD: Developer Guide: Application Configuration

Application Configuration
Advanced Topics
void
aFunction()
{
acutPrintf(TEXT("This is ZsdkProfileSample Test Application...\n"));
// Attach the reactor for the duration of this command. Normally
// this would be added upon application initialization.
//
// Obtain the path for the registry keys and print it out.
//
ACHAR *pstrKey;
acProfileManagerPtr()->ProfileRegistryKey(pstrKey, NULL);
if (pstrKey != NULL) {
acutPrintf(TEXT("\nThe profiles registry key is: %s"), pstrKey);
acutDelString(pstrKey);
}
// Get the list of all profiles in the user's configuration
// and print them out.
//
AcApProfileNameArray arrNameList;
int nProfiles =
acProfileManagerPtr()->ProfileListNames(arrNameList);
acutPrintf(TEXT("\nNumber of profiles currently in the user profile list is: %d"), nProfiles);
for (int i = 0; i < nProfiles; i++)
acutPrintf(TEXT("\nProfile name is: %s"), arrNameList[i]);
// Copy the unnamed profile to the ZsdkTestProfile.
//
acProfileManagerPtr()->ProfileCopy(
TEXT("ZsdkTestProfile"),
TEXT("Default"),
TEXT("This is a test"));
// Reset the newly copied profile to ZWCAD defaults.
//
acProfileManagerPtr()->ProfileReset(TEXT("ZsdkTestProfile"));
// Make this new profile current.
//
acProfileManagerPtr()->ProfileSetCurrent(TEXT("ZsdkTestProfile"));
// Change a value in the profile. For this example, make the
// cursor big.
//
struct resbuf rbCursorSize;
rbCursorSize.restype = RTSHORT;
rbCursorSize.resval.rint = 100;
acedSetVar(TEXT("CURSORSIZE"), &rbCursorSize);
// Rename the profile to a new name.
//
acProfileManagerPtr()->ProfileRename(
TEXT("ZsdkTestProfile2"),
TEXT("ZsdkTestProfile"),
TEXT("This is another test"));
// Export the profile.
//
acProfileManagerPtr()->ProfileExport(
TEXT("ZsdkTestProfile2"),
TEXT("./ZsdkTestProfile2.arg"));
// Import the profile.
//
acProfileManagerPtr()->ProfileImport(
TEXT("ZsdkTestProfile3"),
TEXT("./ZsdkTestProfile2.arg"),
TEXT("This is a copy of ZsdkTestProfile2 by Exporting/Importing"),
Adesk::kTrue);
//
}


ZWSoft ZRX for ZWCAD: Developer Guide: ZrxSample Directory Reference

  • ZrxSample
ZrxSample Directory Reference

Directories

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: ZrxSample Directory Reference

  • ZrxSample
  • ZrxSample
ZrxSample Directory Reference

Directories

zwsoft
© 1998-2022 Copyright ZWSOFT CO., LTD(Guangzhou)
All rights reserved.


ZWSoft ZRX for ZWCAD: Developer Guide: src Directory Reference

  • ZrxSample
  • ZrxSample
  • src
src Directory Reference


ZWSoft ZRX for ZWCAD: Developer Guide: inc Directory Reference

  • ZrxSample
  • ZrxSample
  • inc
inc Directory Reference


ZWSoft ZRX for ZWCAD: Developer Guide: Main Page

ZWSoft ZRX for ZWCAD: Developer Guide Documentation
  • Main Page
  • Modules