WriteMessage() in Event Handlers?

WriteMessage() in Event Handlers?

BlackBox_
Advisor Advisor
965 Views
9 Replies
Message 1 of 10

WriteMessage() in Event Handlers?

BlackBox_
Advisor
Advisor

Has WriteMessage() always not worked for event handlers like this? 

 

Silly question, I know 😬; I've not been writing code since my son was born (he's now 5yo), and am only getting back into it with the NET 8 project upgrades. 

 

The code compiles and executes fine using a breakpoint, but nothing appears at command line. 

 

Is there a better event to hook for reporting/feedback, after first storing the needed info to field in these sort of events?

 

TIA

 

[Edit] - Should also add, that I tried both Application.SystemVariableChanged and Database.SystemVariableChanged alternatives (the latter with an inherent DocumentCreated), but no joy. 

 

        // registered with: acApp.SystemVariableChanged += onSystemVariableChanged;

private static void onSystemVariableChanged(object sender, acAppSrvc.SystemVariableChangedEventArgs e) { // do something useful acDocs.MdiActiveDocument.Editor.WriteMessage("\n >> {0} changed. ", e.Name.ToUpper()); }

 


"How we think determines what we do, and what we do determines what we get."

Chris (BlackBox) Bradley
Managing Partner / Developer / Civil Designer
Quux Software | Sincpac C3D | Style Explorer

0 Likes
Accepted solutions (1)
966 Views
9 Replies
Replies (9)
Message 2 of 10

ActivistInvestor
Mentor
Mentor

I have no problems writing to the console from that event handler or pretty much any other event handler.

 

It might have something to do with what is going on in the editor which is causing the changes to the system variables which you haven't mentioned. 

0 Likes
Message 3 of 10

BlackBox_
Advisor
Advisor

Thanks, Tony.

 

I'm specifically storing DIMSTYLE, CMLEADERSTYLE, and TEXTSTYLE sysvars on acApp.SystemVariableChanging, then conditionally modifying the changed sysvar's respective *LAYER component sysvar in acApp.SystemVariableChanged (both via switch case). 

 

The code successfully changes the *LAYER related sysvar as designed, I'm just not getting WriteMessage() to report to the command line within the active session (as expected) - you mentioned console (within VS?), not command line, if you intended something else. 

 

I have noticed that the only time the event handler properly reports to command line, is when I use the little 'down right' arrow in ribbon UI (which invokes '_dimstyle command), then when done, acApp.SystemVariableChanged fires and WriteMessage() is displayed, making me think I'm missing an obvious context-related step. 

 

If memory serves, when the '_dimstyle command is invoked to set current DIMSTYLE in the dialog, the document is locked with the modal dialog (formulating some of this as I type) - however, when the ribbon UI is used the -DIMSTYLE command is silently invoked, but no joy on WriteMessage(). 

 

Greatly appreciate your time. 

 

Cheers

 

		private static void onSystemVariableChanged(object sender, acAppSrvc.SystemVariableChangedEventArgs e)
        {
            Document doc = acDocs.MdiActiveDocument;
            Editor ed = doc.Editor;

            try
            {
                string varName = e.Name.ToUpper();

                switch (varName)
                {
                    case "CMLEADERSTYLE":
                        // set MLEADERLAYER
						break;

                    case "DIMSTYLE":
                        // set DIMLAYER
                        break;

                    case "TEXTSTYLE":
                        // set TEXTLAYER
                        break;

                    default:
                        // Ignore other system variable changes
                        return;
                }
				
				ed.WriteMessage("\n >> {0} changed. ", e.Name.ToUpper());
            }
            catch (System.Exception ex)
            {
                ed.WriteMessage("\n; error: System.Exception: " + ex.Message);
            }
        }

 


"How we think determines what we do, and what we do determines what we get."

Chris (BlackBox) Bradley
Managing Partner / Developer / Civil Designer
Quux Software | Sincpac C3D | Style Explorer

0 Likes
Message 4 of 10

BlackBox_
Advisor
Advisor

Adding this line after the varName declaration, before switch: 

 

ed.WriteMessage("\nCommandInProgress: {0}, sysvar: {1} ", doc.CommandInProgress, varName);

 

yields no output at command line when using ribbon UI dropdown, but a break point in the code shows CommandInProgress == "-DIMSTYLE" 

 

However, using the 'down right' arrow, which launches the modal dialog ("DIMSTYLE") results in this (where blank spaces are CommandInProgress == ""  )

Command: '_dimstyle
CommandInProgress: , sysvar: SNAPANG
CommandInProgress: , sysvar: UCSNAME
CommandInProgress: , sysvar: *ERRNO
CommandInProgress: , sysvar: *ERRNO
CommandInProgress: DIMSTYLE, sysvar: DIMSTYLE
DIMSTYLE changed from: "Proposed", to: "Existing"
CommandInProgress: DIMSTYLE, sysvar: DIMLAYER
CommandInProgress: DIMSTYLE, sysvar: DIMPOST
CommandInProgress: DIMSTYLE, sysvar: DIMASZ
CommandInProgress: DIMSTYLE, sysvar: DIMEXO
CommandInProgress: DIMSTYLE, sysvar: DIMDLI
CommandInProgress: DIMSTYLE, sysvar: DIMEXE
CommandInProgress: DIMSTYLE, sysvar: DIMTXT
CommandInProgress: DIMSTYLE, sysvar: DIMTXSTY
CommandInProgress: , sysvar: SNAPANG
CommandInProgress: , sysvar: UCSNAME

 

In both cases a command is invoked, so I shouldn't need to account for application vs document context, should I? 


"How we think determines what we do, and what we do determines what we get."

Chris (BlackBox) Bradley
Managing Partner / Developer / Civil Designer
Quux Software | Sincpac C3D | Style Explorer

0 Likes
Message 5 of 10

BlackBox_
Advisor
Advisor

Adding a case for "CLAYER" to the switch statement, does report to command line as expected, and has a CommandInProgress == "" (native SetSystemVariable() call?). 

 

CommandInProgress == "SETVAR" for both "TEXTSTYLE" and "CMLEADERSTYLE" in the switch, with nothing being reported to command line. 

 

As mentioned above, CommandInProgress == "-DIMSTYLE" for "DIMSTYLE" in the switch, with nothing being reported to command line. 

 

Am I missing something or is this inconsistent behavior actually a bug?

 

[Edit] - okay, so when a command is invoked by the UI, no command line output. Commands inherently lock the document, so how do I gain access to the document, so I can access the editor? Feels like I'm finally asking the right question. 

 

		private static void onSystemVariableChanged(object sender, acAppSrvc.SystemVariableChangedEventArgs e)
        {
            Document doc = acDocs.MdiActiveDocument;
            Editor ed = doc.Editor;

            try
            {
                string varName = e.Name.ToUpper();

                switch (varName)
                {
                    case "CMLEADERSTYLE":
                        ed.WriteMessage("\nCommandInProgress: {0}, sysvar: {1} ", doc.CommandInProgress, varName);
						
					break;

                    case "DIMSTYLE":
                        ed.WriteMessage("\nCommandInProgress: {0}, sysvar: {1} ", doc.CommandInProgress, varName);
						
					break;

                    case "TEXTSTYLE":
						ed.WriteMessage("\nCommandInProgress: {0}, sysvar: {1} ", doc.CommandInProgress, varName);
						
					break;
						
					case "CLAYER":
                        ed.WriteMessage("\nCommandInProgress: {0}, sysvar: {1} ", doc.CommandInProgress, varName);
						
					break;

                    default:
                        // Ignore other system variable changes
					return;
                }
            }
            catch (System.Exception ex)
            {
                ed.WriteMessage("\n; error: System.Exception: " + ex.Message);
            }
        }

 


"How we think determines what we do, and what we do determines what we get."

Chris (BlackBox) Bradley
Managing Partner / Developer / Civil Designer
Quux Software | Sincpac C3D | Style Explorer

0 Likes
Message 6 of 10

BlackBox_
Advisor
Advisor

Hi @ActivistInvestor - does the code in my previous post report to the command line when modifying each sysvar via Ribbon UI for you, or only for CLAYER?

 

Please advise.


"How we think determines what we do, and what we do determines what we get."

Chris (BlackBox) Bradley
Managing Partner / Developer / Civil Designer
Quux Software | Sincpac C3D | Style Explorer

0 Likes
Message 7 of 10

ActivistInvestor
Mentor
Mentor

If you include a complete, reproducible case that adds the event handler via a command, I'll try it. 

0 Likes
Message 8 of 10

BlackBox_
Advisor
Advisor

@ActivistInvestor wrote:

If you include a complete, reproducible case that adds the event handler via a command, I'll try it. 


Please and thank you! 

 

This code builds, there's a command to start & stop, and the events fire as expected, but the only sysvar (of those in the switch) where WriteMessage() produces output at the command line is CLAYER. For the *STYLE sysvars, I am manually changing the current Text, Dimension, or MLeader style using the OOTB Ribbon dropdowns to raise the event. 

 

Thanks for your time and assistance. 

 

[Edit] - pretty sure CommandFlags is unnecessary, but just now seeing they go copied in. 

 

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;

using acApp = Autodesk.AutoCAD.ApplicationServices.Application;

using System;

[assembly: CommandClass(typeof(WhySoMany.WriteMessageTroubles))]

namespace WhySoMany
{
    public class WriteMessageTroubles
    {
        private static DocumentCollection acDocs = acApp.DocumentManager;

        [CommandMethod("WriteMessageTroublesStart", CommandFlags.UsePickSet)]
        public static void WriteMessageTroublesStart()
        {
            acApp.SystemVariableChanged += onSystemVariableChanged;

            Document doc = acDocs.MdiActiveDocument;
            if(doc != null)
                doc.Editor.WriteMessage("\n⬛️ WriteMessageTroubles event started.");
        }
        [CommandMethod("WriteMessageTroublesStop", CommandFlags.UsePickSet)]
        public static void WriteMessageTroublesStop()
        {
            acApp.SystemVariableChanged -= onSystemVariableChanged;

            Document doc = acDocs.MdiActiveDocument;
            if (doc != null)
                doc.Editor.WriteMessage("\n⬛️ WriteMessageTroubles event stopped.");
        }
        private static void onSystemVariableChanged(object sender, SystemVariableChangedEventArgs e)
        {
            Document doc = acDocs.MdiActiveDocument;
            Editor ed = doc.Editor;

            try
            {
                string varName = e.Name.ToUpper();

                switch (varName)
                {
                    case "CMLEADERSTYLE":
                        ed.WriteMessage("\nSysvar {0} changed, CommandInProgress: {1} ", varName, doc.CommandInProgress);

                        break;

                    case "DIMSTYLE":
                        ed.WriteMessage("\nSysvar {0} changed, CommandInProgress: {1} ", varName, doc.CommandInProgress);

                        break;

                    case "TEXTSTYLE":
                        ed.WriteMessage("\nSysvar {0} changed, CommandInProgress: {1} ", varName, doc.CommandInProgress);

                        break;

                    case "CLAYER":
                        ed.WriteMessage("\nSysvar {0} changed, CommandInProgress: {1} ", varName, doc.CommandInProgress);

                        break;

                    default:
                        // Ignore other system variable changes
                        return;
                }
            }
            catch (System.Exception ex)
            {
                ed.WriteMessage("\n; error: System.Exception: " + ex.Message);
            }
        }
    }
}

 


"How we think determines what we do, and what we do determines what we get."

Chris (BlackBox) Bradley
Managing Partner / Developer / Civil Designer
Quux Software | Sincpac C3D | Style Explorer

0 Likes
Message 9 of 10

ActivistInvestor
Mentor
Mentor
Accepted solution

The problem isn't related to calling WriteMessage() in event handlers, it has more to do with the execution context which the event handler is called when you use the ribbon to change the system variables.

 

Unfortunately, I can't post code here because it is finding its way into blog posts with no attrition.

 

So, you can download this file, which includes an extension method called WriteMessageAsync().  You can use that method instead of WriteMessage() to display messages on the AutoCAD console.

0 Likes
Message 10 of 10

BlackBox_
Advisor
Advisor

Thank you, @ActivistInvestor - it works exactly as described. :beer:

 

 

I'm sorry to hear that that you're not receiving attribution; I don't follow blogs, usually just find them in search results on a topic. 

 

A book reminded me that if we live to be 80yo, we'll have been on Earth for 4,160 weeks... now, I'm not sure how many you have left, or what possesses you to willingly help so many... but I'm really grateful you choose to share. 

 

I know this is a fairly minor issue (that I couldn't figure out), but you've also helped me in the past; your time, effort (and knowledge) genuinely help. 

 

Cheers


"How we think determines what we do, and what we do determines what we get."

Chris (BlackBox) Bradley
Managing Partner / Developer / Civil Designer
Quux Software | Sincpac C3D | Style Explorer

0 Likes