从D3D将画面渲染至桌面

突然发现这样的的方法,觉得很好玩,但网上被各种转载的方法有句是错误的,导致无法初始化D3D,终于挖到了原始文章,补充一些自己的认识,以此记之。


   首先要明确一下桌面(Desktop)这个东西。桌面,就是那个在所有窗口最底层的窗口,所有的桌面图标,例如我的电脑,我的文档,网上邻居等等图标,都是画在这个Desktop窗口上的。每次启动Windows就会启动Explorer.exe,桌面就是由Explorer.exe维护的。好,下面给出的代码片段,就是获得这个桌面窗口句柄的代码了。获得了Desktop的hWnd,就能将D3D画面绘制到这里了。然而有人会问,将D3D画面绘制到这里干什么??嗯,这个问题还不是很好回答,因为需求是千奇百怪的,有的人想要这样,有的人会想要那样,具体想要干什么就看各人需要了。我在这里介绍这个方法,也仅仅是做一个记录而已,而且根据我在XP中测试结果来看是成功的。

    稍微有些经验的也会说,获得桌面窗口句柄很简单,只要调用一下函数GetDesktopWindow()即可。嗯,我的测试结果是,光这样写,是不行的,不知道什么时候起,GetDesktopWindow()返回的已经不是真正的桌面窗口句柄了。相应的,我们需要这样来获得一个DesktopWindow的句柄:

    // Create the application's window
    // find Program Manager
    HWND hWnd = FindWindowEx(GetDesktopWindow() , 0 , L"Progman" , L"Program Manager");
    // find SHELLDLL_DefView
    hWnd = FindWindowEx(hWnd , 0 , L"SHELLDLL_DefView" , 0);
    // find Desktop Folder!!
    hWnd = FindWindowEx(hWnd , 0 , L"SysListView32" , L"FolderView");
    // initd3d by desktop forlder window!!

    // Initialize Direct3D
    if( SUCCEEDED( InitD3D( hWnd ) ) )
    {
        // Create the scene geometry
        if( SUCCEEDED( InitGeometry() ) )
        {
            // Show the window
            ShowWindow( hWnd, SW_SHOWDEFAULT );
            UpdateWindow( hWnd );
    }

然后为了不占用整个桌面,所以可以自定义一个小一点的窗口。
本人的分辨率是1680*1050,可以通过API获取:如下

    HDC hdc = GetDC(NULL);                            // Get the handld of screen
    int ScrWidth = GetDeviceCaps(hdc, HORZRES);        // screen horizontal resolution
    int ScrHeight = GetDeviceCaps(hdc, VERTRES);    // screen vertical resolution
    ReleaseDC(NULL, hdc);                            // release the handle of screen
    // Present the backbuffer contents to the display
    RECT rect;
    rect.left = ScrWidth-800;
    rect.right = ScrWidth;
    rect.top = 0;
    rect.bottom = ScrHeight;
    // Present the backbuffer contents to the display
    
    g_pd3dDevice->Present( NULL, &rect, NULL, NULL );

效果图:

 根据这个原理可以做很多有意思的事情。

原文地址:https://www.cnblogs.com/yxy8023ustc/p/2806830.html