我编写了一个简单的directX9应用程序(下面的代码),该应用程序至少可以在25个Windows 10安装程序上正常运行,但是在其中一个窗口上的背景只是黑色而不是透明的(上面有测试图)。
所有系统都运行专用的NVIDIA GPU(10系列),所以这不是问题,它们使用具有最新Nvidia驱动程序的最新Windows 10版本。
一种解决方法是将LWA_COLORKEY添加到SetLayeredWindowAttributes,但是我想知道如何解决该系统而不是使用LWA_COLORKEY。 (因为添加LWA_COLORKEY会产生很大的性能)。
SetLayeredWindowAttributes(hWnd, 0, 255, LWA_ALPHA | LWA_COLORKEY);
这是可以重现问题的示例:
#pragma once
#include <Windows.h>
#include <string>
#include <iostream>
// DirectX9
#pragma warning( push )
#pragma warning( disable : 4005)
#include <d3d9.h>
#include <d3dx9.h>
#include <Dwmapi.h>
#include <TlHelp32.h>
#include <Directxmath.h>
#pragma comment(lib, "d3dx9.lib")
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "Dwmapi.lib")
#pragma warning( pop )
using namespace std;
using namespace DirectX;
int s_width = 800;
int s_height = 600;
#define CENTERX (GetSystemMetrics(SM_CXSCREEN)/2)-(s_width/2)
#define CENTERY (GetSystemMetrics(SM_CYSCREEN)/2)-(s_height/2)
LPDIRECT3D9 d3d;
LPDIRECT3DDEVICE9 d3ddev;
HWND hWnd;
LPD3DXFONT pFont;
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
void initD3D(HWND hWnd)
{
d3d = Direct3DCreate9(D3D_SDK_VERSION);
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hWnd;
d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
d3dpp.BackBufferWidth = s_width;
d3dpp.BackBufferHeight = s_height;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
d3dpp.FullScreen_RefreshRateInHz = 0;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
d3dpp.MultiSampleQuality = DEFAULT_QUALITY;
d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &d3ddev);
D3DXCreateFont(d3ddev, 50, 0, FW_BOLD, 1, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Arial", &pFont);
}
void DrawString(int x, int y, DWORD color, LPD3DXFONT g_pFont, const char *fmt, ...)
{
RECT FontPos = { x, y, x + 120, y + 16 };
char buf[1024] = { '\0' };
va_list va_alist;
va_start(va_alist, fmt);
vsprintf_s(buf, fmt, va_alist);
va_end(va_alist);
g_pFont->DrawText(NULL, buf, -1, &FontPos, DT_NOCLIP, color);
}
void render()
{
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0, 0, 0, 0), 1.0f, 0);
d3ddev->BeginScene();
DrawString(10, 50, D3DCOLOR_ARGB(100, 255, 0, 0), pFont, "Test rendering");
d3ddev->EndScene();
d3ddev->Present(NULL, NULL, NULL, NULL);
}
int main()
{
RECT rc = { 0 };
HINSTANCE hInstance = GetModuleHandle(NULL);
WNDCLASSEX wc;
ZeroMemory(&wc, sizeof(WNDCLASSEX));
wc.cbClsExtra = NULL;
wc.cbWndExtra = NULL;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.hInstance = NULL;
wc.lpfnWndProc = WindowProc;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(0, 0, 0));
wc.lpszClassName = "WindowClass";
RegisterClassEx(&wc);
hWnd = CreateWindowExA(WS_EX_LAYERED | WS_EX_TRANSPARENT, "WindowClass", "Title", WS_POPUP | WS_VISIBLE, rc.left, rc.top, s_width, s_height, NULL, NULL, hInstance, NULL);
SetLayeredWindowAttributes(hWnd, 0, 255, LWA_ALPHA);
//DWM_BLURBEHIND bb = { DWM_BB_ENABLE | DWM_BB_BLURREGION, true, CreateRectRgn(0, 0, -1, -1), true };
//if (DwmEnableBlurBehindWindow(hWnd, &bb) != S_OK)
MARGINS margin = { -1 };
DwmExtendFrameIntoClientArea(hWnd, &margin);
initD3D(hWnd);
MSG msg;
while (TRUE)
{
render();
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (msg.message == WM_QUIT)
exit(0);
}
return msg.wParam;
}
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_PAINT:
{
}break;
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
} break;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}