【问题标题】:Why does EnumerateMetafile only work with Aero enabled为什么 EnumerateMetafile 仅适用于启用 Aero
【发布时间】:2014-09-23 03:51:46
【问题描述】:

我的代码enumerates一个元文件:

private void Parse()
{
    Graphics graphics = Graphics.FromHwnd(IntPtr.Zero);
    PointF pointf = new PointF();
    graphics.EnumerateMetafile(_metafile, pointf, ParseCallback);
}

private bool ParseCallback(EmfPlusRecordType recordType, 
    int flags, int dataSize, IntPtr data, PlayRecordCallback callbackData)
{
    // do stuff
}

我的开发机器是 Ubuntu 主机上的 Windows 7 VirtualBox guest。

以前的代码可以正常工作。但是,当我关闭 Aero 时,代码停止工作:永远不会调用 ParseCallback

只有当我重新打开 Aero 时,ParseCallback 才会再次执行。

为什么以及如何使此代码在不支持 Aero 的机器上运行?

【问题讨论】:

  • 这是一个非常晦涩的问题。您肯定必须将该元文件提供给任何人,以便有机会诊断问题。
  • 各种 EMF+ 文件都会出现问题。这是一条(一条简单的对角线):xltoolbox.sf.net/files/test.emf -- 但你是对的,问题很模糊,我开始认为我宁愿实现自己的元文件阅读器来枚举记录。
  • 我建议将 graphics.Dispose() 添加到 Parse 方法的末尾,但我怀疑它是否是主要问题。
  • @Aron 不错!但事实上,我故意决定不启用 Aero——我不喜欢 Glass 设计。另外,我想我在虚拟机上执行pc.Install(GeForce.FromStore()); 会有困难;-)
  • @bovender 你的意思是pc.Install(nVidiaFactory.BuildLatestGfxCard());

标签: c# gdi+ system.drawing.imaging


【解决方案1】:

对于“为什么?”,我没有完整的答案。问题,但它不起作用,因为您从 Window 句柄获取 Graphics GDI+ 对象。相反,您想从 GDI DC 中获取它,如下所示:

private void Parse()
{
    IntPtr hdc = GetDC(IntPtr.Zero); // get entire screen dc
    Graphics graphics = Graphics.FromHdc(hdc));
    PointF pointf = new PointF();
    graphics.EnumerateMetafile(_metafile, pointf, ParseCallback);
    ReleaseDC(IntPtr.Zero, hdc);
}

[DllImport("user32.dll")]
static extern IntPtr GetDC(IntPtr hWnd);

[DllImport("user32.dll")]
static extern IntPtr ReleaseDC(IntPtr hwnd, IntPtr hdc);

请注意,您也可以使用 Form OnPaint(PaintEventArgs e) 方法中的 Graphics 对象,它应该也可以工作,就像此处 EnumerateMetafile 方法的官方示例代码中一样:Graphics.EnumerateMetafile Method

【讨论】:

    猜你喜欢
    • 2011-11-18
    • 2016-01-23
    • 1970-01-01
    • 2012-03-23
    • 2011-10-18
    • 1970-01-01
    • 2018-03-03
    • 1970-01-01
    • 2022-08-19
    相关资源
    最近更新 更多