.NET Drafting tool tip background

.NET Drafting tool tip background

Sgear
Advocate Advocate
1,859 Views
6 Replies
Message 1 of 7

.NET Drafting tool tip background

Sgear
Advocate
Advocate

 

hi

 

is it possible to change "Drafting tool til background" in .NET

 

image.png

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

_gile
Consultant
Consultant

Hi,

 

This value is stored in the registry as an "environment variable".

The value is an  24-bit integer representing the "OLE color" (Blue Red Green).

 

You can use P/Invoke with acedGetEnv and acedSetEnv to get and set environment variables.

 

        [System.Security.SuppressUnmanagedCodeSecurity]
        [DllImport("accore.dll", EntryPoint = "acedGetEnv", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        extern static int acedGetEnv(string envName, string returnValue);

        public static string GetEnv(string envName)
        {
            string returnValue = new string(char.MinValue, 1024);
            int stat = acedGetEnv(envName, returnValue);
            return stat == -5001 ? null : returnValue;
        }

        [System.Security.SuppressUnmanagedCodeSecurity]
        [DllImport("accore.dll", EntryPoint = "acedSetEnv", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        extern static int acedSetEnv(string envName, string newValue);

        public static string SetEnv(string envName, string newValue)
        {
            int stat = acedSetEnv(envName, newValue);
            return stat == -5001 ? null : newValue;
        }

        public int GetModelToolTipBkColor() =>
            Convert.ToInt32(GetEnv("Model bk color"));

        public void SetModelToolTipBkColor(int color) =>
            Convert.ToInt64(SetEnv("Model bk color", color.ToString()));


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 3 of 7

Sgear
Advocate
Advocate

Thanks _gile

 

 

I try to convert this to VB.NET

 

but I get this error

 

Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type.

 

 

       <System.Security.SuppressUnmanagedCodeSecurity()> _
        Private Declare Function acedGetEnv Lib "accore.dll" Alias "acedGetEnv" (ByVal envName As String, ByVal returnValue As String) As Integer

        Public Shared Function GetEnv(envName As String) As String
            Dim returnValue As New String(Char.MinValue, 1024)
            Dim stat As Integer = acedGetEnv(envName, returnValue)
            Return If(stat = -5001, Nothing, returnValue)
        End Function

        <System.Security.SuppressUnmanagedCodeSecurity> _
        Private Declare Function acedSetEnv Lib "accore.dll" Alias "acedSetEnv" (ByVal envName As String, ByVal newValue As String) As Integer

        Public Shared Function SetEnv(envName As String, newValue As String) As String
            Dim stat As Integer = acedSetEnv(envName, newValue)
            Return If(stat = -5001, Nothing, newValue)
        End Function


        <CommandMethod("TESTC")> _
        Public Function GetModelToolTipBkColor() As Integer
            Convert.ToInt32(GetEnv("Model bk color"))
        End Function
0 Likes
Message 4 of 7

ActivistInvestor
Mentor
Mentor

@Sgear wrote:

Thanks _gile

 

 

I try to convert this to VB.NET

 

but I get this error

 

Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type.

 


You don't need to P/Invoke acedGetEnv() to get environment variables.

 

acedGetEnv() is exposed to managed code via HostApplicationServices.GetEnvironmentVariable().

 

The name of the method was changed at some point (don't recall when). On older product releases, it was GetEnvionmentVariableW().

 

Don't bother looking in the managed docs for this (online or offline), as its not there.

 

See the native ObjectARX documentation for the AcDbHostApplicationServices::getEnv() method.

 

 

0 Likes
Message 5 of 7

_gile
Consultant
Consultant
Accepted solution

@ActivistInvestor

Thanks for this one I didn't know.

 

@Sgear

You cannot define a command (CommandMethod attributed method) with a VB Function neither with a Sub which has arguments.

A CommandMethod attributed method must be a Sub (no return value) with none arguments.

 

Here's a VB project example using @ActivistInvestor way for GetEnv which also shows the conversion between Autodesk.AutoCAD.Colors.Color and BRG 24-bit integer OLE color:

 

Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.Colors
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.Windows
Imports System.Runtime.InteropServices
Imports Autodesk.AutoCAD.DatabaseServices

<Assembly: CommandClass(GetType(EnvironmentVariableSample.Commands))>

Namespace EnvironmentVariableSample
    Public Class Commands
        <System.Security.SuppressUnmanagedCodeSecurity>
        <DllImport("accore.dll", EntryPoint:="acedSetEnv",
                   CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.Cdecl)>
        Private Shared Function acedSetEnv(envName As String, newValue As String) As Integer
        End Function

        Public Shared Function SetEnv(envName As String, newValue As String) As String
            Dim stat As Integer = acedSetEnv(envName, newValue)
            Return If(stat = -5001, Nothing, newValue)
        End Function

        ''' <summary>
        ''' Gets the current model space tooltip background color.
        ''' </summary>
        ''' <returns>An instance of Autodesk.AutoCAD.Colors.Color.</returns>
        Public Function GetModelTooltipBackgroundColor() As Color
            ' get the environment variable and convert it to integer
            Dim envVar As String = HostApplicationServices.Current.GetEnvironmentVariable("Model bk color")
            Dim oleColor As Integer = Convert.ToInt32(envVar)
            ' create a new instance of Autodesk.AutoCAD.Colors.Color 
            ' from the BGR 24-bit integer
            Return Color.FromRgb(oleColor And 255, (oleColor >> 8) And 255, oleColor >> 16)
        End Function

        ''' <summary>
        ''' Sets the current model space tooltip background color.
        ''' </summary>
        ''' <param name="color">An instance of Autodesk.AutoCAD.Colors.Color.</param>
        ''' <returns>A string figuring the OLE color (24-bit integer).</returns>
        Public Function SetModelTooltipBackgroundColor(color As Color) As String
            ' convert the Autodesk.AutoCAD.Colors.Color into a System.Drawing.Color
            Dim drawingColor As System.Drawing.Color = color.ColorValue
            ' build a OLE color (BGR 24-bit integer)
            Dim oleColor As Integer = CInt(drawingColor.B) << 16 Or CInt(drawingColor.G) << 8 Or drawingColor.R
            ' set the environment variable
            Return SetEnv("Model bk color", oleColor.ToString())
        End Function

        ' testing command
        <CommandMethod("TEST")>
        Public Sub Test()
            ' create a new instance of AutoCA ColorDialog
            Dim dlg As New ColorDialog()
            dlg.IncludeByBlockByLayer = False

            ' set the default color to the current model space tooltip background color.
            dlg.Color = GetModelTooltipBackgroundColor()

            ' show the dialog
            Dim result As System.Windows.Forms.DialogResult = dlg.ShowDialog()
            ' if result is OK...
            If result = System.Windows.Forms.DialogResult.OK Then
                ' set the model space tooltip background color.
                SetModelTooltipBackgroundColor(dlg.Color)
                ' display the result.
                Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(
                    vbLf & "The current model space tooltip background color is: {0} (OLE color: {1})",
                    dlg.Color.ColorNameForDisplay,
                    HostApplicationServices.Current.GetEnvironmentVariable("Model bk color"))
            End If
        End Sub
    End Class
End Namespace

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 6 of 7

ActivistInvestor
Mentor
Mentor
Accepted solution

@_gile wrote:

@ActivistInvestor

Thanks for this one I didn't know.

 

@Sgear

You cannot define a command (CommandMethod attributed method) with a VB Function neither with a Sub which has arguments.

A CommandMethod attributed method must be a Sub (no return value) with none arguments.

 

Here's a VB project example using @ActivistInvestor way for GetEnv which also shows the conversion between Autodesk.AutoCAD.Colors.Color and BRG 24-bit integer OLE color:

 


Hi @_gile, when I first read this post, I searched my code base for calls to GetEnvironmentVariable and GetEnvironmentVariableW, knowing that I was reading environment variables here and there, but oddly the search turned up nothing. However, a search for "GetEnv", turned up the wrapper that had I built long ago to deal with the change to the name of the method, allowing code that uses it to run on any release.

 

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Linq.Expressions;

namespace Autodesk.AutoCAD.DatabaseServices
{
   public static class HostApplicationServicesExtensions
   {
      /// <summary>
      /// Release-independent access to HostApplicationServices.GetEnvironmentVariable()
      /// </summary>
      /// <remarks>On older product releases the GetEnvironmentVariable() method was
      /// named GetEnvironmentVariableW(), which is a <em>breaking change</em> :(. 
      /// 
      /// This helper class allows that method to be accessed on any product release, 
      /// via the HostApplicationServices.GetEnv() surrogate extension method.</remarks>
      /// <param name="hostApp">The value of the HostApplicationServices.Current property</param>
      /// <param name="name">The name of the environment variable to retrieve</param>
      /// <returns>A string containing the environment variable's value or string.Empty 
      /// if the environment variable was not found</returns>

      public static string GetEnv(this HostApplicationServices hostApp, string name)
      {
         if(hostApp == null)
            throw new ArgumentNullException("hostApp");
         if(string.IsNullOrWhiteSpace(name))
            throw new ArgumentException("name");
         return getEnv(hostApp, name);
      }

      /// <summary>
      /// A strongly-typed version of GetEnv().  To use this, declare a
      /// variable of the type that you want the result cast to (usually
      /// an int, long, or bool), and pass it in the out parameter.
      /// </summary>
      /// <typeparam name="T">The type to convert the environment variable's 
      /// value to (implied by the type of the out parameter)</typeparam>
      /// <param name="hostApp">The value of the HostApplicationServices.Current property</param>
      /// <param name="name">The name of the environment variable to retrieve</param>
      /// <returns>true if the environment variable was found and its value 
      /// was successfully converted to the destination type</returns>

      public static bool GetEnv<T>(this HostApplicationServices hostApp, string name, out T result)
      {
         if(hostApp == null)
            throw new ArgumentNullException("hostApp");
         if(string.IsNullOrWhiteSpace(name))
            throw new ArgumentException("name");
         string res = getEnv(hostApp, name);
         result = default(T);
         if(string.IsNullOrEmpty(res))
            return false;
         try
         {
            result = (T) Convert.ChangeType(res, typeof(T));
            return true;
         }
         catch
         {
            return false;
         }
      }

      static Func<HostApplicationServices, string, string> getEnv = GenerateGetEnv();

      static Func<HostApplicationServices, string, string> GenerateGetEnv()
      {
         Type type = typeof(HostApplicationServices);
         BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;
         MethodInfo method = type.GetMethod("GetEnvironmentVariable", flags)
            ?? type.GetMethod("GetEnvironmentVariableW", flags);
         if(method != null)
         {
            var instance = Expression.Parameter(typeof(HostApplicationServices), "instance");
            var arg = Expression.Parameter(typeof(string), "arg");
            return Expression.Lambda<Func<HostApplicationServices, string, string>>(
               Expression.Call(instance, method, arg), instance, arg).Compile();
         }
         return (a, b) =>
         {
            throw new MissingMethodException(
               "Could not find method GetEnvironmentVariable() or GetEnvironmentVariableW()");
         };
      }
   }
}

 

 

 

 

 

Message 7 of 7

Sgear
Advocate
Advocate

Activist_Investor , _gile thanks for the help


this work better to show diffrent color in "Drafting tool tip background " when somthing is missing Instead of showing it in command bar
More visible to the user

 

Regards

Sgear

 

 

image.png

 

 

0 Likes