Şeffaf bir pencere ayarla

Nov 24 2020

BlueStacks penceresini şeffaf hale getirmeye çalışıyorum :

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 çalışabilir openglve directxyukarıdaki kodu her iki modu da kullanarak test ettim.

MakeWindowTransparent 0 dönüyor

pSetLayeredWindowAttributes auto error = GetLastErrorAsString();döndürülen hatadır: wrong parameter.

Kodu diğer OpenGL pencereleri ile test ettim ve hataların hiçbirinde duraklamadı, ayrıca pencere doğru şekilde şeffaflaştı.

Pencere hakkında topladığım bazı bilgiler:

Herhangi bir yardım için minnettarım.

Yanıtlar

1 VladFeinstein Nov 24 2020 at 06:18

Neden her iki işareti de kullanıyorsunuz LWA_COLORKEY | LWA_ALPHA? Bir renk belirliyorsanız RGB(255, 255, 255), sadece kullanın LWA_COLORKEY.

Ayrıca, neden uğraşıyorsun GetProcAddress? SetLayeredWindowAttributesWindows 2000'den itibaren mevcuttur; bundan daha eski platformları mı hedefliyorsunuz?

Ben aşina değilim BlueStacks , ancak SetLayeredWindowAttributes sadece zaman parçası çalışan bir pencere şeffaf hale getirmek olduğunu göstermektedir SetLayeredWindowAttributesile çalışmıyor Direct3D; BlueStacks'ın kullanıp kullanmadığını biliyor musunuz Direct3D?

Şuna OpenGLbakın: Saydam arka plana sahip bir OpenGL oluşturma bağlamı nasıl oluşturulur?

GÜNCELLEME BlueStacks ile oynuyordum ve başka bir pencereye yeniden ebeveynlik yapabileceğinizi düşündüm (bazı uç durumları halletmeniz gerekeceği için bu önerilmez). Her neyse, mevcut bir Notepadpencere kullandım ve üzerine alfa ayarlayabildim ve bu da alt BlueStacks penceresini etkiledi :

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);
}

Ayrıca şunlardan kurtulmak için işlevinizi de temizledim 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;
}