Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Render to Desktop

I want to be able to render a thing as if it was a wallpaper. I use Windows, and I prefer DirectX. I know that VLC can render the video has a wallpaper in DirectX mode, so it's possible.

So, a quick question, How could I set the rendertarget to render like if it was a wallpaper in Windows?

like image 218
user950760 Avatar asked Nov 05 '22 14:11

user950760


1 Answers

Here is some code which will get you a handle (HWND) to a window that can be used to draw over top of the windows Desktop. The main issue with how this works is that the desktop icons are still present but this will allow you to draw over top of them. If you want the icons to appear as normal (with your stuff behind them) you need to redraw them after you've drawn your stuff, or find a way to avoid drawing over them in the first place. This is fairly non-trivial and something I never completely solved.

This definitely works on XP and Windows 7 (with Areo) for getting something that normal GDI drawing can use. I've never tested it with DirectX but I suspect it would work if you used hMainWnd as your presentation window.

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

... and then for drawing (using GDI), something like this...

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

... and update ValidRGN with the regions of the Desktop icons. Those can be found with a bit of work with the Desktop's listview control window. That is fairly complicated and maybe off topic for this question.

like image 65
SoapBox Avatar answered Nov 15 '22 04:11

SoapBox