微软补丁kb891781 导致的Delphi编写的程序调用DHTMLED.OCX 出错问题的解决
1。打开OleCtrls.pas,新建类 TImpIOleContainer
//IOleContainer//
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 } //IOleContainer//
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;
constructor TImpIOleContainer.Create;
begin
inherited;
end;
destructor TImpIOleContainer.Destroy;
begin
inherited;
end;
//================
2。修改TOleControl的GetContainer方法,返回正确的接口:
function TOleControl.GetContainer(out container: IOleContainer): HResult;
{$ifdef DHTMLED}
const
IID_IOleContainer : TGUID = (
D1: $0000011B
D2: $0000
D3: $0000
D4: ($C0, $00, $00, $00, $00, $00, $00, $46));
var
aCntr : TImpIOleContainer;
{$endif}
begin
{$ifdef DHTMLED}
aCntr := TImpIOleContainer.Create;
Result := aCntr.QueryInterface(IID_IOleContainer, container)
{$else}
Result := E_NOTIMPL;
{$endif}
end;
3。加入编译条件是因为修改后用到webbrowser控件时会出错,我后来才发现的。。。