[2003 Drawing Control]Keeping references to Visio Objects?

S

Scott Metzger

Hi,

I am keeping a reference to the Document when I create my Drawing control...
MyDocument = new CVDocument(MyDrawing->get_Document());

In an OnCellChanged event handler I then try to use this reference and I
get exception (dialog just says "An Exception has occured.")
CString docName = MyDocument->get_Name(); // exception here

The address for MyDocument has not changed. If I do the following in
the OnCellCHanged event everything works fine...
CVDocument* drawDoc = new CVDocument(MyDrawing->get_Document());
CString docName = drawDoc->get_Name();

Why doesn't this work? Is it safe to keep a reference to Visio Objects?

I am using Visio 2003 in a MFC C++ application. I have used the class
wizard to import the type library.

Thank You,
Scott Metzger
 
S

soso

...
In an OnCellChanged event handler I then try to use this reference and I
get exception (dialog just says "An Exception has occured.")
CString docName = MyDocument->get_Name(); // exception here

The address for MyDocument has not changed. ...

But what shows a QuickWatch for the MyDocument object? The address is not
changed, but is the object still valid?
 
M

Markus Breugst

Hi Scott,

as "soso" says: the address may be the same, but your reference may be
invalid. If QuickWatch shows you exceptions in most of the document's
properties, than your reference has expired.

I had the same problem several times with references to shapes. I did not
discover exactly the reason for this problem, but I solved it in the
following way: I implemented a wrapper class for Visio shapes with all shape
methods our application needs to access. Every wrapper method catches
exceptions thrown by the real Visio shape. If an exception occurs, the
wrapper class re-reads the shape reference from Visio (similar to the way
you described in the second half of your posting). The difference to your
case is that I never lost a reference to a document but only to shapes.

However, I am very interested in better solutions.

Best regards,
Markus
 
S

Scott Metzger

Thanks, I found my problem. I was getting a reference to the document
before I loaded in a drawing. It looks like the document object
reference changes when you call put_Src on the drawing control.

Markus said:
I had the same problem several times with references to shapes. I did not
discover exactly the reason for this problem, but I solved it in the
following way: I implemented a wrapper class for Visio shapes with all shape
methods our application needs to access. Every wrapper method catches
exceptions thrown by the real Visio shape. If an exception occurs, the
wrapper class re-reads the shape reference from Visio (similar to the way
you described in the second half of your posting). The difference to your
case is that I never lost a reference to a document but only to shapes.

That does not sound good at all. What language are you using? If your
using C# could your garbage collection be getting in the way? I can
sort of understand why my document object was lost (although there is no
documentation that details this behavior) because the whole Src =
"file", then Src = "", and can't use Document.Save (even though it has
been exposed in the typelibrary) is messed up.

Can anyone comment on why Markus's Shape references are being 'lost'?
 
M

Mark Nelson [MS]

One approach that our internal solution teams have taken is to hang on to
the GUID of a shape and a page ID rather than keep a reference to a shape.
This is generally better than holding actual shape references. When you
need to do something in Visio, get a new shape reference from the Shapes
collection of the appropriate page. Do your work and then discard the
reference before returning control to Visio.
 
S

Scott Metzger

soso said:
Do you mean that the Shape's GUID persistent for a Shape on a Page? If we
will load the same Visio Document another time the GUID for the Shape always
stay the same and unique for the Document's Page, is it? Is the Shape's GUID
unique per Page or per Document?

He is probably talking about Shape.UniqueID as per Visio documentation:
"If a Shape object has a unique ID, no other shape in any other document
will have the same ID."

But this would still require one to make a call to
Shapes.Item(UniqueIDString) to retrieve the shape in question. For me
the whole point of keeping references to the Visio objects is for speed.

Plus, this still doesn't answer the questions about why these objects
are being invalidated. Under what circumstances does a reference to a
Visio object become invalid? Is this intended behavior? Why?

Thanks,
Scott Metzger
 
S

soso

Mark Nelson said:
One approach that our internal solution teams have taken is to hang on to
the GUID of a shape and a page ID rather than keep a reference to a shape.

Do you mean that the Shape's GUID persistent for a Shape on a Page? If we
will load the same Visio Document another time the GUID for the Shape always
stay the same and unique for the Document's Page, is it? Is the Shape's GUID
unique per Page or per Document?



Thank You,

Soso.
 
M

Mark Nelson [MS]

Yes, you get a GUID by using the UniqueID method. I'm not convinced that
hanging on to Shape objects is always faster than getting them again.
Internally Visio has to construct a Shape object and maintain it while you
are holding on to it. There is some overhead involved in keeping this
object instantiated. If you are holding a large number of Shape references,
you may be impacting the performance of the system more than if you get and
discard Shapes as you need them. I wish I had some data to back up this
statement, but this is my understanding of the way the API layer works with
the underlying drawing.

As to when Shape objects become invalid, the obvious scenario is when they
get deleted. Other operations may also impact the shape. For example, Cut
& Paste results in a deletion and addition of the shape. Dragging a shape
from one window to another does too (even if the windows display the same
drawing page). Performing any action in the Shape > Operations menu results
in a new shape. I believe grouping operations may also impact the
reference.
 
S

Scott Metzger

Mark said:
Yes, you get a GUID by using the UniqueID method. I'm not convinced that
hanging on to Shape objects is always faster than getting them again.
Internally Visio has to construct a Shape object and maintain it while you
are holding on to it. There is some overhead involved in keeping this
object instantiated. If you are holding a large number of Shape references,
you may be impacting the performance of the system more than if you get and
discard Shapes as you need them. I wish I had some data to back up this
statement, but this is my understanding of the way the API layer works with
the underlying drawing.

IMO this is counter intuitive. Your saying it takes more processing
speed to keep a reference to an object than it is to destroy an object
and then re-create the reference to the object. Some wierd stuff must
be going on for that to be true. I am talking strictly speed and not
memory issues here.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top