Efektowne okna w stylu Visty

0

W jaki sposób zrobić takie okno, aby tło okna było przeźroczyste, a przyciski nie ?

Samo AlphaBlend działa na całą formę i obiekty na niej się znajdujące, a chodzi tylko o samą formę.
Oczywiście chodzi o taką minisymulację wyglądu z Visty na XPku.

Oto przykłady o co mi chodzi

user image
user image
user image

Tu taj reszta zdjęć z przykładami....

Proszę o jakieś przykłady kodu. Mam nadzieję że pomożecie ;-)

0

niezly z ciebie len
na glownej stronie serwisu jest
http://4programmers.net/Delphi/Artyku%C5%82y/Przezroczysta_forma

0

Po prostu chcesz mi powiedzieć, że się namęczyłem pisząc wyczerpującego arta, a nikt go nie czyta? ;)

0
Szczawik napisał(a)

Po prostu chcesz mi powiedzieć, że się namęczyłem pisząc wyczerpującego arta, a nikt go nie czyta? ;)

Szczawik, nawet twój program sprawdziłem co masz w podpisie "RSS", ale nie zauważyłem tam przeźroczystości okna, jedynie zmieniony kształt okna.

Co do artykułu, zaraz sobie go przejrzę na spokojnie, ale od razu mówię, że jeśli nie osiągnę zamierzonego efektu jaki przedstawiłem wyżej, to będę pisał/pytał do skutku ;]

0
Toom2 napisał(a)

Szczawik, nawet twój program sprawdziłem co masz w podpisie "RSS", ale nie zauważyłem tam przeźroczystości okna, jedynie zmieniony kształt okna.
No wiec jaki problem to zmienić, kod masz gotowy :) na podstawie programu (źródeł) Szczawika można zrobić wieeele.

Toom2 napisał(a)

ale od razu mówię, że jeśli nie osiągnę zamierzonego efektu jaki przedstawiłem wyżej, to będę pisał/pytał do skutku ;]
Pisz może ktoś Ci odpisz [rotfl]

A tak serio zobacz Graphic32 :] przykład: http://img502.imageshack.us/img502/3098/complexstudiosplashsampuk3.jpg

0
mitring napisał(a)
Toom2 napisał(a)

A tak serio zobacz Graphic32 :] przykład: http://img502.imageshack.us/img502/3098/complexstudiosplashsampuk3.jpg

No właśnie o coś takiego mi chodzi ;]

W przykładach G32 nie znalazłem takiego efektu, tylko wykorzystanie przeźroczystości bitmapy i nie wiem jak to przerobić. Poza tym ten pakiet jest dość duży, a wydaje mi się że bez tego da radę to zrobić.

Zaraz zobacze raz jeszcze ten RSS Gadget...

ps. nie odpuszcze [rotfl]

0

Nie potrafię tego przerobić, aby moja bitmapa była wyświetlana z przeźroczystością :-(

Tak to wygląda

user image

A taki mam kod

var
  Form1: TForm1;
  Wnd: TWndClass;
  Hnd: THandle;
  ComponentForm: TForm;

implementation

{$R *.dfm}

//Funkcja obsługująca zdarzenia półprzezroczystego okna
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(ComponentForm.Handle, 0, Rect.Left, Rect.Top, 0, 0, SWP_NOSIZE);
    Result := DefWindowProc(Wnd, uMsg, wPar, lPar);
    end;
  end;
end;

(*
//Funkcja odmalowująca półprzezroczyste okno z uwzględnieniem regionu
procedure PaintLayeredWindow(Hnd: THandle; Region: HRGN);
var blend: BLENDFUNCTION;
    P: TPoint;
    S: TSize;
    X, Y: integer;
    bmpRGB: TBitmap;
    Alpha: byte;
    Linia24: PRGBTriple;
    Linia32: PRGBQuad;

begin
//Tworzenie warstwy RGB
bmpRGB := TBitmap.Create();
try
  bmpRGB.Width := 512;
  bmpRGB.Height := 512;
  bmpRGB.PixelFormat := pf24bit;
  with bmpRGB.Canvas do
    begin
    Brush.Style := bsSolid;
    Brush.Color := clBlack;
    Rectangle(0, 0, bmpRGB.Width-1, bmpRGB.Height-1);
    Brush.Style := bsClear;
    Font.Style := [fsBold];
    Font.Color := clRed;
    Font.Size := 32;
    TextOut(10, 10, 'TEST');
    end;

//Sklejenie RGB oraz wygenerowanego A
  with TBitmap.Create() do
    begin
    try
      Width := bmpRGB.Width;
      Height := bmpRGB.Height;
      PixelFormat := pf32bit;
      for Y := 0 to Height-1 do
        begin
        Linia24 := bmpRGB.ScanLine[Y];
        Linia32 := ScanLine[Y];
        for X := 0 to Width-1 do
          begin
          if PtInRegion(Region, X, Y) then
            Alpha := 0
          else
            Alpha := byte(X xor Y);
          Linia32.rgbRed := MulDiv(Linia24.rgbtRed, Alpha, 255);
          Linia32.rgbGreen := MulDiv(Linia24.rgbtGreen, Alpha, 255);
          Linia32.rgbBlue := MulDiv(Linia24.rgbtBlue, Alpha, 255);
          Linia32.rgbReserved := Alpha;
          inc(Linia32);
          inc(Linia24);
          end;
        end;

//Nakładanie bitmapy
      P := Point(0, 0);
      S.cx := bmpRGB.Width;
      S.cy := bmpRGB.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);
    finally
      Free;
      end;
    end;
finally
  bmpRGB.Free;
  end;
end;
*)

//Tworzenie regionów, wycinanie okna komponentów i tworzenie okna półprzezroczystego
procedure CreateLayered(Form: TForm);
var Region: HRGN;
    ComponentRegion: HRGN;
    i:Integer;
const LayeredWndClass = 'LayeredWndClass';
begin
ComponentForm := Form;
ComponentForm.BorderStyle := bsNone;
Region := CreateRectRgn(0, 0, 0, 0);
for i := 0 to ComponentForm.ControlCount-1 do
  if ComponentForm.Controls[i].Visible then
    begin
    ComponentRegion := CreateRectRgn(ComponentForm.Controls[i].Left, ComponentForm.Controls[i].Top, ComponentForm.Controls[i].Width+ComponentForm.Controls[i].Left, ComponentForm.Controls[i].Height+ComponentForm.Controls[i].Top);
    CombineRgn(Region, Region, ComponentRegion, RGN_OR);
    DeleteObject(ComponentRegion);
    end;
with Wnd do
  begin
  lpfnWndProc := @WndNewProc;
  hInstance := hInstance;
  lpszClassName := LayeredWndClass;
  hbrBackground := COLOR_WINDOW;
  end;
Windows.RegisterClass(Wnd);
Hnd := CreateWindowEx(WS_EX_LAYERED, LayeredWndClass, PChar(ComponentForm.Caption), WS_VISIBLE, ComponentForm.Left, ComponentForm.Top, ComponentForm.Width, ComponentForm.Height, ComponentForm.Handle, 0, hInstance, NIL);
//PaintLayeredWindow(Hnd, Region);
SetWindowRgn(ComponentForm.Handle, Region, TRUE);
DeleteObject(Region);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
CreateLayered(Form1);
end;
0

Jeśli ktokolwiek, dla kogo to nie jest żadnym problemem, bedzie w stanie zrobić taki efekt

user image

i wrzuci na serwer przykład, będę bardzo wdzięczny, bo sam nie dam rady :-(

0
  • od zadania pytania nie minela jeszcze nawet doba a ty juz rezygnujesz i rozkladasz rece
  • ja interfejs do swojej aplikacji tworzylem prawie 2 miesiace (a nie ma w nim przezroczystosci)
  • masz przyklady wiec szukaj i dzialaj
  • wedlug mnie sposob szczawika nie jest super plynny ale to chyba najlepsza droga (chyba ze wymyslisz cos z graphic32)
0
Toom2 napisał(a)
Szczawik napisał(a)

Po prostu chcesz mi powiedzieć, że się namęczyłem pisząc wyczerpującego arta, a nikt go nie czyta? ;)

Szczawik, nawet twój program sprawdziłem co masz w podpisie "RSS", ale nie zauważyłem tam przeźroczystości okna, jedynie zmieniony kształt okna.

To może ja się wypowiem. Przezroczystość jest jak najbardziej - może źle patrzyłeś (choć domyślnie nie jest wielka). Przyjrzyj się uważnie:

user image

Ramki nie są wcale przezroczyste, tak jak tekst. Nagłówek jest lekko mniej przezroczysty niż czarne tło. Widzisz z lewej strony czarnego tła taki okrągławy kształt (zawijas)? To nie różnica kolorów tylko przezroczystości. Zauważ też, że zarówno cień, jak i obramowanie logo RSS gładko przechodzi do przezroczystości.

Szczawik napisał(a)

Co do artykułu, zaraz sobie go przejrzę na spokojnie, ale od razu mówię, że jeśli nie osiągnę zamierzonego efektu jaki przedstawiłem wyżej, to będę pisał/pytał do skutku ;]

Nie masz po co, bo wszystko zostało powiedziane i napisane. Teraz pozostaje przeczytać i wdrożyć.

jamtojest napisał(a)
  • wedlug mnie sposob szczawika nie jest super plynny ale to chyba najlepsza droga (chyba ze wymyslisz cos z graphic32)

Ale po co? Co w tym "niepłynnego"? Kolor? Kwestia bitmapy a nie metody rysowania. Nie chodzi płynnie? Jak to nie, przecież jeśli system pociągnie LayeredWindow to jest to najszybsza z metod :/

0

Wszystko sprowadza się do tego, że nie potrafię wykorzystać swojej bitmapy, bo na formie rysowane są jakieś kwadraty, a mi chodzi o to żeby forma była przeźroczysta.

W tym kodzie wykomentowałem część kodu, która tak mi się wydaje, że rysuje te kwadraty.
Ale jak ją usunąłem to nie działa.

Chodzi mi tylko o przerobienie tego bez rysowania kwadratów czarnych i tekstu na formie.

Toom2 napisał(a)
var
  Form1: TForm1;
  Wnd: TWndClass;
  Hnd: THandle;
  ComponentForm: TForm;

implementation

{$R *.dfm}

//Funkcja obsługująca zdarzenia półprzezroczystego okna
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(ComponentForm.Handle, 0, Rect.Left, Rect.Top, 0, 0, SWP_NOSIZE);
    Result := DefWindowProc(Wnd, uMsg, wPar, lPar);
    end;
  end;
end;

(*
//Funkcja odmalowująca półprzezroczyste okno z uwzględnieniem regionu
procedure PaintLayeredWindow(Hnd: THandle; Region: HRGN);
var blend: BLENDFUNCTION;
    P: TPoint;
    S: TSize;
    X, Y: integer;
    bmpRGB: TBitmap;
    Alpha: byte;
    Linia24: PRGBTriple;
    Linia32: PRGBQuad;

begin
//Tworzenie warstwy RGB
bmpRGB := TBitmap.Create();
try
  bmpRGB.Width := 512;
  bmpRGB.Height := 512;
  bmpRGB.PixelFormat := pf24bit;
  with bmpRGB.Canvas do
    begin
    Brush.Style := bsSolid;
    Brush.Color := clBlack;
    Rectangle(0, 0, bmpRGB.Width-1, bmpRGB.Height-1);
    Brush.Style := bsClear;
    Font.Style := [fsBold];
    Font.Color := clRed;
    Font.Size := 32;
    TextOut(10, 10, 'TEST');
    end;

//Sklejenie RGB oraz wygenerowanego A
  with TBitmap.Create() do
    begin
    try
      Width := bmpRGB.Width;
      Height := bmpRGB.Height;
      PixelFormat := pf32bit;
      for Y := 0 to Height-1 do
        begin
        Linia24 := bmpRGB.ScanLine[Y];
        Linia32 := ScanLine[Y];
        for X := 0 to Width-1 do
          begin
          if PtInRegion(Region, X, Y) then
            Alpha := 0
          else
            Alpha := byte(X xor Y);
          Linia32.rgbRed := MulDiv(Linia24.rgbtRed, Alpha, 255);
          Linia32.rgbGreen := MulDiv(Linia24.rgbtGreen, Alpha, 255);
          Linia32.rgbBlue := MulDiv(Linia24.rgbtBlue, Alpha, 255);
          Linia32.rgbReserved := Alpha;
          inc(Linia32);
          inc(Linia24);
          end;
        end;

//Nakładanie bitmapy
      P := Point(0, 0);
      S.cx := bmpRGB.Width;
      S.cy := bmpRGB.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);
    finally
      Free;
      end;
    end;
finally
  bmpRGB.Free;
  end;
end;
*)

//Tworzenie regionów, wycinanie okna komponentów i tworzenie okna półprzezroczystego
procedure CreateLayered(Form: TForm);
var Region: HRGN;
    ComponentRegion: HRGN;
    i:Integer;
const LayeredWndClass = 'LayeredWndClass';
begin
ComponentForm := Form;
ComponentForm.BorderStyle := bsNone;
Region := CreateRectRgn(0, 0, 0, 0);
for i := 0 to ComponentForm.ControlCount-1 do
  if ComponentForm.Controls[i].Visible then
    begin
    ComponentRegion := CreateRectRgn(ComponentForm.Controls[i].Left, ComponentForm.Controls[i].Top, ComponentForm.Controls[i].Width+ComponentForm.Controls[i].Left, ComponentForm.Controls[i].Height+ComponentForm.Controls[i].Top);
    CombineRgn(Region, Region, ComponentRegion, RGN_OR);
    DeleteObject(ComponentRegion);
    end;
with Wnd do
  begin
  lpfnWndProc := @WndNewProc;
  hInstance := hInstance;
  lpszClassName := LayeredWndClass;
  hbrBackground := COLOR_WINDOW;
  end;
Windows.RegisterClass(Wnd);
Hnd := CreateWindowEx(WS_EX_LAYERED, LayeredWndClass, PChar(ComponentForm.Caption), WS_VISIBLE, ComponentForm.Left, ComponentForm.Top, ComponentForm.Width, ComponentForm.Height, ComponentForm.Handle, 0, hInstance, NIL);
//PaintLayeredWindow(Hnd, Region);
SetWindowRgn(ComponentForm.Handle, Region, TRUE);
DeleteObject(Region);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
CreateLayered(Form1);
end;
0

Kod powyższego okna z bitmapą

Może najpiękniej nie jest, ale nie jestem grafikiem i nie miałem więcej jak 10 minut na dopracowanie tego.

Czasem po prostu myślę, że niemoc i nieumiejętność korzystania z gotowców jest naszą cechą narodową :/ Na szczęście tylko czasem.

0
Szczawik napisał(a)

Kod powyższego okna z bitmapą

Może najpiękniej nie jest, ale nie jestem grafikiem i nie miałem więcej jak 10 minut na dopracowanie tego.

Czasem po prostu myślę, że niemoc i nieumiejętność korzystania z gotowców jest naszą cechą narodową :/ Na szczęście tylko czasem.

Szczawik, Mistrzu. Wielkie dzięki że się zlitowałeś i poświęciłeś czas.

O to mi chodziło. [browar] To jest super.

0

Jestem na kolejnym etapie i pojawił się problem.

user image

Właściwość Transparent komponentu Image i Label nie działa.
Brałem nawet kolor na biały w Label i nadal jest ten siwy.

Da się z tym coś zrobić ? Czy zostaje tylko malowanie ?

Szczawik, chyba tylko w Tobie cała nadzieja ;]

0

Nie działa, ponieważ ta metoda wykorzystuje okno w sposób następujący:

  • tam, gdzie jest widoczny komponent, nie wycina jego prostokąta (razem z tłem) i prezentuje,
  • tam, gdzie nie ma żadnego komponentu, wycina i prezentuje przezroczystą bitmapę.

Rozwiązanie jest dosyć proste, w dodatku częściowo pokazane w artykule.

Wystarczy bitmapę 32bit rozbić na dwie: 24bit RGB oraz 8bit Alpha, na 24bit narysować tekst (kolor dowolny), na 8bit narysować ten sam tekst na biało (całkowita nieprzezroczystość) i z powrotem skleić bitmapy w format 32bit.

To zadanie jednak zostawię dla ciebie.

Od razu zaznaczę, że nie jest to jedyna metoda. Można też na przykład nie wycinać bitmapy pod labelami, a ich tło ustawić na TransparentColor formy. Jednak przy przeciąganiu (ponieważ są to dwa osobne okna) bitmapa może czasem przysłaniać tekst (drobne mruganie tekstu).

//Swoją drogą ustawienie tła labeli na biało wymagałoby wyłączenia transparent - inaczej w tym miejscu jest prezentowany siwy kolor tła formy.

0

Obszedłem to na dwa sposoby, bo jednak to co podpowiadasz mi Szczawik, to dla mnie zbyt trudne w realizacji.

Obszedłem to tak:

user image

Pierwszy tekst to label z Transparent := True i komponentem Image pod spodem w postaci zdjęcia.
Drugi tekst to label z Transparent := False i Lablel.Color := clWhite o czym nie pomyślałem i dlatego miałem siwe tło, tak jak napisałeś Szczawik.

Ogólnie, już jest całkiem przyzwoicie.
Dzięki raz jeszcze Szczawik, bo do tego nie dałbym rady dojść bez twojej pomocy.

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