![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Создание полупрозрачного компонента [D7, WinXP]
Ruzzz © (2009-08-02 12:05:00)Мне нужен компонент который сможет немного "замылить" изображение формы и других компонентов под собой. Не важен эффект, то ли это пролупрозрачный цвет или еще какой-нибудь эффект типа blur.
Если говорить о просто полупрозрачности, нашел такой код:
function SetWindowAlpha(Window: HWND; Alpha: Byte; UseColorKey: Boolean = False; ColorKey: COLORREF = $000000): Boolean;
const
ColorKeys: Array[False..True] of Integer = (0, LWA_COLORKEY);
var
AStyle: Integer;
begin
Result := False;
AStyle := GetWindowLong(Window, GWL_EXSTYLE);
if (Alpha = 255) and (not UseColorKey) then begin
Result := SetWindowLong(Window, GWL_EXSTYLE, AStyle or not WS_EX_LAYERED) <> 0;
end else begin
if SetWindowLong(Window, GWL_EXSTYLE, AStyle or WS_EX_LAYERED) = 0 then Exit;
Result := SetLayeredWindowAttributes(Window, ColorKey, Alpha, LWA_ALPHA or ColorKeys[UseColorKey]);
end;
end;
Но как я понял использовать для не форм SetLayeredWindowAttributes нет возможности?
Также нашел такую информацию, что такой компонент должен иметь стиль WS_EX_TRANSPARENT, для того чтобы при его перерисовке, сперва прорисовывались нижние контралы. Так ли?
Пока что остановилься на изучении AlphaBlend http://msdn.microsoft.com/en-us/library/dd183351(VS.85).aspx
Но вот что для меня проблема это как брать фон?
То есть как я понимаю задача сводится к:
- Берем нижний фон, изображение формы и нижних контралов;
- Применяем какой-либо фильтр, если нужно;
- Рисуем наш контрол, хотя бы просто заливаем цветом;
- Используя AlphaBlend и нужный коеф. alpha, создаем результирующее изображение;
- Рисуем полученный bitmap;
Правильно ли это? Если да, то главная проблема для меня это первый пункт. Как быть? И второй вопрос, как быть если изображение под моим контралом меняется? Поможет ли WS_EX_TRANSPARENT в этом случае?
Спасибо!
KilkennyCat (2009-08-02 17:40:00) [1]Если бы я сие делал, то я бы создал наследников от необходимого с необходимым, а не ненакладывал что-то сверху.
Ruzzz (2009-08-02 17:19:00) [2]А если назначить форме doubleBuf = True, то все вообще портится :(
Получается что прозрачный компонент нормально может существовать только если будет прорисовываться вместе с нижними. Может быть попробовать использовать form.DoubleBufered := True?
Ruzzz (2009-08-02 14:48:00) [3]Вместо panel1.Invalidate; приходится использовать panel1.hide; panel1.show;
Наверное нужно перехватывать wm_paint от тех кто снизу? как я понял WS_EX_TRANSPARENT дает просто гарантию что сообщения прорисовки прийдут позже тех окон что снизу?
Ну хоть бы кто-нибудь подсказал а?
Ruzzz (2009-08-02 14:34:00) [4]Проблема: Нужно как-то заставить перерисоваться форму перед тем как брать с нее "фон" :(
Ruzzz (2009-08-02 13:48:00) [5]Пока делаю так (правда в KOL):
SetWindowPos(panel1.Handle, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOMOVE);
SetWindowLong(panel1.Handle, GWL_EXSTYLE, GetWindowLong(panel1.Handle, GWL_EXSTYLE) or WS_EX_TRANSPARENT);
о WS_EX_TRANSPARENT можна почитать здесь http://msdn.microsoft.com/en-us/library/ms632680(VS.85).aspx
далее в обработчике событий Paint для panel1 делаю примерно так:
procedure TForm1.Panel1Paint(Sender: PControl; DC: HDC);
var
FormDC: HDC;
bmp: PBitmap;
begin
FormDC := GetDC(Form.Handle);
try
bmp := NewDIBBitmap(Panel1.Width, Panel1.Height, pf32bit);
try
BitBlt(bmp.canvas.Handle, 0, 0, Panel1.Width, Panel1.Height, FormDC, Panel1.Left, Panel1.Top, SRCCOPY); // Получаем "фон"
// bmp.RotateRight; // Тут делаем что-то с полученным изображением
BitBlt(DC, 0, 0, Panel1.Width, Panel1.Height, bmp.canvas.Handle, 0, 0, SRCCOPY);
finally
bmp.Free;
end;
finally
ReleaseDC(Form.Handle, FormDC);
end;
end;
Ruzzz (2009-08-02 13:07:00) [6]Поспешил :) вот http://msdn.microsoft.com/en-us/library/ms632680(VS.85).aspx тут написано:
«WS_EX_LAYERED
Windows 2000/XP: Creates a layered window. Note that this cannot be used for child windows. Also, this cannot be used if the window has a class style of either CS_OWNDC or CS_CLASSDC.»
Значит этот способ отпадает, не пойму почему его тогда предлагают? Я что-то не так понимаю?
Ruzzz (2009-08-02 13:02:00) [7]Вот нашел это http://support.microsoft.com/kb/92526- получается что использование WS_EX_LAYERED и SetLayeredWindowAttributes возможно для любых окон?
Ruzzz (2009-08-02 12:23:00) [8]Нашел такой компонент http://www.delphikingdom.com/asp/viewitem.asp?catalogid=1198но проблема в том что он не может быть поверх того же TMemo :( Не знаю стоит ли его смотреть