ウィンドウを透明に設定する

Nov 24 2020

BlueStacksウィンドウを透過的に設定しようとしています:

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はで実行することができますopenglし、directx私は両方のモードを使用して、上記のコードをテストしています、。

MakeWindowTransparent 0を返しています

pSetLayeredWindowAttributes auto error = GetLastErrorAsString();返されるエラーは次のとおりwrong parameterです。

他のOpenGLウィンドウでコードをテストしましたが、どのエラーでも一時停止せず、ウィンドウも正しく透過しました。

ウィンドウに関して収集したいくつかの情報:

助けに感謝します。

回答

1 VladFeinstein Nov 24 2020 at 06:18

なぜ両方のフラグを使用しているのですLWA_COLORKEY | LWA_ALPHAか?色を指定する場合はRGB(255, 255, 255)、を使用してくださいLWA_COLORKEY

また、なぜあなたはいじっているのGetProcAddressですか?SetLayeredWindowAttributesWindows2000以降で利用可能です。それより古いプラットフォームをターゲットにしていますか?

私はBlueStacksに精通していませんが、ウィンドウを透明にするためのSetLayeredWindowAttributesは、一部の時間しか機能してSetLayeredWindowAttributesおらず、それが機能しないことを示唆していDirect3Dます。BlueStacksが使用しているDirect3Dかどうか知っていますか?

以下のためにOpenGLこれを参照してくださいどのように透明な背景を持つOpenGLのレンダリングコンテキストを作るには?

更新私はそのBlueStacksで遊んでいて、別のウィンドウに親を変更できると考えました(いくつかのエッジケースを処理する必要があるため、お勧めしません)。とにかく、私は既存のNotepadウィンドウを使用し、それにアルファを設定することができました、そしてそれは子BlueStacksウィンドウに影響を及ぼしました:

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

私はまたあなたの関数をクリーンアップして取り除きました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;
}