5

在我的程序中,我需要“播放”或“解析”窗口元文件(WMF 和 EMF)。我已经通过 MSDN 和 Google 进行了挖掘,最接近的是 Graphics。枚举元文件方法。我可以让它工作,因为我的 EnumerateMetafileProc 回调被调用,然后我可以调用 PlayRecord。缺少的是如何从回调中获取有用的数据。

我查看的示例:http: //msdn.microsoft.com/en-us/library/ms142060.aspx

回调有一个recordType 参数,它是一个ENUM。好吧,这看起来很有用,除了它们似乎无法将数据转换为任何有用的类型。

我的目标是回放 WMF/EMF 的创建过程,以便我可以对具有 (DrawLine、DrawPoint、DrawArc) 等方法的专用图形类进行函数调用。从某种意义上说,我正在以完全不同的格式(转换)重新创建 WMF/EMF 绘图。

非常感谢您对此的任何帮助。

4

2 回答 2

10

不幸的是, Graphics.EnumerateMetafile是围绕 Win32 API 的一个非常非常薄的层。对于 EMF 中的每条记录,您都会获得特定于记录的结构的非托管内存地址。没有关于它可能包含什么的文档——但是,在 Win32 世界中也没有什么可做的。

所以你需要查阅古籍!

本书附带一个代码示例 CD-ROM,其中包含使用 EMF 播放 API 的示例程序。

这给你留下了两个问题。

  1. 这本书显然已经绝版,因此请确保您购买的任何二手副本都包含一张工作 CD-ROM。

  2. 示例代码全部采用 C/C++ 语言,为用于描述所有 EMF 记录的 100 个左右的结构声明必要的互操作将是一项不平凡的任务。

因此,另一种方法可能是在 .NET 中声明一个巨大的接口,该接口为您需要拦截的每个 GDI 调用提供一个方法,然后使用 C++/CLI 调整示例 C++ 代码,以便它调用每个记录的巨大接口。

更新

尽管 EMF 播放的 MSDN 文档不包含特定 EMF 记录的详细信息,但 Microsoft 已单独发布了截至 2006 年的完整规范:

MS-EMF:增强的元文件格式

我上面链接的书的作者也提供了 CDROM 示例的源代码可供下载:

Windows 图形编程的源代码

于 2010-02-02T12:42:05.573 回答
3

查看这个库:http ://wmf.codeplex.com/

想法是循环遍历WMF记录并将形状,画笔等转换为其他格式

WmfDocument wmf = new WmfDocument();
wmf.Load(path);

foreach (var record in wmf.Records)
{
  if (record is WmfCreateBrushIndirectRecord)
  {
    var brush = record as WmfCreateBrushIndirectRecord;
    Console.WriteLine("Color: " + brush.Color);
    Console.WriteLine("Style: " + brush.Style);
    Console.WriteLine("Hatch: " + brush.Hatch);
    //Do something with brush here...
  }
  else if (record is WmfRectangleRecord)
  {
    var rectangle = record as WmfRectangleRecord;
    //Do something with rectangle...
  }
  else if ... //Other shapes to be implemented
}
于 2012-03-04T18:56:32.180 回答