dhtmledit不支持此接口错误的解决办法

DHTMLEdit是MS多年来提供的一个HTML编辑器,随着IE的蔓延而到处传播,基本上IE5以上就已经有了,作为一个activex,delphi也支持它。自从SP2以后,DHTMLEdit被打上了补丁,delphi却没有相应地更新接口,就产生了错误。安装和一般使用都没问题,只是一用到DOM的时候就出错了。Get_DOM是一个重要的函数,出错的原因是TOleControl必须要有IOleContainer的接口。

有两种方法解决这个问题:

1.TOleControl实现接口IOleContainer。

2.TOleControl.GetContainer中增加语句,使用IOleContainer。

第一种方法的实现:直接将TOleControl加上接口IOleContainer。

将...\Borland\Delphi6\Imports目录下olectrls.pas拷贝到项目文件夹下

modify the
TOleControl definition - add interface IOleContainer - should
look
something like this:

TOleControl = class(TWinControl, IUnknown,
IOleClientSite,
IOleControlSite, IOleInPlaceSite, IOleInPlaceFrame,
IDispatch,
IPropertyNotifySink, ISimpleFrameSite, IOleContainer)  //增加iolecontainer

Add
the following to the protected section of //增加定义
TOleControl

//IOleContainer
function EnumObjects(grfFlags: Longint;
out Enum: IEnumUnknown):
HResult; stdcall;
function LockContainer(fLock:
BOOL): HResult; stdcall;
function ParseDisplayName(const bc: IBindCtx;
pszDisplayName:
POleStr; out chEaten: Longint; out mkOut: IMoniker): HResult;
stdcall;

and the corresponding implementation   //添加实现过程

function
TOleControl.EnumObjects(grfFlags: Integer;
out Enum: IEnumUnknown):
HResult;
begin
Result := E_NOTIMPL;
end;

function
TOleControl.LockContainer(fLock: BOOL): HResult;
begin
Result :=
E_NOTIMPL;
end;

function TOleControl.ParseDisplayName(const bc:
IBindCtx;
pszDisplayName: POleStr; out chEaten: Integer;
out mkOut:
IMoniker): HResult;
begin
Result := E_NOTIMPL;
end;


finally
change TOleControl.GetContainer to//找到Getcontainer修改实现

function TOleControl.GetContainer(out
container: IOleContainer):
HResult;
begin
container:= Self;
Result:=
S_OK;
end;


 

第二种方法:创建一个类实现IOleContainer,然后在TOleControl.GetContainer中使用这个类。

//Create a class with IOleContainer
interface
TImpIOleContainer = class(TObject,
IOleContainer)
private
m_cRef: UINT;
protected
{ IUnknown
}
function QueryInterface(const IID: TGUID; out Obj): HResult;
stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer;
stdcall;
public
{ IOleContainer }
function ParseDisplayName(const bc:
IBindCtx; pszDisplayName: POleStr;
out chEaten: Longint; out mkOut:
IMoniker): HResult; stdcall;
function EnumObjects(grfFlags: Longint; out
Enum: IEnumUnknown):
HResult;
stdcall;
function LockContainer(fLock:
BOOL): HResult; stdcall;
constructor Create;
destructor Destroy;
override;
end;
//=======

{ TImpIOleContainer }

function
TImpIOleContainer._AddRef: Integer;
begin
inc(m_cRef);
Result :=
m_cRef;
end;

function TImpIOleContainer._Release:
Integer;
begin
Dec(m_cRef);
Result := m_cRef;
if m_cRef = 0
then
Free;
end;

function TImpIOleContainer.EnumObjects(grfFlags:
Integer;
out Enum: IEnumUnknown): HResult;
begin
Result :=
E_NOTIMPL;
end;

function TImpIOleContainer.LockContainer(fLock: BOOL):
HResult;
begin
Result := E_NOTIMPL;
end;

function
TImpIOleContainer.ParseDisplayName(const bc: IBindCtx;
pszDisplayName:
POleStr; out chEaten: Integer;
out mkOut: IMoniker):
HResult;
begin
Result := E_NOTIMPL;
end;

function
TImpIOleContainer.QueryInterface(const IID: TGUID; out
Obj):
HResult;
const
IID_IUnknown : TGUID = (
D1: $00000000; D2:
$0000; D3: $0000; D4: ($C0, $00, $00, $00, $00, $00,
$00,
$46));
IID_IOleContainer : TGUID = (
D1: $0000011B; D2: $0000; D3: $0000;
D4: ($C0, $00, $00, $00, $00, $00,
$00, $46));
begin
if
GetInterface(IID, Obj) then begin
Result := S_OK;
Exit;
end;
if
(Guidtostring(IID_IUnknown) = Guidtostring(IID))
or
(Guidtostring(IID_IOleContainer) = Guidtostring(IID)) then
begin
IOleContainer(Obj) := Self;
Result :=
S_OK;
self._AddRef;
end;
end;

//========= modify
TOleControl.GetContainer

function TOleControl.GetContainer(out container:
IOleContainer):
HResult;
const
IID_IOleContainer : TGUID = (
D1:
$0000011B; D2: $0000; D3: $0000; D4: ($C0, $00, $00, $00, $00, $00,
$00,
$46));
var
aCntr : TImpIOleContainer;
begin
aCntr :=
TImpIOleContainer.Create;
Result := aCntr.QueryInterface(IID_IOleContainer,
container);
end;

如果不想修改,可以下载https://files.cnblogs.com/wppt/DHTML.rar

原文地址:https://www.cnblogs.com/wppt/p/487145.html