Przezroczystość formy

0

Znalazłem 1 temat na googlach, ale tam nie wyjaśnił nikt do końca jak rozwiązać problem..
Chcę aby forma była przezroczysta, ale komponenty na niej już nie..
Jak napisane było w tamtym temacie Form1.Transparent odpada..
Mam nadzieję, że tu mi ktoś pomoże ..

I jeszcze jedno pytanie:
Gdy mam TPNGImage z małą przezroczystością ustawioną nie w Delphi, tylko jako obrazek trochę przezroczyste i obrazek ma zaokrąglone rogi, jak mogę zrobić, aby tam gdzie są owe rogi nie było szarego tła ?

0

Wykorzystałem tą opcję
Form1.Brush.Style := bsClear

Ale pozostaje tak samo jak było w tym (http://4programmers.net/Forum/277695) temacie.. Po ruszenu zamiast przezroczystości szarego tła wychodzi mi .. zresztą sam zobacz, bo nie wiem jak to opisać ;-P

Program przed przesunięciem:
user image

Program po przesunięciu w byle którą stronę:
user image

Może ktoś coś poradzić .. ?

Ewentualnie inny sposób ?

0

Ustawienie bsClear nie oznacza braku tła, ale brak jego odmalowania - aplikacja będzie prezentowała to, co było poprzednio w tym miejscu, ale podczas przesuwania nie jest odmalowywana - to nie jest prawdziwa przezroczystość.

Dałem Ci przecież linka powyżej, nawet z działającym przykładem - w czym więc problem?

0

A dokładniej który przykład xD ?

unit Unit1;

interface

uses Windows, Forms, MEssages, Graphics, Controls, ExtCtrls, StdCtrls, Classes, ComCtrls;

type
TForm1 = class(TForm)
ListView1: TListView;
Button1: TButton;
Image1: TImage;
procedure FormShow(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ ***** Do obsługi okna przezroczystego ***** }
Wnd: TWndClass;
Hnd: THandle;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

type
TLinia32 = array[WORD] of TRGBQuad;
PLinia32 = ^TLinia32;
TLinia24 = array[WORD] of TRGBTriple;
PLinia24 = ^TLinia24;
TLinia8 = array[WORD] of byte;
PLinia8 = ^TLinia8;

{ ***** Narysowanie obrazu okna przezroczystego z Image1, uwzględniając w bitmapie rejon z zaznaczonymi komponentami ***** }

procedure PaintLayeredWindow(Image1:TImage; Hnd:THandle; Region:HRGN);
var blend:BLENDFUNCTION;
P:TPoint;
S:TSize;
i,j:integer;
bmpRGB, bmpA:TBitmap;
Linia8:PLinia8;
Linia24:PLinia24;
Linia32:PLinia32;
begin
//Tworzenie warstw RGB oraz A
bmpRGB:=TBitmap.Create();
bmpRGB.Width:=Image1.Width;
bmpRGB.Height:=Image1.Height;
bmpRGB.PixelFormat:=pf24bit;
bmpA:=TBitmap.Create();
bmpA.Width:=Image1.Width;
bmpA.Height:=Image1.Height;
bmpA.PixelFormat:=pf8bit;
//Rozdzielenie Image1.Picture.Bitmap RGBA na RGB oraz A
for j:=0 to Image1.Height-1 do
begin
Linia8:=bmpA.ScanLine[j];
Linia24:=bmpRGB.ScanLine[j];
Linia32:=Image1.Picture.Bitmap.ScanLine[j];
for i:=0 to Image1.Width-1 do
begin
if PtInRegion(Region, i, j) then
Linia8[i]:=0
else
Linia8[i]:=Linia32[i].rgbReserved;
Linia24[i].rgbtBlue:=Linia32[i].rgbBlue;
Linia24[i].rgbtGreen:=Linia32[i].rgbGreen;
Linia24[i].rgbtRed:=Linia32[i].rgbRed;
end;
end;
//Rysowanie po warstwie RGB lub A
bmpRGB.Canvas.Font.Style:=[fsBold];
bmpRGB.Canvas.Brush.Style:=bsClear;
bmpRGB.Canvas.TextOut(10,10,'TEST');
//Sklejenie RGB oraz A
with TBitmap.Create() do
begin
Width:=Image1.Width;
Height:=Image1.Height;
PixelFormat:=pf32bit;
for j:=0 to Height-1 do
begin
Linia8:=bmpA.ScanLine[j];
Linia24:=bmpRGB.ScanLine[j];
Linia32:=ScanLine[j];
for i:=0 to Width-1 do
begin
Linia32[i].rgbRed := MulDiv(Linia24[i].rgbtRed, Linia8[i], 255);
Linia32[i].rgbGreen := MulDiv(Linia24[i].rgbtGreen, Linia8[i], 255);
Linia32[i].rgbBlue := MulDiv(Linia24[i].rgbtBlue, Linia8[i], 255);
Linia32[i].rgbReserved := Linia8[i];
end;
end;
P := Point(0, 0);
S.cx := Image1.Width;
S.cy := Image1.Height;
blend.BlendOp := AC_SRC_OVER;
blend.BlendFlags := 0;
blend.AlphaFormat := AC_SRC_ALPHA;
blend.SourceConstantAlpha := 255;
UpdateLayeredWindow(Hnd, GetDC(0), nil, @S, Canvas.Handle, @P, 0, @blend, ULW_ALPHA);
Free;
end;
bmpA.Free;
bmpRGB.Free;
end;

{ ***** Obsługa komunikatów okna przezroczystego, z przeciąganiem po kliknięciu włącznie ***** }

function WndNewProc(Wnd: HWND; uMsg: UINT; wPar: WPARAM; lPar: LPARAM): LRESULT; stdcall;
var Rect:TRect;
begin
Result := 0;
case uMsg of
WM_DESTROY: PostQuitMessage(0);
WM_LBUTTONDOWN: SendMessage(Wnd, WM_SYSCOMMAND, SC_MOVE+2, 0);
else
begin
if ((uMsg=WM_MOVING) or (uMsg=WM_MOVE)) and GetWindowRect(Wnd, Rect) then
SetWindowPos(Form1.Handle, 0, Rect.Left, Rect.Top, 0, 0, SWP_NOSIZE);
Result := DefWindowProc(Wnd, uMsg, wPar, lPar);
end;
end;
end;

{ ***** Utworzenie okna przezroczystego i wycięcie wg. komponentów okna nieprzezroczystego ***** }

procedure TForm1.FormShow(Sender: TObject);
var Region:HRGN;
ComponentRegion:HRGN;
i:Integer;
begin
Region:=CreateRectRgn(0, 0, 0, 0);
for i:=0 to ControlCount-1 do
if Controls[i].Visible then
begin
ComponentRegion:=CreateRectRgn(Controls[i].Left, Controls[i].Top, Controls[i].Width+Controls[i].Left, Controls[i].Height+Controls[i].Top);
CombineRgn(Region, Region, ComponentRegion, RGN_OR);
DeleteObject(ComponentRegion);
end;
with Wnd do
begin
lpfnWndProc := @WndNewProc;
hInstance := hInstance;
lpszClassName := 'My1stApp';
hbrBackground := COLOR_WINDOW;
end;
Windows.RegisterClass(Wnd);
Hnd:=CreateWindowEx(WS_EX_LAYERED, 'My1stApp', PChar(Form1.Caption), WS_VISIBLE, Form1.Left, Form1.Top, Form1.Width, Form1.Height, Form1.Handle, 0, hInstance, NIL);
PaintLayeredWindow(Image1, Hnd, Region);
SetWindowRgn(Handle, Region, TRUE);
DeleteObject(Region);
end;

{ ***** Zamknięcie aplikacji ***** }

procedure TForm1.Button1Click(Sender: TObject);
begin
Application.Terminate;
end;

end.

Chodziło o ten przykład ? Kombinuję, ale jakoś nie wychodzi.. może popróbuję jeszcze ;-P

0

No oczywiście, że ten. Przeczytaj tamtą dyskusję, a nie rozglądaj się tylko za gotowym kodem, to będziesz wiedział.

0

Spokojnie:) Spokojnie Panowie:)

Aby uzyskac przezroczyste tlo nalezy miec:
WindowsXP/Vista (gdy wlaczony AeroGlass tlo nie jest wycinane - chociaz kolor znika)

ustawic wlasciwosc formy:

TransparentColor:=true;
TrasparentColorValue:=clBtnFace;

w tym przypadku Windows wytnie z okna wszystkie elementy koloru clBtnFace
Wykorzystalem to do stworzenia wlasnej nakladki na Windows Explorer. W polaczeniu z odrobina wyobrazni daje to oszalamiajace efekty:D</image>

0
Enkizeev napisał(a)

tylko jako obrazek trochę przezroczyste i obrazek ma zaokrąglone rogi, jak mogę zrobić, aby tam gdzie są owe rogi nie było szarego tła ?

@BorysBe - jak zrozumiałem, chodzi o stopniowaną przezroczystość, której Twoim sposobem nie da się osiągnąć.

0

#szczawik
Robiłem wszystko co się dało, ale i tak nie uzyskałem przezroczystej formy ..
Może nie do końca dobrze uzyskałem ową przezroczystość na bitmapie, bo mam angielską wersję PSa i nie wiem czy dobrze zrobiłem, to o czym pisałeś w tamtym temacie ..
Mogłbyś jeszcze raz napisać krok po kroku co robić ?
Ewentualnie napisz tego arta, bo jakoś go nie widzę ;-P

#BorysBe
Wybacz ale Visty nie posiadam, a zależy mi na rogach, których Twoim sposobem nie wytnę ;-(
Może ktoś jakieś inne sposoby na wycięcie rogów (pozbycie się tłą na około nich), żeby forma była zaokrąglona ?

0
Enkizeev napisał(a)

user image

Fajnie ci to wyszło.... jak rozwiążesz problemy z tym malowaniem po przesunięciu to, jak możesz... wrzuć źródła na jakiś serwer lub wyślij mi na mejla. [soczek]

0

@Enkizeev: w mojej stopce masz link do programu pokazującego półprzezroczyste RSS na pulpicie: z kompletnymi źródłami i bitmapami 32bit, wkompilowywanymi do zasobów. Masz tam wszystko czego szukasz. Swoją drogą opiera się na kodzie, który zapostowałem.

Z bitmapami chodzi o to, że nie mają one mieć przezroczystości jako części warstwy, ale osobny kanał na samą przezroczystość. Przejrzyj załączone bitmapy, mam nadzieję, że zobaczysz o co chodzi.

0

#Enkizeev

moim sposobem wytniesz kazdy obszar okna o wybranym kolorze, do tego stopnia, ze tam gdzie byl wczesniej ten kolor - okno bedzie niezauwazalne dla uzytkownika systemu Windows XP i bedziesz mogl kliknac na wszystko co jest "pod spodem". Czyli tym samym "jakby" uzyskasz okno o dowolnym ksztalcie. A chyba o to Ci chodzi.

Pozdrawiam:)

0

Właśnie chyba nie o to mu chodzi. Twoim sposobem nie da się uzyskać okna, w którym niektóre piksele na rogach są w różnym stopniu półprzezroczyste (wygładzając efekt wycięcia), a te w środku całkowicie (lub w większym stopniu) nieprzezroczyste.

Wycinanie regionami lub kolorem przezroczystym daje tylko możliwość określenia, czy piksel jest widoczny, czy nie; nie daje możliwości robienia kanału Alpha na bazie bitmapy, a jedynie binarnego określenia - widoczny albo nie.

Nie rozumiem problemu: Zamieściłem cały kod - działający, w stopce mam przykładowy program - działający, w dodatku z krótkim, pełnym kodem i właściwie przygotowanymi obrazkami.. Chyba będzie jednak potrzebny artykuł.

0

No coz. Szukajcie a znajdziecie:)

0
BorysBe napisał(a)

No coz. Szukajcie a znajdziecie:)

Nie możesz podać ? :>

1 użytkowników online, w tym zalogowanych: 0, gości: 1