[Delphi] Przezroczystość okna w stylu ramki visty


(E Mr Koka) #1

Witam, parę razy spotkałem się z takim oto stylem okienka.

51e75e10a71da7ccm.jpg

Ciekawi mnie jak je wykonać, ponieważ efekt wg. mnie jest dość ciekawy.


([alex]) #2

Przezroczystość

Co do "innych" przycisków, ustawisz że okno jest bez belki systemowej, i sam obsługujesz wszystkie zdarzenia NonClient.


(Ryan) #3

W przykładzie powyżej akurat najprawdopodobniej chodzi o standardową funkcjonalność Visty/Win7, którą oferuje DWM. To się nazywa "szklenie okien" i uzyskuje się przy pomocy DwmExtendFrameIntoClientArea().

http://msdn.microsoft.com/en-us/library/aa969512(VS.85).aspx

Oczywiście można to uzyskać i na XP, ale wymaga znacznie więcej kodowania i nie będzie zbyt szybkie. Aero Glass oblicza półprzezroczystość i zmatowienie (w praktyce: blur) na GPU przy użyciu shaderów (DWM pracuje na bazie Direct3D 9Ex, wewnętrznej wersji DX opartej o WDDM).


(E Mr Koka) #4

Dzięki, wasze odpowiedzi nakierowały mnie na dobrą drogę i znalazłem jakąś stronę z opisem lecz po czesku :> i mam jeden problem, gdy kolor formy jest standardowy (clBtnFace) to z formy znika tylko czarne obramowanie, gdy zmienię kolor na clBackground wszystko jest ok, tylko, że jest koloru czarnego a to tak średnio zadowala i wygląda :] Własciwie wszystko co czarne zamienia się w "szkło" ale nic nie mogę na zeszklonym obszarze narysować.

unit Unit1;


interface


uses

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

  Dialogs, ShellApi, StdCtrls;


type

  TForm1 = class(TForm)

    Button1: TButton;

    Button2: TButton;

    Button3: TButton;

    procedure FormCreate(Sender: TObject);

    procedure Button3Click(Sender: TObject);


  private

    { Private declarations }

  public

    { Public declarations }

  end;


  TMargins = packed record

    MLeft, MRight, MTop, MBottom: Integer;

  end;

  PMargins = ^TMargins;


var

  Form1: TForm1;


implementation

  function ExtendArea(destWnd: HWND; Area: Pointer): HRESULT; stdcall; external 'dwmapi.dll' name 'DwmExtendFrameIntoClientArea';


{$R *.dfm}


procedure TForm1.FormCreate(Sender: TObject);

var Margins: TMargins;

begin


  ZeroMemory(@Margins, SizeOf(Margins));


  with Margins do

  begin

    MLeft := 0;

    MRight := 0;

    MTop := 200;

    MBottom := 0;

  end;


  Form1.Canvas.Brush.Color := clBackground; //Tutaj próba namalowanie przezroczystości, oczywiście  

  Form1.Canvas.FillRect(Rect(0,0,Form1.Width, 200)); //jak pisałem nie można malować po zeszklonym obszarze


  ExtendArea(Self.Handle, @Margins);

end;


end.

I jeszcze link do strony na której znalazłem rozwiązanie, może ktoś zrozumie więcej ode mnie.

http://blog.cman.us/programavimas/delphi/3


(Ryan) #5

Słabo szukałeś. ;>

http://stackoverflow.com/questions/1168 ... -windows-7

http://www.aeroxp.org/board/index.php?showtopic=6985

http://xkor.homeip.net/delphi/jwapi2.2a ... Dwmapi.pas

http://blog.delphi-jedi.net/2008/05/01/ ... with-aero/

http://hallvards.blogspot.com/2007/03/r ... rt_06.html

Inne zagadnienia związane z Vista+Delphi:

http://www.installationexcellence.com/a ... Index.html


(M@ster) #6

W Delphi 2007 można to ustawić w parametrach formy, ot wpisuje się jedną liczbę określająca wysokość szklanego obszaru.


(E Mr Koka) #7

Ok, problem rozwiązałem troszkę na łatwiznę ale w końcu wszystko wygląda tak jak powinno.

Użyłem Delphi 2007 do ustawienia marginesu zeszklenia okna i było by ok gdyby próbowane przeze mnie biblioteczki do obsługi PNG na tym tle wychodziły dobrze. Próbowałem ExGraphic, i TPNGImage wyglądało i w pierwszym z nich tło było czarne z przezroczystymi obszarami, a w drugim tło było przezroczyste tylko gdy umieściłem TImage na jednolitym tle formy.

W końcu znalazłem informacje, że w Delphi 2009 wprowadzono obsługę PNG (i się nie pochwalili). Więc wypróbowałem i Delphi 2009. Efekt jest taki jaki chciałem osiągnąć.

tada.th.jpg

Ikonka "ptaszka" zmienia się po najechaniu a obrazki dla niej dodane do pliku z zasobami więc dodam, że aby dodać do nich plik PNG

jako typ(?) należy wpisać RCDATA, a odczyt wygląda w moim przypadku wyglądał tak...

procedure TForm1.ApplyButtonImage(T: Bool);

var Btt: TPNGImage;

begin


  Btt := TPNGImage.Create;

  try

    if(T) then Btt.LoadFromResourceName(hInstance, 'APPLYON')

    else Btt.LoadFromResourceName(hInstance, 'APPLYOFF');

    Image2.Picture.Graphic := Btt;

  finally

    Btt.Free;

  end;


end;

Plik zasobów...

APPLYON RCDATA "apply.png"

APPLYOFF RCDATA "apply2.png"

Może to banalne informacje ale to na wszelki wypadek gdyby ktoś szukał : ].


(M@ster) #8

Można było użyć ikony (.ico). W jej przypadku Delphi też poprawnie obsługuje przeźroczystości (od wersji Turbo a może i wcześniejszych).


([alex]) #9

W windows .ico może być max 48x48.


(E Mr Koka) #10

Kurcze, w sumie, nie pomyślałem : )


(Ryan) #11

W Vista i dalej ikony mogą być większe - 256x256, z 8-bitową przezroczystością.