2017-08-31 14 views
0

Ich schreibe eine Bibliothek, die eine Farbe im Fenster Client-Bereich unsichtbar macht.SetLayeredWindowAttributes funktioniert nicht unter Windows 8+ (C++)

In der Anwendungshälfte, zuerst rufe ich window_fix_transparent_color() auf, um das Fenster zu überlagern. Dann verwende ich window_set_transparent_color(), um eine Farbe im Client-Bereich unsichtbar zu machen.

Hier ist meine Bibliothek Code:

#define _WIN32_WINNT 0x0501 
#include <windows.h> 

extern "C" 
{ 
    void window_fix_transparent_color(double window_handle) 
    { 
     // sets the window flags to support RGB color transparency. 
     SetWindowLong((HWND)(DWORD)window_handle,GWL_EXSTYLE, 
      GetWindowLong((HWND)(DWORD)window_handle,GWL_EXSTYLE)|WS_EX_LAYERED); 
    } 

    void window_set_transparent_color(double window_handle,double red,double green,double blue) 
    { 
     // sets the RGB color to be transparent for the specified window. 
     SetLayeredWindowAttributes((HWND)(DWORD)window_handle,RGB(red,green,blue),255,LWA_COLORKEY); 
    } 
} 

ich die Version von MinGW bin mit, die mit dem neuesten Code verpackt :: Blocks als mein Compiler. Es funktioniert unter Windows 7, aber nicht unter Windows 8, 8.1 oder 10 ...

Irgendwelche Ideen, warum das ist? Außerdem, eine merkwürdige Sache, die es wert ist, daran zu erinnern - sie arbeitete früher unter Windows 8/8.1/10, was mich zu der Annahme verleitet, dass ein bestimmtes Windows-Update für diese Plattformen meinen Code beschädigt haben könnte. Ich habe keine Änderungen an meinem Code vorgenommen, seit er auf den Plattformen nach Windows 7 nicht mehr funktioniert.

Vielen Dank!

+0

Eine GUI-Bibliothek wie Winforms führt [diesen Code] (https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/Control.cs,2895b1373643ef53) wenn die Opazität eines Formulars oder Die Eigenschaft TransparencyKey wurde geändert. Beachten Sie den Aufruf von SetWindowPos(). –

+0

@HansPassant Ich bin mir nicht sicher, ob ich verstehe, was dein Standpunkt ist. –

+0

Sie haben die Frage mit C++ markiert und dann den ganzen Code in extern "C" eingefügt, eher seltsam, wenn Sie mich fragen ... – Anders

Antwort

2

Warum verwenden Sie seltsame Typen und Güsse? Sie sollten niemals einen Handle-Typ auf DWORD umwandeln, verwenden Sie INT_PTR oder UINT_PTR, wenn Sie müssen. A double ist tatsächlich größer als ein HWND in 32-Bit-Anwendungen, so verschwenden Sie tatsächlich Platz verschwenden zusätzlich zu machen Dinge für Sie selbst. A double kann nicht verwendet werden, um ein Handle in einer 64-Bit-Anwendung zu speichern!

Sie überprüfen auch nicht den Rückgabewert von SetLayeredWindowAttributes, so ist es unmöglich zu wissen, was das Problem wirklich ist.

die Funktion Rewrite mit richtigen Typen und Fehlerbehandlung:

void display_error(DWORD error) 
{ 
    char buf[100]; 
    wsprintfA(buf, "Error %u!", error); 
    MessageBoxA(NULL, buf, 0, 0); // Ideally you would pass a window handle here but I don't know if your handle is actually valid 
} 

void window_fix_transparent_color(HWND window_handle) 
{ 
    DWORD error; 

    // get the window flags to see if RGB color transparency is supported. 
    SetLastError(0); 
    LONG_PTR ExStyle = GetWindowLongPtr(window_handle, GWL_EXSTYLE); 
    if (ExStyle == 0) 
    { 
     error = GetLastError(); 
     if (error != 0) 
     { 
      display_error(error); 
      return; 
     } 
    } 

    if ((ExStyle & WS_EX_LAYERED) == 0) 
    { 
     // set the window flags to support RGB color transparency. 
     SetLastError(0); 
     if (!SetWindowLongPtr(window_handle, GWL_EXSTYLE, ExStyle | WS_EX_LAYERED)) 
     { 
      error = GetLastError(); 
      if (error != 0) 
       display_error(error); 
     } 
    } 
} 

void window_set_transparent_color(HWND window_handle, BYTE red, BYTE green, BYTE blue) 
{ 
    // sets the RGB color to be transparent for the specified window. 
    if (!SetLayeredWindowAttributes(window_handle, RGB(red, green, blue), 255, LWA_COLORKEY)) 
    { 
     display_error(GetLastError()); 
    } 
} 

... 

HWND mywindow = CreateWindowEx(...); 
window_fix_transparent_color(mywindow); 
window_set_transparent_color(mywindow, ...); 
+0

SetLayeredWindowAttributes gibt True zurück, obwohl die Farbe in Windows 8+ nicht transparent gemacht wird. Wie bereits erwähnt, funktioniert es auf Windows 7. –

+0

Vielen Dank für den Versuch zu helfen, aber dafür bin ich dankbar. :) –

+0

'HWND's verwenden nie die obere Hälfte ihres Bereichs. Es ist sicher (auch wenn es verwirrend ist), einen Fenstergriff in einem "Doppel" zu speichern. Weitere Informationen finden Sie unter [Interprozesskommunikation zwischen 32-Bit- und 64-Bit-Anwendungen] (https://msdn.microsoft.com/en-us/library/windows/desktop/aa384203.aspx). – IInspectable

1

Meine Vermutung ist, dass Sie „basic“ oder „klassischen“ Thema auf Windows 7. Obwohl ohne Papiere verwenden, ist es die Kompatibilität von Windows XP aktiviert Modus für das Desktop-Fenster Manager, und ändert die Art und Weise, wie Fenster mit Ebenen arbeiten. Das passiert nicht in späteren Versionen von Windows unter .

+0

Ich habe kürzlich herausgefunden, dass mein Code auch auf einigen Windows 10 Computern funktioniert. Es ist wirklich seltsam und macht wenig Sinn für mich. Einige Windows 10 Computer funktionieren und andere nicht. Ich würde deine Antwort akzeptieren, weil es vielversprechend klang, aber dann habe ich das herausgefunden. :( –

Verwandte Themen