C++ 透明窗口使背景不重画(winxp)
我正在尝试创建一个半透明的弹出窗口,它可以用DirectX自动呈现内容 问题在于,只有启用渲染后,背景才会重新绘制自身。只有在更新时(即当我在弹出窗口后面的文本编辑器中选择一行时)才会重画 当我的窗口移到辅助监视器时,魔术开始了。在那里一切都好。透明效果完美,背景不断重画。此外,如果弹出窗口步出显示边框,透明度也开始起作用。(下面是截图。) 操作系统是带有DirectX 9.0c的windows xp SP3和带有最新驱动程序的NVIDIA图形卡 我还用几种不同的显卡在WinVista和Win7上测试了该程序。工作完美 创建窗口C++ 透明窗口使背景不重画(winxp),c++,winapi,directx,transparency,wxwidgets,C++,Winapi,Directx,Transparency,Wxwidgets,我正在尝试创建一个半透明的弹出窗口,它可以用DirectX自动呈现内容 问题在于,只有启用渲染后,背景才会重新绘制自身。只有在更新时(即当我在弹出窗口后面的文本编辑器中选择一行时)才会重画 当我的窗口移到辅助监视器时,魔术开始了。在那里一切都好。透明效果完美,背景不断重画。此外,如果弹出窗口步出显示边框,透明度也开始起作用。(下面是截图。) 操作系统是带有DirectX 9.0c的windows xp SP3和带有最新驱动程序的NVIDIA图形卡 我还用几种不同的显卡在WinVista和Win7
m_popup = new popup(__("pew!"), wxPoint(600, 330), wxSize(250, 250));
m_popup->Show(true);
m_popup->SetWindowStyle(wxSTAY_ON_TOP);
m_popup->SetTransparent(150);
SetTopWindow(m_popup);
来自wxWidgets(2.8.12)的透明代码
DirectX初始化
m_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 = g_size;
d3dpp.BackBufferHeight = g_size;
m_d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &m_d3ddev);
CUSTOMVERTEX vertices[] =
{
{ 320.0f, 50.0f, 0.5f, 1.0f, D3DCOLOR_ARGB(150, 255, 150, 150), },
{ 520.0f, 400.0f, 0.5f, 1.0f, D3DCOLOR_ARGB(150, 150, 255, 150), },
{ 120.0f, 400.0f, 0.5f, 1.0f, D3DCOLOR_ARGB(150, 150, 150, 255), },
};
m_d3ddev->CreateVertexBuffer(3*sizeof(CUSTOMVERTEX),
0,
CUSTOMFVF,
D3DPOOL_MANAGED,
&v_buffer,
NULL);
VOID* pVoid;
v_buffer->Lock(0, 0, (void**)&pVoid, 0);
memcpy(pVoid, vertices, sizeof(vertices));
v_buffer->Unlock();
渲染
if (m_render)
{
m_d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(150, 150, 150, 200), 1.0f, 0);
m_d3ddev->BeginScene();
m_d3ddev->SetFVF(CUSTOMFVF);
m_d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX));
m_d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
m_d3ddev->EndScene();
m_d3ddev->Present(NULL, NULL, NULL, NULL);
}
屏幕截图
部分解决,请参阅评论。只想到一件事:wxWidgets中可能存在一些错误,甚至设计决策(很难以跨平台的方式实现所有这些功能),因此结果与您的预期不符。您可能最好依赖Win32 API本身,而不是wxWidgets。因此,如果您不打算使用“小部件”(我指的是“控件”:按钮、文本字段、选项卡等),并且您的应用程序不跨平台,那么您最好编写自己的窗口处理代码(我相信您的“弹出窗口”只是一个没有边框的窗口)。两种代码都编写并不重要。或者,至少,尝试另一个包装器库。谢谢您的评论。我试图直接用win32 api实现透明性。有同样的错误。wxWidgets似乎使用了与我尝试的相同的实现。正如我在问题中所说的,导致它的唯一原因是设置WS_EX_分层标志。不幸的是,需要使窗口透明。对不起,我对透明窗口不是很熟悉,但是,您是否使用以下三种标志:
WS_EX_LAYERED | WS_EX_toppost | WS_EX_transparent
?(请确保不要使用SetWindowPos()
删除WS\u EX\u最顶部的
)。还可以尝试使用WS_EX_COMPOSITED
。希望能有所帮助。@Drop不,我只使用了WS\u EX\u LAYERED
,尽管我尝试了不同的组合。错误依然存在。我已经尝试使用DirectX(一款游戏)创建一个程序透明的随机窗口。窗户留下了同样的痕迹。所以它看起来像一个驱动程序错误。无法分辨它是哪一个:DirectX、视频驱动程序还是Windows本身。我叫它。
if (m_render)
{
m_d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(150, 150, 150, 200), 1.0f, 0);
m_d3ddev->BeginScene();
m_d3ddev->SetFVF(CUSTOMFVF);
m_d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX));
m_d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
m_d3ddev->EndScene();
m_d3ddev->Present(NULL, NULL, NULL, NULL);
}