我想使用DirectX为Windows 7制作动画桌面背景。我正在使用C#,SlimDX和一些P / Invoke导入的Windows API函数。我对原生Windows编程并不擅长,但我已经在网上搞砸了,我相信我需要做的是:
1)找到包含dekstop壁纸的窗口的句柄,将其连接到DirectX设备并绘制到其中。
2)创建一个新的输出窗口,并将其插入桌面墙纸上方但在桌面图标下方。
我已尝试过这两种方法,但似乎都没有效果。如果我从GetDesktopWindow()返回的句柄开始导航Window heirarchy,我可以去桌面 - > WorkerW - > SHELLDLL_DefView - > SysListView32。如果我将DirectX设备连接到此句柄,我可以绘制整个桌面,但它也包含图标。如果我创建一个Windows窗体,使用SetParent()将其父窗口设置为SHELLDLL_DefView,然后使用SetWindowPos来播放它的Z顺序我只能看到它要么在桌面壁纸后面,要么在桌面+图标前面。
看起来桌面壁纸是包含图标的文件夹视图的背景,因此我尝试做的事情无法正常工作。那么唯一的解决方案是不使用桌面图标,或找到一些替代方案,例如覆盖桌面,然后覆盖一个透明窗口,其中包含某个文件夹内容的视图。
有没有人知道我应该做什么,甚至不知道我想做什么是可能的?看来你可以使用GDI绘制到桌面背景(我相信wxSnow程序会这样做),我看到的东西类似于我想要在Windows XP下使用DirectX壁纸模式的VLC Media Player所做的事情(有趣的是,我似乎无法在我的系统上启用此选项。)
谢谢!
答案 0 :(得分:5)
看起来这可能无法实现。看到这个链接:
http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/69839cec-3424-4300-9ac3-486b8c2fe492
如果您需要绘制一些控件 桌面背景和。之间 桌面图标,另一个步骤是 下面:
- 在Windows控件库中创建用户控件。
- 将用户控件嵌入ActiveX控件中。
- 将ActiveX控件嵌入网页中。
- 启用活动桌面并将网页设置为桌面 背景
醇>这只能在XP中完成 Vista不支持活动桌面。
另一篇帖子暗示你可以用浏览器窗口的背景来做这件事 - 如果你能得到构成它的窗口的句柄。当然,如果可能,那么也可以在图标后面获得桌面窗口的句柄。
更新那么,到目前为止,我发现可能“工作”的唯一事情就是创建Bitmap文件并一遍又一遍地更改壁纸(我怀疑这会很慢,如你所说)。
全屏图像必须驻留在某处的内存中,但如果没有严重的低级内存黑客攻击,可能无法访问它。我要继续寻找。
更新2:这可能会有效,但我不确定:
http://social.msdn.microsoft.com/forums/en-US/vcgeneral/thread/4af734fb-d2c1-414b-a9f1-759b76692802
它的肉是这样的:
HWND p = FindWindow("ProgMan", NULL);
HWND s = FindWindowEx(p, NULL, "SHELLDLL_DefView", NULL);
HWND dtw = FindWindowEx(s, NULL, "SysListView32", NULL);
HDC hdc = GetDC(dtw);
你基本上是从ProgMan窗口开始,从那里向下钻到桌面壁纸(我猜是“SysListView32”)。我打算试一试。
更新3:不行 - 上面的代码确实获得了桌面的DC,但它高于图标,因此BitBlt会覆盖它们。但是,它并没有吸引到屏幕上,因为我可以在一个没有遮盖它的情况下在一个开放的形式下画画,所以这至少取得了进展。
我猜测除了“SysListView32”之外还有一些可用的窗口,它是图标后面的桌面,或者有多个“SysListView32”窗口。
更新4:我很确定使用它的方法可行:
http://msdn.microsoft.com/en-us/library/bb761155(v=VS.85).aspx http://msdn.microsoft.com/en-us/library/bb774742(v=VS.85).aspx
基本上,它是您调用的API方法,传入包含位图句柄的结构。如果调用成功,该位图将成为桌面。
DirectX是否将帧暴露为位图句柄(GDI兼容),还是只暴露DC?在我的例子中,我的动画已经是一个与GDI兼容的位图数组,因此我可以毫不费力地使用这种方法。如果这是唯一的路径,并且DirectX不公开位图句柄(我认为它们不会),那么对于每个帧,您将不得不创建一个新的GDI位图,这将减慢相当多的速度。
实际上,可能有一种更简单的方法,虽然我不确定它会起作用。获得壁纸的实际位图后,可以使用SelectObject
将其选择到设备上下文中,然后将该设备上下文用作BitBlt目标。但是,您可能必须向桌面发送重新绘制的指令,这可能会触发每次重新绘制图标。
你在这里做点什么? :)
答案 1 :(得分:1)
我猜你通过动态生成位图并不断将它们设置为桌面背景,每秒可以获得相当多的帧数。但是,对于CPU来说,这听起来不必要(几乎是愚蠢的)。 更新:现在我想起来了(我写这篇文章已经很晚了),这种方法的主要问题是每次新框架都需要从硬盘驱动器写入和读取位图是要显示。这是不可行的。
您是否真的使用桌面图标?在Windows 7中,开始菜单搜索功能和新任务栏使我不使用桌面图标。
只是一个想法
可能可以通过SendMessage(GetDesktopWindow,WM_SOME_MESSAGE,wParam,lParam)改变桌面窗口,以便您可以实现您想要的效果。我明天可能会进一步调查(目前当地时间凌晨3点)。
答案 2 :(得分:1)
我已经完成了some animation of alpha blended windows,它始终位于Z-Order的顶部。一个想法是忽略尝试修改桌面位图,只是将你的东西绘制为layered window,但以某种方式管理ZOrder,因此它始终是最底层的非桌面窗口(可能通过战略性调用{{1}在正确的时间或某事。)
根据您的尝试,这可能会给您带来与桌面动画相同的效果。