Đặt cửa sổ trong suốt

Nov 24 2020

Tôi đã cố gắng đặt cửa sổ BlueStacks trong suốt:

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 có thể chạy trong opengldirectx, tôi đã thử nghiệm đoạn mã ở trên, sử dụng cả hai chế độ.

MakeWindowTransparent đang trả về 0

pSetLayeredWindowAttributes auto error = GetLastErrorAsString();Lỗi được thông báo là: wrong parameter.

Tôi đã kiểm tra mã với các cửa sổ OpenGL khác và nó không bị tạm dừng trong bất kỳ lỗi nào, cửa sổ cũng trong suốt một cách chính xác.

Một số thông tin tôi đã thu thập được về cửa sổ:

Đánh giá cao bất kỳ sự giúp đỡ nào.

Trả lời

1 VladFeinstein Nov 24 2020 at 06:18

Tại sao bạn sử dụng cả hai cờ LWA_COLORKEY | LWA_ALPHA? Nếu bạn đang chỉ định một màu RGB(255, 255, 255), chỉ cần sử dụng LWA_COLORKEY.

Ngoài ra, tại sao bạn lại gây rối với GetProcAddress? SetLayeredWindowAttributescó sẵn bắt đầu với Windows 2000; bạn đang nhắm mục tiêu các nền tảng cũ hơn thế?

Tôi không quen thuộc với BlueStacks , nhưng SetLayeredWindowAttributes để làm cho cửa sổ trong suốt chỉ hoạt động một phần thời gian gợi ý rằng SetLayeredWindowAttributeskhông hoạt động với Direct3D; bạn có biết nếu BlueStacks sử dụng Direct3D?

Để OpenGLxem phần này: Làm thế nào để tạo bối cảnh kết xuất OpenGL với nền trong suốt?

CẬP NHẬT Tôi đang chơi với BlueStacks đó và nhận thấy rằng bạn có thể cấp lại nó vào một cửa sổ khác (điều đó không được khuyến nghị, vì bạn sẽ cần xử lý một số trường hợp cạnh). Dù sao, tôi đã sử dụng một Notepadcửa sổ hiện có và có thể đặt alpha trên đó, và điều đó đã ảnh hưởng đến cửa sổ BlueStacks con :

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

Tôi cũng đã xóa chức năng của bạn để loại bỏ 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;
}