ObjectARX
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

[ACAD2013-14] ObjectARX - Close Current DWG File

9 REPLIES 9
Reply
Message 1 of 10
Anonymous
1662 Views, 9 Replies

[ACAD2013-14] ObjectARX - Close Current DWG File

Hi,

I have a problem during the closing of the active document.

 

I developed lots of custom commands used by the users.

 

When a user has finished to edit the DWG, he launch the last command which close the current document, calculate an hash of the DWG document and generate an XML File.

 

void _SaveXML()
{
   //object list to export
   std::list<Entities::UploadObjectRecord> * obj_list = _GetObjectsInBillOfMaterial();

   //save file DWG
   acedCommand( RTSTR, _T("_SAVE"), RTSTR, PAUSE, RTNONE );

   CString DWGFileName = _GetFileName();
   CString DWGFilePath = _GetFilePath();
   CString DWGFullFileName = DWGFilePath + DWGFileName;

   //close file to allow MD5SUM to calculate the Hash of the file
   acedCommand( RTSTR, _T("_CLOSE"), RTSTR,  _T(""), RTNONE );

   /////////EXECUTION STOP HERE!/////////////////////////

   //hash MD5 of the DWG file
   CString md5sum = _MD5SUM(DWGFullFileName);

   //build xml file
   Serialize_BillOfMaterialToXMLFile(obj_list,DWGFullFileName + _T(".xml"),md5sum);

   delete obj_list;
}

 

The big problem is after the close command, because after this command, the excecution of my code stop! and I can't go on with processing.

 

What could be a workaround?

Could an ARX extension lives also without an active document?

 

I must close the document in order to calculate the hash of the document.

 

Thank you for your help.

 

Massimo

9 REPLIES 9
Message 2 of 10
Alexander.Rivilis
in reply to: Anonymous

1) First off all command have to be registered with ACRX_CMD_SESSION flag.

2) You have not use AutoCAD command for closing document

3) Some useful links:

Automatically opening a drawing and closing default drawing

Closing documents from an CAdUiDialog derived modal dialog

Close all documents including the current one

 

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

Message 3 of 10
Anonymous
in reply to: Alexander.Rivilis

Hi,

 

I modified the command registration in the following way:

 

ACED_ARXCOMMAND_ENTRY_AUTO(CNodeApp, HS00Node, _SaveXML, SaveXML, ACRX_CMD_TRANSPARENT | ACRX_CMD_SESSION, NULL)

 (I didn't found a good reference for these constants in the ObjectARX documentation.)

 

Anyway,

Now I close the document with the following code:

::acDocManagerPtr()->appContextCloseDocument(acDocManager->curDocument());

 and the execution goes on in the right way.

 

First, as listed in my first post code, I need to save the document programmatically to the last saved position on file system, because now after have added the flag ACRX_CMD_SESSION, my command _SAVE doesn't start the save command on the active document.

 

Is there another command to save the file with the document manager, like for the close command?

 

Thank you for your help.

 

Massimo

Message 4 of 10
Alexander.Rivilis
in reply to: Anonymous

Programmatically saving the active document in C++/ARX applications

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

Message 5 of 10
Anonymous
in reply to: Alexander.Rivilis

Hi,

 

I tried the first way explained,.

 

void saveDwg()
{
 try
 {
   IAcadApplicationPtr pApp = acedGetAcadWinApp()->GetIDispatch(FALSE);
   IAcadDocumentPtr pDoc;
   pApp->get_ActiveDocument(&pDoc);
   pDoc->Save();
 }
 catch(_com_error& e)
 {
   acutPrintf(_T("\nCOM error: %s"), (ACHAR*)e.Description());
 }
}

 It doesn't work, but with some adjustments now it works.

 

#include <acadi.h>

void saveDwg()
{
 try
 {
  IAcadApplication * pApp = (IAcadApplication *)acedGetAcadWinApp()->GetIDispatch(FALSE);
  IAcadDocument * pDoc;
  pApp->get_ActiveDocument(&pDoc);
  pDoc->Save();
 }
 catch(_com_error& e)
 {
  acutPrintf(_T("\nCOM error: %s"), (ACHAR*)e.Description());
 }
}

 

Thank you for your help.

 

Massimo

 

Message 6 of 10
owenwengerd
in reply to: Anonymous

It is an error to cast IDispatch* to IAcadApplication*, even though it will work in practice as long as you're lucky. You must use QueryInterface(), either directly or indirectly as per Alexander's answer.

--
Owen Wengerd
ManuSoft
Message 7 of 10
Anonymous
in reply to: owenwengerd

Hi,

I don't want my application works only because I'm lucky! 🙂

 

How can I fix this?

 

What could be the right code?

 

Thank you for your time.

 

Massimo

Message 8 of 10
Alexander.Rivilis
in reply to: Anonymous

Recommended way to access AutoCAD Interface Object using C++

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

Message 9 of 10
Anonymous
in reply to: Anonymous

Hi, 

owenwengerd means that you can't raw cast from IDispatch to IAcadApplication as you do, this because COM pointer returned by GetIDispatch() may return an actual underlying proxy instance (COM behavior) instead of your object directly.

 

 

	try
	{
		IDispatch *pAppDisp = acedGetAcadWinApp()->GetIDispatch(FALSE);
		//IDispatchPtr pAppDisp = acedGetAcadWinApp()->GetIDispatch(TRUE); //other style, using COM smart pointers (notice TRUE argument)
		CComPtr<IAcadApplication> pApp;
		if (SUCCEEDED(pAppDisp->QueryInterface(IID_IAcadApplication,reinterpret_cast<void**>(&pApp))))
		{
			CComPtr<IAcadDocument> pDoc;
			pApp->get_ActiveDocument(&pDoc);
			pDoc->Save();
		}
	}
	catch(_com_error& e)
	{
		acutPrintf(_T("\nCOM error: %s"), (ACHAR*)e.Description());
	}

 

 Please, also notice that I used COM smart pointers instead of raw pointers. This avoid forgetting to release COM pointers after use.

 

I hope this helps

Message 10 of 10
Anonymous
in reply to: Alexander.Rivilis

Hi,
I especially like Fenton's idiom:

CComQIPtr<IAcadAppplication> acad = acedGetAcadWinApp()->GetIDispatch(TRUE);

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost