Поиск:

Ответ в темуСоздание новой темы Создание опроса
> TResourceStream отказывается работать, Resource <resource name> not found 
:(
    Опции темы
artsb
Дата 29.12.2009, 18:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 39
Всего: 64



Как-то столкнулся с проблемой связанной с TResourceStream. Сейчас решил разобраться, но что-то сам никак...
Код

 HANDLE h = LoadLibrary("c:\\lib.dll");

Вот это отрабатывает отлично:
Код

 Image1->Picture->Icon->Handle = LoadIcon(h, "ADD");

И другие функции, типа ExtractIcon, тоже отлично работают.
Вот так, работать не хочет:
Код

 TResourceStream *st = new TResourceStream((unsigned)h, "ADD", RT_ICON);
 if(st) {
  Image1->Picture->Icon->LoadFromStream(st);
  delete st;
 }

Вылетает AV - "Resource <resource name> not found".

Что это за трабла?

Добавлено через 11 минут и 12 секунд
"Раскопал" реализацию конструктора. Там первым делом проверяется наличие ресурса с помощью FindResource.
Поле таких действий:
Код

HANDLE resH = FindResource(h, "ADD", RT_ICON);

resH равно NULL.
Похоже всё дело в этой функции...


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
586
Дата 29.12.2009, 18:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2243
Регистрация: 8.5.2006

Репутация: 57
Всего: 146



Под именем иконки обычно скрывается IconGroup, где хранится информация о доступных иконках.
Код
TResourceStream *st = new TResourceStream((unsigned)h, "ADD", RT_GROUP_ICON);

Функция LoadIcon парсит этот ресурс (подбирает иконку с необходимым размером и кол-вом цветов), определяет идентификатор иконки для извлечения из ресурса RT_ICON и извлекает её.

Присоединённый файл ( Кол-во скачиваний: 16 )
Присоединённый файл  11111.PNG 51,02 Kb
PM   Вверх
artsb
Дата 29.12.2009, 19:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 39
Всего: 64



586, спасибо. Но я так ничего и не понял. Можно подробнее?

С RT_GROUP_ICON действительно лучше. Но тоже вылетает AV: "exception class EOutOfResources with message 'Не удаётся найти указанный файл'". Какой он файл найти не может smile А иногда выскакивает: "exception class EOutOfResources with message 'Out of system resources'".
Размер потока при этом равен 20 байт, хотя истинный размер иконки 5 Кб.

PS а ведь я пробовал использовать флаг RT_GROUP_ICON. Но разницы между AV не замечал. Это ж как я задолбался...  smile 

Это сообщение отредактировал(а) artsb - 29.12.2009, 19:43


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
artsb
Дата 29.12.2009, 19:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 39
Всего: 64



Кажись понял о чём вы говорили.

Вот что у меня:
user posted image
Тем не менее, при попытке обратиться к иконке по её идентификатору, получаю стандартную виндовую иконку приложения:
Код

TResourceStream *st = new TResourceStream((unsigned)h, 2, RT_ICON);

user posted image


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
586
Дата 29.12.2009, 20:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2243
Регистрация: 8.5.2006

Репутация: 57
Всего: 146



Растр иконки можно загрузить так:
Код
TResourceStream *st = new TResourceStream((unsigned)h, 2, RT_ICON);

Но это растр - заголовка в нём нет. Без заголовка Icon->LoadFromStream не будет грузить иконку.
Вот пример, как загружать иконку с помощью базовых API функций - http://msdn.microsoft.com/en-us/library/ms..._Icon_Resources - код сложноватый. Лучше всего загружать иконку с помощью LoadIcon или с помощью LoadImage. В LoadImage можно указать размер иконки, в отличии от LoadIcon.
PM   Вверх
artsb
Дата 29.12.2009, 20:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 39
Всего: 64



Цитата(586 @  29.12.2009,  20:33 Найти цитируемый пост)
Но это растр - заголовка в нём нет.

Интересно.
А почему так не работает:
Код

TResourceStream *st = new TResourceStream((unsigned)h, "ADD", RT_GROUP_ICON);

Точнее, что-то грузится из ресурсов (а может и не из них), но что?

Цитата(586 @  29.12.2009,  20:33 Найти цитируемый пост)
Вот пример, как загружать иконку с помощью базовых API функций

Да проблема не в том, с помощью чего загрузить. Я просто хочу понять что за чудо - TResourceStream. smile


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
Alexeis
Дата 29.12.2009, 20:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 26
Всего: 459



RT_GROUP_ICON это список иконок (имена ресурсов). Самих иконок тут нет. Иконки есть в  RT_ICON


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
586
Дата 29.12.2009, 20:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2243
Регистрация: 8.5.2006

Репутация: 57
Всего: 146



Цитата(artsb @  29.12.2009,  20:39 Найти цитируемый пост)
Я просто хочу понять что за чудо - TResourceStream. 

LoadFromStream ожидает, что формат иконки будет как у файла .ico. Отсюда и проблемы.
Вот так грузится нормально:
Код
TFileStream *fs = new TFileStream("testIcon.ico", fmOpenRead);
Image1->Picture->Icon->LoadFromStream(fs);
delete fs;


Это сообщение отредактировал(а) 586 - 29.12.2009, 20:58
PM   Вверх
artsb
Дата 29.12.2009, 22:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 39
Всего: 64



Цитата(Alexeis @  29.12.2009,  20:44 Найти цитируемый пост)
RT_GROUP_ICON это список иконок (имена ресурсов). Самих иконок тут нет. Иконки есть в  RT_ICON 

Скорее всего так оно и есть. Иначе как объяснить, что в потоке только 20 байт.

Цитата(586 @  29.12.2009,  20:56 Найти цитируемый пост)
Вот так грузится нормально:

Ну эт понятно. smile

Кстати, вы были правы на счёт битмапа. Но не совсем. smile Информация о цвете пикселей начинается с 40-го байта, причём изображение хранится в зеркальном виде (слева на право), причём с альфа каналом smile
В общем, своял такую функцию:
Код

 TResourceStream *st = new TResourceStream((unsigned)h, eIconIndex->Text.ToInt(), RT_ICON);
 if(st) {
  st->Position = eSeek->Text.ToInt();
  Byte r, g, b, a;
  TColor color;
  Image1->Picture->Bitmap->Height = 32;
  Image1->Picture->Bitmap->Width = 32;
  Image1->Picture->Bitmap->Canvas->Brush->Color = clBtnFace;
  Image1->Picture->Bitmap->Canvas->FillRect(TRect(0,0,32,32));
  for(int i=31; i>=0; i--)
   for(int k=0; k<32; k++) {
    st->Read(&r, sizeof(byte));
    st->Read(&g, sizeof(byte));
    st->Read(&b, sizeof(byte));
    st->Read(&a, sizeof(byte));
    color = Image1->Picture->Bitmap->Canvas->Pixels[k][i];
    r = ((float)r / 255.0 * a) + ((float)GetBValue(color) / 255.0 * (255 - a));
    g = ((float)g / 255.0 * a) + ((float)GetGValue(color) / 255.0 * (255 - a));
    b = ((float)b / 255.0 * a) + ((float)GetRValue(color) / 255.0 * (255 - a));
    color = RGB(b, g, r);
    Image1->Picture->Bitmap->Canvas->Pixels[k][i] = color;
   }
  delete st;
 }

Результат:
user posted image
Но что же хранится до 40-го байта...
И не буду же я каждый раз так извращаться если хочу достать иконку из ресурсов используя TResourceStream. Тем более, здесь есть огромный минус: в Image будет битмап, а не иконка.


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
Alexeis
Дата 29.12.2009, 22:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 26
Всего: 459



Цитата(artsb @  29.12.2009,  21:34 Найти цитируемый пост)
Но что же хранится до 40-го байта...

Как ни странно BitmapInfoHeader

Добавлено через 3 минуты
Цитата(artsb @  29.12.2009,  21:34 Найти цитируемый пост)
И не буду же я каждый раз так извращаться если хочу достать иконку из ресурсов используя TResourceStream

  Можно получить хэндл при помощи LoadImage или LoadIcon и присвоить его созданному экземпляру TIcon. Icon->handle = ...


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
artsb
Дата 29.12.2009, 22:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 39
Всего: 64



Цитата(Alexeis @  29.12.2009,  22:39 Найти цитируемый пост)
Как ни странно BitmapInfoHeader

Наверное.

Цитата(Alexeis @  29.12.2009,  22:39 Найти цитируемый пост)
Можно получить хэндл при помощи LoadImage или LoadIcon и присвоить его созданному экземпляру TIcon. Icon->handle = ... 

Это я знаю. Так работает. И ExtractIcon работает и т.д.
Но я хотел разобраться именно с TResourceStream...


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
artsb
Дата 29.12.2009, 23:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 39
Всего: 64



И всё-таки:

Что хранится в потоке после такой нехитрой операции:
Код

TResourceStream *st = new TResourceStream((unsigned)h, "ADD", RT_GROUP_ICON);

Вывод в Memo показал, что это крякозяблы, а значит явно не текст.

Цитата(Alexeis @  29.12.2009,  22:39 Найти цитируемый пост)
Как ни странно BitmapInfoHeader

Странный битмап, однако.
При попытке сделать следующее:
Код

Image1->Picture->Bitmap->LoadFromStream(fs);

отхватил AV. Хотя, наверное, так и должно быть. В обычном битмапе же не хранится информация об альфа канале (или я не прав?).
Что же это тогда за битмап?


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
Alexeis
Дата 29.12.2009, 23:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 26
Всего: 459



Цитата(artsb @  29.12.2009,  22:26 Найти цитируемый пост)
отхватил AV. Хотя, наверное, так и должно быть. В обычном битмапе же не хранится информация об альфа канале (или я не прав?).

  может и храниться, но обычный битмап имеет еще BitmapFileHeader, а тут его нет, так что нечего удивляться.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
artsb
Дата 30.12.2009, 18:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 39
Всего: 64



А вот если при создании ресурса, присвоить ему какой-нибудь свой тип, например "MY_ICON_TYPE", то всё работает отлично:
Код

 TResourceStream *st = new TResourceStream((unsigned)h, "ADD", "MY_ICON_TYPE");
 if(st) {
  Image1->Picture->Icon->LoadFromStream(st);
  delete st;
 }

Странно. Почему так... Может при обычном типе ("ICON") она сохраняется как-то по особенному...

Это сообщение отредактировал(а) artsb - 30.12.2009, 18:48


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.1250 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.