Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.118.171.20] |
|
Сообщ.
#1
,
|
|
|
Привет всем программерам!
Как сделать такое же выделение как в WinXP? Под выделением подразумеваю рамку, когда выделяешь какие либо объекты (папки, файлы) в проводнике. Как бы полупрозрачный прямоугольник с рамкой - очень эффектно. Я бы хотел сделать точно такое же выделение в своей программе, а именно на ListView, т.к. там выделение стандартное, т.е. обычная рамка. Буду очень благодарен в рейтинговом эквиваленте PS. Если кто меня не понял, а таких я думаю много, то прошу смотреть скриншот >>> Прикреплённый файлscreen.JPG (32.79 Кбайт, скачиваний: 417) |
Сообщ.
#2
,
|
|
|
DrawFocusRect
|
Сообщ.
#3
,
|
|
|
Anatoly Podgoretsky, а можно поподробней?
|
Сообщ.
#4
,
|
|
|
Не знаю почему, но DrawFocusRect здесь не проходит даже с использованием XPManifest. Вообще это и в XP не является умолчанием, а просто опцией, которую можно выставить и снять(в визуализации). Вообще, требуемый эфеект называется альфа-выделение(alpha-selection). Это (утрированно) есть битмап с проставленной степенью прозрачности. Эти эффекты вообще называются alphablending, т.е. дословно "альфасмешивание". Тогда есть выход: нарисовать это выделение руками. В XP наши "коллеги из Microsoft" предоставили такую прекрасную библиотеку Msimg32.dll с функцией для сего альфаблендинга:
BOOL AlphaBlend( HDC hdcDest, // handle to destination DC int nXOriginDest, // x-coord of upper-left corner int nYOriginDest, // y-coord of upper-left corner int nWidthDest, // destination width int nHeightDest, // destination height HDC hdcSrc, // handle to source DC int nXOriginSrc, // x-coord of upper-left corner int nYOriginSrc, // y-coord of upper-left corner int nWidthSrc, // source width int nHeightSrc, // source height BLENDFUNCTION blendFunction // alpha-blending function ) ; Так вот ею и вооружимся. Описать её в интерфейсной части следует вот так: function AlphaBlend( hdcDest:HDC; // handle to destination DC nXOriginDest, // x-coord of upper-left corner nYOriginDest, // y-coord of upper-left corner nWidthDest, // destination width nHeightDest:integer; // destination height hdcSrc:HDC; // handle to source DC nXOriginSrc, // x-coord of upper-left corner nYOriginSrc, // y-coord of upper-left corner nWidthSrc, // source width nHeightSrc:integer; // source height blendFunction:TBLENDFUNCTION // alpha-blending function ) : boolean;stdcall; external 'Msimg32.dll'; В силу того, что она внешняя, реализации в implementation не может быть. Теперь напишем собственную функцию на основе сией внешней(уже в implementation нужно) : procedure blend(alpha:integer;Dest:TListView; Rdest:Trect; source:Tbitmap; Rsource:Trect ); var sourceDC,destDC:HDC; TB:TBLENDFUNCTION; bres:boolean; begin TB.BlendOp:=0; TB.BlendFlags:=0; TB.SourceConstantAlpha:=alpha; TB.AlphaFormat:=0; bres:=alphablend( dest.canvas.handle,rdest.left,rdest.top, rdest.right-rdest.left,rdest.bottom-rdest.top, source.canvas.handle, rsource.left,rsource.top, rsource.right-rsource.left,rsource.bottom-rsource.top, TB); end; В качестве параметров ей передаём: alpha - степень прозрачности(от 0(прозрачный полностью) до 255(насыщенный полностью)), Dest - наш компонент с канвой(здесь - TListView), Rdest - прямоугольная область, на которую распространим альфаблендинг, source - битмап с рисунком, который будем накладывать, Rsource - часть этого битмапа, которую будем использовать. Теперь покажу реализацию на примере простой прорисовки, т.е. по нажатию кнопки: var Bitmap1:TBitmap; ........................ procedure TForm1.Button1Click(Sender: TObject); begin Bitmap1:=TBitmap.Create; Bitmap1.Width:=60; Bitmap1.Height:=60; Bitmap1.Canvas.Brush.Color:=clblue; //цвет заливки Bitmap1.Canvas.Rectangle(Rect(0,0,60,60)); //заливаем Bitmap //теперь наша функция blend(120,ShellListView1,Bitmap1.Canvas.ClipRect,Bitmap1,Bitmap1.Canvas.ClipRect); //теперь обведём рамку bitmap'а: ShellListView1.Canvas.Pen.Color:=clBlack; ShellListView1.Canvas.Polyline([Point(0,0),Point(60,0),Point(60,60),Point(0,60), Point(0,0)]); //освобождаем память Bitmap1.Free; end; Должно получиться то же, что и в Explorer'е. Ну а теперь осталось только реализовать обработчики соответствующих событий мыши для достижения эффекта выделения. По нажатию Fselecting=true; по отжатию Fselecting=false; по MouseMove если fSelecting=true, то меняем координаты блендинга, а вся прорисовка - в OnPaint объекта или его родителя(если нет хэндла у объекта или в лом ловить WM_PAINT). Попробуй и спроси, что непонятно. |
Сообщ.
#5
,
|
|
|
СПАСИБО!
|
Сообщ.
#6
,
|
|
|
Еще раз вернусь к этому вопросу. Представленный выше код не работает! Может я что-то неправильно делаю.. не могли бы вы выложить исходник. У меня Делфи 7.
|
Сообщ.
#7
,
|
|
|
Цитата Kostas @ 18.06.04, 13:34 Еще раз вернусь к этому вопросу. Представленный выше код не работает! Может я что-то неправильно делаю.. не могли бы вы выложить исходник. У меня Делфи 7. Код-то работает, я попытался реализовать дальше (с перемещением мауса), но столкнулся с одной проблемой. Ты ведь собираешься сделать такое выделение, для того, чтобы выбирать итемы из ListView'а? Я выставляю MultiSelect в True, и при MouseDown'е либо не присходит этого события, либо происходит перерисовка и этой альфаблендной рамки не видно... Без MultiSelect'а всё нормально работает... Т.е этот код работает, но сложно реализовать выделение с помощью этой рамки... |
Сообщ.
#8
,
|
|
|
Curve, можешь выложить исходник? а то что-то у меня никак не получается.. Хотя бы с multiselect=False...
|