Сообщество программистов Autodesk в СНГ

ADN Club => ObjectARX => Тема начата: Sergey_K от 21-02-2020, 16:56:12

Название: Иконки в контекстном меню
Отправлено: Sergey_K от 21-02-2020, 16:56:12
Имеется defined.cuix и defined.dll
Из DLL подгружаются в CUIX иконки RCDATA

Пробовал загружать RCDATA и BITMAP через LoadBitmap, LoadImage, LoadResource
HBITMAP грузится, SetMenuItemBitmaps возвращает 1, но иконка не отображается...  :(
файл икон: ICO/BMP 16x16x32bpp

Как назначить иконы из ресурсной DLL контекстному меню?
Название: Re: Иконки в контекстном меню
Отправлено: Александр Ривилис от 21-02-2020, 17:25:17
В RCDATA если мне не изменяет память иконки в формате PNG. А зачем их тебе вручную грузить? Не пойму.
Название: Re: Иконки в контекстном меню
Отправлено: Sergey_K от 21-02-2020, 17:31:35
У меня в RCDATA формат ICO. Работает.
В RCDATA вообще можно засунуть всё что угодно.

Мне нужно добавить иконы в ObjectContextMenu. По умолчанию их там нет
Название: Re: Иконки в контекстном меню
Отправлено: Александр Ривилис от 21-02-2020, 17:33:47
Sergey_K,
LoadIcon() ?
Название: Re: Иконки в контекстном меню
Отправлено: Sergey_K от 21-02-2020, 17:38:16
LoadIcon() ?
SetMenuItemBitmaps работает с битмапами. К тому же LoadIcon не грузит RCDATA
Название: Re: Иконки в контекстном меню
Отправлено: Александр Ривилис от 21-02-2020, 17:41:57
SetMenuItemBitmaps работает с битмапами.
Ну это как раз не проблема преобразовать HICON в HBITMAP:
Код - C++ [Выбрать]
  1. static void GetBitmapFromIcon()
  2. {
  3.   HICON hIcon = LoadIcon(_hdllInstance, MAKEINTRESOURCE(IDI_COMMANDICON));
  4.   ICONINFO info; GetIconInfo(hIcon, &info);
  5.   BITMAP bmp;  GetObject(info.hbmColor, sizeof(bmp), &bmp);
  6.   hBitmap = (HBITMAP)CopyImage(info.hbmColor, IMAGE_BITMAP, 0, 0, 0);
  7. }
К тому же LoadIcon не грузит RCDATA
Точно?
Название: Re: Иконки в контекстном меню
Отправлено: Sergey_K от 21-02-2020, 17:52:27
Точно?
Точно. Во всяком случае у меня )
RCDATA грузится только через LoadResource

Даже если прямо грузить битмап через LoadBitmap, всё равно битмап не отображается
Название: Re: Иконки в контекстном меню
Отправлено: Александр Ривилис от 21-02-2020, 17:59:38
RCDATA грузится только через LoadResource
Ну а если дальше:
Код - C++ [Выбрать]
  1. HGLOBAL hGlobal = ::LoadResource(hModule, hRes);
  2. HICON hIcon = HICON(::LockResource(hGlobal));
  3. ICONINFO info; GetIconInfo(hIcon, &info);
  4. BITMAP bmp;  GetObject(info.hbmColor, sizeof(bmp), &bmp);
  5. HBITMAP hBitmap = (HBITMAP)CopyImage(info.hbmColor, IMAGE_BITMAP, 0, 0, 0);

?
Название: Re: Иконки в контекстном меню
Отправлено: Sergey_K от 21-02-2020, 18:04:00
Дальше создаётся битмап и устанавливается на пункт меню. SetMenuItemBitmaps возвращает TRUE, что означает - иконка успешно назначена
Только нам не шашечки нужны, а ехать )
Название: Re: Иконки в контекстном меню
Отправлено: Алексей Кулик от 21-02-2020, 18:12:00
Я правильно понял, что defuned.dll - чисто ресурсная dll?
Название: Re: Иконки в контекстном меню
Отправлено: Sergey_K от 21-02-2020, 18:22:22
чисто ресурсная dll?
Да, ресурсы RCDATA для CUIX  + 1 BITMAP

Битмап успешно грузится в диалог, а вот в контекстное меню ничего и никак...
Название: Re: Иконки в контекстном меню
Отправлено: Алексей Кулик от 21-02-2020, 18:39:59
У меня были проблемы (VS2012, если не ошибаюсь), когда я собирал:
а) режим не Release x86
б) ресурсы разного типа (bmp / png / ico).
Ну, понятно, ничего кроме ресурсов я туда не кидал - в С++ я понимаю чуть меньше чем ничего.

А в обычное выпадающее меню ресурс подсасывается? Может, проблема вообще в том, что команду надо внутри _.cui повторно импортировать в конт.меню?
На какой-то из версий ресурс даже в обычное меню не подхватывался, т.к. я сдуру поменял нормальное описание команды и то, что было в меню. Может, и здесь нечто подобное вылезло?
Название: Re: Иконки в контекстном меню
Отправлено: Sergey_K от 21-02-2020, 19:07:04
VS2015, SDK 2018, Platform 8.1 Режим сборки Release 86. В экранном меню иконки подгружаются.
Контекстное меню создаётся при инициализации, когда CUI уже загружен. Связи между ними нет.
Были проблемы с экранным меню, когда в resource.h прописались ID RCDATA  -перестали отображаться иконки. Убрал - появились.
получается, что RCDATA для cuix не должна прописываться в resource.h, а ресурсы, используемые в других местах - удобней вставлять IDы в resource.h
С контекстным - что то другое...
Все шаги по инициализации выполняются успешно, а результат нулевой.

Может bit per pixel? ну так стандартные акадовские иконки используют 32bpp. И у меня оно же(в основном меню работают с маской).
Название: Re: Иконки в контекстном меню
Отправлено: Александр Ривилис от 21-02-2020, 20:57:29
Были проблемы с экранным меню, когда в resource.h прописались ID RCDATA  -перестали отображаться иконки. Убрал - появились.
В RCDATA dll, которая используется с CUIX, прописаны не ID_NUM (целые), а "ID_NUM" (строки). Соответственно в resource.h и писать то нечего.
С контекстным - что то другое...
Покажи код, которым ты вообще пытался добавлять контекстное меню.
Кстати вот пример, как я добавлял иконки в меню истории команд: https://adn-cis.org/dobavlenie-ikonki-k-imeni-komandyi-bez-ispolzovaniya-cuix.html
Название: Re: Иконки в контекстном меню
Отправлено: Александр Ривилис от 21-02-2020, 20:59:29
Дальше создаётся битмап и устанавливается на пункт меню. SetMenuItemBitmaps возвращает TRUE, что означает - иконка успешно назначена
Только нам не шашечки нужны, а ехать )
В какой момент это назначается??? Вполне возможно, что AutoCAD игнорирует твоё назначение.
Название: Re: Иконки в контекстном меню
Отправлено: Sergey_K от 21-02-2020, 21:59:11
Покажи код, которым ты вообще пытался добавлять контекстное меню. Кстати вот пример, как я добавлял иконки в меню истории команд: https://adn-cis.org/dobavlenie-ikonki-k-imeni-komandyi-bez-ispolzovaniya-cuix.html

Этот пример НИКАКОГО отношения к контекстному меню не имеет.
Извините, вам запрещён просмотр содержимого спойлеров.
Название: Re: Иконки в контекстном меню
Отправлено: Александр Ривилис от 21-02-2020, 22:04:50
Sergey_K,
Ты так просто не отделаешься. Из какого метода вызывается ContxtMenu::Load() ?
Для меня очевидно, что ::SetMenuItemBitmaps() нужно вызвать не из метода Load, а тогда, когда меню появляется.
Название: Re: Иконки в контекстном меню
Отправлено: Sergey_K от 21-02-2020, 22:18:25
Sergey_K,
Ты так просто не отделаешься. Из какого метода вызывается ContxtMenu::Load() ?
Для меня очевидно, что ::SetMenuItemBitmaps() нужно вызвать не из метода Load, а тогда, когда меню появляется.

Код приведен для примера. Загрузка происходит после инициализации контекстного меню.
::SetMenuItemBitmaps() может вызываться из ЛЮБОГО метода, после создания CMenu и загрузки его ресурса.Собственно ТОГДА меню и появляется )
Название: Re: Иконки в контекстном меню
Отправлено: Александр Ривилис от 21-02-2020, 22:31:25
Sergey_K,
Думаю что ты не прав. Я бы это делал в getMenuContext. Впрочем и это может не помочь, так как AutoCAD использует переданное ему HMENU для встраивания этого меню в своё меню и тут твои назначения для иконок не срабатывают. Боюсь, что без хука на появление меню тут не обойтись.
P.S.: Ну и на всякий случай глянь этот пример: https://www.codeproject.com/Articles/408251/Bitmap-Menu
Название: Re: Иконки в контекстном меню
Отправлено: Sergey_K от 21-02-2020, 22:43:44
Я бы это делал в getMenuContext. Впрочем и это может не помочь, так как AutoCAD использует переданное ему HMENU для встраивания этого меню в своё меню и тут твои назначения для иконок не срабатывают. Боюсь, что без хука на появление меню тут не обойтись.

Автокад должен взять моё меню как субменю и вставить в своё, как есть. А что они там намудрили - неведомо.
Насчёт хуков - ни бельмес. Опять гланды через задний проход лечить )
Название: Re: Иконки в контекстном меню
Отправлено: Sergey_K от 21-02-2020, 22:51:14
пример https://www.codeproject.com/Articles/408251/Bitmap-Menu занимается преобразованием icon в bitmap.
Мне всё равно в каком формате вставлять иконки, и  сделать это можно ДО компиляции.
Нужно отобразить значки, чего Autocad упорно делать не желает
Название: Re: Иконки в контекстном меню
Отправлено: Александр Ривилис от 21-02-2020, 22:52:31
Нужно отобразить значки, чего Autocad упорно делать не желает
И какой размер у тебя значков?
Название: Re: Иконки в контекстном меню
Отправлено: Александр Ривилис от 21-02-2020, 22:58:18
Автокад должен взять моё меню как субменю и вставить в своё, как есть.
Он никому и ничего не должен. Ты можешь это хотеть, но это не значит, что в нём это предусмотрено.
Название: Re: Иконки в контекстном меню
Отправлено: Sergey_K от 21-02-2020, 23:06:43
значки стандартные 16x16 и 32х32. Он конечно ничего не должен.
Элементарная логика должна присутствовать.
Off-Topic: показать
 А с этим у ваятелей от Автодеска далеко не всегда порядок.
Предусмотрено.
В свои меню они иконки пихают
/* Настоятельно прошу оставить свои оценочные суждения при себе. Александр Ривилис. */
Название: Re: Иконки в контекстном меню
Отправлено: Александр Ривилис от 22-02-2020, 00:49:51
В свои меню они иконки пихают
Только думаю, что не таким образом. Ибо:
(https://live.staticflickr.com/65535/49566311618_c81a40cabf_o.png)

Название: Re: Иконки в контекстном меню
Отправлено: Александр Ривилис от 22-02-2020, 22:10:03
На всякий случай я задал вопрос в ADN DevHelp. Если будет дополнительная информация - сообщу.
Название: Re: Иконки в контекстном меню
Отправлено: Sergey_K от 23-02-2020, 18:29:03
Функционал Windows API искусственно ограничен, по ведомым только adsk обстоятельствам. В основном меню иконки можно назначать, а в контекстном нет. Решения НЕТ. Возможно в этом заложен неведомый нам, глубокий сакральный смысл или просто гранаты не той системы?
Цитата:  
Только думаю, что не таким образом. Ибо:
Иной способ – это работа мимо API, напрямую с оборудованием. Adsk пользует WinAPI, по этому иного способа у них нет, а его изобретение влечёт за собой приличные накладные расходы.
Данное твоё оценочное суждение ложно
Цитата:  
На всякий случай я задал вопрос в ADN DevHelp. Если будет дополнительная информация - сообщу
Вряд ли будет что то вразумительное, но тем не менее хотелось бы услышать начхальника механического цеха
Название: Re: Иконки в контекстном меню
Отправлено: Александр Ривилис от 23-02-2020, 23:11:21
Иной способ – это работа мимо API, напрямую с оборудованием.
В ObjectARX нет классов/методов для добавления иконок в контекстное меню динамически (это можно сделать через AutoCAD .NET API в CUIX). Поэтому всё остальное - это работа через Windows API.
Данное твоё оценочное суждение ложно
О чем речь? Если это наезд на Администратора, то читай Правила форума.

Название: Re: Иконки в контекстном меню
Отправлено: Александр Ривилис от 25-02-2020, 16:36:02
Ответ от ADN DevHelp:

Цитировать
Dear Alexander Rivilis,

 

I have found the below reply for a similar query to add bitmap to the custom context menu(created with acedAddDefaultContextMenu)

of the ArxDbg tool , from our databases. Below code works for me without any issues.


>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

Please check the following code which adds a new menu item having both an icon and a string to the ArxDbg popup sub menu.

// Please include the GDI+ header and use its namespace.


#include

using namespace Gdiplus;

// Don't forget to like GdiPlus.lib into your project. ArxDbgEdUiContextApp::ArxDbgEdUiContextApp()


ArxDbgEdUiContextApp::ArxDbgEdUiContextApp()

{     

       CAcModuleResourceOverride(ArxDbgApp::getApp()->dllInstance());

 

    m_cMenu = new CMenu;

    BOOL res = m_cMenu->LoadMenu(ARXDBG_MNU_APP);

    VERIFY(res);

    if (!res) {

        delete m_cMenu;

        m_cMenu = NULL;

    }

     

       HBITMAP hbmp = ::LoadBitmap(ArxDbgApp::getApp()->dllInstance(), L"ARXDBG_BMP_REMOVE");

       ASSERT(hbmp != NULL);

       Gdiplus::Bitmap* pBmp = Gdiplus::Bitmap::FromHBITMAP(hbmp, NULL);

       ASSERT(pBmp->GetLastStatus() == Ok);

 

       // Add a "Test" menu item.

       MENUITEMINFO mii = { 0 };

       mii.cbSize = sizeof(mii);

       //MIIM_DATA must be used for bitmaps.

       mii.fMask = MIIM_ID | MIIM_DATA | MIIM_STRING | MIIM_FTYPE;

       mii.wID = 5555;

       //We need to set the type as MFT_OWNERDRAW;

       mii.fType = MFT_OWNERDRAW;

       mii.dwTypeData = TEXT("&Test from Bill Zhang");

       mii.cch = _tcslen(mii.dwTypeData) + 1;

       mii.dwItemData = (ULONG_PTR)pBmp;

       BOOL ret = InsertMenuItem(m_cMenu->GetSubMenu(0)->GetSafeHmenu(),

             5,

             TRUE,

             &mii);

       ASSERT(ret);

     

}


Please note a few points:

We need to use GDI+ bitmap object (Bitmap) instead of GDI or MFC one (CBitmap).

Because of the above, we need to include the GdiPlus header, use its namespace and link with its library.

MIIM_DATA must be combined with other masks in order to use bitmaps.

The fType should be set as MFT_OWNERDRAW.

The cch member of the MENUITEMINFO struct should be the string length.

The dwItemData member of the struct contains the pointer to the GDI+ bitmap.

The bitmap should be 16*16 size. Otherwise the InsertMenuItem() will fail.

Please don't forget to delete the bitmap object (HBITMAP ) when your application exits. You can use DeleteObject() function to do the job.

GdiPlus initialization and uninitialization may be needed if you use GdiPlus functions. The following code can be used for this purpose:


//GdiplusStartupInput gdiplusStartupInput;

//ULONG_PTR gdiplusToken;

//GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

// GDI+ functions call

//......

//

//GdiplusShutdown(gdiplusToken);

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


 


Hope this helps.

 

Best Regards,

Deepak A S Nadig

Если интересно - тестируй.
Название: Re: Иконки в контекстном меню
Отправлено: Sergey_K от 27-02-2020, 12:30:23
Уже теплее.

Одна неточность
The bitmap should be 16*16 size. Otherwise the InsertMenuItem() will fail
Не проверял, конкретно InsertMenuItem(), но пара вызовов GetMenuItemInfo и SetMenuItemInfo позволяет в контекстное меню установить иконки как 16х16, так и 32х32
Код - C++ [Выбрать]
  1. MENUITEMINFO mii = { 0 };
  2. mii.cbSize = sizeof(mii);
  3. mii.fMask = MIIM_ID | MIIM_DATA | MIIM_STRING | MIIM_FTYPE;
  4. TCHAR buf[MAX_PATH];
  5. mii.dwTypeData = buf;
  6. mii.cch = MAX_PATH;
  7.    
  8. menu->GetSubMenu(0)->GetMenuItemInfo(MENU_ITEM_ID, &mii);
  9. mii.fType |= MFT_OWNERDRAW;
  10.    
  11. GdiPlusBitmapPtr = GetSystemMetrics(SM_CXICON) >= 32 ? gdiPlusBitmapPtr32 : gdiPlusBitmapPtr16;
  12. mii.dwItemData = reinterpret_cast<ULONG_PTR> (GdiPlusBitmapPtr);
  13. menu->SetMenuItemInfo(MENU_ITEM_ID, &mii);
  14.  
Название: Re: Иконки в контекстном меню
Отправлено: Александр Ривилис от 27-02-2020, 15:24:16
Одна неточность
Я так понимаю, что этому коду уже порядка десятка лет и вполне возможно, что он несколько устарел. Во всяком случае сайта с базой знаний и подобных кодов, на который был доступ только у действительных членов ADN уже лет пять как нет. Часть кодов перенесли на https://adndevblog.typepad.com/autocad/ но что-то при этом забыли...
Название: Re: Иконки в контекстном меню
Отправлено: Sergey_K от 27-02-2020, 17:58:58
удивительно, что подобных базовых вещей нет в SDK...
Если руки не доходят сделать функцию в AcEdUIContext, то могли бы хоть черкнуть пару строк
Название: Re: Иконки в контекстном меню
Отправлено: Александр Ривилис от 27-02-2020, 18:05:47
удивительно, что подобных базовых вещей нет в SDK...
Если руки не доходят сделать функцию в AcEdUIContext, то могли бы хоть черкнуть пару строк
Ничего удивительного. Такого рода "базовых" вещей миллионы... Есть запросы от сторонних разработчиков на всякие дополнения/исправления в SDK, есть ограниченные ресурсы у команды разработчиков  (AutoCAD DevTeam) и есть расставленные приоритеты.
Подробнее здесь: https://adn-cis.org/forum/index.php?topic=2640.0