C++ 透明窗口使背景不重画(winxp)

C++ 透明窗口使背景不重画(winxp),c++,winapi,directx,transparency,wxwidgets,C++,Winapi,Directx,Transparency,Wxwidgets,我正在尝试创建一个半透明的弹出窗口,它可以用DirectX自动呈现内容 问题在于,只有启用渲染后,背景才会重新绘制自身。只有在更新时(即当我在弹出窗口后面的文本编辑器中选择一行时)才会重画 当我的窗口移到辅助监视器时,魔术开始了。在那里一切都好。透明效果完美,背景不断重画。此外,如果弹出窗口步出显示边框,透明度也开始起作用。(下面是截图。) 操作系统是带有DirectX 9.0c的windows xp SP3和带有最新驱动程序的NVIDIA图形卡 我还用几种不同的显卡在WinVista和Win7

我正在尝试创建一个半透明的弹出窗口,它可以用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);
    }
屏幕截图

  • 透明度失败:

  • 当弹出窗口超出显示边框时,透明度正常:

  • 我还想发布一个屏幕截图,说明它是如何在二级显示器上工作的,但我不能,因为rep,我也不能直接将图像发布到。想象一下,它在二级屏幕截图上就可以了

    多谢各位


    部分解决,请参阅评论。只想到一件事: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);
        }