【问题标题】:Render to Desktop渲染到桌面
【发布时间】:2011-09-17 23:41:06
【问题描述】:

我希望能够像壁纸一样渲染事物。我使用 Windows,我更喜欢 DirectX。我知道VLC可以在DirectX模式下渲染视频有壁纸,所以这是可能的。

所以,一个简单的问题,我如何设置渲染目标来渲染,就像它是 Windows 中的壁纸一样?

【问题讨论】:

    标签: c++ windows directx rendering wallpaper


    【解决方案1】:

    这里有一些代码可以为您提供一个窗口句柄 (HWND),该窗口可用于在 Windows 桌面顶部进行绘制。其工作原理的主要问题是桌面图标仍然存在,但这将允许您在它们之上绘制。如果您希望图标正常显示(后面有您的东西),您需要在绘制完您的东西后重新绘制它们,或者找到一种方法来避免首先绘制它们。这是相当重要的,也是我从未完全解决的问题。

    这绝对适用于 XP 和 Windows 7(带有 Areo),以获得普通 GDI 绘图可以使用的东西。我从未使用 DirectX 对其进行过测试,但我怀疑如果您使用 hMainWnd 作为演示窗口,它会起作用。

    HWND hProgMan = NULL;
    HWND hShell = NULL;
    HWND hMainWnd = NULL;
    unsigned int ScreenWidth = 0;
    unsigned int ScreenHeight = 0;
    int ScreenTop = 0;
    int ScreenLeft = 0;
    HRGN ValidRGN = NULL;
    
    // ...
    
        ScreenWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
        if ( ScreenWidth == 0 ) 
            ScreenWidth = GetSystemMetrics( SM_CXSCREEN );
    
        ScreenHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
        if ( ScreenHeight == 0 ) 
            ScreenHeight = GetSystemMetrics(SM_CYSCREEN);
    
        ScreenTop = GetSystemMetrics(SM_YVIRTUALSCREEN);
        ScreenLeft = GetSystemMetrics(SM_XVIRTUALSCREEN);
    
        ValidRGN = CreateRectRgn(0,0,ScreenWidth,ScreenHeight);
    
        hProgMan = FindWindow("Progman", "Program Manager");
        if(hProgMan != NULL)
        {
            hShell = FindWindowEx(hProgMan, 0, "SHELLDLL_DefView", NULL);
        }
        else
        {
            hProgMan = FindWindow("DesktopBackgroundClass", NULL);
            if(hProgMan != NULL)
                hShell = FindWindowEx(hProgMan, 0, "DeskFolder", NULL);
        }
    
        hMainWnd = CreateWindowEx( WS_EX_TRANSPARENT, "MyWindowClass", "Window Title", WS_CHILDWINDOW | WS_OVERLAPPED | WS_CLIPCHILDREN, 0,0,ScreenWidth,ScreenHeight, hShell,NULL,hInstance,NULL );
        EnableWindow(hMainWnd,FALSE);
        SetWindowPos(hMainWnd,HWND_BOTTOM,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);
    

    ...然后用于绘图(使用 GDI),类似这样...

        HDC hDC = GetDC( hMainWnd );
        SelectClipRgn(hDC,ValidRGN);
        BitBlt( hDC, 0, 0, ScreenX, ScreenY, hBackBuffer, 0, 0, SRCCOPY );
        ReleaseDC( hMainWnd, hDC );
    

    ...并使用桌面图标区域更新ValidRGN。这些可以通过桌面的列表视图控制窗口的一些工作找到。这相当复杂,可能与这个问题无关。

    【讨论】:

    • 嗯,我希望它表现得像普通壁纸一样,上面有图标。无论如何,我会看看你的代码,看看是否可以做些什么来在图标后面渲染它。谢谢。
    • 看起来你可以从桌面抓取一个 DC 并绘制到它:social.msdn.microsoft.com/Forums/en-US/winforms/thread/… 而不创建子窗口。该线程中的作者无法将 Direct3D 与该 DC 一起使用,但您应该能够呈现到隐藏窗口,捕获结果,然后将其 blit 到桌面。
    猜你喜欢
    • 2018-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多