【发布时间】:2015-03-21 08:51:56
【问题描述】:
如何在继承其他接口的类中实现IServiceProvider,以便实际调用它们的方法?现在我总是从QueryInterface 得到E_NOINTERFACE。
TPassthrough = class(TComObject, IInternetProtocolRoot, IInternetProtocolSink, IInternetProtocol, IServiceProvider)
private
FDefaultSink: IInternetProtocol;
FProtSink: IInternetProtocolSink;
FBindInfo: IInternetBindInfo;
public
{ IServiceProvider }
function QueryService(const rsid, iid: TGuid; out Obj): HResult; stdcall;
{ IInternetProtocolSink }
function Switch(const ProtocolData: TProtocolData): HResult; stdcall;
function ReportProgress(ulStatusCode: ULONG; szStatusText: LPCWSTR): HResult; stdcall;
function ReportData(grfBSCF: DWORD; ulProgress, ulProgressMax: ULONG): HResult; stdcall;
function ReportResult(hrResult: HResult; dwError: DWORD; szResult: LPCWSTR): HResult; stdcall;
{ IInternetProtocolRoot }
function Start(szUrl: LPCWSTR; OIProtSink: IInternetProtocolSink; OIBindInfo: IInternetBindInfo; grfPI, dwReserved: DWORD): HResult; stdcall;
function Continue(const ProtocolData: TProtocolData): HResult; overload; stdcall;
function Abort(hrReason: HResult; dwOptions: DWORD): HResult; stdcall;
function Terminate(dwOptions: DWORD): HResult; stdcall;
function Suspend: HResult; stdcall;
function Resume: HResult; stdcall;
{ IInternetProtocol }
function Read(pv: Pointer; cb: ULONG; out cbRead: ULONG): HResult; stdcall;
function Seek(dlibMove: LARGE_INTEGER; dwOrigin: DWORD; out libNewPosition: ULARGE_INTEGER): HResult; stdcall;
function LockRequest(dwOptions: DWORD): HResult; stdcall;
function UnlockRequest: HResult; stdcall;
end;
...
function TPassthrough.Start(szUrl: LPCWSTR; OIProtSink: IInternetProtocolSink; OIBindInfo: IInternetBindInfo; grfPI, dwReserved: DWORD): HResult; stdcall;
begin
if (FDefaultSink = nil) then
OleCheck(CoCreateInstance(CLSID_HttpProtocol, nil, CLSCTX_INPROC_SERVER, IUnknown, FDefaultSink));
FBindInfo := OIBindInfo;
FProtSink := OIProtSink;
if (Assigned(FDefaultSink)) then
Result := (FDefaultSink as IInternetProtocolRoot).Start(szUrl, Self, Self, grfPI, dwReserved)
else
Result := E_NOTIMPL;
end;
function TPassthrough.QueryService(const rsid, iid: TGuid; out Obj): HResult; stdcall;
begin
Result := E_NOINTERFACE;
Pointer(Obj) := nil;
if Succeeded(QueryInterface(rsid, Obj)) and
Assigned(Pointer(Obj))
then
Result := S_OK;
end;
【问题讨论】:
-
很难看出
TPassthrough.QueryInterface无法返回接口。您确定在正确的对象上调用了QI吗? -
谁调用QueryService?你的其他部分代码还是外部代码?愚蠢的问题,但你确定 QueryService 的 rsid (iid) 参数等于 IID_IInternetProtocolRoot 或 IID_IInternetProtocolSink 或 IID_IInternetProtocol?
-
您没有显示相关代码。我认为我们可以假设
QI有效。要么您在错误的对象上调用QI,要么传递了错误的 IID。
标签: delphi com bho delphi-xe7 urlmon