我想注册一个DirectWrite的(Windows 7中的Windows 8)基于API的字体文件加载程序,并在Delphi中,重新从Windows 7 SDK CustomFont的演示 ,演示如何使用DirectWrite
API的使用自定义的字体集合。 这使得DirectWrite的使用你从内未在全球范围内Windows字体系统注册的应用程序资源加载自己的字体。 我坚持访问冲突。 一个最小的样品如下。
首先一个疑问我对德尔福的Direct2D界面,船舶XE6。 在Delphi单元Winapi.D2D1是IDWriteFactory
类型。 一个特定的接口方法可以让你注册一个字体文件加载程序: RegisterFontFileLoader
IDWriteFactory = interface(IUnknown)
[SID_IDWriteFactory]
....
function RegisterFontFileLoader(
var fontFileLoader: IDWriteFontFileLoader): HResult; stdcall;
....
end;
在这个比较对C ++的Direct2D头,我发现自己想知道如果上述被正确翻译。 下面是C / C ++的Direct2D头(dwrite.h)当量:
interface DWRITE_DECLARE_INTERFACE("b859ee5a-d838-4b5b-a2e8-1adc7d93db48") IDWriteFactory : public IUnknown
{ ...
STDMETHOD(RegisterFontFileLoader)(
IDWriteFontFileLoader* fontFileLoader
) PURE;
...
}
请注意,在普通的C ++你不类型的变量工作“IDWriteFontFileLoader fontFileLoader”,接口引用的类型是“IDWriteFontFileLoader *”。 因此,我质疑的适用性var
在上面的接口关键字。
这里是一个内部崩溃我的示例代码dwrite.dll
访问冲突。 我做得显然是错误的吗? 该TLoader对象是平凡的,它是一个TInterfacedObject,我创建它,可是,我不能注册的对象。 我怀疑这个方法的单一参数不正确传递中,我不知道如果我做错了事,或者如果我发现在德尔福RTL的Direct2D的包装代码中的错误。
unit DirectWriteBugMain;
interface
uses
WinApi.Windows,
System.Types,
Vcl.Direct2D,
WinAPI.D2D1,
System.SysUtils;
type
TLoader =class(TInterfacedObject,IDWriteFontFileLoader)
function CreateStreamFromKey(
fontFileReferenceKey: Pointer;
fontFileReferenceKeySize: Cardinal;
out fontFileStream: IDWriteFontFileStream): HResult; stdcall;
end;
procedure main; { called from dpr, in a console app }
implementation
function TLoader.CreateStreamFromKey(
fontFileReferenceKey: Pointer;
fontFileReferenceKeySize: Cardinal;
out fontFileStream: IDWriteFontFileStream): HResult; stdcall;
begin
fontFileStream := nil;
result := E_FAIL;
end;
procedure main;
var
Loader:IDWriteFontFileLoader;
begin
try
Loader := TLoader.Create as IDWriteFontFileLoader;
DWriteFactory.RegisterFontFileLoader( Loader);
except
on E: Exception do
begin
Writeln(E.ClassName, ': ', E.Message);
ReadLn;
end;
end;
end;
end.
在C ++工作示例在Windows SDK中找到。 上面的代码,在C ++出现在C ++演示,随着工厂的DirectWrite和D2D1厂之后完成的第一件事被创建:
if (FAILED(hr = g_dwriteFactory->RegisterFontFileLoader(ResourceFontFileLoader::GetLoader())))
return hr;
所述ResourceFontFileLoader::GetLoader()
简单地返回一个构造C ++对象投射到接口类型,在通常的C ++方法:
class ResourceFontFileLoader : public IDWriteFontFileLoader
{
public:
ResourceFontFileLoader() : refCount_(0)
{
}
// IUnknown methods
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject);
virtual ULONG STDMETHODCALLTYPE AddRef();
virtual ULONG STDMETHODCALLTYPE Release();
// IDWriteFontFileLoader methods
virtual HRESULT STDMETHODCALLTYPE CreateStreamFromKey(
void const* fontFileReferenceKey, // [fontFileReferenceKeySize] in bytes
UINT32 fontFileReferenceKeySize,
OUT IDWriteFontFileStream** fontFileStream
);
// Gets the singleton loader instance.
static IDWriteFontFileLoader* GetLoader()
{
return instance_;
}
...
}
上面的代码手动C ++实现的IUnknown,而我的代码使用的Delphi TInterfacedObject
其干净地实现的IUnknown。 只有一个在接口IDWriteFontFileLoader方法,CreateStreamFromKey方法,并且它不是在当注册发生C ++演示调用,因此实际的代码就不可能是一个因素,仅调用约定,堆栈和先决条件状态或用于DirectWrite的出厂设置步骤似乎是可能的原因。