兄弟我一直写vc的程序,现在要修改别人的delphi程序。
只好试着写了我的问题是,一个nt service的守护程序,我使用了一个对象,它有event,可以在接收到请求时触发,但我不知道代码该怎样写,谢谢各位了
只好试着写了我的问题是,一个nt service的守护程序,我使用了一个对象,它有event,可以在接收到请求时触发,但我不知道代码该怎样写,谢谢各位了
解决方案 »
- 【求助】 如何避免使用一个已经被 free过的form1.
- 帮将要出来的小宝宝取名字
- dephi网络编程?
- 求助!!!!!
- 需要DBdatatimepicker控件 而且日期显示为当天开始 明一大早急用
- 关于多个DBChart同步缩放和移动的问题,请多指教!急!(100分,不够再加!)
- 请问一个关于抛出exception的问题
- 帮忙看一下关于ADOQuery和StringGrid的。
- 1000 分求 压缩算法(急!)
- DELPHI中如何将数据写到WORD文档,请给实例,多谢
- 请问这样的报表怎么设计界面?
- 我在notebook控件的每一子页上放了一个image做底图,切换子页时图片总要闪一下,有办法解决吗?
分不是问题,我还有7000多分。
在接口里的invoke里实现事件代码,
创建ole对象后,
用InterfaceConnect将该接口连接上ole对象,
这样便可处理ole对象触发的事件了,
ole对象销毁前需要用InterfaceDisconnect断开之
不过它给出的代码量有点大,
这里给出一个较简单的实现方法,第一步:创建一个EventSink(整个过程你只需写几行代码)File -> New -> ActiveX -> Automation object -> (Instancing Internal),
delphi为为你自动生成一个内部的自动化对象,
我们将用它作为EventSink,
把目标ole对象的事件定义加入它的方法列表,
(如:假定事件目标ole对象为某个网页的一个按钮的onclick事件,则往你的EventSink里加上一个同名的方法onclick,参数也要一致)
此时delphi会自动为你生成该事件的代码,不过是空的,往里面填上你的功能代码即可。
显然,我们需要实现对事件接口的支持,
故需重载ObjQueryInterface方法(被QueryInterface所调用),
当传入iid为ole事件接口的iid时返回S_OK即可,
以下为EventSink相应代码:function TEventSink.ObjQueryInterface(const IID: TGUID; out Obj): HResult;
begin
if IsEqualGUID(IID, Form1.OleEventIID) and GetInterface(IDispatch, Obj) then
Result := S_OK
else
Result := inherited ObjQueryInterface(IID, Obj);
end;procedure TEventSink.OnClear;
begin
Form1.Memo1.Clear;
end;procedure TEventSink.OnTextChanged(const NewText: WideString);
begin
Form1.Memo1.Text := NewText;
end;
第二步:绑定该EventSink到ole对象上在ole对象创建之后(假定在FormCreate中创建)
procedure TForm1.FormCreate(Sender: TObject);
begin
FServer := CreateOleObject('MyTyplib.MyObj')
FEvent := TEventSink.Create;
TheOleEventIID := ?;
//TheOleEventIID: TGUID 为ole对象事件接口的iid, 可查其类型库得到
InterfaceConnect(FServer, OleEventIID, FEvent, FConnection);
//if FConnection > 0 then ShowMessage('连接成功。');
end;//ok, 大功告成。
//如有疑问,可向我要源代码例子
演示了动态绑定web页面中按钮点击事件的例子
//请注意,这里onclick指定的dispid跟HTMLButtonElementEvents2的IID一致。unit OleEventDemo_TLB;
{$TYPEDADDRESS OFF}
interface
uses Windows, ActiveX, Classes, Graphics, OleServer, OleCtrls, StdVCL;
const
// TypeLibrary Major and minor versions
ClientDemo2MajorVersion = 1;
ClientDemo2MinorVersion = 0; LIBID_ClientDemo2: TGUID = '{8BE97D79-E940-458D-9C82-FCA7E0D4ED61}'; IID_IEventSink: TGUID = '{D7EB2580-1D81-4049-A211-B7438DE62D56}';
CLASS_EventSink: TGUID = '{C4BE29E4-7139-4B3C-9AA0-4C476E293EAA}';
type
IEventSink = interface;
IEventSinkDisp = dispinterface; EventSink = IEventSink;
IEventSink = interface(IDispatch)
['{D7EB2580-1D81-4049-A211-B7438DE62D56}']
function onclick(const dispSource: IDispatch): WordBool; safecall;
end; IEventSinkDisp = dispinterface
['{D7EB2580-1D81-4049-A211-B7438DE62D56}']
function onclick(const dispSource: IDispatch): WordBool; dispid -600;
end; CoEventSink = class
class function Create: IEventSink;
class function CreateRemote(const MachineName: string): IEventSink;
end;implementationuses ComObj;class function CoEventSink.Create: IEventSink;
begin
Result := CreateComObject(CLASS_EventSink) as IEventSink;
end;class function CoEventSink.CreateRemote(const MachineName: string): IEventSink;
begin
Result := CreateRemoteComObject(MachineName, CLASS_EventSink) as IEventSink;
end;end.
//这个是内部接口,无需注册
//注意其中的onclick代码,dispSource即网页中的event对象unit u_EventSink;interfaceuses
ComObj, ActiveX, OleEventDemo_TLB, StdVcl, SysUtils;type
TEventSink = class(TAutoObject, IEventSink)
protected
function onclick(const dispSource: IDispatch): WordBool; safecall;
{ Protected declarations }
public
function ObjQueryInterface(const IID: TGUID; out Obj): HResult; override; stdcall;
end;implementation
uses ComServ, u_Main, Windows;function TEventSink.ObjQueryInterface(const IID: TGUID; out Obj): HResult;
begin
if IsEqualGUID(IID, Form1.FEventIID) and GetInterface(IDispatch, Obj) then
Result := S_OK
else
Result := inherited ObjQueryInterface(IID, Obj);
end;function TEventSink.onclick(const dispSource: IDispatch): WordBool;
begin
OleVariant(dispSource).srcElement.style.backgroundColor := '#' + IntToHex(RGB(Random(256), Random(256), Random(256)), 6);
Result := True;
end;initialization
TAutoObjectFactory.Create(ComServer, TEventSink, Class_EventSink,
ciInternal, tmApartment);
end.
unit u_Main;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ToolWin, ComCtrls, OleEventDemo_TLB, ActiveX,
OleCtrls, SHDocVw, MSHtml;type
TForm1 = class(TForm)
ToolBar1: TToolBar;
wb: TWebBrowser;
Button1: TButton;
Button2: TButton;
Button3: TButton;
StatusBar1: TStatusBar;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
procedure WriteHtml(const AHtml: String);
public
{ Public declarations }
FServer: IHTMLButtonElement;
FEventIID: TGUID;
FEvent: IEventSink;
FConnection: Integer;
end;var
Form1: TForm1;implementation
uses ComObj, u_EventSink;{$R *.DFM}procedure TForm1.FormCreate(Sender: TObject);
begin
wb.Navigate('about:blank');
end;procedure TForm1.Button1Click(Sender: TObject);
begin
WriteHtml('<html><body><button id=btn>测试按钮</button><br/>本页面中按钮响应代码来自delphi</body></html>');
end;procedure TForm1.Button2Click(Sender: TObject);
var doc: IHTMLDocument2; btn: IHTMLButtonElement;
begin
doc := wb.Document as IHTMLDocument2;
btn := doc.all.item('btn', EmptyParam) as IHTMLButtonElement;
FServer := btn;
FEvent := TEventSink.Create;
FEventIID := HTMLButtonElementEvents2;
FConnection := 0;
InterfaceConnect(FServer, FEventIID, FEvent, FConnection);
StatusBar1.SimpleText := IntToStr(FConnection);
end;procedure TForm1.WriteHtml(const AHtml: String);
var
Stream: ActiveX.IStream;
hHTMLText: HGLOBAL;
psi: IPersistStreamInit;
begin
if not Assigned(wb.Document) then Exit;
hHTMLText := GlobalAlloc(GPTR, Length(AHtml) + 1);
if 0 = hHTMLText then RaiseLastWin32Error;
CopyMemory(Pointer(hHTMLText), PChar(AHtml), Length(AHtml));
OleCheck(CreateStreamOnHGlobal(hHTMLText, True, Stream));
try
OleCheck(wb.Document.QueryInterface(IPersistStreamInit, psi));
try
OleCheck(psi.InitNew);
OleCheck(psi.Load(Stream));
finally
psi := nil;
end;
finally
Stream := nil;
end;
end;procedure TForm1.Button3Click(Sender: TObject);
begin
FServer.value := '已取消。';
ComObj.InterfaceDisconnect(FServer, FEventIID, FConnection);
StatusBar1.SimpleText := IntToStr(FConnection);
FEvent := nil;
FServer := nil;
end;end.