Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi GetLayeredWindowAttributes funktioniert nicht noch Resize (https://www.delphipraxis.net/142052-getlayeredwindowattributes-funktioniert-nicht-noch-resize.html)

virus82 21. Okt 2009 08:53


GetLayeredWindowAttributes funktioniert nicht noch Resize
 
Hey,

an alle Windows API Spezialisten. Ich hab folgendes Problem, seit WinXP gibt es die Funktion GetLayeredWindowAttributes in der user32.dll, die allerdings nur funktioniert wenn ich das Fenster weder Minimiere, Maximiere oder die Größe verändere. Sobald die Größe verändert wird liefert die Funktion immer False zurück, aber ohne Fehler (GetLastError ist auch immer 0).

Ziel ist es das ich AlphaBlendValue für ein beliebiges sichtbares Fenster ermitteln will (zum Beispiel Notepad). Ich setze als erstes den AlphaBlendValue mit SetLayeredWindowAttributes auf 200 und versuche es dann wieder zu ermitteln. Das klappt auch soweit. Minimiere ich allerdings das Fenster und zeige es wieder an, liefert GetLayeredWindowAttributes immer wieder False zurück.

Irgendeiner ne Idee woran das liegt, ist es ein Bug in WinXP oder ich mach irgendwas total falsch.

Hier mal ein einfaches Beispiel, ein Notepad Fenster muß geöffnet sein.

Delphi-Quellcode:
function GetLayeredWindowAttributes(hwnd: HWND; var crKey: COLORREF; var bAlpha: BYTE;
  var dwFlags: DWORD): BOOL; stdcall; external user32 name 'GetLayeredWindowAttributes';
function SetLayeredWindowAttributes(hwnd: HWND; crKey: COLORREF; bAlpha: Byte;
  dwFlags: DWORD): BOOL; stdcall; external user32 name 'SetLayeredWindowAttributes';

implementation

...

procedure TestAlphaBlend;
var
  hHandle: THandle;
  ExStyle: DWORD;
  bResSet: Boolean;
  bResGet: Boolean;
  AlphaValue: Byte;
  TranspColor: COLORREF;
  Flags: DWORD;
  Error: Cardinal;
  s: String;
begin
  s := 'nix';
  AlphaValue := 0;
  Flags := 0;
  hHandle := FindWindowEx(0, 0, 'Notepad', nil); //Fensterhandle von einem Notepad
  if ((hHandle <> INVALID_HANDLE_VALUE) and //gültiges Handle
      (IsWindowVisible(hHandle))) then //Fenster sichtbar
    begin
      s := '';
      ExStyle := GetWindowLong(hHandle, GWL_EXSTYLE); //Extended Style holen
      if ((ExStyle and WS_EX_LAYERED) = 0) then //wenn kein Layered Fenster
        SetWindowLong(hHandle, GWL_EXSTYLE, ExStyle or WS_EX_LAYERED); //dann Layered setzen

      bResSet := SetLayeredWindowAttributes(hHandle, 0, 200, LWA_ALPHA); //AlphaBlend mit Wert 200 setzen
      if bResSet then
        s := s + 'SetLayeredWindowAttributes erfolgreich' + #10#13
      else
        s := s + 'SetLayeredWindowAttributes nicht erfolgreich' + #10#13; //kommt nie vor

      bResGet := GetLayeredWindowAttributes(hHandle, TranspColor, AlphaValue, Flags); //AlphaBlend ermitteln
      if bResGet then
        begin
          s := s + 'GetLayeredWindowAttributes erfolgreich' + #10#13;
          if ((Flags and LWA_ALPHA) > 0) then //ob AlphaBlend gesetzt ist
            s := s + 'AlphaBlend = True' + #10#13
          else
            s := s + 'AlphaBlend = False' + #10#13
        end
      else
        s := s + 'GetLayeredWindowAttributes nicht erfolgreich' + #10#13;

      s := s + 'AlphaBlendValue = ' + IntToStr(AlphaValue) + #10#13; //einfach immer ausgeben

      Error := GetLastError; //Fehler holen
      if (Error = 0) then
        s := s + 'GetLastError = 0' + #10#13
      else
        s := s + 'GetLastError = ' + IntToStr(Error) + #10#13;
    end;

  ShowMessage(s);
end;

procedure TFormMain.Button1Click(Sender: TObject);
begin
  TestAlphaBlend;
end;
Ach ja ich nutze Delphi2009, auf Windows XP Professional SP3.

Irgendwie bin ich ratlos.

himitsu 21. Okt 2009 09:07

Re: GetLayeredWindowAttributes funktioniert nicht noch Resiz
 
Zitat:

Zitat von virus82
Ach ja ich nutze Delphi2009, auf Windows XP Professional SP3.

Selbes System (32 Bit) ... keine Probleme (egal ob eigenes Fenster oder Notepad minimiert wurde)



Außerdem: GetLastError sollte man sich gleich holen und nicht erst irgendwas anderes ziwschendurch machen, welches den Wert verändern könnte.


Also selbst wenn SetLayeredWindowAttributes fehlschlägt und dann aber GetLayeredWindowAttributes erfolgreich ist und auch noch den Fehler-Code zurück/neu setzt, dann würdest du da nie einen Fehler von SetLayeredWindowAttributes erhalten.

Delphi-Quellcode:
procedure TestAlphaBlend;
var
  hHandle: THandle;
  ExStyle: DWORD;
  bResSet: Boolean;
  bResGet: Boolean;
  AlphaValue: Byte;
  TranspColor: COLORREF;
  Flags: DWORD;
  Error: Cardinal;
  s: String;
begin
  s := 'nix';
  AlphaValue := 0;
  Flags := 0;
  hHandle := FindWindowEx(0, 0, 'Notepad', nil); //Fensterhandle von einem Notepad
  if ((hHandle <> INVALID_HANDLE_VALUE) and //gültiges Handle
      (IsWindowVisible(hHandle))) then //Fenster sichtbar
    begin
      s := '';
      ExStyle := GetWindowLong(hHandle, GWL_EXSTYLE); //Extended Style holen
      if ((ExStyle and WS_EX_LAYERED) = 0) then //wenn kein Layered Fenster
        SetWindowLong(hHandle, GWL_EXSTYLE, ExStyle or WS_EX_LAYERED); //dann Layered setzen

      bResSet := SetLayeredWindowAttributes(hHandle, 0, 200, LWA_ALPHA); //AlphaBlend mit Wert 200 setzen
      if bResSet then
        s := s + 'SetLayeredWindowAttributes erfolgreich' + #10#13
      else
        begin
          Error := GetLastError; //Fehler holen
          s := s + 'SetLayeredWindowAttributes nicht erfolgreich' + #10#13; //kommt nie vor
          if (Error = 0) then
            s := s + 'GetLastError = 0' + #10#13
          else
            s := s + 'GetLastError = ' + IntToStr(Error) + #10#13;
        end;

      bResGet := GetLayeredWindowAttributes(hHandle, TranspColor, AlphaValue, Flags); //AlphaBlend ermitteln

      if bResGet then
        begin
          s := s + 'GetLayeredWindowAttributes erfolgreich' + #10#13;
          if ((Flags and LWA_ALPHA) > 0) then //ob AlphaBlend gesetzt ist
            s := s + 'AlphaBlend = True' + #10#13
          else
            s := s + 'AlphaBlend = False' + #10#13
        end
      else
        begin
          Error := GetLastError; //Fehler holen
          s := s + 'GetLayeredWindowAttributes nicht erfolgreich' + #10#13;
          if (Error = 0) then
            s := s + 'GetLastError = 0' + #10#13
          else
            s := s + 'GetLastError = ' + IntToStr(Error) + #10#13;
        end;

      s := s + 'AlphaBlendValue = ' + IntToStr(AlphaValue) + #10#13; //einfach immer ausgeben
    end;

  ShowMessage(s);
end;

virus82 26. Okt 2009 21:26

Re: GetLayeredWindowAttributes funktioniert nicht noch Resiz
 
ok das mit getlasterror stimmt. Ist auch hier im Beispiel nur so, hole ich sonst gleich nach GetLayeredWindowAttributes.

Nur noch mal zur Erinnerung, mit SetLayeredWindowAttributes gibt es keine Probleme und Fehler, nur mit GetLayeredWindowAttributes.

1. Notepad starten
2. Notepad StLayeredWindowAttributes -> funzt
3. Notepad GetLayeredWindowAttributes -> funzt
4. Notepad minimieren und wieder herstellen oder maximieren
4. Notepad GetLayeredWindowAttributes -> funzt nicht und GetLastError ist ebenfalls 0

Und da weiß ich nicht weshalb. Bin irgendwie ratlos.

Geändertes Beispiel

Delphi-Quellcode:
procedure TestAlphaBlend;
var
  hHandle: THandle;
  ExStyle: DWORD;
  bResSet: Boolean;
  bResGet: Boolean;
  AlphaValue: Byte;
  TranspColor: COLORREF;
  Flags: DWORD;
  Error: Cardinal;
  s: String;
begin
  s := 'nix';
  AlphaValue := 0;
  Flags := 0;
  hHandle := FindWindowEx(0, 0, 'Notepad', nil); //Fensterhandle von einem Notepad
  if ((hHandle <> INVALID_HANDLE_VALUE) and //gültiges Handle
      (IsWindowVisible(hHandle))) then //Fenster sichtbar
    begin
      s := '';
      ExStyle := GetWindowLong(hHandle, GWL_EXSTYLE); //Extended Style holen
      if ((ExStyle and WS_EX_LAYERED) = 0) then //wenn kein Layered Fenster
        SetWindowLong(hHandle, GWL_EXSTYLE, ExStyle or WS_EX_LAYERED); //dann Layered setzen

      //funktioniert
      bResSet := SetLayeredWindowAttributes(hHandle, 0, 200, LWA_ALPHA); //AlphaBlend mit Wert 200 setzen
      Error := GetLastError;
      if (bResSet and (Error = 0)) then
        s := s + 'SetLayeredWindowAttributes erfolgreich' + #10#13
      else
        s := s + 'SetLayeredWindowAttributes nicht erfolgreich' + #10#13; //kommt nie vor
      s := s + 'SetLayeredWindowAttributes GetLastError = ' + IntToStr(Error) + #10#13; //gemerkten Fehler

      //funktioniert
      bResGet := GetLayeredWindowAttributes(hHandle, TranspColor, AlphaValue, Flags); //AlphaBlend ermitteln
      Error := GetLastError;
      if (bResGet and (Error = 0)) then
        begin
          s := s + 'GetLayeredWindowAttributes erfolgreich' + #10#13;
          if ((Flags and LWA_ALPHA) > 0) then //ob AlphaBlend gesetzt ist
            s := s + 'AlphaBlend = True' + #10#13
          else
            s := s + 'AlphaBlend = False' + #10#13
        end
      else
        s := s + 'GetLayeredWindowAttributes nicht erfolgreich' + #10#13;
      s := s + 'GetLayeredWindowAttributes GetLastError = ' + IntToStr(Error) + #10#13; //gemerkten Fehler

      ShowWindow(hHandle, SW_MINIMIZE); //Minimieren
      ShowWindow(hHandle, SW_RESTORE); //Wiederherstellen

      //funktioniert nicht mehr
      bResGet := GetLayeredWindowAttributes(hHandle, TranspColor, AlphaValue, Flags); //AlphaBlend ermitteln
      Error := GetLastError;
      if (bResGet and (Error = 0)) then
        begin
          s := s + 'GetLayeredWindowAttributes erfolgreich' + #10#13;
          if ((Flags and LWA_ALPHA) > 0) then //ob AlphaBlend gesetzt ist
            s := s + 'AlphaBlend = True' + #10#13
          else
            s := s + 'AlphaBlend = False' + #10#13
        end
      else
        s := s + 'GetLayeredWindowAttributes nicht erfolgreich' + #10#13;
      s := s + 'GetLayeredWindowAttributes GetLastError = ' + IntToStr(Error) + #10#13; //gemerkten Fehler

    end;

  ShowMessage(s);
end;

virus82 30. Okt 2009 14:59

Re: GetLayeredWindowAttributes funktioniert nicht noch Resiz
 
Kann mir wirklich niemand helfen, oder ne Erklärung geben?

virus82 4. Nov 2009 23:26

Re: GetLayeredWindowAttributes funktioniert nicht noch Resiz
 
Da bin wohl nicht nur ich ratlos.

virus82 9. Nov 2009 14:46

Re: GetLayeredWindowAttributes funktioniert nicht noch Resiz
 
Muß ich mich damit abfinden das es nicht geht, oder kennt noch jemand ne Lösung?

virus82 23. Nov 2009 23:02

Re: GetLayeredWindowAttributes funktioniert nicht noch Resiz
 
Mir ist auch noch aufgefallen das manche Fenster die einen andern Skin benutzen (Windows Media Player, MSN) nach dem setzen der Tranzparenz unter WinXP dieser Skin ebenfalls nicht korrekt dargestellt wird.

virus82 22. Feb 2010 22:53

Re: GetLayeredWindowAttributes funktioniert nicht noch Resiz
 
Scheint wohl irgendein Bug unter WinXP zu sein, hatte es unter Vista getestet und dort geht es.

Hmm ... blöd sowas. :?


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:27 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz