Preventing AutoCAD from entering a zero doc state
Published date: 2005-03-04
ID: TS46546
Applies to:
AutoCAD® 2005
Issue
How do I prevent AutoCAD from entering a zero document state?
Solution
When AutoCAD is in a zero document state, you have very limited access to AutoCAD's functionality.
In addtion, there are additional complications.
One straightforward method of solving this problem is to prevent AutoCAD from entering the zero document state.
You can plant an AcApDocManagerReactor and override documentToBeDestroyed(), and call AcApDocManager::appContextNewDocument{}.
But this combination will not work because using document manipulation functions within a reactor callback is
unsafe. You cannot determine what state AutoCAD is in.
A workaround, is to install a timer. Make a reasonable estimate about how
long it will take AutoCAD to close a drawing, then set the timer accordingly.
Within the timer callback function, you can safely create a new drawing.The
following code demonstrates how this is done.
Published date: 2005-03-04
ID: TS46546
Applies to:
AutoCAD® 2005
Issue
How do I prevent AutoCAD from entering a zero document state?
Solution
When AutoCAD is in a zero document state, you have very limited access to AutoCAD's functionality.
In addtion, there are additional complications.
One straightforward method of solving this problem is to prevent AutoCAD from entering the zero document state.
You can plant an AcApDocManagerReactor and override documentToBeDestroyed(), and call AcApDocManager::appContextNewDocument{}.
But this combination will not work because using document manipulation functions within a reactor callback is
unsafe. You cannot determine what state AutoCAD is in.
A workaround, is to install a timer. Make a reasonable estimate about how
long it will take AutoCAD to close a drawing, then set the timer accordingly.
Within the timer callback function, you can safely create a new drawing.The
following code demonstrates how this is done.
//
// Notice that AsdkDataManager is the wizard generated,
// this is a modified version.
//
template <class T>
class AsdkDataManager : public AcApDocManagerReactor
{
public:
AsdkDataManager()
{
acDocManager->addReactor(this);
}
~AsdkDataManager()
{
acDocManager->removeReactor(this);
}
virtual void documentToBeDestroyed( AcApDocument *pDoc )
{
m_dataMap.erase(pDoc);
// If we know we're going to enter zero doc state
// add a new document so we're not.
if(acDocManager->documentCount() == 1)
m_timerId = ::SetTimer(NULL, 0, 100,
AsdkDataManager::TimerProc);
}
// notice the static callback function
static void CALLBACK EXPORT TimerProc(
HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
{
::KillTimer(NULL, m_timerId);
// if you don't like this to be the default template file
// change it to whatever you like
const char fileName[] = "acad.dwt";
Acad::ErrorStatus es = acDocManager->appContextNewDocument(fileName);
ASSERT(es == Acad::eOk);
acutPrintf("\nThere is a mechanism in place to prevent zero doc
state.");
acedPostCommandPrompt();
}
T& docData(AcApDocument* pDoc)
{
std::map<AcApDocument*, T>::iterator i;
i = m_dataMap.find(pDoc);
if (i==m_dataMap.end())
return m_dataMap[ pDoc ];
else
return (*i).second;
}
T& docData()
{
return docData(acDocManager->curDocument());
}
private:
std::map<AcApDocument*, T> m_dataMap;
static UINT m_timerId;
};
template <class T>
UINT AsdkDataManager<T>::m_timerId = 0;
댓글
댓글 쓰기