Open DWG with ARX in MDI

Open DWG with ARX in MDI

sandip.chaudhari8FDDH
Participant Participant
1,711 Views
12 Replies
Message 1 of 13

Open DWG with ARX in MDI

sandip.chaudhari8FDDH
Participant
Participant

Using AutoCAD ObjectARX: 2023 , C++

 

trying to open a DWG file in MDI mode using below code :
Acad::ErrorStatus es = Acad::eOk;
if (acDocManager->isApplicationContext())
{
    es = acDocManager->appContextOpenDocument(strDrawingFile);
}

 

But appContextOpenDocument() fails with error Acad::eFilerError.

 

Opening the same DWG file in SDI mode using below API is successful :
Acad::ErrorStatus es = acedSyncFileOpen(strDrawingFile);

 

Please suggest how to resolve error while opening DWG file in MDI mode.
The command is registered with commandFlag as "ACRX_CMD_MODAL | ACRX_CMD_SESSION".
Also tried with executeInApplicationContext() in case when command is not registered with ACRX_CMD_SESSION.

0 Likes
1,712 Views
12 Replies
Replies (12)
Message 2 of 13

moogalm
Autodesk Support
Autodesk Support

I don't see any error, may be you can share full code snippet.
Following code is what I tested.

void openDocHelper(void* pData)
{
    if (acDocManager->isApplicationContext())
    {
        AcString* dwg = (AcString*)pData;
        Acad::ErrorStatus result
            = acDocManager->appContextOpenDocument(*dwg);
        if (result != Acad::eOk)
            acutPrintf(L"\nERROR: %s\n", acadErrorStatusText(result));
    }
    else
        acutPrintf(L"\nERROR: in Document context :%s\n", acDocManager->curDocument()->fileName());
}

void OpenDwg()
{
    Acad::ErrorStatus es;
    AcString dwgpath = L"D:\\Temp\\XYZ.dwg"; 
    if (acDocManager->isApplicationContext()) //if Command is registered for SESSION
    {
         es = acDocManager->appContextOpenDocument(dwgpath);
        if (es != Acad::eOk)
            acutPrintf(L"\nERROR: %s\n", acadErrorStatusText(es));
    }
    else //if COmmand is registered for MODAL only
        acDocManager->executeInApplicationContext(openDocHelper, &dwgpath);
}

 

0 Likes
Message 3 of 13

sandip.chaudhari8FDDH
Participant
Participant

I am using the same code.

PrepareForImport is getting called from a button in the ribbon in ACAD. We have a very old application, is there something at the start of loading the application can affect this?

I have attached the code and image as well. 

 

void openDocHelper(void* pData)
{
if (acDocManager->isApplicationContext())
{
AcString* dwg = (AcString*)pData;
Acad::ErrorStatus result
= acDocManager->appContextOpenDocument(*dwg);
if (result != Acad::eOk)
acutPrintf(L"\nERROR: %s\n", acadErrorStatusText(result));
}
else
acutPrintf(L"\nERROR: in Document context :%s\n", acDocManager->curDocument()->fileName());
}

void OpenDwg()
{
Acad::ErrorStatus es;
AcString dwgpath = L"F:\\Project\\FactoryCAD\\data\\sample1.dwg";
if (acDocManager->isApplicationContext()) //if Command is registered for SESSION
{
es = acDocManager->appContextOpenDocument(dwgpath);
if (es != Acad::eOk)
acutPrintf(L"\nERROR: %s\n", acadErrorStatusText(es));
}
else //if COmmand is registered for MODAL only
acDocManager->executeInApplicationContext(openDocHelper, &dwgpath);
}

void CimfCommands::PrepareForImport()
{
OpenDwg();

return;
}

0 Likes
Message 4 of 13

moogalm
Autodesk Support
Autodesk Support
PrepareForImport is getting called from a button in the ribbon in ACAD.

if PrepareForImport is a command, you need to execute this command through sendStringToExecute, that will allow execution in command context.

0 Likes
Message 5 of 13

sandip.chaudhari8FDDH
Participant
Participant

cannot call directly  sendStringToExecute as we are not explicitly calling this command. its called from button

This is command registration.

 

 AddCommand(CimfCommands::PrepareForImport, STR_CMDUI_CIMF_UB_COMMAND, STR_CMDUI_CIMFPREPAREFORIMPORT, STR_CMDUI_CIMFPREPAREFORIMPORT, ACRX_CMD_MODAL);

 

Tried with and without  ACRX_CMD_MODAL/ACRX_CMD_SESSION

 

I think need to align code for the respective flag to get correct application context, not sure how to give it.

 

0 Likes
Message 6 of 13

moogalm
Autodesk Support
Autodesk Support

In the button logic, use Sendstringtoexcute to call the registered command, you should find many examples on the internet.

0 Likes
Message 7 of 13

sandip.chaudhari8FDDH
Participant
Participant

most of the examples are calling command from some function

we didn't find example for Sendstringtoexcute  that is called from button.

 

we required way to do in from macro as in below image

or simply way to open the drawing on button click.

 

acad_macro.png

 

0 Likes
Message 8 of 13

moogalm
Autodesk Support
Autodesk Support

if `imfPrepareForImport` is command, that will be executed in application context, 

es = acDocManager->appContextOpenDocument(dwgpath);

This should work without any hassle

It appears to me something is missing in your environment.


0 Likes
Message 9 of 13

sandip.chaudhari8FDDH
Participant
Participant

How you have added callback function to command ?

we are using

 AddCommand(CimfCommands::PrepareForImport, STR_CMDUI_CIMF_UB_COMMAND, STR_CMDUI_CIMFPREPAREFORIMPORT, STR_CMDUI_CIMFPREPAREFORIMPORT, ACRX_CMD_MODAL)

0 Likes
Message 10 of 13

moogalm
Autodesk Support
Autodesk Support

Just call this STR_CMDUI_CIMFPREPAREFORIMPORT this from your macro, when you click the button, the macro executes by calling the registered command, if the command is registered as MODAL, use this acDocManager->executeInApplicationContext(openDocHelper, &dwgpath);

or, if the command is registered for Session , use this es = acDocManager->appContextOpenDocument(dwgpath);

0 Likes
Message 11 of 13

sandip.chaudhari8FDDH
Participant
Participant

still not got what mechanism you have used for mapping command string to function name command.

command name : STR_CMDUI_CIMFPREPAREFORIMPORT 

command function : CimfCommands::PrepareForImport

 

can you please try with AddCommand , this is what we have in the existing application.

 

AddCommand(CimfCommands PrepareForImport, STR_CMDUI_CIMF_UB_COMMAND, STR_CMDUI_CIMFPREPAREFORIMPORT, STR_CMDUI_CIMFPREPAREFORIMPORT, ACRX_CMD_MODAL);

0 Likes
Message 12 of 13

moogalm
Autodesk Support
Autodesk Support
void openDocHelper(void* pData)
{
    if (acDocManager->isApplicationContext())
    {
        AcString* dwg = (AcString*)pData;
        Acad::ErrorStatus result
            = acDocManager->appContextOpenDocument(*dwg);
        if (result != Acad::eOk)
            acutPrintf(L"\nERROR: %s\n", acadErrorStatusText(result));
    }
    else
        acutPrintf(L"\nERROR: in Document context :%s\n", acDocManager->curDocument()->fileName());
}

void OpenDwg()
{
    Acad::ErrorStatus es;
    AcString dwgpath = L"D:\\Temp\\XYZ.dwg"; 
    if (acDocManager->isApplicationContext()) //if Command is registered for SESSION
    {
         es = acDocManager->appContextOpenDocument(dwgpath);
        if (es != Acad::eOk)
            acutPrintf(L"\nERROR: %s\n", acadErrorStatusText(es));
    }
    else //if command is registered for MODAL only
        acDocManager->executeInApplicationContext(openDocHelper, &dwgpath);
}




void initApp()
{


    acedRegCmds->addCommand(_T("ASDK_MAKE_ENTS"),
        _T("OPENDOC"),
        _T("OPENDOC"),
        ACRX_CMD_MODAL,
        OpenDwg);

}

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

extern "C" 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;
}

Here is code snippet I used, in the command macro just type _OPENDOC

0 Likes
Message 13 of 13

shaohuilv
Explorer
Explorer

acedRegCmds->addCommand(_T("ASDK_MAKE_ENTS"), _T("OPENDOC"), _T("OPENDOC"), ACRX_CMD_MODAL|ACRX_CMD_SESSION, OpenDwg);

0 Likes