Change temporary entity during selection, by using mouse button pan - C#

Change temporary entity during selection, by using mouse button pan - C#

cadVDJ3M
Enthusiast Enthusiast
1,397 Views
6 Replies
Message 1 of 7

Change temporary entity during selection, by using mouse button pan - C#

cadVDJ3M
Enthusiast
Enthusiast

Hi to all..

I'm using this code posted by @norman.yuan  in my applications and it works just perfect.

https://drive-cad-with-code.blogspot.com/2020/04/show-temporary-entityshape-during-user_21.html

 

 

I temporarily generate a DbText, which displays a type of count over the selection and places it in the upper left corner of the screen.

I would like to update the text position every time the user uses the PAN by the middle mouse button or Zoom by the MouseWhell.
Thus ensuring that the text maintains the same visual appearance as before.

It turns out that I can't interact with the entity temporarily generated by WordDraw. When trying to change this I cause a fatal error in AutoCAD.


this is the example.

temp_ent1.png

temp_ent2.png


When I use the PAN the entity leaves the screen, and I would like to update its position after the end of the pan. (Middle Button Mouse)

In the WordDraw method that triggers the drawing of the temporary entity, I create a CopyEnt variable, to save the data of this entity... here...

        public override bool WorldDraw(Drawable drawable, WorldDraw wd)
        {
            var ent = drawable as Entity;

            if (ent is BlockReference)
            {
                using (var tempEnt = _createTempEntityFunction(ent.ObjectId))
                {
                    copyEnt = tempEnt; // Copy Of entity to try future change,
                    wd.Geometry.Draw(tempEnt);
                    wd.SubEntityTraits.Color = 191;
                }
            }
            else if (ent is AttributeReference)
            {
                wd.SubEntityTraits.Color = 2;
            }
            else if (ent is Autodesk.AutoCAD.DatabaseServices.Polyline)
            {
                using (var tempEnt = _createTempEntityFunction(ent.ObjectId))
                {
                    copyEnt = tempEnt;
                    wd.Geometry.Draw(tempEnt);
                    wd.SubEntityTraits.Color = 191;
                }
            }
            else 
            {
                wd.SubEntityTraits.Color = 191;
            }

            return base.WorldDraw(drawable, wd);

        }


And this function captures the mouse Mbutton, to try to interact with Temporary Entity

 

        public static void VhmouseHandlerMidButton(object sender, PreTranslateMessageEventArgs e)
        {
            // Only look at mouse messages
            if (e.Message.message == WM_MBUTTONUP || e.Message.message == WM_MOUSEHWHEEL)
            {
                if (MySelectionDrawableOverrule.Overruling)
                {
                    DBText acText = (DBText)MySelectionDrawableOverrule.copyEnt;
                    Point3d pvScreenCenter = (Point3d)Application.GetSystemVariable("VIEWCTR");
                    Point2d pvScreenSize = (Point2d)Application.GetSystemVariable("SCREENSIZE");
                    Double pdHeight = (Double)Application.GetSystemVariable("VIEWSIZE");
                    Double pdWidth = pdHeight * (pvScreenSize.X / pvScreenSize.Y);
                    Point3d pdText = new Point3d(pvScreenCenter.X - (pdWidth / 2.15), pvScreenCenter.Y + (pdHeight / 2.95), 0);
                    acText.UpgradeOpen(); // Any interaction to change this entity causes a FATAL ERROR,
                    acText.Height = pdHeight / 7; // Any interaction to change this entity causes a FATAL ERROR,
                    acText.Position = pdText; // Any interaction to change this entity causes a FATAL ERROR,
                }
            }
        }

 Any idea how to modify the position of this Temporary Entity, or make it always remain in this position on the screen, regardless of the point?


Thank you... 

0 Likes
Accepted solutions (1)
1,398 Views
6 Replies
Replies (6)
Message 2 of 7

norman.yuan
Mentor
Mentor

Maybe, instead of capturing mouse message, you could try to set its position in Document.ViewChanged event handler?

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 3 of 7

cadVDJ3M
Enthusiast
Enthusiast

Hi @norman.yuan, I made the change as I said, about ViewChanged, much more practical, thanks for the tip..

 

But my problem remains.. The temporary entity is drawn by a WorldDraw, and I don't know what happens after it is drawn, but apparently I can't access it anymore, so I can't change it anymore and I can't draw a new one either.

I believe the entity is drawn on this line.

WorldDraw.png

 


I innocently made the copy of the entity to access it later, but I'm doing something very wrong.

See how the Object appears to me in VisualStudio.

Error_acText.png

 

This is the way I'm trying to access this entity.

DBText acText = (DBText)MySelectionDrawableOverrule.copyEnt;
acText.UpgradeOpen(); // Any interaction is not possible
acText.Height = pdHeight; // Any interaction is not possible
acText.Position = pdText; // Any interaction is not possible

 

Is there any way to do this?

 

 

 

0 Likes
Message 4 of 7

norman.yuan
Mentor
Mentor

The temporary entity is only created for the WorldDraw method to drawing its shape (as Drawable object). As the code shows, it is created in a "using (var tempEnt = ...){...}, that means after it is used for drawing the graphic, it is disposed at the end of the "using..." block. 

 

I am not very sure I understand the goal you are to achieve. In my article you referred to, the reason I used DrawableOverrule was that I wanted to draw extra graphic for EACH selected (thus overrules) entity. However, in your case, it seems to me that you only want to drawing one single drawable regardless which/how entities (it seems then are block references) ae selected. That is, you want to draw a temporary, eye-catching text in the view, showing how many entities are selected. If that is the case, overruling the selected entities does not make sense to me. Again not sure exactly what you are to achieve, hard to say more.

 

Norman Yuan

Drive CAD With Code

EESignature

Message 5 of 7

cadVDJ3M
Enthusiast
Enthusiast

Exactly @norman.yuan , I draw a single entity and that represents a count, but this count is based on attribute values ​​of the selected blocks.

 

The objective is for the user to select blocks within a sum range of 8 to 12, where 10 is the optimal number.

When the user finishes the command, the software creates a Polyline around these entities forming a cell.

This works fine, but when the user modifies the view, I would like to update the position and size of this temporary entity so that it appears to be fixed on the screen.

 

If after modifying the view the user selects some other block, then a new temporary entity is redrawn and appears in the correct position.

 

If there is some way to force the WorldDraw method to execute without having clicked on an object automatically the temporary entity would be correct.

 

An example of is applied

DuringDuring

nc_tela2.png

 

Sorry for mistakes in English, fault of Google Translate.. 😉

Thank you...

0 Likes
Message 6 of 7

norman.yuan
Mentor
Mentor
Accepted solution

If you did similar overrule as my article showed, then yare overruling the BlockReferences user selected, aren't you? If so, as I said in previous reply, the overruling does not make sense to the goal you are to achieve. I'd rather just use Transient Graphics in conjunction with Document,ViewChanged event handler to do it. It should fairly simple, I thought.

 

Well, I decided to spend a while to actually write some code to demonstrate how I would do it. As usual, to make the code easier to read, I post the code as a new article in my blog here:

 

https://drive-cad-with-code.blogspot.com/2022/02/using-transient-graphics-to-prompt-user.html 

 

For simplicity, in the code I omitted the code to set the "temporary" DBText's TextStyle.

 

HTH

 

Norman Yuan

Drive CAD With Code

EESignature

Message 7 of 7

cadVDJ3M
Enthusiast
Enthusiast

 

This is perfect Yuan... Congratulations again.

 

This works perfectly, I'll keep the Overruling just to be able to use the SubEntityTraits.Color .

 

I continued using GetSelection() and called the transients update in Editor.SelectionAdded , Editor.SelectionRemoved and also dwg_ViewChanged .

 

Thank you.

0 Likes