Где взять стандартные иконки команд

Автор Тема: Где взять стандартные иконки команд  (Прочитано 12528 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

Оффлайн avcАвтор темы

  • ADN Club
  • *****
  • Сообщений: 839
  • Карма: 168
    • Мои плагины к Автокаду
Кто-нибудь знает из какой ресурсной dll Автокад грузит иконки для стандартных команд? Хочу задействовать их на своих панелях. Перебрал все dll в папке Автокад - нет там почти никаких картинок из интерфейса Автокада и иконок команд тоже не вижу. Понятно что можно пытаться сделать свои похожие иконки, выдернуть с экрана или экспортировать из диалога CUI. Но в следующей версии опять поменяют иконки надо будет начинать с начала. Есть путь по проще?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
Поизучай файлы acadbtn.xmx и acadbtn_light.xmx (это для светлой темы)
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн avcАвтор темы

  • ADN Club
  • *****
  • Сообщений: 839
  • Карма: 168
    • Мои плагины к Автокаду
Первым делом полез в эти файлы. Там текстом прописаны цвета темы - тоже полезная вещь. Но до конца долистать я не догадался. А в конце там строки вида
Код - XML [Выбрать]
  1. <String name="VScrollBarAddLine" value=":/VScrollBar_AddLine.png"/>

Но это не то. Это описание мелких элементов интерфейса, а не команд и объектов чертежа. И даже для этих элементов эти png у меня на всем системном диске не находятся. То есть они тоже к каких-то ресурсах/архивах запакованы.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
avc,
Плохо ты искал. И подход у тебя .NET-чика. А ресурсы там как в обычной native dll:

Для AutoCAD 2021 всего там 3202 иконки.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн avcАвтор темы

  • ADN Club
  • *****
  • Сообщений: 839
  • Карма: 168
    • Мои плагины к Автокаду
Извиняюсь, не туда смотрел. Я полез в папку Themes и там изучал DarkTheme.xbel.
Конечно xmx я не догадался попытаться открыть, да и если б попытался - VS показывает его как двоичный файл, не видит ресурсов.
Что ресурсы бываю какие-то разные - я и не в курсе. Спасибо за ссылочки, теперь разберусь.
А что внутри этих ресурсов? Resource Hacker просто как двоичные данные показывает. И я в них не вижу заголовка PNG. и на BMP большинство не похожи. Первые символы в основном II* Что это?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
А что внутри этих ресурсов?
.ico
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн avcАвтор темы

  • ADN Club
  • *****
  • Сообщений: 839
  • Карма: 168
    • Мои плагины к Автокаду
Что-то не получается.
Код - C# [Выбрать]
  1.  internal static class ResourceManager
  2.   {
  3.     [DllImport("kernel32.dll", SetLastError = true)]
  4.     public static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hFile, uint dwFlags);
  5.  
  6.     [DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  7.     public static extern IntPtr LoadLibrary(string lpFileName);
  8.  
  9.     [DllImport("kernel32.dll", SetLastError = true)]
  10.     public static extern IntPtr FindResource(IntPtr hModule, string lpName, string lpType);
  11.  
  12.     [DllImport("kernel32.dll", SetLastError = true)]
  13.     public static extern IntPtr LoadResource(IntPtr hModule, IntPtr hResInfo);
  14.  
  15.     [DllImport("kernel32.dll", SetLastError = true)]
  16.     public static extern IntPtr LockResource(IntPtr hResData);
  17.  
  18.     [DllImport("kernel32.dll", SetLastError = true)]
  19.     public static extern uint SizeofResource(IntPtr hModule, IntPtr hResInfo);
  20.  
  21.     internal static Icon GetIcon(string lpFileName, string lpName, string lpType)
  22.     {
  23.       IntPtr hModule = LoadLibrary(lpFileName);
  24.       if (hModule == IntPtr.Zero) return null;
  25.       IntPtr hResource = FindResource(hModule, lpName, lpType);
  26.       if (hResource == IntPtr.Zero) return null;
  27.       uint resSize = SizeofResource(hModule, hResource);
  28.       IntPtr resData = LoadResource(hModule, hResource);
  29.       if (resData == IntPtr.Zero) return null;
  30.       byte[] uiBytes = new byte[resSize];
  31.       IntPtr ipMemorySource = LockResource(resData);
  32.       Marshal.Copy(ipMemorySource, uiBytes, 0, (int)resSize);
  33.       using MemoryStream m = new MemoryStream(uiBytes);
  34.       return new Icon(m);
  35.     }
  36.  
  37.     internal static void SaveIcon(string lpFileName, string lpName, string lpType, string toFolder)
  38.     {
  39.       Icon ico = GetIcon(lpFileName, lpName, lpType);
  40.       if (ico == null) return;
  41.       using FileStream file = File.Create(Path.Combine(toFolder, lpName) + ".ico");
  42.       ico.Save(file);
  43.     }
и для теста
Код - C# [Выбрать]
  1.     [CommandMethod("IconTest")]
  2.     public static void IconTestCommand()
  3.     {
  4.       ResourceManager.SaveIcon(@"c:\Program Files\Autodesk\AutoCAD 2021\acadbtn.xmx",
  5.       "RCDATA_16_2DOPTIM",
  6.       "RCData",
  7.       @"Z:\test"
  8.       );
  9.     }

Библиотека подгружается. Но FindResource всегда возвращает 0

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
Ну не так всё просто. :) Это тебе не на C# писать... :D

Код - C# [Выбрать]
  1. using Autodesk.AutoCAD.Runtime;
  2. using System;
  3. using System.IO;
  4. using System.Runtime.InteropServices;
  5.  
  6. // This line is not mandatory, but improves loading performances
  7. [assembly: CommandClass(typeof(GetIconFromAcadXMX.MyCommands))]
  8.  
  9. namespace GetIconFromAcadXMX
  10. {
  11.   static class NativeResourceManager
  12.   {
  13.     public const uint LOAD_LIBRARY_AS_DATAFILE = 0x00000002;
  14.     public const uint LOAD_LIBRARY_AS_IMAGE_RESOURCE = 0x00000020;
  15.     public static IntPtr RC_RCDATA = (IntPtr)((UInt16)10);
  16.  
  17.     [DllImport("kernel32.dll", SetLastError = true)]
  18.     public static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hFile, uint dwFlags);
  19.  
  20.     [DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  21.     public static extern IntPtr LoadLibrary(string lpFileName);
  22.  
  23.     [DllImport("kernel32.dll", SetLastError = true)]
  24.     public static extern IntPtr FindResource(IntPtr hModule, string lpName, IntPtr lpType);
  25.  
  26.     [DllImport("kernel32.dll", SetLastError = true)]
  27.     public static extern IntPtr LoadResource(IntPtr hModule, IntPtr hResInfo);
  28.  
  29.     [DllImport("kernel32.dll", SetLastError = true)]
  30.     public static extern IntPtr LockResource(IntPtr hResData);
  31.  
  32.     [DllImport("kernel32.dll", SetLastError = true)]
  33.     public static extern uint SizeofResource(IntPtr hModule, IntPtr hResInfo);
  34.  
  35.     public static MemoryStream GetIcon(string lpFileName, string lpName, IntPtr lpType)
  36.     {
  37.       IntPtr hModule = LoadLibraryEx(lpFileName, IntPtr.Zero,
  38.         LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE);
  39.       if (hModule == IntPtr.Zero) return null;
  40.       IntPtr hResource = FindResource(hModule, lpName, lpType);
  41.       if (hResource == IntPtr.Zero) return null;
  42.       uint resSize = SizeofResource(hModule, hResource);
  43.       IntPtr resData = LoadResource(hModule, hResource);
  44.       if (resData == IntPtr.Zero) return null;
  45.       byte[] uiBytes = new byte[resSize];
  46.       IntPtr ipMemorySource = LockResource(resData);
  47.       Marshal.Copy(ipMemorySource, uiBytes, 0, (int)resSize);
  48.       return new MemoryStream(uiBytes);
  49.     }
  50.  
  51.     public static void SaveIcon(string lpFileName, string lpName, IntPtr lpType, string toFolder)
  52.     {
  53.       using (MemoryStream ico = GetIcon(lpFileName, lpName, lpType)) {
  54.         if (ico == null) return;
  55.         using (FileStream file = File.Create(Path.Combine(toFolder, lpName) + ".ico"))
  56.           file.Write(ico.ToArray(),0, (int)ico.Length);
  57.       }
  58.     }
  59.   }
  60.   public class MyCommands
  61.   {
  62.     [CommandMethod("IconTest")]
  63.     public static void IconTestCommand()
  64.     {
  65.       NativeResourceManager.SaveIcon(@"c:\Program Files\Autodesk\AutoCAD 2021\acadbtn.xmx",
  66.       "RCDATA_16_2DOPTIM",
  67.       NativeResourceManager.RC_RCDATA,
  68.       @"Z:\test"
  69.       );
  70.     }
  71.   }
  72. }
  73.  
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн avcАвтор темы

  • ADN Club
  • *****
  • Сообщений: 839
  • Карма: 168
    • Мои плагины к Автокаду
Я так и думал, что надо тип ресурса цифрой передать как во всех остальных примерах. Но нигде не мог найти значение этой константы RC_RCDATA. Спасибо!
Но! Иконок в этой библиотеке нет. Создать Icon на этих данных невозможно. Зато эти данные прекрасно считывает Bitmap. И оказалось, что большинство картинок - это TIFы. II* - это заголовок TIF. А вот с остальными не очень понятно. Bitmap сообщает, что RawFormat == Ico, но при этом сохраняет в PNG с переконвертацией (вижу, что внутри файла уже не то содержимое). Но вобщем-то это все уже не имеет значние, потому что Bitmap можно присвоить почти любому контролу WinForm, не зависимо от содержимого (надеюсь, что независимо. еще не проверял)
Код - C# [Выбрать]
  1.     static Bitmap GetBitmap(string lpFileName, string lpName, IntPtr lpType)
  2.     {
  3.       IntPtr hModule = LoadLibrary(lpFileName);
  4.       if (hModule == IntPtr.Zero) return null;
  5.       IntPtr hResource = FindResource(hModule, lpName, lpType);
  6.       if (hResource == IntPtr.Zero) return null;
  7.       uint resSize = SizeofResource(hModule, hResource);
  8.       IntPtr resData = LoadResource(hModule, hResource);
  9.       if (resData == IntPtr.Zero) return null;
  10.       byte[] uiBytes = new byte[resSize];
  11.       IntPtr ipMemorySource = LockResource(resData);
  12.       Marshal.Copy(ipMemorySource, uiBytes, 0, (int)resSize);
  13.       using MemoryStream m = new MemoryStream(uiBytes);
  14.       return new Bitmap(m);
  15.     }
  16.  
  17.     internal static void SaveBitmap(string lpFileName, string lpName, IntPtr lpType, string toFolder)
  18.     {
  19.       Bitmap bmp = GetBitmap(lpFileName, lpName, lpType);
  20.       if (bmp == null) return;
  21.       Guid format = bmp.RawFormat.Guid;
  22.       string ext =
  23.         format == ImageFormat.Png.Guid ? "png" :
  24.         format == ImageFormat.Gif.Guid ? "gif" :
  25.         format == ImageFormat.Tiff.Guid ? "tif" :
  26.         format == ImageFormat.Jpeg.Guid ? "jpg":
  27.         format == ImageFormat.Icon.Guid ? "ico":
  28.         format == ImageFormat.Wmf.Guid ? "wmf":
  29.         format == ImageFormat.Exif.Guid ? "exif":
  30.         "bmp";
  31.       bmp.Save($"{toFolder}\\{lpName}.{ext}");
  32.     }

Код - C# [Выбрать]
  1.     [CommandMethod("IconTest")]
  2.     public static void IconTestCommand()
  3.     {
  4.       ResourceManager.SaveBitmap(@"c:\Program Files\Autodesk\AutoCAD 2021\acadbtn.xmx",
  5.       "IDB_TBAR_SMILEY",   ResourceManager.RC_RCDATA,  @"Z:\test" );
  6.       ResourceManager.SaveBitmap(@"c:\Program Files\Autodesk\AutoCAD 2021\acadbtn.xmx",
  7.       "RCDATA_16_2DOPTIM", ResourceManager.RC_RCDATA, @"Z:\test");
  8.       ResourceManager.SaveBitmap(@"c:\Program Files\Autodesk\AutoCAD 2021\acadbtn.xmx",
  9.       "RCDATA_16_2DSTEERINGWHEEL", ResourceManager.RC_RCDATA, @"Z:\test");
  10.       ResourceManager.SaveBitmap(@"c:\Program Files\Autodesk\AutoCAD 2021\acadbtn.xmx",
  11.       "RCDATA_16_3DALIGN", ResourceManager.RC_RCDATA, @"Z:\test");
  12.       ResourceManager.SaveBitmap(@"c:\Program Files\Autodesk\AutoCAD 2021\acadbtn.xmx",
  13.       "RCDATA_16_3DARRAY", ResourceManager.RC_RCDATA, @"Z:\test");
  14.     }

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
Иконок в этой библиотеке нет.
Это не те иконки. Я же сказал, что каждый из этих ресурсов - это .ico-файл. Описание этого формата:
https://ru.wikipedia.org/wiki/ICO_(формат_файла)
https://en.wikipedia.org/wiki/ICO_(file_format)
Английское описание полнее.
« Последнее редактирование: 26-10-2020, 21:36:24 от Александр Ривилис »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 738
Понятно что можно пытаться сделать свои похожие иконки, выдернуть с экрана или экспортировать из диалога CUI.
Что-то мне начинает казаться, что этот способ проще )

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
Что-то мне начинает казаться, что этот способ проще )
Это если парочку. А если все 3202???
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн avcАвтор темы

  • ADN Club
  • *****
  • Сообщений: 839
  • Карма: 168
    • Мои плагины к Автокаду
Что-то мне начинает казаться, что этот способ проще )
Неее. Восстанавливать прозрачность на иконках - то еще развлечение. А процедурка получилась простенькая - обычное обращение к Win32. Осталось оформить с поиском текущей папки Автокад. Можно даже сделать с учетом светлой/темной темы.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
Осталось оформить с поиском текущей папки Автокад.
Ты имеешь в виду каталог с acad.exe? Из своего плагина, загруженного внутрь AutoCAD?
Как вариант:
Код - C# [Выбрать]
  1. System.Windows.Forms.Application.ExecutablePath;
Или
Код - C# [Выбрать]
  1. AppDomain.CurrentDomain.BaseDirectory();
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение