• Industries
  • Products
  • Buy
  • Services & Support
  • Communities
  • Discussion Groups

    Autodesk ObjectARX

    Reply
    Active Member
    Posts: 6
    Registered: ‎08-17-2012

    Hiding AutoCAD messages while processing on drawings

    384 Views, 4 Replies
    09-25-2012 12:33 AM

    Can anyone help?

    I'm working on an application in which I want to automatically open a drawing file in AutoCAD and do some processing on it then close that drawing automatically. And this process will be without user interventions. But in some of the drawings I am getting some messages while loading it in AutoCAD. ex. Missing language pack, Educational stamp and proxy related messages. I have managed the proxy related message, but how to hide the remaining messages and what are the other messages which I will get while loading the drawing in AutoCAD?

     

    Thanks & Regards,

    Abhishek

    Please use plain text.
    ADN Support Specialist
    Balaji_Ram
    Posts: 384
    Registered: ‎03-21-2011

    Re: Hiding AutoCAD messages while processing on drawings

    10-01-2012 08:56 AM in reply to: abhisheka

    Hi Abhishek,

     

    There is no such comprehensive collection of messages that you can expect.

     

    The "NOMUTT" and "CMDECHO" are the system variables related to suppressing messages, but they do not suppress all the messages.

     

    You may try them to see if it helps.

     

     

     

     



    Balaji
    Developer Technical Services
    Autodesk Developer Network

    Please use plain text.
    *Expert Elite*
    dgorsman
    Posts: 3,388
    Registered: ‎10-12-2006

    Re: Hiding AutoCAD messages while processing on drawings

    10-01-2012 11:24 AM in reply to: abhisheka

    Educational content warnings should *never* be ignored in a professional environment.  They should throw up (literally and figuratively) a massive stop sign and stop program execution so that drawing can be dealt with immediately, same as if a virus infected file is found.

    ----------------------------------
    If you are going to fly by the seat of your pants, expect friction burns.
    Adopt. Adapt. Overcome. Or be overcome.


    Please use plain text.
    ADN Support Specialist
    Posts: 261
    Registered: ‎05-22-2006

    Re: Hiding AutoCAD messages while processing on drawings

    10-01-2012 02:08 PM in reply to: dgorsman

    I suppose someone somewhere may have a reason for wanting to add educational stamps to all their drawings :smileywink:. But there's a difference between dismissing the dialog and moving to the next drawing, and dismissing the dialog and carrying on processing the drawing regardless. 

     

    As an additional consideration (for the proxy dialog) if you have proxy objects in the drawing, then some editing you may want to apply may not work correctly (e.g. if kCloningAllowed is not set) - so you need to log that for the user too.

     

    Anyway, here is a copy of an old ADN DevNote (from 2006), which I'm blindly copying here without checking its still applicable in case it helps. Note that AutoCAD 2006 was pre-unicode port. Sorry for the sub-optimal formatting:

     

    >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

    Batch processing drawings - how to dismiss the recover Warning errors found message?

    Published date: 2006-06-11
    ID: TS87239

    Applies to:
    AutoCAD® 2006

    Issue

    Our application opens and closes DWG files. The process is stopped by a recover needed message. If the dialog is dismissed the drawing is recovered and opens. Is there a way to dismiss this dialog without user intervention?

    Solution

    Here are several suggestions to consider. (There is not an AutoCAD API event that can be used to dismiss the Recover needed dialog).

    1) See related DevNote TS70296 "How to discard unwanted dialogs during scripts"for a VB example that will close dialogs without user intervention.Also there is a shareware app called BUZOF downloadable from http://www.basta.com/ProdBuzof.htm, and some other download sites like CNET (http://www.download.com/Buzof/3000-2094_4-5405349.html?tag=tab_pub).  You can use it free for 30 days, after which you must purchase it (15.00 USD).

    2) Setup a Windows CBT hook and watch for the creation of the dialog with specific name. If it matches just close it.


    HHOOK MyHook;
    LRESULT CALLBACK CBTHook(int nCode, WPARAM wParam, LPARAM lParam);
    LRESULT CALLBACK CBTHook(int nCode, WPARAM wParam, LPARAM lParam)
    {
                    try
                    {
                                   if (HCBT_CREATEWND == nCode)
                                    {
                                                    char winName[256];
                                                    memset(winName,0,256);
                                                    GetWindowText(GetActiveWindow(),winName,256);

     

                                                    if(0 == strcmpi(winName,"Security Options")) //check for the name
                                                    {
                                                                    SendMessage(GetActiveWindow(),WM_CLOSE,0,0);
                                                                    acutPrintf("\nsecurity options disabled");
                                                    }

                                    }

                    }
                    catch(...)
                    {}
                   return (::CallNextHookEx(MyHook,nCode,wParam,lParam));
     }

    Call the following in the On_kInitAppMsg
    MyHook=::smileyfrustrated:etWindowsHookEx(WH_CBT,(HOOKPROC)CBTHook,(HINSTANCE)NULL, ::GetCurrentThreadId());

    And this in the On_kUnloadAppMsg:
    ::UnhookWindowsHookEx(MyHook); //unhook

     

    3) You can invoke the Recover command directly to open the drawings. The only problem with this is that there is no way to invoke recover other than by the command line, and because the recover command is a mix of document context *and* Application context's.

     
    //-----------------------------------------------------------------------------
    // This is command 'OPENDWGDOC, by Fenton Webb [29/08/2003], DevTech, Autodesk
    void asdkopendwgDoc()
    {
     CString dwgNameToOpen;
     dwgNameToOpen = "c:\\temp\\test.dwg" ;
     
     if(acDocManager->isApplicationContext()) {
      acDocManager->appContextOpenDocument(dwgNameToOpen);
     }
     else acDocManager->executeInApplicationContext(OpenDwgFromApplicationContext, &dwgNameToOpen);
    }

     


    void OpenDwgFromApplicationContext(void *pData)
    {
     if(acDocManager->isApplicationContext())
     {
      CString *dwgNameToOpen = reinterpret_cast<CString*>(pData);
      acDocManager->sendStringToExecute(curDoc(), "_.recover ");
      //acDocManager->appContextOpenDocument(*dwgNameToOpen);
      acedGetAcadFrame()->SetTimer(999, 1000, RecoverTimer);
     }
     else return;
     
     acDocManager->setCurDocument(acDocManager->mdiActiveDocument());
    }
    // my timer proc, this will show the direction in which the entities are generated
    void CALLBACK EXPORT RecoverTimer (HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime)
    {
     CString cmd = "c:\\temp\\test.dwg\n";
     //  RegisterAPP() ;
     COPYDATASTRUCT cmdMsg;
     HWND hWndACAD;
     hWndACAD = adsw_acadMainWnd();
     cmdMsg.dwData = (DWORD)1;
     cmdMsg.cbData = (DWORD)_tcslen(cmd) + 1;
     cmdMsg.lpData = cmd.GetBuffer(cmd.GetLength()+1) ;                  
     // Send the message to AutoCAD.
     SendMessage(hWndACAD, WM_COPYDATA, (WPARAM)hWndACAD, (LPARAM)&cmdMsg);
     
     acedGetAcadFrame()->KillTimer(nIDEvent);
    }

     


    4) Another option is to iterate the child windows of AutoCAD using the WIn32 SDK func EnumChildWIndows(). Put this into a timerproc which fires every .5 of a second. If the EnumWindows finds a Y/N dialog simply pump the "Y" key to it.
     
    Here's some code which uses EnumChildWindows(), it is specific for finding a ToolBar in AutoCAD but can be easily adjusted for the Recover dialog.
     


    //////////////////////////////////////////////////////////////////////////
    // calls GetWindowFromName and then scans the main window for a specific control class name
    CWnd *CApplicationGlobals::GetControlFromWindow(CString windowName, CString className, int index)
    {
     // set the control index to the first one
     mSetControlIndex(0);
     // set the marker index to the one passed
     mSetControlIndexCount(index);
     // make sure the control is invalid first
     mSetControl(NULL);
     
     // find the window
     CWnd *window = CApplicationGlobals::GetWindowFromName(windowName);
     // if ok
     if (window)
     {
      CString windowText;
      window->GetWindowText(windowText);
      // now find the child windows of out toolbar
      if (EnumChildWindows(window->m_hWnd, (WNDENUMPROC)ChildWndProc, (LPARAM)&(className)))
       return NULL;
     
      // return the control window
      return mGetControl();
     }
     // if not ok, the window might be docked in which case we need to find the application window first
     // and then enumerate the children
     else
     {
      CString applicationText;
      // find the parent window
      acedGetAcadFrame()->GetWindowText(applicationText);
      // now find the application window
      CWnd *appWindow = CApplicationGlobals::GetWindowFromName(applicationText);
      // if ok
      if (appWindow)
      {
       mSetControl(appWindow);
       // lets loop until we find the control we want
       for (int controlBarCount=0; mGetControl() != NULL; ++controlBarCount)
       {
        // reset the counter
        mSetControlIndexCount(0);
        // set the control we want
        mSetControlIndex(controlBarCount);
     
        // now find the child windows of the toolbar, the first combobox
        if (EnumChildWindows(appWindow->m_hWnd, (WNDENUMPROC)ChildWndProc, (LPARAM)&(CString("AfxControlBar"))))
         continue;
     
        // if we found a control bar
        if (mGetControl() != NULL)
        {
         // set these to the first controlwindow in the controlbar
         mSetControlIndexCount(0);
         mSetControlIndex(0);
         // now lets look for the AfxWnd for the toolbar
         if (EnumChildWindows(mGetControl()->m_hWnd, (WNDENUMPROC)ChildWndProc, (LPARAM)&(CString("AfxWnd70"))))
          continue;
         // if we found it
         if (mGetControl() != NULL)
         {
          CString afxWndName;
          // check the name
          mGetControl()->GetWindowText(afxWndName);
          // if it's the one we want
          if (afxWndName == windowName)
          {
           // set these to the first item in the controlwindow
           mSetControlIndexCount(0);
           mSetControlIndex(0);
           // we definitly have the toolbar we want
           // so now get the combo box
           if (EnumChildWindows(mGetControl()->m_hWnd, (WNDENUMPROC)ChildWndProc, (LPARAM)&(className)))
            continue;
           //return NULL;
     
           // return the control window
           return mGetControl();
          }
         }
         else
         {
          AfxMessageBox("Failed to find AfxWnd70");
          break;
         }
        }
        else
        {
         AfxMessageBox("Failed to find AfxControlBar");
         break;
        }
       }
      }
     }
     
     AfxMessageBox("Here10");
     return NULL;
    }
     
    //////////////////////////////////////////////////////////////////////////
    // called for child windows of a hwnd
    BOOL CALLBACK CApplicationGlobals::ChildWndProc(HWND hwnd, LPARAM lParam)
    {
    #define CLASS_SIZE 500
     char wndowclass[CLASS_SIZE];
     
     // extract the class name
     if (!GetClassName(hwnd, wndowclass, CLASS_SIZE))
      return TRUE;
     
     CString className(wndowclass);
     // check to see if this is the combobox
     if (className == *((CString*)lParam))
     {
      // check to see if this is the control we want
      if (mGetControlIndex() == mGetControlIndexCount())
      {
       // convert the hwnd to a CWnd
       CWnd *window = CWnd::FromHandle(hwnd);
       // set the member variable to say we have it 
       mSetControl(window);
     
       // stop the enumeration as we have found the control
       return FALSE;
      }
      else
       // increment the counter
       mSetControlIndexCount(mGetControlIndexCount()+1);
     }
     
     return TRUE;
    }

    <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

     

     

    Cheers,

    Stephen Preston
    Autodesk Developer Network
    Please use plain text.
    Active Member
    Posts: 6
    Registered: ‎08-17-2012

    Re: Hiding AutoCAD messages while processing on drawings

    10-05-2012 09:41 PM in reply to: abhisheka

    Thanls All,

     

    We recieve these drawing files from our various customers, so I will have to check various drawing files to find out what different messages gets invoked. I have tried Windows CBT hook but unable to catch and control all the messages(ex. Educational version message, Foreign DWG file message, etc). Is there any other way to hide such messages so that my application can run smoothly without user intervention?

    About that missing language pack message, now I am not getting that message. I am not sure but I think it is because of my Antivirus update.

     

    Thanks & Regards,

    Abhishek

    Please use plain text.