| | | | |
Полный текст материала
Другие публикации автора: Сергей Галездинов
Цитата или краткий комментарий: «... Пример использования градиентной заливки для украшения интерфейса. ...» |
Важно:- Страница предназначена для обсуждения материала, его содержания, полезности, соответствия действительности и так далее. Смысл не в разборке, а в приближении к истине :о) и пользе для всех.
- Любые другие сообщения или вопросы, а так же личные эмоции в адрес авторов и полемика, не относящаяся к теме обсуждаемого материала, будут удаляться без предупреждения авторов, дабы не мешать жителям нормально общаться.
- При голосовании учитывайте уровень, на который расчитан материал. "Интересность и полезность" имеет смысл оценивать относительно того, кому именно предназначался материал.
- Размер одного сообщений не должен превышать 5К. Если Вам нужно сказать больше, сделайте это за два раза. Или, что в данной ситуации правильнее, напишите свою статью.
Всегда легче осудить сделанное, нежели сделать самому. Поэтому, пожалуйста, соблюдайте правила Королевства и уважайте друг друга.
Добавить свое мнение.
| | Содержит полезные и(или) интересные сведения | [1] | 3 | 75% | | | | Ничего особенно нового и интересного | [2] | 1 | 25% | | | | Написано неверно (обязательно укажите почему) | [3] | 0 | 0% | | Всего проголосовали: 4 | | | Все понятно, материал читается легко | [1] | 3 | 75% | | | | Есть неясности в изложении | [2] | 1 | 25% | | | | Непонятно написано, трудно читается | [3] | 0 | 0% | | Всего проголосовали: 4 |
[TButton] [Фоновые рисунки, прозрачность, скины ] [WM_PAINT]
Отслеживать это обсуждение
Всего сообщений: 2111-11-2009 05:34>>> Вообще то может »вопрос КС №74005« но для всех нижележащих контролов будет вызывать Invalidate.
Вообще-то, не может. То, на что Вы намекаете, это псевдопрозрачность. Если бы он действительно мог быть прозрачным, то никакого Invalidate вызывать было бы не нужно.
Ктсати, альтернтативный вариант прозрачного контрола -- использование окна неправильной формы (например, с вырезами). Вот ту действительно будет прозрачность ;-) |
|
11-11-2009 04:37Наследник TWinControl не может быть прозрачным, поищите на королевстве по слову "DrawParentBackground"
Вообще то может »вопрос КС №74005« но для всех нижележащих контролов будет вызывать Invalidate. |
|
10-11-2009 11:442 Sega-Zero:
Изменил кусок кода по отрисовке скина
h := FSkinBitmap.Height div 4;
w := FSkinBitmap.Width;
if FSkinTransparent then
begin
DrawParentBackground(Handle, FCanvas.Handle, @RC);
case State of
bsDisabled:
TransparentBlt(FCanvas.Handle, 0, 0, w, h, FSkinBitmap.Canvas.Handle, 0, 0, w, h, FSkinTransparentColor);
bsUp:
TransparentBlt(FCanvas.Handle, 0, 0, w, h, FSkinBitmap.Canvas.Handle, 0, h, w, h, FSkinTransparentColor);
bsOver:
TransparentBlt(FCanvas.Handle, 0, 0, w, h, FSkinBitmap.Canvas.Handle, 0, 2*h, w, h, FSkinTransparentColor);
bsDown:
TransparentBlt(FCanvas.Handle, 0, 0, w, h, FSkinBitmap.Canvas.Handle, 0, 3*h, w, h, FSkinTransparentColor);
end;
end else
begin
case State of
bsDisabled:
BitBlt(FCanvas.Handle, 0, 0, w, h, FSkinBitmap.Canvas.Handle, 0, 0, SRCCOPY);
bsUp:
BitBlt(FCanvas.Handle, 0, 0, w, h, FSkinBitmap.Canvas.Handle, 0, h, SRCCOPY);
bsOver:
BitBlt(FCanvas.Handle, 0, 0, w, h, FSkinBitmap.Canvas.Handle, 0, 2*h, SRCCOPY);
bsDown:
BitBlt(FCanvas.Handle, 0, 0, w, h, FSkinBitmap.Canvas.Handle, 0, 3*h, SRCCOPY);
end;
end;
Всё отлично! Огромное спасибо за помощь :) |
|
10-11-2009 09:14сообщение от автора материала Наследник TWinControl не может быть прозрачным, поищите на королевстве по слову "DrawParentBackground" |
|
10-11-2009 09:03Сделал через переопределение стиля с BS_OWNERDRAW (исходник модуля ниже). Столкнулся с проблемой прозрачности в скине. Те места на кнопке, через которые должен быть виден фон формы - остаются каким цветом они и есть (использую цвет $00ff00ff). Подскажите что я не учел?
...
TMyButton = class(TButton)
private
FCanvas: TCanvas;
...
FSkinBitmap: TBitmap;
FTransparent: Boolean;
FTransparentColor: TColor;
procedure SetSkinBitmap(const ABitmap: TBitmap);
procedure SetTransparent(const AValue: Boolean);
procedure SetTransparentColor(const AColor: TColor);
...
protected
procedure CreateParams(var Params: TCreateParams); override;
...
public
...
published
property SkinBitmap: TBitmap read FSkinBitmap write SetSkinBitmap;
property Transparent: Boolean read FTransparent write SetTransparent default false;
property TransparentColor: TColor read FTransparentColor write SetTransparentColor default clNone;
end;
...
implementation
...
procedure TMyButton.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
with Params do
Style := Style or BS_OWNERDRAW;
end;
procedure TMyButton.SetSkinBitmap(const ABitmap: TBitmap);
begin
FSkinBitmap.Assign(ABitmap);
Invalidate;
end;
procedure TMyButton.SetTransparent(const AValue: Boolean);
begin
FTransparent := AValue;
Invalidate;
end;
procedure TMyButton.SetTransparentColor(const AColor: TColor);
begin
FTransparentColor := AColor;
Invalidate;
end;
...
procedure TMyButton.CNDrawItem(var Message: TWMDrawItem);
var
...
h, w: integer;
begin
...
h := FSkinBitmap.Height div 4;
w := FSkinBitmap.Width;
FSkinBitmap.Transparent := FTransparent;
FSkinBitmap.TransparentColor := FTransparentColor;
case State of
bsDisabled:
FCanvas.CopyRect(Rect(0, 0, w, h), FSkinBitmap.Canvas, Rect(0, 0, w, h));
bsUp:
FCanvas.CopyRect(Rect(0, 0, w, h), FSkinBitmap.Canvas, Rect(0, h, w, 2*h));
bsOver:
FCanvas.CopyRect(Rect(0, 0, w, h), FSkinBitmap.Canvas, Rect(0, 2*h, w, 3*h));
bsDown:
FCanvas.CopyRect(Rect(0, 0, w, h), FSkinBitmap.Canvas, Rect(0, 3*h, w, 4*h));
end;
...
end;
...
end.
Присваиваю скин кнопке так:
Bitmap := TBitmap.Create;
Bitmap.Height := 80;
Bitmap.Width := 82;
Bitmap.PixelFormat := pf24bit;
MyButton.SkinBitmap := Bitmap;
MyButton.Transparent := true;
MyButton.TransparentColor := $00ff00ff;
Bitmap содержит изображения 4-х состояний кнопки сложенные вертикально (82х20px каждое) |
|
10-11-2009 05:34>>>реакторов свойств.
редакторов свойств |
|
10-11-2009 05:30Пачеко (и Тексейра) тут вообще не при чем, т.к. у них в книге написано про создание экспертов в Дельфи, а статья Инны Аринович - совсем про другое, про создание реакторов свойств. |
|
10-11-2009 05:25сообщение от автора материала Давайте на этом закроем тему невежественности и 1С. К статье это не относится (ну, разве что невежество :))
Если есть желание - велкам на базарную площадь, можно обсудить все прелести 1С по сравнению с делфи |
|
10-11-2009 05:21Проблема в том, что создано решение, позволяющее очень быстро создавать проекты по работе с базами данных. Сам факт наличия такой халявы может усилит позиции этой платформы в данном секторе. Безусловно Delphi - универсальная среда, но ее основное применение в нашей стране - какие-то учетные системы. При этом в Delphi нужно думать об архитектуре приложения. Это требует определенных умственных способностей, плюс, как минимум, временные затраты на создание (дописывание) компонент, чтобы хоть как-то обосновывать конкурентные преимущества. В 1С думать особо не очем, масштаб действительно не тот, раньше это было, безусловно, недостатком, сейчас это скорее плюс системы. Народу дали халяву. Скоро ей начнут сначала пользоваться, а потом и злоупотреблять... И не важно работают эти решения с 1С или без нее, масштабны они или нет, халява есть халява...
Честно говоря, ничего подобно еще нигде не встречал. Есть множество различных технологий, но готовую архитектуру никто не предлагает. Исключеним разве что может являтся сектор ERP, но по цене 1С даже со своей Консолидацией и УПП намного дешевле. А в ряде случаев и красивее (например, по сравнению с SyteLine).
Ну да ладно... скосячил сильно... каюсь еще раз... просто много невежества вокруг, не выдержал...
ps: Я Паченко таки по диалапу качал и даже Совершенный код Макконела (~100 mb)... |
|
10-11-2009 05:04сообщение от автора материала Ну вообще, Николай тут в обсуждении верно сказал. Гораздо правильнее переопределить стиль на BS_OWNERDRAW и обрабатывать CN_DRAWTEM
тогда не нужно будет отслеживать все эти нажатия и прочее:) |
|
10-11-2009 04:47Задал вопрос и стал инициатором странной дискусси о версиях 1С??
2 Андрей: Вы вообще к чему все это написали? Мне это ни сколько не помогло. Хотите помочь, ну так ткните меня в нужное место указанной Вами литературы.
2 Sega-Zero: Возможно я позже воспользуюсь каким-нибудь другим решением, но сейчас хочу реализовать именно это. Считайте, что это забавы ради. Если не рекомендуете пользоваться этой кнопкой, тогда может порекомендуете альтернативное решение? |
|
10-11-2009 03:29сообщение от автора материала 2 Shoorf:
Я настойчиво не рекомендую использовать эту кнопку:) Код писался в период изучения VCL и без боли в глазах на этот код уже не глянешь:)
2 Андрей:
В 2004 году книгу Пачеко было почти не достать в бумаге и практически нереально скачать, ибо диалап. Так что все изучалось опытным путем:)
Что касается 1С - немного разные весовые категории, чтобы сравнивать. Не буду разжигать холивар - это тема для базарной площади. Но скажу лишь одно: попробуйте запустить программу на 1С без 1С:) И как деплоить оную. Никак, нужен рантайм:) И просто так его на машину без лицензии не поставишь. Так что цена вполне объяснима. |
|
10-11-2009 02:15Прошу прощения, с 2009 годом, конечно загнул, сбило с толку дата последней публикации в ответах. Подумал, что это дата создания статьи. Про 1С все верно, про остальное приношу извенения.. |
|
10-11-2009 02:10Вообще забавно, что человек в 2009 году не видел статьи 2004 года, автор которой, на момент написания, явно не читала Паченко с Тексерой про Delphi 5 (которая наверное в году 2000 уже была в электронном виде), где во втором томе описывается как создавать эксперты под Tools API. Им нравиться творить подвиги, заниматься reversing-ом VCL (в случае с Tools API это, безусловно, небходимо, но прочитав классиков намного легче) и совершать, тем самым, глобальные научные открытия. Ток шоу "Я сама".
Не менее забавно то, что человек сам признается в том, что работу не доделал ("тяжела жизнь студента"... япона месть... да у студентов самая халявная жизнь...), но статью он таки решил опубликовать (под сессию понадобилась публикация? почему нельзя было все доделать а потом опубликовать?).
И оказывается, что статья отражает "идею", т.е. "содержание", а не "форму". А в чем собственно идея? В том что можно чего-то добиться не вникая в основы предметной области?
Сейчас руковожу разработкой конфигурации под 1С 8.2. У этой версии есть существенные отличия по сравнению с 8.1. Есть в отделе соотвествующая литература. Для тех кто не знает, книжки по 1С по сравнению с книжками до Delphi (за исключением одной) очень небольшого объема с кучей картинок. Так вот сегодня заметил, что один из сотрудников делает на старый манер увязку двух реквезитов, один из которых является владельцем другого. Было написано несколько процедур и где-то под сотню строчек кода. Если бы не поленился и прочитал букварь, то знал бы что такое в новой версии делается за три клика в редакторе дочернего реквизита...
Сам являюсь противником 1С, работаю с ней потому что платят больше, считаю что 8.2 через несколько лет похоронит всех кустарно мыслящих Дельфистов типа автора статьи, т.к. эта версия платформы представляет декларативную разработку в терминах предметной области с очень функциональным и красивым интерфейсом, а также очень скудным (т.е. очень простым для освоения) языком программирования. Любителям чего-то готового не нужно больше страдать в поисках каких-то готовых компонент, чтобы что-то соорудить. В 1С уже все для вас придумали, и скоро исправят большинство ошибок (по собственным наблюдениям: IDE Delphi 2009 у меня падает намного чаще, чем конфигуратор 1С 8.2, ну а до IDE Delphi 7 им пока еще далеко). При этом лицензии у 1С существенно дешевле чем у Embarcodero. Пока еще не портировали основные конфигурации с 8.1 под 8.2 (на мой взгляд: 4-6 месяцев не больше) у вас еще есть время изучить этот продукт к моменту его интенсивного использования... |
|
09-11-2009 14:41Если нажать на кнопку, но увести курсор не отпуская клавишу мыши, и отпустить где нибудь в другом месте (не над кнопкой) - событие OnClick все равно происходит! Как это можно исправить? |
|
03-12-2006 23:44Небольшое примечание:
Придется переопределить пару-тройку методов, чтобы не было видно старой отрисовки кнопки.
Достаточно переопределить CreateParams и добавить стиль BS_OWNERDRAW, тогда никакой дефолтовой отрисовки не будет вообще. Кнопка после этого станет получать сообщение CN_DRAWITEM (могу ошибиться, лучше точно посмотреть в исходниках того же TBitBtn), в обработчике которого и рисуем все, что нужно. В принципе мождо даже не заводить глобальную канву, т.к. в обработчик передается контекст, на котором нужно рисовать. |
|
01-12-2006 09:23сообщение от автора материала Возможно, повторюсь, но я в статье показывал принцип использования градиентной заливки. Как использовать - это решать разработчику. Все зависит от его фантазии.
P.S. GradientFill хороша, быстра, эффективная, и более того, я никоим образом не заставляю использовать именно мой код. Сделайте свой. Я показывал лишь свой подход, вносящий немного творчества. В большинстве случаев, конечно, вертикальной и горизонтальной заливкой можно обойтись. |
|
01-12-2006 08:32На мой взгляд градиентную заливку можно упростить реализовав её через функцию GradientFill (модуль Windows).
Только учтите что в D7 структура TTriVertex в Windows.pas объявлена с ошибкой (точнее не она, а COLOR16), кто то из Borland-а перепутал SmallInt и ShortInt (а вот нефиг их было так называть, а то я и сам путаюсь). Вобщем функция GradientFillCanvas взятая из Turbo, под D7 будет выглядеть как-то так:type
TGradientDirection=(gdHorizontal,gdVertical);
procedure GradientFillCanvas(Canvas:TCanvas;StartColor,EndColor:TColor;const ARect:TRect;Direction:TGradientDirection);
const
cGradientDirections:array[TGradientDirection] of Cardinal=
(GRADIENT_FILL_RECT_H,GRADIENT_FILL_RECT_V);
type
TTriVertex=packed record
x:LongInt;
y:LongInt;
Red:Word;
Green:Word;
Blue:Word;
Alpha:Word;
end;
var
Vertexes:array[0..1] of TTriVertex;
GradientRect:TGradientRect;
begin
StartColor:=ColorToRGB(StartColor);
EndColor:=ColorToRGB(EndColor);
Vertexes[0].x:=ARect.Left;
Vertexes[0].y:=ARect.Top;
Vertexes[0].Red:=GetRValue(StartColor)shl 8;
Vertexes[0].Blue:=GetBValue(StartColor)shl 8;
Vertexes[0].Green:=GetGValue(StartColor)shl 8;
Vertexes[0].Alpha:=0;
Vertexes[1].x:=ARect.Right;
Vertexes[1].y:=ARect.Bottom;
Vertexes[1].Red:=GetRValue(EndColor)shl 8;
Vertexes[1].Blue:=GetBValue(EndColor)shl 8;
Vertexes[1].Green:=GetGValue(EndColor)shl 8;
Vertexes[1].Alpha:=0;
GradientRect.UpperLeft:=0;
GradientRect.LowerRight:=1;
GradientFill(Canvas.Handle,Windows.PTriVertex(@Vertexes[0])^,2,@GradientRect,1,cGradientDirections[Direction]);
end; |
|
30-11-2006 16:48На мой взгляд градиентную заливку можно упростить реализовав её через функцию GradientFill (модуль Windows). |
|
16-11-2006 18:52Чтобы не мерцало при прорисовке, используй свойство DoubleBuffered (см. справку). Если true, то перед показом производится прорисовка на bitmap в памяти, который потом показывается пользователю (принцип похож на DirectDraw). |
|
15-06-2006 09:05Очень полезная статья! Хотелось бы увидеть обновленный вариант с исправлениями замечаний автора.
Спасибо! |
|
|
|