.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Creating New Drawings Using Templates

10 REPLIES 10
Reply
Message 1 of 11
bjhuffine
1040 Views, 10 Replies

Creating New Drawings Using Templates

I have a simple application that needs to create a series of new drawings (it can leave them open for the user to save later if need be) where each drawing is based on a special drawing template (*.dwt). I have looked long and hard on these and other forums and I cannot find anything... arrrggggghhhh....

What I've found so far is (in a very, very simplified form):

Public Shared Sub CreateNewDocument()
Dim acDocMgr As DocumentCollection = Application.DocumentManager
Dim acDoc As Document = acDocMgr.Add("..\mytemplate.dwt")
End Sub

However, I don't want to create the document in the Command method!!! Nor do I want to create the documents in the same class!!! And unfortunately, once this set of code leaves this method and class, I end up with a COM exception... So basically, this example (which comes from the Autodesk Developers Guide) is only good in the class where the commandflags are defined...

What am I doing wrong? Is there another way?
10 REPLIES 10
Message 2 of 11
Anonymous
in reply to: bjhuffine

You can only open, close or switch documents from code that
runs in the application execution context, which is what using the
CommandFlags.Session attribute does - it causes your command
method to run in the application context.

If the code where you want to open a file is running in the document
context, the only chance you have, is to call the DocumentCollection's
ExecuteInApplicationContext method, and pass it a delgate that will
be called in the application context, where it can open a document.

However, you will also have to ensure that the document that was
active when you called ExecuteInApplicationContext remains the
active document, or the code that calls ExecuteInApplicationContext
will be blocked until the document that was active when it called that
API is made active again.

Any questions?

--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD
Supporting AutoCAD 2000 through 2010

http://www.acadxtabs.com

Email: string.Format("{0}@{1}.com", "tonyt", "caddzone");

wrote in message news:6343759@discussion.autodesk.com...
I have a simple application that needs to create a series of new drawings (it
can leave them open for the user to save later if need be) where each drawing is
based on a special drawing template (*.dwt). I have looked long and hard on
these and other forums and I cannot find anything... arrrggggghhhh....

What I've found so far is (in a very, very simplified form):

Public Shared Sub
CreateNewDocument()
Dim acDocMgr As DocumentCollection = Application.DocumentManager
Dim acDoc As Document = acDocMgr.Add("..\mytemplate.dwt")
End Sub

However, I don't want to create the document in the Command method!!! Nor do I
want to create the documents in the same class!!! And unfortunately, once this
set of code leaves this method and class, I end up with a COM exception... So
basically, this example (which comes from the Autodesk Developers Guide) is only
good in the class where the commandflags are defined...

What am I doing wrong? Is there another way?
Message 3 of 11
bjhuffine
in reply to: bjhuffine

Well, I think I understand where you're going with this... but I'm not sure how to put it all together. The method's parameter is looking for an ExecuteInApplicationContextCallback object (I assume the delegate to which you are referring to) as well as a data parameter as object. Do you know if there's any sample code anywhere that would help clear up use of this tool? I'll apologize in advance, I'm a learning developer... especially with AutoCAD.

Thanks...
Message 4 of 11
bjhuffine
in reply to: bjhuffine

After playing around with it a bit I come out with the following for a first attempt. Note that I just created a small sample program to test the concept:

Imports Autodesk.AutoCAD.ApplicationServices

Public Class frmSample

Private Sub frmSample_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

Dim DocMgr As DocumentCollection = Application.DocumentManager
DocMgr.ExecuteInApplicationContext(New ExecuteInApplicationContextCallback(AddressOf TemplateDelegate), Nothing)

DocMgr.ExecuteInApplicationContext(New ExecuteInApplicationContextCallback(AddressOf TemplateDelegate), Nothing)

DocMgr.ExecuteInApplicationContext(New ExecuteInApplicationContextCallback(AddressOf TemplateDelegate), Nothing)

End Sub

Private Sub TemplateDelegate()
Dim Dwg As Document
Dwg = Application.DocumentManager.MdiActiveDocument
Dim DocMgr As DocumentCollection = Application.DocumentManager
Dim Doc As Document = DocMgr.Add("C:\Documents and Settings\BJHUFFIN\Desktop\Testing\mytemplate.dwt")

Application.DocumentManager.MdiActiveDocument = Dwg
End Sub

End Class

Not sure what the data parameter needs so I just gave it Nothing. Is this close?
Message 5 of 11
Anonymous
in reply to: bjhuffine

The callback is just a method (which can be an instance method
or a static/shared method), that takes a single argument typed as
System.Object, and returns void (e.g., a sub not a function):

{code}

Public Class Class1

' Runs the callback that opens the document in the
' Application execution context:

Public Sub OpenInAppContext( ByVal filename As String )
Dim docs As DocumentCollection = Application.DocumentManager
docs.ExecuteInApplicationContext( AddressOf Me.MyCallback ), filename )
End Sub

' The callback that will run in the application
' execution context:

Public Sub MyCallback( ByVal Data As Object )

' Open the document here, whose name was passed in
' the Data parameter

End Sub

End Class

{code}


--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD
Supporting AutoCAD 2000 through 2010

http://www.acadxtabs.com

Email: string.Format("{0}@{1}.com", "tonyt", "caddzone");

wrote in message news:6343804@discussion.autodesk.com...
Well, I think I understand where you're going with this... but I'm not sure how
to put it all together. The method's parameter is looking for an
ExecuteInApplicationContextCallback object (I assume the delegate to which you
are referring to) as well as a data parameter as object. Do you know if there's
any sample code anywhere that would help clear up use of this tool? I'll
apologize in advance, I'm a learning developer... especially with AutoCAD.

Thanks...
Message 6 of 11
Anonymous
in reply to: bjhuffine

Hello bjhuffin,
Maybe I'm missing something but why can't you just use the built in .NET
file copy command? I do this reading an excel file that creates about 40
different template files (from a base Civil3D template) and creates the layers
and filters according to specified parameters. I do some exception handling
but the code below is the basic flow.

Dim fi as New FileInfo(templateFilename)
Dim doc as Document
if fi.Exists then
'create new file from template
File.Copy(tempPlateFilename, newFilename, True)
fi = New FileInfo(newFilename)
'if template was readonly, new file will be readonly, turn readonly
off
if fi.Exists then
if fi.IsReadOnly then
fi.IsReadOnly = False
End If
End If

doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.Open(newFilename,
False)
Dim doclock as DocumentLock = doc.LockDocument
'Do your special stuff here
doclock.Dispose()
doc.CloseAndSave(newFilename)
End If


> I have a simple application that needs to create a series of new
> drawings (it can leave them open for the user to save later if need
> be) where each drawing is based on a special drawing template (*.dwt).
> I have looked long and hard on these and other forums and I cannot
> find anything... arrrggggghhhh....
>
> What I've found so far is (in a very, very simplified form):
>
> Public Shared Sub
> CreateNewDocument()
> Dim acDocMgr As DocumentCollection =
> Application.DocumentManager
> Dim acDoc As Document = acDocMgr.Add("..\mytemplate.dwt")
> End Sub
> However, I don't want to create the document in the Command method!!!
> Nor do I want to create the documents in the same class!!! And
> unfortunately, once this set of code leaves this method and class, I
> end up with a COM exception... So basically, this example (which
> comes from the Autodesk Developers Guide) is only good in the class
> where the commandflags are defined...
>
> What am I doing wrong? Is there another way?
>
Message 7 of 11
bjhuffine
in reply to: bjhuffine

Mostly because I'm stubborn... and knew that in one or two lines of code you could easily do this with the old VBA API so I figured it should be capable of being accomplished with the .Net API as well. I was struggling to figure that out. Also, I'm leaving it up to the users to save the files after they've been created and altered off the templates... So there's no need to determine the directory. Normally I'd go the extra mile for this, but I'm being rushed to recreate what someone else already had done in VBA due to some issues with the VBA API. This means wysiwyg for this.

It's also made for a great learning experience attempting to piece together the concept of application and document-level context for our coding (Thanks Tony!!!). Definitely something to continue thinking about... such as what methods will work in the document context and what needs to be run in the application context, etc...

I have to admit that I hadn't thought about using the FileCopy approach. Good suggestion!!
Message 8 of 11
bjhuffine
in reply to: bjhuffine

Okay, so now I can't seem to modify the drawings. I get a fatal error when Upgrading the open from read to write. Below is a short sample, only to simplify what I show you I tried to open as Write first thing... I get the error either way. What's causing this? Did I do something wrong when using the delegate?

> 'The calling method's statements...

> 'Create and process drawings in the application context
> Dim Docs As DocumentCollection = Application.DocumentManager
> Docs.ExecuteInApplicationContext(AddressOf CreateDrawingCallback, RemoveLayers)
>


> Public Sub CreateDrawingCallback(ByVal RemoveLayers As Generic.List(Of String))
>

> 'Determine the currently active document
> Dim ActiveDoc As Document = Application.DocumentManager.MdiActiveDocument
>

> 'Create drawings and remove excessive layers
> For Each Template As BaseTemplate In Templates
>

> 'Create document object
> Dim Docs As DocumentCollection = Application.DocumentManager
> Dim Dwg As Document = Docs.Add(Template.TemplatePath)
>

> 'Remove objects identified on specified layers and update properties
> Using trn As Transaction = Dwg.TransactionManager.StartTransaction
>

> Dim bt As BlockTable = trn.GetObject(Dwg.Database.BlockTableId, OpenMode.ForWrite, False)
> Dim btrModelSpace As BlockTableRecord = trn.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite, False)
>

> Dim bteEntities As BlockTableRecordEnumerator = btrModelSpace.GetEnumerator
>

Message 9 of 11
bjhuffine
in reply to: bjhuffine

Woops... I found this one... I forgot to lock the document. It all works now... Thanks!
Message 10 of 11
mconley
in reply to: bjhuffine


@Anonymous wrote:
Woops... I found this one... I forgot to lock the document. It all works now... Thanks!

I am trying to use parts of your code in the previous post.     Where did you place the document lock.   Can you post the solution with the document lock?

Message 11 of 11
mconley
in reply to: mconley

Nevermind, I solved my problem.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost