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
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
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
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
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
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.
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
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
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
Can't find what you're looking for? Ask the community or share your knowledge.