Форум: "Начинающим";
Текущий архив: 2010.01.31;
Скачать: [xml.tar.bz2];
Вниз32 битные битмапы с альфой на TSpeedButton Найти похожие ветки
← →
VS (2009-12-08 10:56) [0]ДОбрый день. Столкнулся с небольшой проблемой.. необходимо вывести 32битные битмапы на кнопки. SpeedButton.Glyph чтобы то есть рисовался красиво, прям ух))
Как то не особо давно antonn выкладывал на этом форуме приятную процедуру для рисования 32 битных битмапов с альфой.procedure BlendBitmap_GDI(ACanvas: TCanvas; BT:Tbitmap; x,y:integer);
const
MaxPixelCountA = MaxInt div SizeOf(TRGBQuad);
type
PRGBAArray = ^TRGBAArray;
TRGBAArray = array[0..MaxPixelCountA-1] of TRGBQuad;
var xTo,sx,YTo,ddx,ddy,sy,w,h,dstw,dsth: integer;
bt_buff:Tbitmap; i,ii,itemp:integer; RSource,RDest:PRGBAArray; dd:double;
begin
if bt.PixelFormat<>pf32bit then Exit;
w:=BT.Width;
h:=bt.Height;
dstw:=ACanvas.ClipRect.Right-ACanvas.ClipRect.Left;
dsth:=ACanvas.ClipRect.Bottom-ACanvas.ClipRect.Top;
XTo:=x+W-1; YTo:=y+H-1;
if (y>=dstH) or (x>=dstW) or (YTo<0) or (XTo<0) then exit;
ddx:=0; ddy:=0;
sx:=W; sy:=H;
if X<0 then
begin
ddx:=-X;
inc(sx,X);
x:=0;
end;
if Y<0 then
begin
ddy:=-Y;
inc(sy,Y);
y:=0;
end;
if XTo>=dstw then dec(sx,XTo-dstw+1);
if YTo>=dsth then dec(sy,YTo-dsth+1);
if (sx<=0) or (sy<=0) then exit;
bt_buff:=Tbitmap.Create;
try
bt_buff.Width:=sx;
bt_buff.Height:=sy;
bt_buff.canvas.CopyRect( rect(0,0,bt_buff.Width,bt_buff.Height), ACanvas ,rect(x,y,x+sx,y+sy) );
bt_buff.PixelFormat:=pf32bit;
for i:=0 to sy-1 do begin
RSource:=BT.ScanLine[i+ddy];
RDest:=bt_buff.ScanLine[i];
for ii:=0 to sx-1 do begin
dd:=(1/255)*RSource[ii+ddx].rgbReserved;
itemp:=round(RDest[ii].rgbRed+(RSource[ii+ddx].rgbRed-RDest[ii].rgbRed)*dd);
if itemp>255 then itemp:=255 else if itemp<0 then itemp:=0;
RDest[ii].rgbRed:=itemp;
itemp:=round(RDest[ii].rgbGreen+(RSource[ii+ddx].rgbGreen-RDest[ii].rgbGreen)*dd);
if itemp>255 then itemp:=255 else if itemp<0 then itemp:=0;
RDest[ii].rgbGreen:=itemp;
itemp:=round(RDest[ii].rgbBlue+(RSource[ii+ddx].rgbBlue-RDest[ii].rgbBlue)*dd);
if itemp>255 then itemp:=255 else if itemp<0 then itemp:=0;
RDest[ii].rgbBlue:=itemp;
end;
end;
ACanvas.CopyRect( rect(x,y,x+sx,y+sy), bt_buff.canvas ,rect(0,0,bt_buff.Width,bt_buff.Height) );
finally
bt_buff.Free;
end;
end;
Эта процедура чудесно рисует 32 битные битмапы, поэтому решив себя сильно не запаривать, я подумал что можно отрисовать битмапы на кнопках при помощи этой процедуры. Без особой боли в сердце я изъял из VCL Buttons.pas (переименовав его и подключив к своему проекту) и заместо тамошней отрисовки кнопкиTButtonGlyph(FGlyph).Draw(Canvas, PaintRect, Offset, Caption, FLayout, FMargin, FSpacing, FState, Transparent, DrawTextBiDiModeFlags(0));
я начал рисовать этой процедурой. Кнопочки стали как картинки, такие аккуратненькие, и радовали мой глаз, но недолго.. Все было бы хорошо,
если бы не одна не особо приятная вещь, которая начала твориться. Кнопки перерисовывались только после того, как мышью по ним проведешь, ну или после любого другого действия, которое приводит к перерисовке. То есть если затащишь форму с такой кнопко за пределы экрана, а потом вытащишь обратно, то картинка пропадает. Навел мышку или сресайзил форму - и картинка появилась.
Тогда я решил использовать Windows.AlphaBlend()
Проблема пропала, картинки с кнопок не исчезают, все приятно.. но не радует глаз, потому что Windows.AlphaBlend менее красивую картинку выдает.
Вопрос к мастерам. Как бы мне так сделать, чтобы качество картинки было как с первой процедуры, но картинка не исчезала.
Сердцем чую, что проблема в процедуре BlendBitmap_GDI.
Ибо даже когда с ее помощью выводишь на вкладки PageControl-a рисунки, то они также затираются.
Но никак не могу понять из-за какого криминального места происходит сие поведение. Прошу помощи.
← →
clickmaker © (2009-12-08 13:21) [1]> то они также затираются
они наверно не затираются, а просто не отрисовываются
TButtonGlyph(FGlyph).Draw вызывается в четырех местах
← →
VS (2009-12-08 13:42) [2]Я в 1м посте облажался, не то написал слегка, но смысл тот же.
TButtonGlyph(FGlyph).Draw вызывает TButtonGlyph.DrawButtonGlyph и вот там я закомментил ThemeServices.DrawIcon(Canvas.Handle, Details, R, FGlyphList.Handle, Index); и отрисовал Glyph процедурой BlendBitmap_GDI
Непонятно все равно поведение, почему Windows.AlphaBlend в том же самом месте пишешь и ничего не стирается, а BlendBitmap_GDI заместо него пишешь - кнопки не перерисовываются.
Ну проблема ведь в этой процедуре (почти на 100% уверен), потому что также я при помощи этой процедуры рисую на TVirtualDrawTree, и также, как и с кнопками, после того как затащишь форму за пределы экрана - картинки пропадают, до момента вызова процедуры перерисовки. И на PageControl-e та же хрень.
← →
VS (2009-12-09 07:47) [3]Не, народ, я конечно понимаю, что можно подряд вызвать 2 процедуры рисования, последняя из которых будет BlendBitmap_GDI, но ведь это некрасивое решение, хотя визуально практически незаметно когда какой процедурой отрисовано (имею ввиду кто не знает - не заметит). Но ведь это неправильный "выход" из ситуации. У кого-нибудь есть идеи?
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2010.01.31;
Скачать: [xml.tar.bz2];
Память: 0.46 MB
Время: 0.004 c