![]() |
Korrekte Verwendung von Blend?
Ich suche eine Lösung um AnimateWindow unter Verwendung von aktivierten Aero im System ohne flackern zu verwenden.
Ich meine die erarbeitet zu haben. Die Window ExStyle sind beim start der Anwendung 0 Danach addiere ich das Flag WS_EX_LAYERED.
Delphi-Quellcode:
Alles gut und schön kein flackern mehr bei der Animation.
if SKAERO_AnimateWindowCreate(KVPlayerIni) then
begin AnimateWindowCreate := true; try if SKAERO_GetAnimatorClassID = 2 then begin OldStyle := GetWindowLong(MainHandle, GWL_EXSTYLE); SetWindowLong(MainHandle, GWL_EXSTYLE, OldStyle or WS_EX_LAYERED); end; SKAERO_AnimateWindow(MainHandle); finally KVPlayerIni.Free; SKAERO_AnimateWindowDestroy; OldStyle := GetWindowLong(MainHandle, GWL_EXSTYLE); SetWindowLong(MainHandle, GWL_EXSTYLE, OldStyle and not WS_EX_LAYERED); RedrawWindow(MainHandle, nil, 0, RDW_ERASE or RDW_INVALIDATE or RDW_FRAME or RDW_ALLCHILDREN); AnimateWindowCreate := false; end; end; Der Nebeneffekt ist aber nun das bei RedrawWindow das komplette Fenster kurz komplett Weiß wird (nervig )habe noch keine Lösung wie ich das vermeiden kann. Um was es aber eigentlich geht ist die BlendFunktion inklusive UpdateLayeredWindow.
Delphi-Quellcode:
Leider findet man keine Informationen darüber ob es legitim ist UpdateLayeredWindow innerhalb von WM_PRINT zu verwenden.
WM_PRINT:
begin GetClientRect(WinHandle, rc); if AnimateWindowCreate then begin if SKAERO_GetAnimatorClassID = 2 then //(AnimateWindow) begin SetForegroundWindow(WinHandle); SrcDC := SKAERO_GetProperty(WinHandle, FORM_PaintDC); BitBlt(wP, 0, 0, rc.Right, rc.Bottom, SrcDC, 0, 0, SRCCOPY); ptSrc.x := 0; ptSrc.Y := 0; ls.cx := rc.Right; ls.cy := rc.Bottom; bf.BlendOp := AC_SRC_OVER; bf.BlendFlags := 0; bf.AlphaFormat := AC_SRC_ALPHA; bf.SourceConstantAlpha := 255; UpdateLayeredWindow(WinHandle, wP, nil, @ls, SrcDC, @ptSrc, 0, @bf, ULW_ALPHA); ReleaseDC(WinHandle, SrcDC); end else begin SrcDC := SKAERO_GetProperty(WinHandle, FORM_PaintDC); BitBlt(wP, 0, 0, rc.Right, rc.Bottom, SrcDC, 0, 0, SRCCOPY); ReleaseDC(WinHandle, SrcDC); end; end; end; Hat jemand irgendwelche Informationen darüber? Die beste Lösung zur Animation wäre das Flag WS_EX_LAYERED eingeschaltet zu lassen. Nur dann funktioniert seltsamer weise WM_PAINT nicht mehr korrekt. Ein MouseMove auf irgendein Control löst kein Neuzeichnen des selbigen aus bzw.. ich kann das Hover Image nicht mehr sehen. Irgendwie seltsam das ganze. gruss |
AW: Korrekte Verwendung von Blend?
Antworte mir selbst vielleicht hat jemand ein ähnliches Problem.
Das Problem war UpdateLayeredWindow. Über UpdateLayeredWindow kann man die transparente Farbe nicht festlegen deshalb blink der Hintergrund beim aktualisieren weiß auf. Aus der Anwendung
Delphi-Quellcode:
AnimateWindow zeichnen
if SKAERO_AnimateWindowCreate(KVPlayerIni) then //Load Value stored in IniFiles
begin try SKAERO_AnimateWindow(MainHandle); // start AnimateWindow finally KVPlayerIni.Free; // Free Inifile ressource SKAERO_AnimateWindowDestroy; // Destroy AnimateWindow Class end; end;
Delphi-Quellcode:
erstelle den WS_EX_LAYERED Style setze transparente Farbe, Blend oder Colorkey Value
procedure TWinAnimator.AnimateForm(WinHandle: HWND);
const t: array [0 .. 7] of Integer = (AW_HOR_POSITIVE, AW_HOR_NEGATIVE, AW_VER_POSITIVE, AW_VER_NEGATIVE, AW_HOR_POSITIVE or AW_VER_POSITIVE, AW_HOR_NEGATIVE or AW_VER_POSITIVE, AW_HOR_POSITIVE or AW_VER_NEGATIVE, AW_HOR_NEGATIVE or AW_VER_NEGATIVE); var Value: Integer; begin SetForegroundWindow(WinHandle); SkinEngine.FInvalidateRect(WinHandle, false); Value := Random(4); // do not use WS_EX_LAYERD on AW_BLEND or without CompositionEnabled if (Value > 0) and SkinEngine.IsCompositionEnabled then begin GAnimatorManager.AlphaBlend := True; // create WS_EX_LAYERED Style GAnimatorManager.TransparentColor := True; // using Colorkey GAnimatorManager.TransparentColorValue := $FF00FF; // set Color GAnimatorManager.AlphaBlendValue := 255; // set Alpha Value end; case Value of 0: AnimateWindow(WinHandle, TimeMax, AW_BLEND); 1: AnimateWindow(WinHandle, TimeMax, AW_CENTER); 2: AnimateWindow(WinHandle, TimeMax, t[Random( High(t) + 1)]); 3: AnimateWindow(WinHandle, TimeMax, AW_SLIDE or t[Random( High(t) + 1)]); end; GAnimatorManager.AlphaBlend := False; // remove WS_EX_LAYERED Style end;
Delphi-Quellcode:
WM_PRINT in der Anwendung
procedure TAnimatorManager.SetLayeredAttribs;
const cUseAlpha: array [Boolean] of Integer = (0, LWA_ALPHA); cUseColorKey: array [Boolean] of Integer = (0, LWA_COLORKEY); var AStyle: Integer; begin AStyle := GetWindowLong(Handle, GWL_EXSTYLE); if FAlphaBlend then begin if (AStyle and WS_EX_LAYERED) = 0 then SetWindowLong(Handle, GWL_EXSTYLE, AStyle or WS_EX_LAYERED); SetLayeredWindowAttributes(Handle, ColorToRGB(FTransparentColorValue), FAlphaBlendValue, cUseAlpha[FAlphaBlend] or cUseColorKey[FTransparentColor]); end else begin SetWindowLong(Handle, GWL_EXSTYLE, AStyle and not WS_EX_LAYERED); RedrawWindow(Handle, nil, 0, RDW_ERASE or RDW_INVALIDATE or RDW_FRAME or RDW_ALLCHILDREN); end; end;
Delphi-Quellcode:
Funktioniert nun mit allen von mir erstellten WindowsWM_PRINT: begin GetClientRect(WinHandle, rc); SrcDC := SKAERO_GetProperty(WinHandle, FORM_PaintDC); BitBlt(wP, 0, 0, rc.Right, rc.Bottom, SrcDC, 0, 0, SRCCOPY); ReleaseDC(WinHandle, SrcDC); end; greets |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:31 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz