COM 개체의 이벤트를 받고 싶습니다. 다른 언어로 작성된 COM 이구요. VB 로 돌려본 결과
COM 에서는 이상 없었습니다. 이벤트 잘 발생시키고 VB 에서도 이벤트 잘 받아오더군요.
델파이가 처음이다 보니 어떤 방식으로 접근해야 할 지 잘 몰라서, 2가지 방법으로 시도해보았습니다.
어떤 방법이 맞는 것인지도 잘 모르겠고, 각각의 문제를 어떻게 해결해야 할 지도 잘 모르겠습니다.
답변부탁드립니다.
1. Import Type Library 에서 CreateUnit 을 클릭한다.
이 방식으로 하니 _TLB 파일이 생성되더군요.
그런데, 여기서 어떤 방식으로 COM 에서 발생되는 이벤트를 프로시져와 연결시켜줘야 할 지를
모르겠습니다.
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
WeatherNotify1 : IWeatherNotify;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
// 객체 생성하고 COM 에 값을 설정하여 내부적으로 이벤트 발생 시킨다.
procedure TForm1.Button1Click(Sender: TObject);
begin
WeatherNotify1 := CoWeatherNotify_.Create;
WeatherNotify1.WindSpeed := 1000;
end;
end.
2. Import Type Library 에서 Install 을 클릭한다.
콤포넌트 생성 되어서 폼위에 컨트롤 올렸습니다.
컨트롤의 Properties 와 Events 를 살펴본 결과 Event 를 연결하는 곳이 있길래
특정 이벤트를 OnWarning() 프로시져에 연결시켜줬습니다.
그런데, 아무런 반응이 없습니다. 즉, 이벤트를 못 받는것 같습니다.
type
TForm1 = class(TForm)
WeatherNotify1: TWeatherNotify;
Button1: TButton;
procedure OnWarning(ASender: TObject; nWindSpeed: Integer);
procedure Button1Click(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
// 이벤트 받는 프로시져입니다.
procedure TForm1.OnWarning(ASender: TObject; nWindSpeed: Integer);
begin
Application.MessageBox('WARNING','',MB_OKCANCEL)
end;
// 버튼 클릭하면 WeatherNotify 라는 COM 에게 값을 전달해주고 내부적으로 이벤트가 발생됩니다.
procedure TForm1.Button1Click(Sender: TObject);
begin
WeatherNotify1.WindSpeed := 1000;
end;
end.
======================================================================
참고로 아래는 TLB 내용입니다.
======================================================================
unit WeatherNotify_TLB;
// ************************************************************************ //
// WARNING
// -------
// The types declared in this file were generated from data read from a
// Type Library. If this type library is explicitly or indirectly (via
// another type library referring to this type library) re-imported, or the
// 'Refresh' command of the Type Library Editor activated while editing the
// Type Library, the contents of this file will be regenerated and all
// manual modifications will be lost.
// ************************************************************************ //
// PASTLWTR : 1.2
// File generated on 2004-03-24 오후 4:38:33 from Type Library described below.
// ************************************************************************ //
// Type Lib: D:\Private Project\vbEventTest\WeatherNotify.tlb (1)
// LIBID: {A97AF36A-C1BD-37EA-93CB-F6FF3AFF1AEA}
// LCID: 0
// Helpfile:
// HelpString:
// DepndLst:
// (1) v2.0 stdole, (C:\WINNT\system32\STDOLE2.TLB)
// (2) v1.10 mscorlib, (C:\WINNT\Microsoft.NET\Framework\v1.1.4322\mscorlib.tlb)
// Errors:
// Hint: TypeInfo 'WeatherNotify' changed to 'WeatherNotify_'
// Error creating palette bitmap of (TWeatherNotify) : Server mscoree.dll contains no icons
// ************************************************************************ //
// *************************************************************************//
// NOTE:
// Items guarded by $IFDEF_LIVE_SERVER_AT_DESIGN_TIME are used by properties
// which return objects that may need to be explicitly created via a function
// call prior to any access via the property. These items have been disabled
// in order to prevent accidental use from within the object inspector. You
// may enable them by defining LIVE_SERVER_AT_DESIGN_TIME or by selectively
// removing them from the $IFDEF blocks. However, such items must still be
// programmatically created via a method of the appropriate CoClass before
// they can be used.
{$TYPEDADDRESS OFF} // Unit must be compiled without type-checked pointers.
{$WARN SYMBOL_PLATFORM OFF}
{$WRITEABLECONST ON}
{$VARPROPSETTER ON}
interface
uses Windows, ActiveX, Classes, Graphics, mscorlib_TLB, OleServer, StdVCL, Variants;
// *********************************************************************//
// GUIDS declared in the TypeLibrary. Following prefixes are used:
// Type Libraries : LIBID_xxxx
// CoClasses : CLASS_xxxx
// DISPInterfaces : DIID_xxxx
// Non-DISP interfaces: IID_xxxx
// *********************************************************************//
const
// TypeLibrary Major and minor versions
WeatherNotifyMajorVersion = 1;
WeatherNotifyMinorVersion = 0;
LIBID_WeatherNotify: TGUID = '{A97AF36A-C1BD-37EA-93CB-F6FF3AFF1AEA}';
DIID_ITornadoWatchEvents: TGUID = '{768DB129-3743-3742-9AD2-B00509A29762}';
IID_IWeatherNotify: TGUID = '{EF89FAA1-C3C2-382B-B2DE-E68C658F2FD7}';
CLASS_WeatherNotify_: TGUID = '{9BC7F75A-0291-3412-894A-0145BCEF40A4}';
IID__TornadoWarningDelegate: TGUID = '{921D843D-8B16-32A2-8104-888CD0CD0730}';
CLASS_TornadoWarningDelegate: TGUID = '{35E61CFA-2DDA-33C6-9FCB-EBEFC5301704}';
type
// *********************************************************************//
// Forward declaration of types defined in TypeLibrary
// *********************************************************************//
ITornadoWatchEvents = dispinterface;
IWeatherNotify = interface;
IWeatherNotifyDisp = dispinterface;
_TornadoWarningDelegate = interface;
_TornadoWarningDelegateDisp = dispinterface;
// *********************************************************************//
// Declaration of CoClasses defined in Type Library
// (NOTE: Here we map each CoClass to its Default Interface)
// *********************************************************************//
WeatherNotify_ = IWeatherNotify;
TornadoWarningDelegate = _TornadoWarningDelegate;
// *********************************************************************//
// DispIntf: ITornadoWatchEvents
// Flags: (4096) Dispatchable
// GUID: {768DB129-3743-3742-9AD2-B00509A29762}
// *********************************************************************//
ITornadoWatchEvents = dispinterface
['{768DB129-3743-3742-9AD2-B00509A29762}']
procedure OnTornadoWarning(nWindSpeed: Integer); dispid 1610743808;
end;
// *********************************************************************//
// Interface: IWeatherNotify
// Flags: (4416) Dual OleAutomation Dispatchable
// GUID: {EF89FAA1-C3C2-382B-B2DE-E68C658F2FD7}
// *********************************************************************//
IWeatherNotify = interface(IDispatch)
['{EF89FAA1-C3C2-382B-B2DE-E68C658F2FD7}']
function Get_WindSpeed: Integer; safecall;
procedure Set_WindSpeed(pRetVal: Integer); safecall;
property WindSpeed: Integer read Get_WindSpeed write Set_WindSpeed;
end;
// *********************************************************************//
// DispIntf: IWeatherNotifyDisp
// Flags: (4416) Dual OleAutomation Dispatchable
// GUID: {EF89FAA1-C3C2-382B-B2DE-E68C658F2FD7}
// *********************************************************************//
IWeatherNotifyDisp = dispinterface
['{EF89FAA1-C3C2-382B-B2DE-E68C658F2FD7}']
property WindSpeed: Integer dispid 1610743808;
end;
// *********************************************************************//
// Interface: _TornadoWarningDelegate
// Flags: (4432) Hidden Dual OleAutomation Dispatchable
// GUID: {921D843D-8B16-32A2-8104-888CD0CD0730}
// *********************************************************************//
_TornadoWarningDelegate = interface(IDispatch)
['{921D843D-8B16-32A2-8104-888CD0CD0730}']
end;
// *********************************************************************//
// DispIntf: _TornadoWarningDelegateDisp
// Flags: (4432) Hidden Dual OleAutomation Dispatchable
// GUID: {921D843D-8B16-32A2-8104-888CD0CD0730}
// *********************************************************************//
_TornadoWarningDelegateDisp = dispinterface
['{921D843D-8B16-32A2-8104-888CD0CD0730}']
end;
// *********************************************************************//
// The Class CoWeatherNotify_ provides a Create and CreateRemote method to
// create instances of the default interface IWeatherNotify exposed by
// the CoClass WeatherNotify_. The functions are intended to be used by
// clients wishing to automate the CoClass objects exposed by the
// server of this typelibrary.
// *********************************************************************//
CoWeatherNotify_ = class
class function Create: IWeatherNotify;
class function CreateRemote(const MachineName: string): IWeatherNotify;
end;
TWeatherNotifyOnTornadoWarning = procedure(ASender: TObject; nWindSpeed: Integer) of object;
// *********************************************************************//
// OLE Server Proxy class declaration
// Server Object : TWeatherNotify
// Help String :
// Default Interface: IWeatherNotify
// Def. Intf. DISP? : No
// Event Interface: ITornadoWatchEvents
// TypeFlags : (2) CanCreate
// *********************************************************************//
{$IFDEF LIVE_SERVER_AT_DESIGN_TIME}
TWeatherNotifyProperties= class;
{$ENDIF}
TWeatherNotify = class(TOleServer)
private
FOnTornadoWarning: TWeatherNotifyOnTornadoWarning;
FIntf: IWeatherNotify;
{$IFDEF LIVE_SERVER_AT_DESIGN_TIME}
FProps: TWeatherNotifyProperties;
function GetServerProperties: TWeatherNotifyProperties;
{$ENDIF}
function GetDefaultInterface: IWeatherNotify;
protected
procedure InitServerData; override;
procedure InvokeEvent(DispID: TDispID; var Params: TVariantArray); override;
function Get_WindSpeed: Integer;
procedure Set_WindSpeed(pRetVal: Integer);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Connect; override;
procedure ConnectTo(svrIntf: IWeatherNotify);
procedure Disconnect; override;
property DefaultInterface: IWeatherNotify read GetDefaultInterface;
property WindSpeed: Integer read Get_WindSpeed write Set_WindSpeed;
published
{$IFDEF LIVE_SERVER_AT_DESIGN_TIME}
property Server: TWeatherNotifyProperties read GetServerProperties;
{$ENDIF}
property OnTornadoWarning: TWeatherNotifyOnTornadoWarning read FOnTornadoWarning write FOnTornadoWarning;
end;
{$IFDEF LIVE_SERVER_AT_DESIGN_TIME}
// *********************************************************************//
// OLE Server Properties Proxy Class
// Server Object : TWeatherNotify
// (This object is used by the IDE's Property Inspector to allow editing
// of the properties of this server)
// *********************************************************************//
TWeatherNotifyProperties = class(TPersistent)
private
FServer: TWeatherNotify;
function GetDefaultInterface: IWeatherNotify;
constructor Create(AServer: TWeatherNotify);
protected
function Get_WindSpeed: Integer;
procedure Set_WindSpeed(pRetVal: Integer);
public
property DefaultInterface: IWeatherNotify read GetDefaultInterface;
published
property WindSpeed: Integer read Get_WindSpeed write Set_WindSpeed;
end;
{$ENDIF}
// *********************************************************************//
// The Class CoTornadoWarningDelegate provides a Create and CreateRemote method to
// create instances of the default interface _TornadoWarningDelegate exposed by
// the CoClass TornadoWarningDelegate. The functions are intended to be used by
// clients wishing to automate the CoClass objects exposed by the
// server of this typelibrary.
// *********************************************************************//
CoTornadoWarningDelegate = class
class function Create: _TornadoWarningDelegate;
class function CreateRemote(const MachineName: string): _TornadoWarningDelegate;
end;
procedure Register;
resourcestring
dtlServerPage = 'Standard';
dtlOcxPage = 'Standard';
implementation
uses ComObj;
class function CoWeatherNotify_.Create: IWeatherNotify;
begin
Result := CreateComObject(CLASS_WeatherNotify_) as IWeatherNotify;
end;
class function CoWeatherNotify_.CreateRemote(const MachineName: string): IWeatherNotify;
begin
Result := CreateRemoteComObject(MachineName, CLASS_WeatherNotify_) as IWeatherNotify;
end;
procedure TWeatherNotify.InitServerData;
const
CServerData: TServerData = (
ClassID: '{9BC7F75A-0291-3412-894A-0145BCEF40A4}';
IntfIID: '{EF89FAA1-C3C2-382B-B2DE-E68C658F2FD7}';
EventIID: '{768DB129-3743-3742-9AD2-B00509A29762}';
LicenseKey: nil;
Version: 500);
begin
ServerData := @CServerData;
end;
procedure TWeatherNotify.Connect;
var
punk: IUnknown;
begin
if FIntf = nil then
begin
punk := GetServer;
ConnectEvents(punk);
Fintf:= punk as IWeatherNotify;
end;
end;
procedure TWeatherNotify.ConnectTo(svrIntf: IWeatherNotify);
begin
Disconnect;
FIntf := svrIntf;
ConnectEvents(FIntf);
end;
procedure TWeatherNotify.DisConnect;
begin
if Fintf <> nil then
begin
DisconnectEvents(FIntf);
FIntf := nil;
end;
end;
function TWeatherNotify.GetDefaultInterface: IWeatherNotify;
begin
if FIntf = nil then
Connect;
Assert(FIntf <> nil, 'DefaultInterface is NULL. Component is not connected to Server. You must call ''Connect'' or ''ConnectTo'' before this operation');
Result := FIntf;
end;
constructor TWeatherNotify.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
{$IFDEF LIVE_SERVER_AT_DESIGN_TIME}
FProps := TWeatherNotifyProperties.Create(Self);
{$ENDIF}
end;
destructor TWeatherNotify.Destroy;
begin
{$IFDEF LIVE_SERVER_AT_DESIGN_TIME}
FProps.Free;
{$ENDIF}
inherited Destroy;
end;
{$IFDEF LIVE_SERVER_AT_DESIGN_TIME}
function TWeatherNotify.GetServerProperties: TWeatherNotifyProperties;
begin
Result := FProps;
end;
{$ENDIF}
procedure TWeatherNotify.InvokeEvent(DispID: TDispID; var Params: TVariantArray);
begin
case DispID of
-1: Exit; // DISPID_UNKNOWN
(*{The DispID for this method is DISPID_UNKNOWN!?. }
-1: if Assigned(FOnTornadoWarning) then
FOnTornadoWarning(Self, Params[0] {Integer});
*)
end; {case DispID}
end;
function TWeatherNotify.Get_WindSpeed: Integer;
begin
Result := DefaultInterface.WindSpeed;
end;
procedure TWeatherNotify.Set_WindSpeed(pRetVal: Integer);
begin
DefaultInterface.Set_WindSpeed(pRetVal);
end;
{$IFDEF LIVE_SERVER_AT_DESIGN_TIME}
constructor TWeatherNotifyProperties.Create(AServer: TWeatherNotify);
begin
inherited Create;
FServer := AServer;
end;
function TWeatherNotifyProperties.GetDefaultInterface: IWeatherNotify;
begin
Result := FServer.DefaultInterface;
end;
function TWeatherNotifyProperties.Get_WindSpeed: Integer;
begin
Result := DefaultInterface.WindSpeed;
end;
procedure TWeatherNotifyProperties.Set_WindSpeed(pRetVal: Integer);
begin
DefaultInterface.Set_WindSpeed(pRetVal);
end;
{$ENDIF}
class function CoTornadoWarningDelegate.Create: _TornadoWarningDelegate;
begin
Result := CreateComObject(CLASS_TornadoWarningDelegate) as _TornadoWarningDelegate;
end;
class function CoTornadoWarningDelegate.CreateRemote(const MachineName: string): _TornadoWarningDelegate;
begin
Result := CreateRemoteComObject(MachineName, CLASS_TornadoWarningDelegate) as _TornadoWarningDelegate;
end;
procedure Register;
begin
RegisterComponents(dtlServerPage, [TWeatherNotify]);
end;
end.
여기서 제공되는 툴을 써서 이벤트관련 TLB를 생성하세요.
TLB외에 이벤트관련 유닛이 하나 더 생깁니다.
그것으로 이벤트를 정의하고 사용하시면 됩니다.
즉 VB의 withevents와 같은 이벤트를 사용할 수 있습니다.