DirectX桌面

Jon*_*han 19 c# windows directx

我想使用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程序会这样做),我看到的东西类似于我想要的VLC Media Player在Windows XP下使用DirectX壁纸模式(有趣的是,我似乎无法在我的系统上启用此选项).

谢谢!

Mus*_*sis 5

看起来这可能是不可能的.看到这个链接:

http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/69839cec-3424-4300-9ac3-486b8c2fe492

如果您需要在桌面背景和桌面图标之间绘制一些控件,则可以采用以下替代步骤:

  1. 在Windows控件库中创建用户控件.
  2. 将用户控件嵌入ActiveX控件中.
  3. 将ActiveX控件嵌入到网页中.
  4. 启用活动桌面并将网页设置为桌面背景.

这只能在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);
Run Code Online (Sandbox Code Playgroud)

你基本上是从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目标.但是,您可能必须向桌面发送重新绘制指令,这可能会触发每次重绘图标.

你在这里做点工作怎么样?:)


And*_*and 1

我想通过动态生成位图并不断将它们设置为桌面背景,您可以每秒获得相当多的帧。然而,这对于 CPU 来说听起来不必要(几乎是愚蠢的)沉重。更新:现在我想起来了(我写这篇文章的时候已经很晚了),这种方法的主要问题是每次显示新帧时都需要从硬盘驱动器写入和读取位图。这是不可行的。

您真的在使用桌面图标吗?Windows 7中的开始菜单搜索功能和新的任务栏让我不再使用桌面图标。

只是一个想法

可以通过 SendMessage(GetDesktopWindow, WM_SOME_MESSAGE, wParam, lParam) 来更改桌面窗口,以便您可以实现您想要的效果我明天可能会进一步调查这个问题(目前是当地时间凌晨 3 点)。