Ole控件的事件辅助类
林镇群
<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /><chsdate isrocdate="False" islunardate="False" day="6" month="12" year="2008" w:st="on"><span lang="EN-US"><font color="#000000" size="3">2008-12-6</font></span></chsdate>
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
概述
Delphi对Ole控件作了很好的封装,使用起来要比C++的方便地多,比如想用IE控件,只需要将TWebBrowser拖到窗体上,设置相关属性,处理相关事件,一切和其他控件没有什么区别。
但是使用过程中,我们会发现一个问题,拿TWebBrowser来说,它没有OnNavigateError事件,如果我们想在连接错误的时候做一些事情,比如要用一个更漂亮的网页来代替IE预定义的错误页面,那么似乎是没有办法的了。
出现这个问题的原因是IE控件的版本,越高版本功能越多,比如错误事件是在IE 6才有的,而TWebBrowser显然是用更低版本的IE类型库生成的。解决办法之一是通过更新的类型库生成更新的控件,但这仍然不大方便,如果下一版本的IE提供了更多的事件,你就必须重新生成控件了。
我这里提供了一个更好的办法,无需要生成类型库就可以接收所有的事件。下面就是代码:
代码
(**
*OLE控件的事件辅助类
*
*bylinzhenqun<chsdate isrocdate="False" islunardate="False" day="6" month="12" year="2008" w:st="on">2008-12-6</chsdate>
*)
unitOleCtrlEventHelper;
{
用法:
1、开始时:创建TOleCtrlEventHelper,建立连接点,添加想处理的事件:
FOleCtrlEventHelper:=TOleCtrlEventHelper.Create(DIID_DWebBrowserEvents2);
FOleCtrlEventHelper.EventConnect(Webbrowser.DefaultInterface);
FOleCtrlEventHelper.AddEvent($<chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="10" unitname="F">10F</chmetcnv>,Method(Self,@TMyClass.OnNavigateError));
2、结束时:断开连接点,消毁TOleCtrlEventHelper
FOleCtrlEventHelper.EventDisconnect(Webbrowser.DefaultInterface);
FOleCtrlEventHelper.Free;
---linzhenqun
}
interface
uses
SysUtils,ActiveX,Classes;
type
PEventRec=^TEventRec;
TEventRec=record
DispID:TDispID;
Method:TMethod;
end;
TOleCtrlEventHelper=class(TObject,IUnknown,IDispatch)
private
FEventIID:TGUID;
FEventList:TList;
FEventsConnection:LongInt;
private
procedureClearEvent;
procedureInvokeEvent(DispID:TDispID;varParams:TDispParams);
protected
{IUnknown}
functionQueryInterface(constIID:TGUID;outObj):HResult;stdcall;
function_AddRef:Integer;stdcall;
function_Release:Integer;stdcall;
{IDispatch}
functionGetTypeInfoCount(outCount:Integer):HResult;stdcall;
functionGetTypeInfo(Index,LocaleID:Integer;outTypeInfo):HResult;stdcall;
functionGetIDsOfNames(constIID:TGUID;Names:Pointer;
NameCount,LocaleID:Integer;DispIDs:Pointer):HResult;stdcall;
functionInvoke(DispID:Integer;constIID:TGUID;LocaleID:Integer;
Flags:Word;varParams;VarResult,ExcepInfo,ArgErr:Pointer):HResult;stdcall;
public
constructorCreate(constEventIID:TGUID);
destructorDestroy;override;
functionAddEvent(DispID:TDispID;constMethod:TMethod):Boolean;
functionRemoveEvent(DispID:TDispID):Boolean;
functionGetEvent(DispID:TDispID;varMethod:TMethod):Boolean;
procedureEventConnect(Source:IInterface);
procedureEventDisconnect(Source:IInterface);
end;
functionMethod(Data,Code:Pointer):TMethod;
implementation
uses
ComObj;
functionMethod(Data,Code:Pointer):TMethod;
begin
Result.Code:=Code;
Result.Data:=Data;
end;
{TOleCtrlEventHelper}
functionTOleCtrlEventHelper.AddEvent(DispID:TDispID;constMethod:TMethod):Boolean;
var
M:TMethod;
EventRec:PEventRec;
begin
Result:=False;
ifnotGetEvent(DispID,M)then
begin
New(EventRec);
EventRec^.DispID:=DispID;
EventRec^.Method:=Method;
FEventList.Add(EventRec);
Result:=True;
end;
end;
procedureTOleCtrlEventHelper.ClearEvent;
var
i:Integer;
begin
fori:=0toFEventList.Count-1do
Dispose(FEventList.Items[i]);
FEventList.Clear;
end;
constructorTOleCtrlEventHelper.Create(constEventIID:TGUID);
begin
FEventIID:=EventIID;
FEventList:=TList.Create;
end;
destructorTOleCtrlEventHelper.Destroy;
begin
ClearEvent;
FEventList.Free;
inherited;
end;
procedureTOleCtrlEventHelper.EventConnect(Source:IInterface);
begin
InterfaceConnect(Source,FEventIID,Self,FEventsConnection);
end;
procedureTOleCtrlEventHelper.EventDisconnect(Source:IInterface);
begin
InterfaceDisconnect(Source,FEventIID,FEventsConnection);
end;
functionTOleCtrlEventHelper.GetEvent(DispID:TDispID;varMethod:TMethod):Boolean;
var
i:Integer;
EventRec:PEventRec;
begin
Result:=False;
fori:=FEventList.Count-1downto0do
begin
EventRec:=PEventRec(FEventList[i]);
ifEventRec^.DispID=DispIDthen
begin
Method:=EventRec^.Method;
Result:=True;
Break;
end;
end;
end;
functionTOleCtrlEventHelper.GetIDsOfNames(constIID:TGUID;Names:Pointer;
NameCount,LocaleID:Integer;DispIDs:Pointer):HResult;
begin
Result:=E_NOTIMPL;
end;
functionTOleCtrlEventHelper.GetTypeInfo(Index,LocaleID:Integer;
outTypeInfo):HResult;
begin
Pointer(TypeInfo):=nil;
Result:=E_NOTIMPL;
end;
functionTOleCtrlEventHelper.GetTypeInfoCount(outCount:Integer):HResult;
begin
Count:=0;
Result:=S_OK;
end;
functionTOleCtrlEventHelper.Invoke(DispID:Integer;constIID:TGUID;
LocaleID:Integer;Flags:Word;varParams;VarResult,ExcepInfo,
ArgErr:Pointer):HResult;
begin
ifnot((DispID>=DISPID_MOUSEUP)and(DispID<=DISPID_CLICK))then
InvokeEvent(DispID,TDispParams(Params));
Result:=S_OK;
end;
procedureTOleCtrlEventHelper.InvokeEvent(DispID:TDispID;
varParams:TDispParams);
var
EventMethod:TMethod;
begin
ifnotGetEvent(DispID,EventMethod)or
(Integer(EventMethod.Code)<$10000)thenExit;
//copyfromolectrls.pas:TOleControl.InvokeEvent
try
asm
PUSHEBX
PUSHESI
MOVESI,Params
MOVEBX,[ESI].TDispParams.cArgs
TESTEBX,EBX
JZ@@7
MOVESI,[ESI].TDispParams.rgvarg
MOVEAX,EBX
SHLEAX,4//count*sizeof(TVarArg)
XOREDX,EDX
ADDESI,EAX//EDI=Params.rgvarg^[ArgCount]
@@1:SUBESI,16//Sizeof(TVarArg)
MOVEAX,dwordptr[ESI]
CMPAX,varSingle//4bytestopush
JA@@3
JE@@5
@@2:TESTDL,DL
JNE@@<chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="2" unitname="a"><span lang="EN-US" style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt">2</span><span lang="EN-US" style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt">a</span></chmetcnv>
MOVECX,ESI
INCDL
TESTEAX,varArray
JNZ@@6
MOVECX,dwordptr[ESI+8]
JMP@@6
@@<chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="2" unitname="a"><span lang="EN-US" style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt">2</span><span lang="EN-US" style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt">a</span></chmetcnv>:TESTEAX,varArray
JZ@@5
PUSHESI
JMP@@6
@@3:CMPAX,varDate//8bytestopush
JA@@2
@@4:PUSHdwordptr[ESI+12]
@@5:PUSHdwordptr[ESI+8]
@@6:DECEBX
JNE@@1
@@7:MOVEDX,Self
MOVEAX,EventMethod.Data
CALLEventMethod.Code
POPESI
POPEBX
end;
except
end;
end;
functionTOleCtrlEventHelper.QueryInterface(constIID:TGUID;outObj):HResult;
begin
ifGetInterface(IID,Obj)then
begin
Result:=S_OK;
Exit;
end;
ifIsEqualIID(IID,FEventIID)then
begin
GetInterface(IDispatch,Obj);
Result:=S_OK;
Exit;
end;
Result:=E_NOINTERFACE;
end;
functionTOleCtrlEventHelper.RemoveEvent(DispID:TDispID):Boolean;
var
i:Integer;
EventRec:PEventRec;
begin
Result:=False;
fori:=FEventList.Count-1downto0do
begin
EventRec:=PEventRec(FEventList[i]);
ifEventRec^.DispID=DispIDthen
begin
FEventList.Remove(EventRec);
Dispose(EventRec);
Result:=True;
Break;
end;
end;
end;
functionTOleCtrlEventHelper._AddRef:Integer;
begin
Result:=-1;
end;
functionTOleCtrlEventHelper._Release:Integer;f
分享到:
相关推荐
而OLE View 控件查看器则是对这一技术进行深入探究的窗口,它可以显示系统中所有注册的OLE控件、服务器、类型库、接口和类的信息。通过这个工具,开发者可以查看到每个对象的详细元数据,如CLSID(Class ID)、IID...
OCX控件,全称是OLE Control Extension,是Microsoft在ActiveX技术框架下开发的一种控件格式。这种控件主要用于Windows应用程序,特别是基于Visual Basic、VB.NET或VC++等编程环境,提供图形用户界面(GUI)元素,如...
4. 检视事件和事件处理程序:某些控件支持事件驱动编程,OLE/COM对象查看器可以揭示这些事件以及相应的事件处理程序。 5. 浏览接口继承关系:查看器可以帮助理解接口之间的继承层次,这对于设计和实现多层接口结构...
OLE控件(现在称为ActiveX控件)是一种早期的组件技术,允许在不同应用程序之间共享功能。比如,`WebBrowser控件`就是一个OXC,可以在应用程序中嵌入网页浏览功能。然而,由于安全问题,现代开发中已较少使用OXC,...
OCX控件,全称是Object Linking and Embedding (OLE) Custom Controls,是Microsoft Windows平台上的一种组件技术。它基于ActiveX技术,允许开发者创建可重用的软件组件,这些组件可以嵌入到其他应用程序中,增强其...
除了MScomm控件,该工具还支持注册其他的OCX(OLE控件)文件,OCX是ActiveX控件的一种文件格式,包含了可重用的用户界面元素和控件。 注册OCX文件通常涉及到以下步骤: 1. 打开命令提示符,通常以管理员身份运行。 ...
这类控件通常是一个动态链接库(DLL)或对象链接与嵌入(OLE)控件,可以被集成到各种编程环境中,如Visual Basic、C++或.NET等,使得开发者能够轻松地在他们的应用中添加CAD文件的浏览和编辑功能。 描述中提到的...
OCX控件,全称是OLE Control Extension,是Microsoft在Windows平台上推出的一种组件技术,它扩展了OLE(Object Linking and Embedding)的功能,使得开发者能够创建可复用的、图形化的用户界面控件。这些控件可以在...
OCX控件,全称是OLE Control Extension,是微软在Windows平台上推出的一种组件技术,它是一种ActiveX控件,用于创建可复用的用户界面元素。OCX控件可以嵌入到各种应用程序中,提供丰富的功能,如图表、按钮、日历等...
Oledb操作辅助类 OleDbHelper.cs 使用OleDb数据源执行SQL语句 ?Common Class Name File Function 执行命令类 CmdUtil.cs 执行各类命令;如:cmd.exe 公历/农历类 CNDate.cs 公历、农历、星座、气节等相关转换 日期格式...
"另类其它"可能意味着这是一类不常见的或者不典型的应用,可能包含了一些特殊的编程技巧或者用法。"控件"指的是可能在程序中使用的用户界面元素,如按钮、文本框等,它们是程序交互的重要组成部分。"源码"表明这个...
"OCX"代表"OLE定制控件",是微软在早期Windows操作系统中引入的一种技术,用于创建可重用的组件。这些控件可以插入到应用程序中,提供各种用户界面功能。在本例中,我们关注的是一个名为"MenuListCon.ocx"的OCX控件...
OCX控件,全称是OLE Control Extension,是微软在Windows平台上推出的一种组件技术,用于构建用户界面元素。它基于ActiveX技术,允许开发者创建可重用的、自包含的软件组件,这些组件可以在多种应用程序中嵌入和交互...
ActiveX控件是微软对OLE(对象链接和嵌入)技术的扩展,允许开发者创建可交互的、自包含的软件部件,它们可以在多种环境中运行,如Internet Explorer浏览器或Windows应用程序。这些控件通常用于增强用户界面,提供...
5. IPOcx.cpp和MyIpCtrl.cpp:这些可能是其他辅助源代码文件,IPOcx.cpp可能包含控件的核心函数和全局变量,而MyIpCtrl.cpp可能包含了自定义的控件类实现。 6. StdAfx.cpp:这是标准预编译头文件,包含了项目常用的...
在运行时创建的OLE对象需要正确地在屏幕上显示,VB中的OLE控件为此提供了sizemode属性。通过调整sizemode的值,可以控制OLE容器如何显示OLE对象。例如,设置不同的sizemode值会改变OLE对象在容器中的显示方式。 4. ...
这类控件通常提供API接口或函数,使得开发者能够轻松地在应用程序中集成加密和解密功能。以下是对给定文件信息的详细解读: 1. **加密解密**:这是数据安全的核心技术,其目的是保护敏感信息不被未经授权的用户访问...
在压缩包中的`Show.exe`可能是一个用来演示或辅助查看ActiveX控件信息的工具。使用这个工具,用户可能可以直接查看和分析控件的ClassID、函数名和其他相关属性,无需深入底层的注册表或代码。但是,由于具体文件无法...