Stellen Sie ein transparentes Fenster ein

Nov 24 2020

Ich habe versucht, das BlueStacks- Fenster transparent zu machen:

DWORD MakeWindowTransparent(HWND hWnd, unsigned char factor)
{
    /* First, see if we can get the API call we need. If we've tried
     * once, we don't need to try again. */
    if (!initialized)
    {
        HMODULE hDLL = LoadLibrary(L"user32");

        pSetLayeredWindowAttributes =
            (PSLWA)GetProcAddress(hDLL, "SetLayeredWindowAttributes");

        initialized = TRUE;
    }

    if (pSetLayeredWindowAttributes == NULL)
        return FALSE;

    /* Windows need to be layered to be made transparent. This is done
     * by modifying the extended style bits to contain WS_EX_LAYARED. */
    SetLastError(0);

    auto winlong = SetWindowLong(hWnd,
    GWL_EXSTYLE,
    GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_LAYERED);

    if ((winlong == 0) && (GetLastError() != 0)) { 
        auto error = GetLastErrorAsString(); 
        return FALSE;
    } 

    if (!pSetLayeredWindowAttributes(hWnd,RGB(255, 255, 255),factor, LWA_COLORKEY | LWA_ALPHA))
    { 
        auto error = GetLastErrorAsString(); 
        return FALSE; 
    } 

    return TRUE;
}


int main() {
  HWND hWnd = FindWindowA(NULL, L"BlueStacks");
  MakeWindowTransparent(hWnd, 0);
}

BlueStacks können ausgeführt werden, openglund directxich habe den obigen Code in beiden Modi getestet.

MakeWindowTransparent gibt 0 zurück

pSetLayeredWindowAttributes auto error = GetLastErrorAsString();Der zurückgegebene Fehler lautet : wrong parameter.

Ich habe den Code mit anderen OpenGL-Fenstern getestet und er hat bei keinem der Fehler angehalten, auch das Fenster wurde korrekt transparent.

Einige Informationen, die ich über das Fenster gesammelt habe:

Schätzen Sie jede Hilfe.

Antworten

1 VladFeinstein Nov 24 2020 at 06:18

Warum benutzt du beide Flags LWA_COLORKEY | LWA_ALPHA? Wenn Sie eine Farbe angeben RGB(255, 255, 255), verwenden Sie einfach LWA_COLORKEY.

Und warum spielst du mit GetProcAddress? SetLayeredWindowAttributesist ab Windows 2000 verfügbar; zielen Sie auf ältere Plattformen ab?

Ich bin mit BlueStacks nicht vertraut , aber SetLayeredWindowAttributes, um ein Fenster transparent zu machen, funktioniert nur teilweise , was darauf hindeutet, dass SetLayeredWindowAttributesdies nicht funktioniert Direct3D. Wissen Sie, ob BlueStacks verwendet Direct3D?

Für OpenGLdiese sehen: Wie einen OpenGL - Rendering - Kontext mit transparentem Hintergrund machen?

UPDATE Ich habe mit diesen BlueStacks gespielt und festgestellt , dass Sie sie einem anderen Fenster zuordnen können (dies wird nicht empfohlen, da Sie einige Randfälle behandeln müssen). Wie auch immer, ich habe ein vorhandenes NotepadFenster verwendet und konnte Alpha darauf setzen, was sich auf das untergeordnete BlueStacks- Fenster auswirkte :

int main() {
  HWND hWnd = FindWindow(NULL, L"BlueStacks");
  HWND hWndN = FindWindow(NULL, L"Untitled - Notepad");
  ::SetParent(hWnd, hWndN);

  auto winlong1 = SetWindowLongPtr(hWnd, GWL_EXSTYLE, 0);
  auto winlong2 = SetWindowLongPtr(hWnd, GWL_STYLE, WS_CHILD | WS_VISIBLE);
  ::SetWindowPos(hWnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOZORDER | SWP_NOREDRAW | SWP_NOACTIVATE);

  MakeWindowTransparent(hWndN, 200);
}

Ich habe auch Ihre Funktion aufgeräumt, um Folgendes loszuwerden GetProcAddress:

DWORD MakeWindowTransparent(HWND hWnd, unsigned char factor)
{
  auto winlong = SetWindowLong(hWnd,
    GWL_EXSTYLE,
    GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_LAYERED);

  if ((winlong == 0) && (GetLastError() != 0)) {
    return FALSE;
  }

  if (!SetLayeredWindowAttributes(hWnd, 0, factor, LWA_ALPHA))
  {
    return FALSE;
  }

  return TRUE;
}