wyb36870 发表于 2023-4-12 15:05:35

关于CAD自定义鼠标样式

本帖最后由 wyb36870 于 2023-4-12 15:09 编辑

直接贴上代码,不懂的可以问我

using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.GraphicsInterface;
using Copper.AutocadApi.Properties;
using System.Drawing;

namespace Copper.AutocadApi.ExtendedMethod;

public static class Utils
{
    private static ImageBGRA32 _FormatBrushImage = null;
    public static void CreateFormatBrushCursor()
    {
      if (_FormatBrushImage==null)
      {
            using var bmp =Resources.FormatBrush;//把透明背景的图片放到资源里面直接调用
            for (var i = 0; i < bmp.Width; i++)
            {
                for (var j = 0; j < bmp.Height; j++)
                {
                  var pixel = bmp.GetPixel(i, j);
                  if ((pixel.A == 0 && pixel.R == 0 && pixel.G == 0 && pixel.B == 0)|| pixel.A == 0 && pixel.R == 255 && pixel.G == 255 && pixel.B == 255)
                  {
                        bmp.SetPixel(i, j, Color.Magenta);
                  }
                }
            }
            _FormatBrushImage = Autodesk.AutoCAD.Internal.Utils.ConvertBitmapToAcGiImageBGRA32(bmp);
      }
      new CursorBadgeUtilities().AddSupplementalCursorImage(_FormatBrushImage, 1);
    }

    public static void DeleteFormatBrushCursor()
    {
      var cbu = new CursorBadgeUtilities();

      if (cbu.HasSupplementalCursorImage() && _FormatBrushImage!=null)
      {
            cbu.RemoveSupplementalCursorImage(_FormatBrushImage);
      }
    }
}这里有个关键点,要注意图的背景色更改为Color.Magenta,如下
bmp.SetPixel(i, j, Color.Magenta);调用时把方法放在你需要更改鼠标样式的位置,如下

public class CopyPropertiesCmd : AutocadCommand
{
    protected override void Execute()
    {
         ......
      if (!this.TryCreateFilterForSelectBlockByName(new List<string> { bref.GetBlockName() }, out var filter)) return;
      var sourseFilter = new SelectionFilter(filter);
      var sourseOption = new PromptSelectionOptions
      {
            ......
      };
      Utils.CreateFormatBrushCursor();//此处设置图标
      var objSel = Ed.GetSelection(sourseOption, sourseFilter);
      Utils.DeleteFormatBrushCursor();//此处取消
      if (objSel.Status != PromptStatus.OK) return;
      var targetIds = objSel.Value.GetObjectIds();
      foreach (var id in targetIds)
      {
            ... ...
      }
    }
}

本做法参考了keanw的博客地址如下:
https://www.keanw.com/2014/05/ad ... 2015-using-net.html

using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.GraphicsInterface;
using Autodesk.AutoCAD.Internal;
using Autodesk.AutoCAD.Runtime;
using System.Drawing;

namespace CursorBadges
{
public class Commands
{
    private ImageBGRA32 _img = null;
   
    public void AddCursorBadge()
    {
      if (_img == null)
      {
      using (var bmp = new Bitmap(85, 85))
      {
          using (var g = Graphics.FromImage(bmp))
          {
            // The transparent colour used for these badges is
            // Magenta, I've found. Let's use that as a background
            // and then draw three concentric, filled circles
            // (looking a bit like the RAF logo)
            g.Clear(Color.Magenta);
            g.FillEllipse(Brushes.Blue, 5, 5, 60, 60);
            g.FillEllipse(Brushes.White, 15, 15, 40, 40);
            g.FillEllipse(Brushes.Red, 25, 25, 20, 20);
          }
          _img = Utils.ConvertBitmapToAcGiImageBGRA32(bmp);
      }
      }

      // Adding the badge with a priority of 1 means that it
      // will get replaced by selection-related badges. Changing
      // this to 3 is enough to give it precedence over these
      // (a higher number still will increase the chances
      // of it staying shown)
      var cbu = new CursorBadgeUtilities();
      cbu.AddSupplementalCursorImage(_img, 1);
    }

   
    public void RemoveCursorBadge()
    {
      var cbu = new CursorBadgeUtilities();
      if (cbu.HasSupplementalCursorImage() && _img != null)
      cbu.RemoveSupplementalCursorImage(_img);
    }
}

}

mokson 发表于 2023-4-12 18:54:16

上张图吧。

nsh935 发表于 2023-4-14 11:00:30

谢谢大佬分享!!!

闻人南131 发表于 2023-4-14 13:38:10


谢谢大佬分享!!!

tiancao100 发表于 2023-4-21 10:30:08

我喜欢VB,帮大家转个VB.Net 代码。
改成Bitmap.FromFile() 加载32位BMP


Imports System.Drawing
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.Internal
Imports Autodesk.AutoCAD.GraphicsInterface
Imports Autodesk.AutoCAD.EditorInput

Namespace CursorBadges
Public Class Commands
    Private _img As ImageBGRA32 = Nothing
    <CommandMethod("ACB")> _
    Public Sub AddCursorBadge()
      If _img Is Nothing Then
       'Using bmp As New Bitmap(85, 85)
                '    Using g As Object = Graphics.FromImage(bmp)
                '      ' The transparent colour used for these badges is
                '      ' Magenta, I've found. Let's use that as a background
                '      ' and then draw three concentric, filled circles
                '      ' (looking a bit like the RAF logo)
                '      g.Clear(Color.Magenta)
                '      g.FillEllipse(Brushes.Blue, 5, 5, 60, 60)
                '      g.FillEllipse(Brushes.White, 15, 15, 40, 40)
                '      g.FillEllipse(Brushes.Red, 25, 25, 20, 20)
                '    End Using
                '    _img = Utils.ConvertBitmapToAcGiImageBGRA32(bmp)
                'End Using
                Dim bmp As Bitmap = Bitmap.FromFile(My.Application.Info.DirectoryPath & "\images\CAD_Cursor.bmp")
                _img = Utils.ConvertBitmapToAcGiImageBGRA32(bmp)
      End If

      ' Adding the badge with a priority of 1 means that it
      ' will get replaced by selection-related badges. Changing
      ' this to 3 is enough to give it precedence over these
      ' (a higher number still will increase the chances
      ' of it staying shown)
      Dim cbu As New CursorBadgeUtilities()
      cbu.AddSupplementalCursorImage(_img, 1)
    End Sub

    <CommandMethod("RCB")> _
    Public Sub RemoveCursorBadge()
      Dim cbu As New CursorBadgeUtilities()
      If cbu.HasSupplementalCursorImage() AndAlso _img IsNot Nothing Then
      cbu.RemoveSupplementalCursorImage(_img)
      End If
    End Sub
End Class

End NamespaceNamespace Copper.AutocadApi.ExtendedMethod
    Public NotInheritable Class Utils
      Private Sub New()
      End Sub
      Private Shared _FormatBrushImage As ImageBGRA32 = Nothing
      Public Shared Sub CreateFormatBrushCursor()
            If _FormatBrushImage Is Nothing Then
                'Using bmp As Bitmap = Bitmap.FromFile(My.Application.Info.DirectoryPath & "\images\CAD_Cursor.bmp")
                Using bmp As Bitmap = New Bitmap(CType(My.Resources.ResourceManager.GetObject("CAD_Cursor"), Image))
                  '把透明背景的图片放到资源里面直接调用
                  Dim i As Object = 0
                  While i < bmp.Width
                        Dim j As Object = 0
                        While j < bmp.Height
                            Dim pixel As Object = bmp.GetPixel(i, j)
                            If (pixel.A = 0 AndAlso pixel.R = 0 AndAlso pixel.G = 0 AndAlso pixel.B = 0) OrElse pixel.A = 0 AndAlso pixel.R = 255 AndAlso pixel.G = 255 AndAlso pixel.B = 255 Then
                              bmp.SetPixel(i, j, Color.Magenta)
                            End If
                            j += 1
                        End While
                        i += 1
                  End While
                  _FormatBrushImage = Autodesk.AutoCAD.Internal.Utils.ConvertBitmapToAcGiImageBGRA32(bmp)
                End Using
            End If
            Dim cbu As New CursorBadgeUtilities()
            cbu.AddSupplementalCursorImage(_FormatBrushImage, 1)
      End Sub

      Public Shared Sub DeleteFormatBrushCursor()
            Dim cbu As Object = New CursorBadgeUtilities()
            If cbu.HasSupplementalCursorImage() AndAlso _FormatBrushImage IsNot Nothing Then
                cbu.RemoveSupplementalCursorImage(_FormatBrushImage)
            End If
      End Sub
    End Class
    Public Class TcCursor
      <CommandMethod("TcCursor", CommandFlags.Redraw)>
      Sub TcCursor()
            Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
            Utils.CreateFormatBrushCursor()
            '此处设置图标
            Dim objSel As Object = acDoc.Editor.GetSelection()
            Utils.DeleteFormatBrushCursor()
            '此处取消
            If objSel.Status <> PromptStatus.OK Then
                Return
            End If
            Dim targetIds As Object = objSel.Value.GetObjectIds()
            For Each id As Object In targetIds
                MsgBox(id.ToString)
            Next
      End Sub
    End Class
End Namespace


页: [1]
查看完整版本: 关于CAD自定义鼠标样式