Author Topic: Take me to your leader  (Read 7679 times)

0 Members and 1 Guest are viewing this topic.

sinc

  • Guest
Take me to your leader
« on: June 29, 2008, 12:07:54 PM »
Has anyone tried messing with leaders or dimensions in .NET?

I was trying to get to and modify the MText portion of a MLEADER, and not having any luck.  When I take a look at the MLeader.MText property, it's always a DBObject with ObjectId = 0, which means I haven't found any way to open it for writing.  Is there some trick I'm overlooking?

I was also playing with standard dimensions.  Now those are bizarre...  They seem to use an MText as well, but they seem to delete and recreate the MText every time the dimension is modified (even a simple drag to another location).  I was actually able to create something that can turn on background masks for standard dimensions, but they all get reset when the drawing is saved and reopened.  And there doesn't seem to be any way to get to the text part - there is no Dimension.MText method.  So I couldn't get anything useful to work.

Chuck Gabriel

  • Guest
Re: Take me to your leader
« Reply #1 on: June 30, 2008, 07:04:05 AM »
Not sure about the first part, but for the second part, won't setting the Dimtfill property of the dimension do what you want?

sinc

  • Guest
Re: Take me to your leader
« Reply #2 on: June 30, 2008, 10:02:55 AM »
Wow!  How long as that been in Autocad?  Why is it so hidden?  I couldn't even find a mention of it in the help, except for in the system variables, once I knew to search for DIMTFILL.

So, after a dimension is created, how do I turn the background mask on and off?  Or can I?

But yeah, that helps!  We've been drawing wipeouts behind all our dimensions.  Maybe I should tell the other guys this is a new feature I just added in the Sincpac, and not that it's something we've had in Autocad for a while...    :-D

Chuck Gabriel

  • Guest
Re: Take me to your leader
« Reply #3 on: June 30, 2008, 10:41:04 AM »
So, after a dimension is created, how do I turn the background mask on and off?  Or can I?

I thinks it's all in that one property.

Quote
Accesses the dimension background color state, which can be one of the following values:
0 means the background color is disabled
1 means the use background color from dimtfillclr
2 means the use drawing's background color

sinc

  • Guest
Re: Take me to your leader
« Reply #4 on: June 30, 2008, 11:59:12 AM »
Yeah, but as far as I can tell, all that does is affect the setting for newly-created dimensions.

I was wondering if there's a way to turn the background mask on or off for dimensions that are already in the drawing.  As far as I can tell, the answer is no...

Chuck Gabriel

  • Guest
Re: Take me to your leader
« Reply #5 on: June 30, 2008, 12:56:05 PM »
Yeah, but as far as I can tell, all that does is affect the setting for newly-created dimensions.

I was wondering if there's a way to turn the background mask on or off for dimensions that are already in the drawing.  As far as I can tell, the answer is no...

I pulled that information from the Managed API documentation for the Dimension class.  That implies to me that each Dimension object can have its background fill property set individually.

I don't think we are on the same wavelength here.  Either that, or I am overlooking something obvious.

Glenn R

  • Guest
Re: Take me to your leader
« Reply #6 on: June 30, 2008, 12:59:29 PM »
It's an override on the individual dimension as well as being present when a style is created.

sinc

  • Guest
Re: Take me to your leader
« Reply #7 on: June 30, 2008, 01:42:30 PM »
Oh, jeez.

In the properties, set "Fill Color" to "Background".  No wonder I never saw it.  I was busily looking for a property that was easily-understood, like "Background mask".

Gotta put on my Autodesk cap, and think about things in a "skew" fashion, and then it makes sense...

Use either DIMTFILL or "Fill Color" to turn on background masks for dimensions.  I would have found this years ago if it was clearly stated in the Help, or if it was named something better, but I got it now.  Better late than never, eh?   :-)

OK, so now how about getting to the text component of MLEADERS via .NET?  Anyone tried that?  Had any luck?

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Take me to your leader
« Reply #8 on: June 30, 2008, 02:07:07 PM »
I haven't looked at mleaders, but are the associated with a block?  If so, then you will have to change the mtext in the block definition.  Just a guess though.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

Chuck Gabriel

  • Guest
Re: Take me to your leader
« Reply #9 on: June 30, 2008, 02:18:05 PM »
OK, so now how about getting to the text component of MLEADERS via .NET?  Anyone tried that?  Had any luck?

I think the Annotation property gets you the ObjectId of the annotation object.

Glenn R

  • Guest
Re: Take me to your leader
« Reply #10 on: June 30, 2008, 03:08:25 PM »
Sample code?

sinc

  • Guest
Re: Take me to your leader
« Reply #11 on: June 30, 2008, 04:07:57 PM »
Like I stated in my first post, there is an MLeader.MText property which returns the MTEXT entity used by the MLEADER.  The only problem is that it always has ObjectID = 0, so if I try to edit it, I get an access violation error.  At least, I think that's why I get the crash.

Glenn R

  • Guest
Re: Take me to your leader
« Reply #12 on: June 30, 2008, 04:17:34 PM »
The only problem is that it always has ObjectID = 0, so if I try to edit it, I get an access violation error.  At least, I think that's why I get the crash.

More than likely, as that equates to a null ObjectId, however it's a lot easier for people to test and try to get a solution if they have either:

A. Sample test code to recreate the problem or,
B. The actual code that is causing the crash.

Preferably both, depending on the circumstances/crash. Also, I can only assume by your sig that you're using Civ 3d 2009...is that correct?

Glenn R

  • Guest
Re: Take me to your leader
« Reply #13 on: June 30, 2008, 05:15:59 PM »
Code: [Select]
[CommandMethod("tcgsMleader")]
public static void tcgsMleaderCommand()
{
Document doc = acadApp.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;

PromptEntityOptions promptEntOpts = new PromptEntityOptions("Select MLeader: ");
promptEntOpts.SetRejectMessage("Selected entity is not an MLeader!");
promptEntOpts.AddAllowedClass(typeof(MLeader), true);


PromptEntityResult promptEntRes = ed.GetEntity(promptEntOpts);
if (promptEntRes.Status != PromptStatus.OK)
return;

using (Transaction tr = db.TransactionManager.StartTransaction())
{
MLeader ml = tr.GetObject(promptEntRes.ObjectId, OpenMode.ForRead, true) as MLeader;
if (ml == null)
return;

if (ml.HasContent())
{

MText leaderMtext = ml.MText;
if (leaderMtext == null)
{
ed.WriteMessage("{0}Error: Failed to get MText object of MLeader!", System.Environment.NewLine);
return;
}

ml.UpgradeOpen();

leaderMtext.Contents = "Helloooo TheSwamp!";
ml.MText = leaderMtext;

}

tr.Commit();
}
}

From the ARX docs:

Quote
Acad::ErrorStatus

setMText(

const AcDbMText* pMText);

pMText Input the pointer of MText object.

Sets a MText object to mleader.

Mleader will not change the input pMText. It doesn’t mind whether the pMText is database resident too. It just copies the content and fields of input MText to itself.

Returns Acad::eOk if successful.


The keyword here is 'copies' when referenced to this:

Quote
AcDbMText *

mtext() const;

Gets a clone of mleader’s mtext content

User need to release the returned mtext.

Returns the cloned mtext. If there is no mtext content, it returns NULL.


Keyword there is 'cloned'. So, changing the MText object's contents won't do anything until you reassign, as the value returned for the MText is a 'clone'.


The code was developed in Vis Stud 2008 Express and using AutoCAD Map 2008 for testing.

Glenn R

  • Guest
Re: Take me to your leader
« Reply #14 on: June 30, 2008, 05:19:17 PM »
BTW, this was tested in Map 2008 by starting Acad and in the initial blank drawing creating an MLEADER.
If this doesn't work in your test drawing, it's possibly an associativity issue...

Glenn R

  • Guest
Re: Take me to your leader
« Reply #15 on: June 30, 2008, 05:21:21 PM »
...as this would probably mean the MText content is null...

sinc

  • Guest
Re: Take me to your leader
« Reply #16 on: June 30, 2008, 05:36:26 PM »
OK, guess I'll have to dig into it more.

That looks identical to what I've tried, but I only get crashes.

Oh, I should probably add that I'm attempting to change the item from the Database.ObjectAppended event handler.  Well, not exactly there, because attempting to edit it there would cause a crash.  But I store the ObjectId of the newly-created MLeader in my event handler for Database.ObjectAppended, and then I try to access it in the DocumentManager.DocumentLockModeWillChange event handler.  When I try to do that, the ObjectId is 0, and the UpgradeOpen fails.

Glenn R

  • Guest
Re: Take me to your leader
« Reply #17 on: June 30, 2008, 05:47:39 PM »
Oh, I should probably add that I'm attempting to change the item from the Database.ObjectAppended event handler.  Well, not exactly there, because attempting to edit it there would cause a crash.  But I store the ObjectId of the newly-created MLeader in my event handler for Database.ObjectAppended, and then I try to access it in the DocumentManager.DocumentLockModeWillChange event handler.  When I try to do that, the ObjectId is 0, and the UpgradeOpen fails.

I'm not surprised one little bit. Also, you're only just mentioning this? This is why I asked for sample code.
None of that will work as AutoCAD is 'doing stuff' and has it open. Also, don't even try modifying objects in DocLockModWillChange as you're just asking for trouble.

Redesign your attack.

Glenn R

  • Guest
Re: Take me to your leader
« Reply #18 on: June 30, 2008, 06:00:00 PM »
Sorry - I made an incorrect statement when I posted that ObjectId = 0 is null.

Before I consulted the docs, I was under the impression that the MText property returned an ObjectId - this is not the case. It returns a pointer to the clone and in C based languages, a null pointer can be initialised to 0 (or NULL in the MS implementations which is an alias for 0).

sinc

  • Guest
Re: Take me to your leader
« Reply #19 on: June 30, 2008, 09:39:59 PM »
Well, as you might imagine, it would not be easy to extract the code in question, especially into a self-contained snippet that someone could actually run.  It's embedded in a rather large application.

But yeah, I understand that code samples make it easier to detect issues.

So where is the approved place of modifying an object that has just been appended to the database?  I put it where I did because I was copying either a post by Tony Tanzillo or Kean, I can't remember which.  But I may have mis-applied it - I'll have to look again for the post that caused me to do what I did, and see if I misread it.

But to get back to the important point, where is the approved place to modify a newly-appended database entity?

sinc

  • Guest
Re: Take me to your leader
« Reply #20 on: June 30, 2008, 10:07:18 PM »
Is Document.CommandEnded a good place to modify database entities?

MickD

  • King Gator
  • Posts: 3636
  • (x-in)->[process]->(y-out) ... simples!
Re: Take me to your leader
« Reply #21 on: June 30, 2008, 10:20:57 PM »
ent.upgrade open maybe??
I'm sure in ARX until you close the object even after adding it to the db you can edit it, can't quite remember though...
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

sinc

  • Guest
Re: Take me to your leader
« Reply #22 on: July 01, 2008, 02:27:54 AM »
Is Document.CommandEnded a good place to modify database entities?

Well, I checked in CommandEnded, and the ObjectId is still 0 there, so that doesn't work.

But I also saw a post by Tony T that said doing things in CommandEnded can cause problems with Undo/Redo.  So that doesn't seem to be a good idea in any case.

I found the sample code that caused me to put it in DocumentLockModeWillChange in the first place, and sure enough, it came from Kean Walmsley's column, where he uses the technique on blocks:

http://through-the-interface.typepad.com/through_the_interface/files/auto-bubble-creation-part4.cs

Glenn R

  • Guest
Re: Take me to your leader
« Reply #23 on: July 01, 2008, 05:24:30 AM »
ent.upgrade open maybe??
I'm sure in ARX until you close the object even after adding it to the db you can edit it, can't quite remember though...

Acad still has it open for write during the event Mick. Many may read, but 'there can be only one' for write.
Think of a polyline.

The poly header gets added and ObjectAppended fires.
Next vertex is added and ObjectAppended fires.

At this stage, you do not have a complete object to work with.

Next vertex is added and ObjectAppended fires.
Command is finished and SEQEND is added to poly and entity closed.

The best way to see this is to fire up ArxDbg, enable it events for the dbase and start adding things.
You will be surprised as to the order of event invocation.

Glenn R

  • Guest
Re: Take me to your leader
« Reply #24 on: July 01, 2008, 04:02:17 PM »
Also, WRT my post quoting the docs, you will need to destroy the MText object.

Glenn R

  • Guest
Re: Take me to your leader
« Reply #25 on: July 02, 2008, 02:30:57 PM »
...as it's a clone and not dbase resident. I suspect that if you didn't do this, you would end up in memory-leak-land.