1. 程式人生 > >[ObjectARX]示範建立新圖層和iterator的使用

[ObjectARX]示範建立新圖層和iterator的使用

在該應用程式中,

  1. 示範建立一個新的圖層,怎樣設定層的顏色和線型;
  2. 示範怎樣使用瀏覽器(iterator).

一、命令函式aaaMyGroupMyCommand的實現:

static void aaaMyGroupMyCommand () {
		acutPrintf(_T("\n進入Mycommand函式!"));
		ACHAR lyrName[256];
		ACHAR kw[20];
		int rc;  //return code
		int col; //Color value
		AcDbObjectId ltypeId; //We need the object id of the linetype
		                     //for layer creation
		rc = acedGetString(0, _T("\nNew layer name:"), lyrName);
		switch (rc)
		{
		case RTCAN:
			acutPrintf(_T("User canceled"));
			return;
		case RTERROR:
			acutPrintf(_T("\nError with input of new layer name!"));
			return;
			break;
		}
		if (lyrName[0] == '\0')
		{
			acutPrintf(_T("\nEmpty string for new layer name invalid!"));
			return;
		}

		acutPrintf(_T("\n獲取圖層顏色!"));
		//Get the layer color
		acedInitGet(RSG_NONULL + RSG_NONEG + RSG_NOZERO, NULL);
		acedGetInt(_T("\nLayer color (1-7 only)"), &col);
		if (col > 7)
		{
			acutPrintf(_T("\nToo high a color value."));
			return;
		}

		//Get the layer line type default = 'CONTINUOUS'
		acutPrintf(_T("\nGet the layer line type default = 'CONTINUOUS'!"));
		if (!COtherUtil::getNewLyrltId(ltypeId))
		{
			acutPrintf(_T("\nUnable to retrieve the linetype AcDbObjectId."));
			return;
		}

		//Now that we have a layer name.layer color and line type ask user 
		//if he wants to make the new layer the current layer
		acedInitGet(NULL, _T("Yes No"));
		rc = acedGetKword(_T("\nMake new layer current [Yes/No]<Yes>:"), kw);
		switch (rc)
		{
		case RTCAN:
			acutPrintf(_T("\nUser canceled!"));
			break;
		case RTERROR:
			acutPrintf(_T("\nError in acedGetKword function"));
			break;
		case RTNONE:
			//if the user presses the [ENTER] key
			//we take this as a "Yes"
			COtherUtil::createNewLayer(lyrName, col, ltypeId, Adesk::kTrue);
			break;
		case RTNORM:
			if (strcmp(reinterpret_cast<char*>(kw), reinterpret_cast<char*>(_T("Yes"))) == 0)
			{
				COtherUtil::createNewLayer(lyrName, col, ltypeId, Adesk::kTrue);
			}
			else if (strcmp(reinterpret_cast<char *>(kw), reinterpret_cast<char*>(_T("No"))) == 0)
			{
				COtherUtil::createNewLayer(lyrName, col, ltypeId, Adesk::kFalse);
			}
			break;
		}

	
		acutPrintf(_T("\n完成MyCommand函式!"));
	}

二、getNewLyrltId函式的實現:

Adesk::Boolean COtherUtil::getNewLyrltId(AcDbObjectId &ltypeId)
{
	acutPrintf(_T("\n進入getNewLyrltId(AcDbObjectId &ltypeId)函式!"));
	//We know that the linetype 'CONTINUOUS' exists,
	//so give the user a choice of pressing [ENTER]
	//for 'CONTINUOUS' linetype or a listing option
	//to show all the linetype available or input a linetype name
	ACHAR kw[20];
	ACHAR lineType[50];
	ACHAR *pLtName;
	AcDbDatabase *pCurDb = NULL;
	
	AcDbLinetypeTable *pltTable;
	AcDbLinetypeTableRecord *pLtTableRcd;
	AcDbLinetypeTableIterator *pLtIterator;
	int rc;

	pCurDb = acdbHostApplicationServices()
		->workingDatabase();
	acedInitGet(NULL, _T("Name List Continues"));
	rc = acedGetKword(_T("\nLinetype [Name/List/Continuous]<Continuous>:"), kw);
	switch (rc)
	{
	case RTCAN:
		acutPrintf(_T("\nUser canceled."));
		return Adesk::kFalse;
	case RTERROR:
		acutPrintf(_T("\nFailed in getNewlyLyrLtId() function."));
		return Adesk::kFalse;
		break;
	case RTNONE:
		pCurDb->getLinetypeTable(pltTable, AcDb::kForRead);
		pltTable->getAt(_T("CONTINUOUS"), ltypeId);
		pltTable->close();
		return Adesk::kTrue;
		break;
	case RTNORM:
		if (strcmp(reinterpret_cast<char*>(kw), reinterpret_cast<char*>(_T("Name"))) == 0)
		{
			rc = acedGetString(0, _T("\nEnter linetype string name:"), lineType);
			switch (rc)
			{
			case RTCAN:
			case RTERROR:
				acutPrintf(_T("\nError in retrieving linetype name."));
				return Adesk::kFalse;
				break;
			case RTNORM:
				if (lineType[0] == '\0')
				{
					acutPrintf(_T("\nNo layer name given."));
					return Adesk::kFalse;

				}
				//Check to see if the linetype exists
				acutPrintf(_T("\nCheck to see if the linetype exists!"));
				pCurDb->getLinetypeTable(pltTable, AcDb::kForRead);
				if (pltTable->has(lineType))
				{
					//Retrieve the AcDbObjectId of the layer table record
					acutPrintf(_T("\nRetrieve the AcDbObjectId of the layer table record!"));
					pltTable->getAt(lineType, ltypeId);
					pltTable->close();
					return Adesk::kTrue;
				}
				acutPrintf(_T("\nLinetype '%s' does not exist using CONTINUOUS."), lineType);
				pltTable->getAt(_T("CONTINUOUS"), ltypeId);
				pltTable->close();
				return Adesk::kTrue;
				break;
			}//switch
		}//if
		else if (strcmp(reinterpret_cast<char*>(kw), reinterpret_cast<char*>(_T("List"))))
		{
			//Here we will use a Linetype Table Iterator
			//to list out all the available linetype
			//and then ask the user to enter a 
			//valid name for one of the layers
			acutPrintf(_T("\nThe following linetypes are available!"));
			pCurDb->getLinetypeTable(pltTable, AcDb::kForRead);
			pltTable->newIterator(pLtIterator);
			for (; !pLtIterator->done(); pLtIterator->step())
			{
				acutPrintf(_T("\nget the current linetype record from the iterator!"));
				//get the current linetype record from the iterator.
				//opened for read 
				pLtIterator->getRecord(pLtTableRcd, AcDb::kForRead);

				//get the linetype name from the linetype record
				//and store it in pLtName
				pLtTableRcd->getName(pLtName);
				//close the linetype record
				pLtTableRcd->close();
				acutPrintf(_T("\nLinetype name:%s"), pLtName);
				delete[]pLtName;
			}//for
			//Don't forget to delete the iterator
			//that's your responsity
			acutPrintf(_T("\nDon't forget to delete the iterator!"));
			delete pLtIterator;

			rc = acedGetString(0, _T("\nEnter linetype string name:"), lineType);
			switch (rc)
			{
			case RTCAN:
			case RTERROR:
				acutPrintf(_T("\nError in retrieving linetype name."));
				return Adesk::kFalse;
				break;

			case RTNORM:
				if (lineType[0] == '\0')
				{
					acutPrintf(_T("\nNo layer name given."));
					return Adesk::kFalse;
				}

				//Check to see if the linetype exits
				acutPrintf(_T("\nCheck to see if the linetype exits!"));
				pCurDb->getLinetypeTable(pltTable, AcDb::kForRead);
				if (pltTable->has(lineType))
				{
					//Retrieve the AcDbObjectId of the layer table record
					acutPrintf(_T("\nRetrieve the AcDbObjectId of the layer table record!"));
					pltTable->getAt(lineType, ltypeId);
					pltTable->close();
					return Adesk::kTrue;
				}
				acutPrintf(_T("Linetype '%s' does not exits using CONTINUOUS."), lineType);
				pltTable->getAt(_T("CONTINUOUS"), ltypeId);
				pltTable->close();
				return Adesk::kTrue;
				break;

			}//switch

		}
		else if (strcmp(reinterpret_cast<char*>(kw),
			reinterpret_cast<char*>(_T("Continuous"))) == 0)
		{
			//Remenber the CONTINUOUS linetype always exists in a drawing file.
			acutPrintf(_T("\nRemenber the CONTINUOUS linetype always exists in a drawing file!"));
			pCurDb->getLinetypeTable(pltTable, AcDb::kForRead);
			pltTable->getAt(_T("CONTINUOUS"), ltypeId);
			pltTable->close();
			return Adesk::kTrue;
		}
		else
		{
			return Adesk::kFalse;
		}
		break;
	}//switch
	return Adesk::kFalse;
	
	acutPrintf(_T("\n完成getNewLyrltId函式!"));
}

三、createNewLayer函式的實現:

void COtherUtil::createNewLayer(ACHAR* lyrname, Adesk::UInt16 clr,
	AcDbObjectId ltypeId, Adesk::Boolean current)
{
	acutPrintf(_T("\n進入createNewLayer函式!"));
	//We need to check if the layer name exists
	//If the layer name exists.apply the color
	//linetype id and whether to make it current
	//or not.In order to be current it cannot be
	//frozen.so we need to check for this also.
	//If the layer name dose not exist we just create
	//a new layer with the properties contained in the arguments.
	AcDbLayerTable *pLyrTable;
	AcDbLayerTableRecord *pLyrTblRecord;
	AcDbObjectId recId;
	AcCmColor color;
	color.setColorIndex(clr);//set color to parameter clr
	AcDbDatabase *pCurDb = NULL;
	pCurDb = acdbHostApplicationServices()
		->workingDatabase();
	pCurDb->getLayerTable(pLyrTable, AcDb::kForRead);

	//Check to see if the layer name exists
	acutPrintf(_T("\nCheck to see if the layer name exists!"));
	if (pLyrTable->has(lyrname))
	{
		acutPrintf(_T("\npLyrTable->has(lyrname)!"));
		pLyrTable->getAt(lyrname, pLyrTblRecord,
			AcDb::kForWrite, Adesk::kFalse);
		//pLyrTableRecord now points at the layer table record
		//which was opened for write
		pLyrTblRecord->setIsFrozen(Adesk::kFalse);
		pLyrTblRecord->setColor(color);
		pLyrTblRecord->setLinetypeObjectId(ltypeId);
	}
	else
	{
		//Note how we can change the open mode
		//of the layer table from AcDb::kForRead
		//to AcDb::kForWrite
		acutPrintf(_T("\npLyrTable->has(lyrname)為假!"));
		pLyrTable->upgradeOpen();
		pLyrTblRecord = new AcDbLayerTableRecord;
		pLyrTblRecord->setName(lyrname);
		pLyrTblRecord->setColor(color);
		pLyrTblRecord->setLinetypeObjectId(ltypeId);
		pLyrTable->add(pLyrTblRecord);
	}
	//Get the layer Table ObjectId
	acutPrintf(_T("\nGet the layer Table ObjectId!"));
	recId = pLyrTblRecord->objectId();
	pLyrTblRecord->close();
	pLyrTable->close();

	//Set the layer current if current is equal to Adesk::kTrue;
	//pCurDb is point to the current drawing database;
	//The database AcDbDatabase has a number of query and 
	//edit functions for the header variables
	if (current)
	{
		pCurDb->setClayer(recId);
	}
	acutPrintf(_T("\n完成createNewLayer函式!"));
}

效果:

1)按Ctrl+F2 我的命令輸入如下: image 2)生成自定義生成的圖層“HelloWorld” image

參考資料: 《AutoCAD 2000 ObjectARX 程式設計指南》