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
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.
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.
I suppose someone somewhere may have a reason for wanting to add educational stamps to all their drawings . 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?
Applies to:
AutoCAD® 2006
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?
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=::SetWindowsHookEx(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;
}
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
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