Delphi и 48x48 (или больше) списки изображений - есть ли обходной путь? - PullRequest
4 голосов
/ 28 января 2011

Я получаю системный список изображений (с SHGetFileInfo и SHGFI_LARGEICON), добавляю два моих собственных значка и присоединяю его к TListView.

Проблема в том, что если размер значка пользователя не установлен в 32x32 (как, например, он установлен в 48x48), Delphi7 TImageList завершается ошибкой «Неверный размер изображения».

Кто-нибудь знает, доступен ли обходной путь? Я пытался использовать TPngImageList, но это приводит к другим проблемам.

Также обратите внимание, что я бы хотел сохранить альфа-канал иконок. Обычной 1-битной прозрачности недостаточно, так как значки выглядят так ужасно.

Спасибо!

Ответы [ 3 ]

5 голосов
/ 28 января 2011

Мне не известно о каких-либо ограничениях по размеру изображений, которые может содержать TImageList. Мне кажется, что ваша проблема в том, что у вас есть значки разных размеров, и вы не можете держать значки разных размеров в одном списке изображений.

Если вы работаете с иконками разных размеров, вам нужно будет увеличить меньшие по размеру. Вам придется создать его в коде, используя растровое изображение. Вы заполняете растровое изображение прозрачным альфа-каналом и затем перетаскиваете меньший значок в центр растрового изображения.

Другим вариантом может быть поддержание двух отдельных списков изображений, но если вам нужно нарисовать значки в одном и том же виде списка, то я думаю, что эта работа не будет выполнена. Я предполагаю, что вам нужно вырастить маленькие иконки.

Для альфы вам понадобится создать дескриптор списка изображений самостоятельно, так как свойство ColorDepth не существует в D7. Из-за этого ванильный D7 TImageList просто не может поддерживать иконки с альфа-каналами.

Чтобы обойти это ограничение, вы должны позвонить ImageList_Create, передать ILC_COLOR32 и присвоить результат ImageList.Handle. Сделайте это, прежде чем добавлять какие-либо изображения. Вам придется заполнять список во время выполнения, а не во время разработки, но, похоже, вы уже это делаете.

Вот снимок экрана кнопки инструмента 48x48 со значком 32bpp с альфа-прозрачностью:

48px icon from image list

Это правда, что я сделал это в D2010, но мой вышеупомянутый обходной путь будет работать для D7 - я использовал этот механизм до недавнего времени с D6. Я просто показываю это, чтобы доказать, что список изображений может содержать иконки размером 48 пикселей. Поскольку TImageList является просто оболочкой для компонента списка системных образов, я считаю, что то, что вы пытаетесь сделать, должно быть вполне осуществимым.

3 голосов
/ 28 января 2011

Как раз когда я собирался сдать эту страницу, я пришел к решению: http://delphihaven.wordpress.com/2010/09/06/custom-drawing-on-glass-2/

Очевидно, что если вы попытаетесь добавить значок размером больше 32x32 в список изображений в Delphi7, VCLвыдаст ошибку «Недопустимый размер изображения», в то время как он может просто вызвать API-интерфейс himagelist - который легко может с этим справиться.

Вот полное решение:

unit ImageListFix;

interface

uses CommCtrl, Graphics, ImgList;

type
  TImageListFixer = class(TCustomImageList)
  public
    function AddIcon(Image: TIcon): Integer;
  end;

implementation

function TImageListFixer.AddIcon(Image: TIcon): Integer;
begin
  if Image = nil then
    Result := Add(nil, nil)
  else
  begin
    Result := ImageList_AddIcon(Handle, Image.Handle);
    Change;
  end;
end;

end.

И код длядобавление значков в системный список изображений:

DocumentImgList:=TImageListFixer(GetSystemLargeIconsList);

IconToAdd:=TIcon.Create;
try
  IconToAdd.Handle := LoadImage(0, 'c:\Ico1.ico', IMAGE_ICON, DocumentImgList.Width, DocumentImgList.Height, LR_LOADFROMFILE);
  DocumentImgList.AddIcon(IconToAdd);

  IconToAdd.Handle := LoadImage(0, 'c:\Ico2.ico', IMAGE_ICON, DocumentImgList.Width, DocumentImgList.Height, LR_LOADFROMFILE);
  DocumentImgList.AddIcon(IconToAdd);
finally
  IconToAdd.Free;
end;
1 голос
/ 29 января 2011

TImageList генерирует ошибку «Неверный размер изображения» только при 2 условиях:

1) Свойство TImageList «Высота» или «Ширина» меньше 1 или свойство «Высота» больше 32768, когда TImageList изначальносозданный с помощью конструктора CreateSize () (нет таких ограничений, налагаемых установщиками свойств Height и Width).

2) вы пытаетесь добавить / вставить новый TBitmap или TIcon, размеры которых не вписываются во внутренние TImageListизображение.

...