我用CreateOleObject引用了一个Aotomation对象,但我如何引用它的事件呢?(50分)

  • 主题发起人 主题发起人 还是朋友
  • 开始时间 开始时间

还是朋友

Unregistered / Unconfirmed
GUEST, unregistred user!

代码如下:

gSQLServer := CreateOleObject('SQLDMO.SQLServer');
oBackUp := CreateOleObject('SQLDMO.BackUp');

gSQLServer.LoginSecure := false;
gSQLServer.LoginTimeout := 15;
gSQLServer.Connect('angel', 'sa', 'zonekingsa');

oBackUp.Files := 'c:/Northwind.bak';
oBackUp.DataBase := 'Northwind';
oBackUp.SQLBackUp(gSQLServer);
ShowMessage('success');

gSQLServer := Unassigned;
oBackUp := Unassigned;

oBackUp对象有一个CompletePercent事件,
如果我想引用此事件,如何引用呢?
 
将事件看作为属性,直接对这个事件赋值就可以,当然“值”与属性的值不一样要是过程名称,并且这个过程要和事件定义的过程声明一样,然后在你所定义的过程中加入你的处理语句就可以了。
 
windbell谢谢你:

我这样做过,但编译如何也不能通过。。。
不知为何。。
 
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComObj, OleServer, SQLDMO_TLB;

type
TForm1 = class(TForm)
Button1: TButton;
SQLDMODBFile1: TSQLDMODBFile;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
gSQLServer, oBackup, oBackupEvent: variant;
procedure MyPercentComplete(Msg: string; Percent: integer);
end;

var
Form1: TForm1;
implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
begin
gSQLServer := CreateOleObject('SQLDMO.SQLServer');
oBackUp := CreateOleObject('SQLDMO.BackUp');

//这句不能通过,说是MyPercentComplete没有参数
oBackUp.PercentComplete := MyPercentComplete;
gSQLServer.LoginSecure := false;
gSQLServer.LoginTimeout := 15;
gSQLServer.Connect('angel', 'sa', 'zonekingsa');

oBackUp.Files := 'c:/Northwind.bak';
oBackUp.DataBase := 'Northwind';
oBackUp.SQLBackUp(gSQLServer);
ShowMessage('success');

gSQLServer := Unassigned;
oBackUp := Unassigned;
end;

procedure TForm1.MyPercentComplete(Msg: string; Percent: integer);
begin
end;

end.
 
当然不行了,最好的办法是把它导入并封装成DELPHI组件,其中就会有事件的响应,而且用early binding的性能也要好些。
如果你一定要用late binding,那么你就要自己实现一个EventSink,这个就复杂了,看MSDN去吧。
 
猛禽兄弟:
我就是在msdn上找到的源码,不过是VC,VB呀,我转不成delphi。。。。

奇怪,我封装成组件,结果数据库备份出错,我也不知为何,我就是把sqldmo.dll引入,
然后把此pas文件编译,,此时事件倒是有了,可是备份出错,

所以我才用CreateOleObject这种方法。。。。
 
我这儿不会出错的
 
将你的事件声明过程改成下面格式试试:(我没试过)
type TpercentComplete=procedure (Msg: string; Percent: integer) of object;

oBackUp.PercentComplete := TpercentComplete(MyPercentComplete);

强制类型转换一下.
 
windbell:
谢谢。。

可是依旧不能通过。
提示:无效的类型转换。
 
兄台如果安装了SQLServer,可以试一下。。

谢谢了。
 
我又看了一下sqldmo.dll的引入文件。
发现了一个接品BackUpSink,

可是不太会用,,
唉。。
 
你干吗一定要重载PercentComplete
应该可以通过oBackUp.PercentCompleteNotification来实现呀
 
cxz9:
用oBackUp.PercentCompleteNotification如何实现呀?
我看了一下,
PercentCompleteNotification只是一个属性呀,
而且执行oBackUp.SQLBack的时候,这个属性会变化吗?

能给段可以执行的代码吗??
如果真的可以,再开一贴,200分送上。。。

谢谢了。。。。
 
Remarks
With SQL-DMO, use the SQLBackup, SQLRestore, and SQLVerify methods to start a backup or restore operation.

By default, SQL-DMO raises the PercentComplete event as each tenth of a backup or restore operation completes (when the percent of the operation completed is 10, 20, 30, and so on). Use the PercentCompleteNotification property of the Backup and Restore objects to change default behavior.

For the Replication object, the PercentComplete event is reserved for future use.

 
#define STRICT // strict type checking
#define WIN32_LEAN_AND_MEAN // do not include the world
#define INC_OLE2 // include OLE/COM files
#define UNICODE
#define _UNICODE

#include <windows.h>
#include <initguid.h>
#include <tchar.h>
#include "C:/Program Files/Microsoft SQL Server/80/Tools/DevTools/include/sqldmoid.h"
#include "C:/Program Files/Microsoft SQL Server/80/Tools/DevTools/include/sqldmo.h"
#include <stdlib.h>
#include <stdio.h>
#include <olectl.h>

#include "backupdb.h"

// **********************************************************************
// function declarations
// **********************************************************************
int DisplayError();

STDMETHODIMP CMyBackupSink::QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
{
if (riid == IID_IUnknown || riid == IID_ISQLDMOBackupSink)
{
AddRef();
*ppvObj = this;
return NOERROR;
}
return E_NOINTERFACE;
}

// Backup Sink Methords.
//
STDMETHODIMP CMyBackupSink::Complete(THIS_ SQLDMO_LPCSTR Message)
{
// Backup object calls us when backup is completed.
//
printf("Backup Completed/n");

return NOERROR;
}

STDMETHODIMP CMyBackupSink::PercentComplete(THIS_ SQLDMO_LPCSTR Message, long Percent)
{
// Backup object calls us with new percent complete.
//
printf("%ld%s Completed/n", Percent,"%");

return NOERROR;
}

STDMETHODIMP CMyBackupSink::NextMedia(THIS_ SQLDMO_LPCSTR Message)
{
// Backup object calls us when it's ready for next volume.
//
printf("Next Volume Message: %s /n", Message);
return NOERROR;
}

// **********************************************************************
// main()
// **********************************************************************
int main(void)
{
HRESULT hr;
if FAILED(hr = CoInitialize (NULL))
{
_tprintf(TEXT("CoInitialize Failed/n"));
return (0);
}

LPSQLDMOSERVER pSQLServer = NULL;

if FAILED(hr = CoCreateInstance(
CLSID_SQLDMOServer,
NULL,
CLSCTX_INPROC_SERVER,
IID_ISQLDMOServer,
(LPVOID*)&pSQLServer))
{
_tprintf(TEXT("CoCreateInstance Failed/n"));
return (0);
}

pSQLServer->SetLoginTimeout(10);
pSQLServer->SetLoginSecure(TRUE);

if FAILED(hr = pSQLServer->Connect(TEXT(""),TEXT("sa"),TEXT("")))
{
return DisplayError();
}

LPSQLDMOBACKUP pSQLBackup = NULL;

if FAILED(hr = CoCreateInstance(
CLSID_SQLDMOBackup,
NULL,
CLSCTX_INPROC_SERVER,
IID_ISQLDMOBackup,
(LPVOID*)&pSQLBackup))
{
_tprintf(TEXT("CoCreateInstance Failed/n"));
return (0);
}

LPCONNECTIONPOINTCONTAINER pMyConnectionPointContainer;
LPCONNECTIONPOINT pMyConnectionPoint;

CMyBackupSink* pMyBackupSink = new CMyBackupSink();
pMyBackupSink->AddRef();

if (!pMyBackupSink)
{
return(0);
}

DWORD dwCookie;

// ask the connectable object (pSQLBackup) about its outgoing interface,
// by using QI on IID_IConnectionPointContainer. If fails, this object
// does not support outgoing interface
//
if FAILED(pSQLBackup->QueryInterface(
IID_IConnectionPointContainer,
(LPVOID FAR*) &pMyConnectionPointContainer))
{
return DisplayError();
}

// find the specific outgoing interface IID_ISQLDMOBackupSink and retrieve
// a pointer to the connectionpoint object. If fails, the object does not
// support this outgoing interface
//
if FAILED(pMyConnectionPointContainer->FindConnectionPoint(
IID_ISQLDMOBackupSink,
(LPCONNECTIONPOINT FAR*)&pMyConnectionPoint))
{
return DisplayError();
}

// establish the connection between the Sink and the ConnectionPoint object.
// Retrieve a key (cookie) value for terminating the connection later. If
// this fails, the Sink and ConnectionPoint object do not support the same interface
//
if (S_OK != (hr = pMyConnectionPoint->Advise((LPUNKNOWN)pMyBackupSink, &dwCookie)))
{
return DisplayError();
}

if FAILED(hr = pSQLBackup->SetFiles(TEXT("c://test.dmp") ))
{
return DisplayError();
}

if FAILED(hr = pSQLBackup->SetDatabase(TEXT("pubs") ))
{
return DisplayError();
}

printf("Backup Start/n");
if FAILED(hr = pSQLBackup->SQLBackup(pSQLServer))
{
return DisplayError();
}

// terminate the connection using the same connection key
//
pMyConnectionPoint->Unadvise(dwCookie);
pMyConnectionPoint->Release ();
pMyConnectionPointContainer->Release ();
pSQLBackup->Release ();
pSQLServer->Release ();

CoUninitialize ();
return (0);
}

// **********************************************************************
// display error information
// **********************************************************************
int DisplayError()
{
LPERRORINFO pErrorInfo = NULL;
BSTR strDescription, strSource;

GetErrorInfo(0,&pErrorInfo);

pErrorInfo->GetDescription (&strDescription);
pErrorInfo->GetSource(&strSource);

_tprintf(TEXT("%s/n"),strDescription);
_tprintf(TEXT("%s/n"),strSource);

pErrorInfo->Release();

SysFreeString(strDescription);
SysFreeString(strSource);

return(0);
}
 
cxz9:
谢谢你了。。

我也看到了MSDN里VB与VC的例子,
可是一是看不懂,二是就是不知道在delphi里如何加入事件,

不知如何引入BackUpSink接口。。

唉。。
 
这个可能比较麻烦了
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1142842
不好办!在Delphi中还没有想到办法!
MSDN中有VB的例子,用WithEvents声明一个对象就行了
简单得让人难以想象,可我和大家一样,都不喜欢用vb,微软真是TMD坏透了!


来自:manfeel, 时间:2002-6-8 1:20:00, ID:1150181
黑干两天两夜,终于被我编出来了!
代码:
[blue]
// --------------------------------------------------------------- 
// 在WebBrowser中得到当前鼠标下图片和对象的链接                    
// Get the element's url under the mouse pointer in WebBrowser     
// Copyright (c) 2002 Powered by Manfeel                           
// Manfeel保留版权,转载请保留作者信息!                           
//                                            [red]Mingtao@sina.com[/red] 
// --------------------------------------------------------------- 
[/blue]
unit main;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 OleCtrls, SHDocVw, MSHTML, ActiveX, ComObj, ExtCtrls, StdCtrls;

type
 TForm1 = class(TForm)
   Panel1: TPanel;
   Splitter1: TSplitter;
   Panel2: TPanel;
   WebBrowser1: TWebBrowser;
   Memo1: TMemo;
   PanelTop: TPanel;
   Edit1: TEdit;
   procedure FormActivate(Sender: TObject);
   procedure WebBrowser1DocumentComplete(Sender: TObject;
     const pDisp: IDispatch; var URL: OleVariant);
   procedure Edit1KeyDown(Sender: TObject; var Key: Word;
     Shift: TShiftState);
   procedure FormShow(Sender: TObject);
   procedure FormDestroy(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

 TEventSink = class(TObject, IUnknown, IDispatch)
 private
   FRefCount:Longint;
   FControl:TControl;
 protected
   { IUnknown }
   function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
   function _AddRef: Integer; stdcall;
   function _Release: Integer; stdcall;
   { IDispatch }
   function GetTypeInfoCount(out Count: Integer): HResult; stdcall;
   function GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult; stdcall;
   function GetIDsOfNames(const IID: TGUID; Names: Pointer;
     NameCount, LocaleID: Integer; DispIDs: Pointer): HResult; stdcall;
   function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;
     Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult; stdcall;
   property Control:TControl read FControl;      
 public
   constructor Create(Control: TControl);
 end;

const
 IID_IConnectionPointContainer: TGUID = '{B196B284-BAB4-101A-B69C-00AA00341D07}';
 DISPID_HTMLElement_ONMouseOver  = -2147418104 ;  
var
 Form1: TForm1;
 CPC:IConnectionPointContainer;
 CP:IConnectionPoint;
 Cookie:Integer;
 EventSink:TEventSink;
implementation

{$R *.DFM}
constructor TEventSink.Create(Control: TControl);
begin
 FControl := Control;
end;

function TEventSink.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
 if GetInterface(IID, Obj) then
   Result := S_OK
 else
   Result := E_NOINTERFACE;
end;

function TEventSink._AddRef: Integer;
begin
 Inc(FRefCount);
 Result := FRefCount;
end;

function TEventSink._Release: Integer;
begin
 Dec(FRefCount);
 Result := FRefCount;
end;

{ TEventSink.IDispatch }

function TEventSink.GetTypeInfoCount(out Count: Integer): HResult;
begin
 Count := 0;
 Result := S_OK;
end;

function TEventSink.GetTypeInfo(Index, LocaleID: Integer;
 out TypeInfo): HResult;
begin
 Pointer(TypeInfo) := nil;
 Result := E_NOTIMPL;
end;

function TEventSink.GetIDsOfNames(const IID: TGUID; Names: Pointer;
 NameCount, LocaleID: Integer; DispIDs: Pointer): HResult;
begin
 Result := E_NOTIMPL;
end;


function TEventSink.Invoke(DispID: integer; const IID: TGUID; LocaleID: Integer;
   Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult;
var
 WB:IHTMLDocument2;
 Anchor:IHTMLElement;
begin
 if (DispID = DISPID_HTMLElement_ONMouseOver) then
 begin
   WB:=(FControl as TForm1).WebBrowser1.Document as IHTMLDocument2;
   Anchor:=WB.parentWindow.event.srcElement;
   if (Anchor.tagName='A') then
   begin
     (Fcontrol as TForm1).Memo1.lines.Add((Anchor as IHTMLAnchorElement).href);
   end;
   if (Anchor.parentElement.tagName='A') then
   begin
     (Fcontrol as TForm1).Memo1.lines.Add((Anchor.parentElement as IHTMLAnchorElement).href);
   end;
 end;
 Result := S_OK;
end;


procedure TForm1.FormActivate(Sender: TObject);
begin
 WebBrowser1.Navigate('about:blank');
end;

procedure TForm1.WebBrowser1DocumentComplete(Sender: TObject;
 const pDisp: IDispatch; var URL: OleVariant);
var
 Doc:IHTMLDocument2;
begin
 Doc:=WebBrowser1.Document as IHTMLDocument2;
 OleCheck(Doc.QueryInterface(IID_IConnectionPointContainer, CPC));
 OleCheck(CPC.FindConnectionPoint(DIID_HTMLDocumentEvents2,CP));
 EventSink:= TEventSink.Create(Self);
 OleCheck(CP.Advise(IUnKnown(EventSink),Cookie));
end;

procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;
 Shift: TShiftState);
begin
 if Key = VK_RETURN then WeBbrowser1.Navigate(Edit1.text);
end;

procedure TForm1.FormShow(Sender: TObject);
begin
 Edit1.Align := alClient;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
 CP.Unadvise(Cookie);
end;

end.
 
>>>MSDN中有VB的例子,用WithEvents声明一个对象就行了
>>>简单得让人难以想象,可我和大家一样,都不喜欢用vb,微软真是TMD坏透了!

唉,是呀,可是我们又没有办法
毕竟VB与SQLServer都是人家的产品。。

这段代码很像VC带的那个例子,
我研究一下。
 
cxz9:
我想问另我一个问题。

用CreateOleOject这样,
自己加事件较难,,

我引入了sql.dll,
并且把单元文件编译成功。
安装了所有的组件。

把TBackUp组件直接放在窗体上,
此时就有了OnPercentComplete事件,
可用它进行数据库备份,总是出错。。。

不知为什么。。
 
后退
顶部