Win32: 如何确定是否启用了DirectDraw?

5
在使用GDIPlus中的CachedBitmaps时,如果Windows视频的“硬件加速”降低得太多(例如禁用了DirectDraw),则会出现图形损坏。

enter image description here

硬件加速有六个级别:

  • 禁用所有加速
  • 禁用除基本加速外的所有加速。(服务器上的默认设置)
  • 禁用所有DirectDraw和Direct3D加速,以及所有光标和高级加速
  • 禁用所有光标和高级绘图加速
  • 禁用光标和位图加速
  • 启用所有加速(桌面机器上的默认设置)

如果禁用了DirectDraw,则在GDI+中使用DrawCachedBitmap将导致图形损坏。如果DirectDraw未启用,我可以很容易地使用更慢的DrawImage() API - 但我必须能够检测DirectDraw是否已禁用。

如何通过编程方式检查DirectDraw是否已启用?


问题是:dxdiag 是如何做到这一点的:

alt text

另请参阅

KB191660 - DirectDraw或Direct3D选项不可用 (档案)


我实际上并没有使用DirectDraw,所以如果它被禁用,我不会受到影响。另一方面,我无法决定GDIPlus使用的底层技术。而我之所以说“Direct Draw”,只是因为首先引起问题的滑块选项提到了“DirectDraw和Direct3D”,我假设GDI+没有使用Direct3D,只剩下DirectDraw。 - Ian Boyd
听起来像是视频驱动程序的错误。此外,微软可能还没有为这样的事情制定官方API。如果您想要一个不太正式的解决方案,请使用Procmon来识别用于存储此设置的注册表键。 - SteelBytes
1
@steelbytes 如果这是一个驱动程序的错误,那么它存在于每个操作系统的每个视频卡驱动程序中。 - Ian Boyd
看起来Stackoverflow将强制接受一个不正确的答案。当我复制问题时,我会更新问题并附上链接。 - Ian Boyd
1
它不会强制执行,只会授予悬赏(仅限于获得2个或更多赞的答案)。对我们所有答案进行负投票是相当无聊的。我们在这里尝试帮助您,我们提供的所有信息都是“有用”的。祝好运。 - rwilliams
显示剩余2条评论
3个回答

4
如果你下载最新的DirectX SDK(我相信旧版本的sdk也有类似的例子),就会发现一个查询DXDIAG信息的例子。
这个例子位于(SDK根目录)\Samples\C++\Misc\DxDiagReport。
在dxdiaginfo.cpp中,有一些值得注意的方法。
CDxDiagInfo::CDxDiagInfo
CDxDiagInfo::Init
CDxDiagInfo::QueryDxDiagViaDll    
CDxDiagInfo::GetDisplayInfo

如果运行程序,它会输出一个巨大的值列表。我认为你感兴趣的值是pDisplayInfo->m_szDDStatusEnglish

很不幸,需要CLSID_DxDiagProvider类在Windows 2000上不可用。同样,IID_IDxDiagProvider在收集信息方面非常缓慢 - 不适用于生产代码。 - Ian Boyd
DXDIAG也不是立即启动的。如果您想要有文档记录,那就得到了。 (如果您想支持Windows 2000,则应使用上面的DDraw方法,因为Win2K的DX支持上限肯定包括DDraw作为其中一部分。如果没有DXDIAG支持,可能仍然可以尝试它,反正DDraw还会存在一段时间。) - please delete me
好的,GDI+仍然依赖于ddraw,后者是WinForms的基础。 - Ian Boyd

0
你可以查询 IDirectDraw 接口 并查看它的功能。我假设如果硬件加速被关闭,它将会失败,但是你可能想测试 GetCaps() 或 TestCooperativeLevel()。
LPDIRECTDRAW lpdd7 = NULL; // DirectDraw 7.0

// first initialize COM, this will load the COM libraries
// if they aren't already loaded
if (FAILED(CoInitialize(NULL)))
   {
   // error
   } // end if

// Create the DirectDraw object by using the
// CoCreateInstance() function
if (FAILED(CoCreateInstance(&CLSID_DirectDraw,
                         NULL, CLSCTX_ALL,
                         &IID_IDirectDraw7,
                         &lpdd7)))
   {
   // error
   }


// now before using the DirectDraw object, it must
// be initialized using the initialize method

if (FAILED(IDirectDraw7_Initialize(lpdd7, NULL)))
{
    // error
}

lpdd7->Release();
lpdd7 = NULL; // set to NULL for safety

// now that we're done with COM, uninitialize it
CoUninitialize();

很遗憾,DirectDraw文档不再包含在SDK中。您可能需要旧版本才能获取示例和头文件。


调用IDirectDraw.Initialize始终失败,无论滑块是否被调低。由于没有文档,我无法确定Initialize方法的用途。另外,由于DirectDraw不再有文档,因此此答案定义上不是检查直接绘制是否可用的文档方式。 - Ian Boyd
DDraw在最新的DirectX SDK中仍然可以正常使用;提供了完整的库和头文件集合,包括x64版本。(尽管您可能希望从C/C++中使用它。)它不会很快消失,就像Windows API的任何其他部分一样。这几乎肯定是正确的答案,我敢打赌这就是DXDIAG所做的,然后检查DDCAPS_NOHARDWARE标志 - 尽管我没有使用IDA Pro进行检查。(附言:http://www.megaupload.com/?d=Y01BRYFX - 快点下载吧。) - please delete me
我编辑时间用完了。我的意思是,如果你确定检查DirectDraw加速的可用性是正确的检查方式,那么这几乎肯定是正确的答案。(也就是说,你确定对话框没有调整其他设置。) - please delete me

0
你可以检查注册表以获取加速滑块的值。
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Video\{'some hex string'}\0000\Acceleration.Level

你可能需要循环遍历Video中的所有文件夹,因为通常会有多个条目。

Acceleration.Level 值

  • 5 禁用所有加速
  • 4 禁用所有但基本加速。(服务器机器上的默认设置)
  • 3 禁用所有 DirectDraw 和 Direct3D 加速,以及所有光标和高级加速
  • 2 禁用所有光标和高级绘图加速
  • 1 禁用光标和位图加速
  • 0 所有加速都启用(桌面机器上的默认设置)

更新:

这是一个关于程序化更改/检查加速级别的旧线程。 http://www.autoitscript.com/forum/topic/61185-hardware-acceleration/


我猜一个真正的答案必须解释一下滑块的作用。 滑块完全不意味着启用了DirectDraw。 而最小化也不意味着DirectDraw一定被禁用。 - Ian Boyd
Windows 7,在那里没有滑块。 - Ian Boyd
@Ian Boyd:没有滑块是因为你的显示驱动程序正在覆盖它。注册表值仍然准确。我在Windows 7上测试得到了这些信息。 - rwilliams

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接