Text Height Update In C Sharp

Text Height Update In C Sharp

muckmailer
Collaborator Collaborator
4,185 Views
45 Replies
Message 1 of 46

Text Height Update In C Sharp

muckmailer
Collaborator
Collaborator

The following Lisp route will update text by style. Can this be done in C sharp?

 

I am looking for a c sharp routine that would have an select all so I can make changes to all text in the drawing.

 

 

;;  TextHeightUpdate.lsp [command name: THU]
;;  To Update the Height of Text and Mtext in Styles with defined heights,
;;    when height has been changed in Style definition.  Checks Style of all
;;    selected Text/Mtext, and it has a defined height, imposes that on object.
(defun C:THU (/ ss n obj ht)
  (prompt "\nTo Update the Height of fixed-height Text/Mtext,")
  (if (setq ss (ssget '((0 . "TEXT,MTEXT"))))
    (repeat (setq n (sslength ss))
      (setq obj (vlax-ename->vla-object (ssname ss (setq n (1- n)))))
      (if
        (> (setq ht (cdr (assoc 40 (tblsearch "style" (vla-get-StyleName obj))))) 0)
        (vla-put-Height obj ht); then
      ); if
    ); repeat
  ); if
  (princ)
); defun
(vl-load-com)
(prompt "\nType THU for Text Height Update.")

Thank you

 

0 Likes
Accepted solutions (1)
4,186 Views
45 Replies
Replies (45)
Message 21 of 46

_gile
Consultant
Consultant

Oupss!...

 

Missing links to mtext format code in my previous message >>here<< and >>there<<.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 22 of 46

muckmailer
Collaborator
Collaborator

In Statement 

var regex = new Regex(@"\\W\d*(\.\d+)?;", RegexOptions.IgnoreCase);

New Regex is missing an assembly reference. 

Is there a reference library that  I might be missing?

 

Thank you,

0 Likes
Message 23 of 46

_gile
Consultant
Consultant

Visual Studio should help you if extend the popup near the electric light bulb.

 

using System.Text.RegularExpressions;


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 24 of 46

muckmailer
Collaborator
Collaborator

I have been working with the routine a little and it appears that it is not change Mtext height the

two statements.

 

else
                    {
                        //var mtext = (MText)tr.GetObject(id, OpenMode.ForRead);
                        var mtext = (MText)tr.GetObject(id, OpenMode.ForWrite);
                        mtext.Height = textStyles[mtext.TextStyleName];
                    }

 

Any suggestions?

 

Thank you,

0 Likes
Message 25 of 46

_gile
Consultant
Consultant

Have you watched the formatting of the mtext?

As for the width, the height can be affected by this formatting.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 26 of 46

muckmailer
Collaborator
Collaborator

Well I have tried the following:

using (var tr = db.TransactionManager.StartTransaction())
            {
                foreach (SelectedObject so in psr.Value)
                {
                    var id = so.ObjectId;
                    if (id.ObjectClass.IsDerivedFrom(textClass))
                    {
                        var text = (DBText)tr.GetObject(id, OpenMode.ForWrite);
                        text.Height = textStyles[text.TextStyleName];
                    }
                    else
                    {
                        
                        var mtext = (MText)tr.GetObject(id, OpenMode.ForRead);
                        //var mtext = (MText)tr.GetObject(id, OpenMode.ForWrite);
                        mtext.Height = textStyles[mtext.TextStyleName];
                        var regex = new System.Text.RegularExpressions.Regex(@"\\W\d*(\.\d+)?;", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                        mtext.Contents = regex.Replace(mtext.Contents, "");
                    }
                }
                tr.Commit();
            }
        }

Right now I am getting the error message 

ErrorMessage.png

0 Likes
Message 27 of 46

ActivistInvestor
Mentor
Mentor
Look at the error message.  What do you think eNotOpenForWrite means?

You can't modify an object unless you open it for write.



@muckmailer wrote:

Well I have tried the following:

using (var tr = db.TransactionManager.StartTransaction())
            {
                foreach (SelectedObject so in psr.Value)
                {
                    var id = so.ObjectId;
                    if (id.ObjectClass.IsDerivedFrom(textClass))
                    {
                        var text = (DBText)tr.GetObject(id, OpenMode.ForWrite);
                        text.Height = textStyles[text.TextStyleName];
                    }
                    else
                    {
                        
                        var mtext = (MText)tr.GetObject(id, OpenMode.ForRead);
                        //var mtext = (MText)tr.GetObject(id, OpenMode.ForWrite);
                        mtext.Height = textStyles[mtext.TextStyleName];
                        var regex = new System.Text.RegularExpressions.Regex(@"\\W\d*(\.\d+)?;", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                        mtext.Contents = regex.Replace(mtext.Contents, "");
                    }
                }
                tr.Commit();
            }
        }

Right now I am getting the error message 

ErrorMessage.png


 

0 Likes
Message 28 of 46

muckmailer
Collaborator
Collaborator

Yes I found the "For read" problem.

 

Could the mtext be exploded to text then formatted to height and width.

 

In the intellosense I see Mtext.explode but I don't know how to use it
and I don't know where to go to find reference material on it other than google.

 

Thank you,

0 Likes
Message 29 of 46

_gile
Consultant
Consultant

This seems to work from the some tests I did.

 

        [CommandMethod("THWU")]
        public void TextHeightWidthUpdate()
        {
            var doc = Application.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;

            var textStyleHeights = GetFixedHeightTextStyles(db);
            var textStyleWidths = GetFixedWidthTextStyles(db);

            var filter = new SelectionFilter(new[] { new TypedValue(0, "MTEXT,TEXT") });
            var psr = ed.SelectAll(filter);
            if (psr.Status != PromptStatus.OK)
                return;

            var textClass = RXObject.GetClass(typeof(DBText));

            using (var tr = db.TransactionManager.StartTransaction())
            {
                foreach (SelectedObject so in psr.Value)
                {
                    var id = so.ObjectId;
                    if (id.ObjectClass.IsDerivedFrom(textClass))
                    {
                        var text = (DBText)tr.GetObject(id, OpenMode.ForWrite);
                        if (textStyleHeights.ContainsKey(text.TextStyleName))
                            text.Height = textStyleHeights[text.TextStyleName];
                        if (textStyleWidths.ContainsKey(text.TextStyleName))
                            text.WidthFactor = textStyleWidths[text.TextStyleName];
                    }
                    else
                    {
                        var mtext = (MText)tr.GetObject(id, OpenMode.ForWrite);
                        // set the text height equal to the textstyle height (if different from 0)
                        if (textStyleHeights.ContainsKey(mtext.TextStyleName))
                            mtext.TextHeight = textStyleHeights[mtext.TextStyleName];
                        // remove width and height formatting
                        double widthFactor = textStyleWidths.ContainsKey(mtext.TextStyleName) ?
                            textStyleWidths[mtext.TextStyleName] :
                            1.0;
                        TextEditor textEditor = TextEditor.CreateTextEditor(mtext);
                        textEditor.SelectAll();
                        textEditor.Selection.WidthScale = widthFactor;
                        textEditor.Selection.Height = textEditor.TextHeight;
                        textEditor.Close(TextEditor.ExitStatus.ExitSave);
                    }
                }
                tr.Commit();
            }
        }

        Dictionary<string, double> GetFixedHeightTextStyles(Database db)
        {
            using (var tr = db.TransactionManager.StartOpenCloseTransaction())
            {
                return ((TextStyleTable)tr.GetObject(db.TextStyleTableId, OpenMode.ForRead))
                    .Cast<ObjectId>()
                    .Select(id => (TextStyleTableRecord)tr.GetObject(id, OpenMode.ForRead))
                    .Where(ts => ts.TextSize > 0.0)
                    .ToDictionary(ts => ts.Name, ts => ts.TextSize);
            }
        }

        Dictionary<string, double> GetFixedWidthTextStyles(Database db)
        {
            using (var tr = db.TransactionManager.StartOpenCloseTransaction())
            {
                return ((TextStyleTable)tr.GetObject(db.TextStyleTableId, OpenMode.ForRead))
                    .Cast<ObjectId>()
                    .Select(id => (TextStyleTableRecord)tr.GetObject(id, OpenMode.ForRead))
                    .Where(ts => ts.XScale > 1.0)
                    .ToDictionary(ts => ts.Name, ts => ts.XScale);
            }
        }


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 30 of 46

muckmailer
Collaborator
Collaborator

 

 Give me a little time to work with this routine.

 Since I am a beginner and not my primary job it will take some time.

 I plan on keeping the thread open for that reason.  

 

I looked at of your tutorial webpages.

Do you have any of your tutorials that are in English?

 

Thank you,

0 Likes
Message 31 of 46

_gile
Consultant
Consultant

@muckmailer wrote:

 

I looked at of your tutorial webpages.

Do you have any of your tutorials that are in English?

 


Only this one which was mainly translated with Bing and/or Google I don't remember.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 32 of 46

muckmailer
Collaborator
Collaborator

The routine works but how do I learn how to create such a routine?

 

How do I know how to use the keywords to use in intellisense show to properly
make a usable statement in c sharp and AutoCAD? Do you use the AutoDesk Developer
wepage to do that?

 

I am also looking for a good C sharp AutoCAD tutorial because I don't know what some
terms mean. For example I think you used "casting".

 

There should be some good material out there somewhere for the beginner but I
can't find it.

 

Thank you,

0 Likes
Message 33 of 46

_gile
Consultant
Consultant

You should learn C# / .NET / Visual Studio / OOP outside of AutoCAD first. There's a big amount of learning material for this.

And only after you're cumfortable with all this stuff, you can come back to AutoCAD programming with some background which will compensate the lack of documentation of the AutoCAD API.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 34 of 46

ActivistInvestor
Mentor
Mentor

@muckmailer wrote:

The routine works but how do I learn how to create such a routine?

 

How do I know how to use the keywords to use in intellisense show to properly
make a usable statement in c sharp and AutoCAD? Do you use the AutoDesk Developer
wepage to do that?

 

I am also looking for a good C sharp AutoCAD tutorial because I don't know what some
terms mean. For example I think you used "casting".

 

There should be some good material out there somewhere for the beginner but I
can't find it.

 

Thank you,


In that case, I would suggest first learning how to use the Internet as a resource.

 

For example, learning how to use google to search for learning material for programming.

 

 

0 Likes
Message 35 of 46

muckmailer
Collaborator
Collaborator

Would looking at VS class view give me some ideal how the AutoCAD.net paths are organized?

Could this be done in VS object browser?

Do need to look at Autodesk webpages to get an ideal of AutoCAD structure that
determines how these path are composed?

0 Likes
Message 36 of 46

ActivistInvestor
Mentor
Mentor

@muckmailer wrote:

Would looking at VS class view give me some ideal how the AutoCAD.net paths are organized?

Could this be done in VS object browser?

Do need to look at Autodesk webpages to get an ideal of AutoCAD structure that
determines how these path are composed?


I'm not sure what you mean by 'paths'.

 

The API is very large and contains many classes. The only way to become familiar with it is to read the docs, and study the code samples, or enroll in some sort of training class.

0 Likes
Message 37 of 46

_gile
Consultant
Consultant

If you have (and you should have) download and install some ObjectARX SDK, you can find in the class map folder, a classmap.dwg file showing the class hierarchy.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 38 of 46

muckmailer
Collaborator
Collaborator

Well I just down loaded and installed. Looks like there is a docs folder with a setup files. I installed those files but I don't know where to go to use  the documents files.  Is there some useful tools in that folder? 

ArxImage1.PNG

 

 

0 Likes
Message 39 of 46

ActivistInvestor
Mentor
Mentor

Double-click on arxmgd.chm

 


@muckmailer wrote:

Well I just down loaded and installed. Looks like there is a docs folder with a setup files. I installed those files but I don't know where to go to use  the documents files.  Is there some useful tools in that folder? 

 

 

 


 

 

 

0 Likes
Message 40 of 46

muckmailer
Collaborator
Collaborator

If I start the update routine using a form button with the attached code the
routine does not do anything until after:

1. The button is pushed
2. I exit the form the button is in.
3. I hit the return key on the keyboard

 

How can I put this routine in a loop?
For example a file loop to that open and closes
several drawings for update?

Thank you,

private void button7_Click(object sender, EventArgs e)
        {
           //Routine TextHeightUpdateNoElock() [CommandMethod("THWU")]
            var doc = Autodesk.AutoCAD.ApplicationServices.Core.Application.DocumentManager.MdiActiveDocument;
            if (doc != null)
                doc.SendStringToExecute("THWU", false, false, false);
        }

 

0 Likes