这段代码怎么也过不去了,反反复复找不到原因;有谁知道,万望提醒我一下。
上面是刚碰到错误时的求助信息;现在终于找到错误了:是 D2D1.pas 的代码有问题,修改方法如下:
{ 1、把 D2D1.pas 中 4142 行中的 var 修改为 const 或者去掉 } function SetInlineObject(var inlineObject: IDWriteInlineObject; textRange: TDwriteTextRange): HResult; stdcall; { 2、重新编译 Direct2D.pas、D2D1.pas,最好在 Debug 和 Release 两种模式下分别编译 } { 3、把编译后的相关 dcu 分别覆盖到 \Program Files\Embarcadero\RAD Studio\8.0\lib\win32\ 的相应目录下 }
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Direct2D, D2D1, Wincodec, ActiveX; type TForm1 = class(TForm) procedure FormPaint(Sender: TObject); procedure FormResize(Sender: TObject); end; {实现 IDWriteInlineObject 的类} TDWriteInlineObject = class(TInterfacedObject, IDWriteInlineObject) private FRenderTarge: ID2D1RenderTarget; FBitmap: ID2D1Bitmap; public constructor Create(ARenderTarge: ID2D1RenderTarget; ABitmap: ID2D1Bitmap); function Draw(clientDrawingContext: Pointer; var renderer: IDWriteTextRenderer; originX: Single; originY: Single; isSideways: LongBool; isRightToLeft: LongBool; const clientDrawingEffect: IInterface): HRESULT; stdcall; function GetMetrics(var metrics: DWRITE_INLINE_OBJECT_METRICS): HRESULT; stdcall; function GetOverhangMetrics(var overhangs: DWRITE_OVERHANG_METRICS): HRESULT; stdcall; function GetBreakConditions(var breakConditionBefore: DWRITE_BREAK_CONDITION; var breakConditionAfter: DWRITE_BREAK_CONDITION): HRESULT; stdcall; end; var Form1: TForm1; implementation {$R *.dfm} {从指定文件建立 ID2D1Bitmap 的函数} function GetD2D1Bitmap(RenderTarget: ID2D1RenderTarget; imgPath: string): ID2D1Bitmap; var iWicFactory: IWICImagingFactory; iWICDecoder: IWICBitmapDecoder; iWICFrameDecode: IWICBitmapFrameDecode; iFormatConverter: IWICFormatConverter; begin CoCreateInstance(CLSID_WICImagingFactory, nil, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, iWicFactory); iWicFactory.CreateDecoderFromFilename(PWideChar(imgPath), GUID_NULL, GENERIC_READ, WICDecodeMetadataCacheOnLoad, iWICDecoder); iWicDecoder.GetFrame(0, iWICFrameDecode); iWicFactory.CreateFormatConverter(iFormatConverter); iFormatConverter.Initialize(iWICFrameDecode, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, nil, 0, WICBitmapPaletteTypeMedianCut); RenderTarget.CreateBitmapFromWicBitmap(iFormatConverter, nil, Result); end; {构建 DWRITE_TEXT_RANGE 结构的函数} function DWriteTextRange(pos,len: Cardinal): TDwriteTextRange; begin Result.startPosition := pos; Result.length := len; end; procedure TForm1.FormPaint(Sender: TObject); var cvs: TDirect2DCanvas; str: string; iTextFormat: IDWriteTextFormat; iTextLayout: IDWriteTextLayout; iInlineObject: IDWriteInlineObject; iBitmap: ID2D1Bitmap; iBrush: ID2D1SolidColorBrush; begin str := 'Inline Object * Example'; DWriteFactory.CreateTextFormat( 'Gabriola', nil, DWRITE_FONT_WEIGHT_REGULAR, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, 72.0, 'en-us', iTextFormat ); iTextFormat.SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER); iTextFormat.SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER); DWriteFactory.CreateTextLayout( PWideChar(str), Length(str), iTextFormat, ClientWidth, ClientHeight, iTextLayout ); cvs := TDirect2DCanvas.Create(Canvas, ClientRect); cvs.RenderTarget.BeginDraw; cvs.RenderTarget.Clear(D2D1ColorF(clWhite)); iBitmap := GetD2D1Bitmap(cvs.RenderTarget, 'C:\Temp\Test.jpg'); iInlineObject := TDWriteInlineObject.Create(cvs.RenderTarget, iBitmap); // DWriteFactory.CreateEllipsisTrimmingSign(iTextLayout, iInlineObject); //使用这行代码可以生成表示 "..." 符号的 IDWriteInlineObject iTextLayout.SetInlineObject(iInlineObject, DWriteTextRange(14, 1)); {!!!} cvs.RenderTarget.CreateSolidColorBrush(D2D1ColorF(clBlack), nil, iBrush); cvs.RenderTarget.DrawTextLayout(D2D1PointF(0,0), iTextLayout, iBrush); cvs.RenderTarget.EndDraw(); cvs.Free; end; procedure TForm1.FormResize(Sender: TObject); begin Repaint; end; { TDWriteInlineObject } constructor TDWriteInlineObject.Create(ARenderTarge: ID2D1RenderTarget; ABitmap: ID2D1Bitmap); begin inherited Create; FRenderTarge := ARenderTarge; FBitmap := ABitmap; end; function TDWriteInlineObject.Draw(clientDrawingContext: Pointer; var renderer: IDWriteTextRenderer; originX, originY: Single; isSideways, isRightToLeft: LongBool; const clientDrawingEffect: IInterface): HRESULT; var rSizeF: TD2DSizeF; rRectF: TD2DRectF; begin FBitmap.GetSize(rSizeF); rRectF := D2D1RectF(originX, originY, originX+rSizeF.width, originY+rSizeF.height); FRenderTarge.DrawBitmap(FBitmap, @rRectF); Result := S_OK; end; function TDWriteInlineObject.GetBreakConditions(var breakConditionBefore, breakConditionAfter: DWRITE_BREAK_CONDITION): HRESULT; begin breakConditionBefore := DWRITE_BREAK_CONDITION_NEUTRAL; breakConditionAfter := DWRITE_BREAK_CONDITION_NEUTRAL; Result := S_OK; end; function TDWriteInlineObject.GetMetrics(var metrics: DWRITE_INLINE_OBJECT_METRICS): HRESULT; var rSizeF: TD2DSizeF; begin FBitmap.GetSize(rSizeF); metrics.width := rSizeF.width; metrics.height := rSizeF.height; metrics.baseline := rSizeF.height; Result := S_OK; end; function TDWriteInlineObject.GetOverhangMetrics(var overhangs: DWRITE_OVERHANG_METRICS): HRESULT; begin overhangs.left := 0; overhangs.top := 0; overhangs.right := 0; overhangs.bottom := 0; Result := S_OK; end; end.
效果图: