从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 );
效果图:
根据这个原理可以做很多有意思的事情。