c# - DirectX 桌面

标签 c# windows directx

我想使用 DirectX 为 Windows 7 制作动画桌面背景。我正在使用 C#、SlimDX 和几个 Windows API 函数的 P/Invoke 导入。我对 native Windows 编程并不擅长,但我在网上浏览了一下,我认为我需要做的是:

1) 找到包含桌面墙纸的窗口句柄,将其连接到 DirectX 设备并在其中绘制。

2) 制作一个新的输出窗口,并将其插入桌面墙纸上方但桌面图标下方。

这两种我都试过了,但似乎都不起作用。如果我从 GetDesktopWindow() 返回的句柄开始导航窗口层次结构,我可以转到桌面 -> WorkerW -> SHELLDLL_DefView -> SysListView32。如果我将 DirectX 设备连接到这个 handle ,我可以在整个桌面上绘制,但它也会覆盖图标。如果我创建一个 Windows 窗体,使用 SetParent() 将其父级设置为 SHELLDLL_DefView,然后使用 SetWindowPos 来玩它的 Z 顺序,我似乎只能让它在桌面墙纸后面或桌面 + 图标前面。

看起来好像桌面墙纸是包含图标的文件夹 View 的背景,因此我尝试做的事情不起作用。唯一的解决方案就是不使用桌面图标,或者寻找一些替代方案,例如覆盖桌面,然后覆盖一个包含某个文件夹内容 View 的透明窗口。

有没有人知道我应该做什么,或者我想做的事情是否可行?看起来你可以使用 GDI 绘制到桌面背景(我相信 wxSnow 程序就是这样做的),而且我已经看到了类似于我想要在 Windows XP 下使用 DirectX 壁纸模式的 VLC Media Player 所做的事情(有趣的是,我似乎无法在我的系统上启用此选项)。

谢谢!

最佳答案

看起来这可能是不可能的。请参阅此链接:

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

If you need to draw some controls between the desktop background and desktop icons, an alternative step is below:

  1. Create your user control in a windows control library.
  2. Embed the user control in an ActiveX control.
  3. Embed the ActiveX control in a web page.
  4. Enable active desktop and set the web page to be your desktop background.

This can only be done in XP since Vista doesn’t support active desktop.

那里的另一篇文章建议您可以在资源管理器窗口的背景下执行此操作 - 如果您可以获得构成它的窗口的句柄。当然,如果可能的话,也有可能获得图标后面的桌面窗口句柄。

更新:到目前为止,我发现唯一可能“有效”的方法就是创建位图文件并一遍又一遍地更改墙纸(我怀疑这会很慢,正如你提到的)。

该全屏图像必须驻留在内存中的某个地方,但如果不进行一些严重的低级内存黑客攻击,则可能无法访问它。我会继续寻找。

更新 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 目标。不过,您可能必须向桌面发送重绘指令,这可能会触发图标每次都重绘。

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

关于c# - DirectX 桌面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2619331/

相关文章:

c++ - 远离 Windows\C++ 中的虚拟内存

c++ - 在不同的着色器中使用相同的常量缓冲区

c++ - 绑定(bind) Texture2D 和 TextureCube

图像的 C# .net Core 圆角

c# - 为什么 ConcurrentDictionary.GetOrAdd(key, valueFactory) 允许 valueFactory 被调用两次?

c# - WebSecurity.IsAuthenticated 如何检查您是否已登录?

c# - int 或 long 变量类型以实现长期可扩展性

java - Logstash 加载错误

c++ - 一种在没有光线转换和多个目标的情况下使用 3D 寻路的方法

python - 在Windows Anaconda2上安装Tensorflow