Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2002.12.23;
Скачать: CL | DM;

Вниз

Как узнать какой цвет прозрачный у объекта TIcon?   Найти похожие ветки 

 
МитяЙ2 ©   (2002-09-01 07:48) [0]

Как узнать какой цвет прозрачный у объекта TIcon?
(про пиксел в нижнем левом углу я уже слышал - это не то!)



1. Я извлекаю маленькую первую иконку из exe-шника:
(все отлично работает)

var Icon:TIcon;
IconLarge,IconSmall:HIcon;

ExtractIconEx("c:\winnt\explorer.exe", 0,IconLarge,IconSmall,1);
Icon.Handle:=IconSmall;

2. Добавляю объект в ListBox:


if Icon.Handle<>0 then // Если иконка извлечена из exe-шника...
begin
Bitmap:=TBitmap.Create;
Bitmap.Width:=16;
Bitmap.Height:=16;

Bitmap.TransparentColor:=clNone; // НЕ ЗНАЮ КАКОЙ ЦВЕТ!!!
// Если ставишь clWhite
// страшно смотреть, т.к.
// белый цвет становится прозрачным.
Bitmap.Transparent:=true;
Bitmap.TransparentMode:=tmFixed; // tmFixed означает, что
// TransparentColor мы сами
// назначаем.

// Теперь иконку прорисовываем на канве Bitmap"а...
DrawIconEx(Bitmap.Canvas.Handle,0,0,Icon.Handle,16,16,0,0,DI_NORMAL);

// И добавляем объект в список
Form.ListBox1.Items.AddObject(<текст>, TBitmap(Bitmap));

end;

3. В методе ListBox1DrawItem, который вызывается при прорисовке содержимого
ListBox1 выполняю следующее:

procedure TForm.ListBox1DrawItem(Control: TWinControl; Index: Integer;
Rect: TRect; State: TOwnerDrawState);
var Bitmap:TBitmap;
Offset:integer;

Begin

with Control as TListBox, Canvas do
Begin

Bitmap:=TBitmap(Items.Objects[index]); // index - номер прорисовываемого объекта...

if Bitmap<>nil then // Если была ранее загружена иконка...
Begin
// Выводим на канву картинку...
BrushCopy(Bounds(Rect.Left+4,Rect.Top,Bitmap.Width,Bitmap.Height),
Bitmap,
Bounds(0,0,Bitmap.Width,Bitmap.Height),
Bitmap.TransparentColor); // Последний параметр - цвет, который заменяется
// на цвет канвы (т.е. "прозрачный" цвет),
// который в пункту 2. я НЕ ЗНАЮ КАК ОПРЕДЕЛИТЬ!
Offset:=Bitmap.Width+7;
End else Offset:=23;

// Выводим на канву текст...
TextOut(Rect.Left+Offset,Rect.Top,Items[index]);
End;



ВСЕМ! ЗАРАНЕЕ ОГРОМНОЕ СПАСИБО!

С меня пиво, если Вы из Барнаула или будете проездом! Серьезно!
Приезжайте к нам! У нас скоро День Города и 65-ти летие Алт. края!



Меньше Вам багов коллеги! МитяЙ.


 
Poirot ©   (2002-09-01 10:20) [1]

Я торможу, но зачем после чтения иконки надо рисовать битмап... а?
Помоему иконка нарисуется великолепно?
I am wrong?


 
МитяЙ2 ©   (2002-09-01 10:45) [2]

Дело в том, что в ListBox1 можно поместить TBitmap, а объект TIcon
нет.


 
Ketmar ©   (2002-09-01 12:08) [3]

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

Satanas Nobiscum! 01-Sep-XXXVII A.S.


 
МитяЙ2 ©   (2002-09-01 12:54) [4]

А в мыслях сразу возник такой вопрос!

Но это сделать не сложно. Спасибо!
Будем пробовать.

Пишите, если ещё кто-нибудь с этим сталкивался!


 
МитяЙ2 ©   (2002-09-01 17:51) [5]

Так пиво никому не досталось (кроме меня)!

Все разобрался:


Bitmap:=TBitmap.Create;
Brush:=TBrush.Create;
Brush.Color:=ListColor; // ListColor - цвет фона в ListBox"e

Bitmap.Width:=16;
Bitmap.Height:=16;

Bitmap.TransparentColor:=ListColor;
Bitmap.Transparent:=true;

DrawIconEx(Bitmap.Canvas.Handle,0,0,Icon.Handle,16,16,0, Brush.Handle,DI_NORMAL);
Bitmap.TransparentMode:=tmFixed;


Пошел обмывать............................


 
msts   (2002-09-02 10:01) [6]

не знаю для чего конкретно используешь свой код
но например можно сделать так:

function ????.LoadIconByPath(Path: string): integer;
var
FileInfo: TSHFileInfo;
LIcon : TIcon;
LPath : string;
begin
LPath := Path;
LIcon := TIcon.Create;
result:=-1;
try
SHGetFileInfo(PChar(LPath), 0, FileInfo, SizeOf(FileInfo), SHGFI_ICON or SHGFI_SMALLICON);
LIcon.Handle := FileInfo.hIcon;
result:=ilSystem.AddIcon(LIcon);
finally
LIcon.Free;
end;
end;

возвращает номер картинки в списке (ilSystem - TImageList)
далее сохраняешь номер и по нему рисуешь, я так делал когда
в списке картинок помимо загружаемых есть другие (в дизайнтайме указанные)

можно по другому - получить хендел системного imagelist
и переопределить его у уже созданного (как в LIcon.Handle := FileInfo.hIcon; только для TImageList) -

FSmallImages := SHGetFileInfo("C:\", { Do not localize }
0, FileInfo, SizeOf(FileInfo), SHGFI_SYSICONINDEX or SHGFI_SMALLICON);
FLargeImages := SHGetFileInfo("C:\", { Do not localize }
0, FileInfo, SizeOf(FileInfo), SHGFI_SYSICONINDEX or SHGFI_LARGEICON);
FRoot := SRFDesktop;

кусок из \Borland\Delphi6\Demos\ShellControls\ShellCtrls.pas


 
Митяй2 ©   (2002-09-08 14:41) [7]

Да, попробовал!

Спасибо, msts

Все работает и программный код стал меньше и иконки
корректно отображаются!


Вот, только, можно перед добавлением в ImageList
как-нибудь проверить наличие добавляемой иконки,
может она уже есть и нужно возвратить только
индекс? Так, например, если есть сотня другая
одинаковых иконок, то логичнее было бы не добавлять
новую иконку в ImageList, а найдя её возвратить пор. номер
и присвоить объекту, находящемуся в ImageList.
Т.е. у меня каждому эл-ту ListBox сопоставляется индекс
иконки. А раньше я вместо индекса "загонял" сам объект
в список.
Пробовал сделать через TStringList (как дополнительный
объект хранящий пути к иконкам) - работает. Но это
не есть хороший способ программирования.



Страницы: 1 вся ветка

Текущий архив: 2002.12.23;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.013 c
1-74669
Jony
2002-12-13 10:46
2002.12.23
Исчезает надпись.


4-75047
Danger
2002-11-10 23:00
2002.12.23
Не могу поставить компоненту


1-74790
dakus
2002-12-10 11:33
2002.12.23
Классы


1-74787
Zirus
2002-12-11 12:09
2002.12.23
Работа с памятью


6-74882
Rob
2002-10-28 10:23
2002.12.23
D7 и TClient&Server Socket