如何从TOleContainer中提取元文件?

4
我有一个使用TOleContainer控件的Delphi(BDS 2006)应用程序。它内部包含一个OLE对象,即来自MS Office 2003的MS Equation公式(名称为“Equation.3”)。
我该如何从公式图像中提取矢量元文件,以便在没有OLE支持的情况下将其插入到Web页面或其他文档中?
TOleContainer仅包含'Equation.3'对象,没有其他可能性。我尝试使用.Copy方法通过剪贴板进行复制,但复制的是一个空白图像。

“没有OLE支持”是什么意思?您已经在使用TOleContainer了,这就是OLE。 - Ondrej Kelle
我的软件可以创建不同类型的文档,其中一些应该在没有OLE支持的其他软件中打开。 - Andrew
2个回答

4

OLE容器有一个底层的IOLEObject接口,您可以访问它。您可以将其传递给OLEDraw函数并使用自己的画布。您可以使用位图或元文件画布,然后以所需格式保存图像。

OleDraw(OleContainer.OleObjectInterface,DVASPECT_CONTENT,Bmp.Canvas.Handle,R);


{
  DrawOleOnBmp
  ---------------------------------------------------------------------------
  Take a OleObject and draw it to a bitmap canvas.  The bitmap will be sized
  to match the normal size of the OLE Object.
}
procedure DrawOleOnBmp(Ole: IOleObject; Bmp: TBitmap);
var
  ViewObject2: IViewObject2;
  ViewSize: TPoint;
  AdjustedSize: TPoint;

  DC: HDC;
  R: TRect;
begin

  if Succeeded(Ole.QueryInterface(IViewObject2, ViewObject2)) then
  begin
    ViewObject2.GetExtent(DVASPECT_CONTENT, -1, nil, ViewSize);

    DC := GetDC(0);
    AdjustedSize.X := MulDiv(ViewSize.X, GetDeviceCaps(DC, LOGPIXELSX), 2540);
    AdjustedSize.Y := MulDiv(ViewSize.Y, GetDeviceCaps(DC, LOGPIXELSY), 2540);
    ReleaseDC(0, DC);

    Bmp.Height := AdjustedSize.Y;
    Bmp.Width := AdjustedSize.X;

    SetRect(R, 0, 0, Bmp.Width, Bmp.Height);

    OleDraw(Ole, DVASPECT_CONTENT, Bmp.Canvas.Handle, R);
  end
  else
  begin
    raise Exception.Create('Could not get the IViewObject2 interfact on the OleObject');
  end;

end;


是的,这个解决方案肯定比SaveAsDocument简单得多。谢谢你,马克。 - Andrew
如果您首先使用纯色(例如白色)填充画布,则还可以使用GR32。只需将TBitmap更改为TBitmap32并将GR32添加到您的uses子句中即可。即使您不使用TBitmap32,也最好使用纯色填充画布,否则OleDraw将简单地将OLEObject的图像数据添加到画布上已有的任何内容中,如下所示:Bmp.FillRect(0, 0, Bmp.Width, Bmp.Height, clWhite); - James L.

3
当您使用OleContainer的SaveAsDocument方法时,将创建一个复合文档。该文档将包含一个IStream,其名称为#2OlePress000(#2是字节值2)。此流的内容是方程式的缓存表示形式,并用于在未安装方程式编辑器的计算机上显示它。
如果您知道该流的格式,也许可以使用它创建一个图像以在网页上显示。

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