Solved

COM can call my program?  Event Handler.

Posted on 1998-09-15
18
496 Views
Last Modified: 2008-03-06
Using the COM interface that I imported, I can set properties and call functions, but now I need the COM thing to call my program at certain events.  I don't know how much I need to include, but if you want more points I can certainly be generous because I'd like a quick *complete* answer.

I imported the type library and everything works fine.  The handler that I'd like to implement is:

IEICUserWatcher = interface(IDispatch)
    ['{918EBE75-FA5D-11D1-8001-00A0C9A79E7C}']
    procedure StatusChanged(const p_NewStatus: WideString; p_UntilDateTime: TDateTime); safecall;
    procedure UserChanged; safecall;
  end;

If I try to do this
var UserWatcher
begin
  UserWatcher := CoUserWatcher.Create;
end;

it tells me class is not registered.

The help file says that I need to implement this in my client application, but I obviously don't know how.

Any suggestions are welcome.
0
Comment
Question by:loucks
  • 9
  • 8
18 Comments
 
LVL 20

Expert Comment

by:Madshi
ID: 1339785
I'm no real experts in COM things, but perhaps I can help you a little bit?
I think you have to work with COM factories (look at TComObjectFactory), or am I wrong? I've never seen someone creating an instance of an interface by calling "interfaceInstance:=Interface.Create".

Hope I've not told you nonsense...
Regards, Madshi.
0
 

Author Comment

by:loucks
ID: 1339786
I've looked at that and got a headache!  I will look at it again though as long as you think that is a good place to start.
0
 
LVL 20

Expert Comment

by:Madshi
ID: 1339787
The problem is, I don't really understand what you're going to do. Probably because I've not enough COM knowledge.
Perhaps you should look at Delphi\Demos\ActiveX. These demos have been a great help to me.

Regards, Madshi.

P.S: I've Delphi 4. I hope you too. If you don't find the demos, give me your eMail and I will mail them to you.
0
 
LVL 1

Expert Comment

by:lowlevel
ID: 1339788
what COM interface did you import, and was that another Delphi COM server? If so, do you have the source to it? Or is it a 3rd party thing?

Please also post the entire *TLB*.pas file for that COM-server,
I'll take a look at it.


0
 

Author Comment

by:loucks
ID: 1339789
I actually got it to work (sort of) by looking at and emulating the TCopyHook example.  It is a 3rd party and I am checking to make sure I have permission to post it.  I will also post what I did to implement it.  

The sort of is that when I originally implemented it, I put a ShowMessage in the handlers that the DLL calls.  That made the program appear to "lock-up".  Then I made it change the caption of the main form.  That didn't lock it up, but when it changes the caption, using a simple assignment "form1.caption := p_UserStatus", the form caption totally disappears.  Then when I click on the form, it presents the correct text.

So now my question has evolved to:

When they say "stub-handler", is my handler supposed to turn around and call another handler in the main program?
0
 
LVL 20

Expert Comment

by:Madshi
ID: 1339790
Your problem with the main caption seems to be that nobody handles the window messages. Where have you opened this window and does this instance (program or dll) has a message loop?

Sorry, I don't understand the suff with the "stub-handler". What is a "stub-handler" and what is your problem with it?

Regards, Madshi.

P.S: Are you using factories now?
0
 

Author Comment

by:loucks
ID: 1339791
Below are two units:  Unit1 is the main program,
EICClientCOMLib_TLB is what Delphi imported.  This is in Delphi 3, but I have 4 if you want me to use that.  I think I am using factories...  Tell me if I am.  I don't know whether or not their dll has a message loop.  

Stub-handler is something I saw in the Web, Delphi Docs, or 3rd party help.  Basically, I think what it refers to is that you write a handler (the stub) that calls another handler (the real thing) in your main program.  I'm not sure if that is helpful, but there you have it.

unit Unit1;

interface

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

type TUserWatcher = Class(TComObject, IEICUserWatcher)
  public
    procedure StatusChanged(const p_NewStatus: WideString; p_UntilDateTime: TDateTime); safecall;
    procedure UserChanged; safecall;
    function GetTypeInfoCount(out Count: Integer): Integer; stdcall;
    function GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): Integer; stdcall;
    function GetIDsOfNames(const IID: TGUID; Names: Pointer; NameCount, LocaleID: Integer; DispIDs: Pointer): Integer; stdcall;
    function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer; Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): Integer; stdcall;
end;


type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
    EIC : IEICConnection;
    User : IEICUser;
    UserWatch: TUserWatcher;
  public
    { Public declarations }
  end;



var
  Form1: TForm1;
implementation

Uses ComServ;

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(User.StatusMessage);
//User.SetChangeHandler(Self as EICUserWatcher);

end;


procedure TForm1.FormCreate(Sender: TObject);
begin
EIC := CoEICConnection.Create;
EIC.Connect('Testing Still', 'ELECTRICAL', '', '', '', True);
User := CoEICUser.Create;
User.Set_Id(EIC.User);

end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
UserWatch.Free;
User._Release;
EIC._Release;
end;

procedure TUserWatcher.StatusChanged(const p_NewStatus: WideString; p_UntilDateTime: TDateTime);
begin
Form1.Caption := String(p_NewStatus);
Form1.Repaint;
end;

procedure TUserWatcher.UserChanged;
begin
//ShowMessage('UserChanged');
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
UserWatch := TUserWatcher.Create;
User.SetChangeHandler(UserWatch);
end;

    function TUserWatcher.GetTypeInfoCount(out Count: Integer): Integer; stdcall;
    begin
    Result := 0;
    end;

    function TUserWatcher.GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): Integer; stdcall;
    begin
    Result := 0;
    end;
    function TUserWatcher.GetIDsOfNames(const IID: TGUID; Names: Pointer; NameCount, LocaleID: Integer; DispIDs: Pointer): Integer; stdcall;
    begin
    Result := 0;
    end;
    function TUserWatcher.Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer; Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): Integer; stdcall;

    begin
    Result := 0;
    end;

type TUserWatcherFactory = Class(TComObjectFactory)

end;

initialization
TUserWatcherFactory.Create(ComServer, TUserWatcher, Class_EICUserWatcher, '',
   'Test Me', ciMultiInstance);


end.





unit EICClientCOMLib_TLB;

{ This file contains pascal declarations imported from a type library.
  This file will be written during each import or refresh of the type
  library editor.  Changes to this file will be discarded during the
  refresh process. }

{ EIC Client COM Classes version 1.0 }
{ Version 1.0 }

{ Conversion log:
  Warning: 'Type' is a reserved word. IEICQueue.Type changed to Type_
  Warning: 'Record' is a reserved word. IEICCallObject.Record changed to Record_
  Warning: 'Private' is a reserved word. IEICCallObject.Private changed to Private_
 }

interface

uses Windows, ActiveX, Classes, Graphics, OleCtrls, StdVCL;

const
  LIBID_EICClientCOMLib: TGUID = '{DCC7AD35-F185-11D1-BFFE-00A0C9A79E7C}';

const

{ Component class GUIDs }
  Class_EICConnection: TGUID = '{1143B9A7-F0BD-11D1-BFFE-00A0C9A79E7C}';
  Class_EICQueue: TGUID = '{52344756-D0B4-11D1-BFF4-00A0C9A79E7C}';
  Class_EICQueueWatcher: TGUID = '{1143B9AA-F0BD-11D1-BFFE-00A0C9A79E7C}';
  Class_EICQueueObject: TGUID = '{87EC0165-EE57-11D1-BFFC-00A0C9A79E7C}';
  Class_EICQueueObjectWatcher: TGUID = '{B638F3B9-F4A4-11D1-BFFE-00A0C9A79E7C}';
  Class_EICCallObject: TGUID = '{DCC7AD4C-F185-11D1-BFFE-00A0C9A79E7C}';
  Class_EICUser: TGUID = '{871962B4-FA2D-11D1-8001-00A0C9A79E7C}';
  Class_EICUserWatcher: TGUID = '{918EBE76-FA5D-11D1-8001-00A0C9A79E7C}';
  Class_EICWorkgroup: TGUID = '{C574F7B6-FEDE-11D1-8001-00A0C9A79E7C}';
  Class_EICWorkgroupWatcher: TGUID = '{C574F7B8-FEDE-11D1-8001-00A0C9A79E7C}';
  Class_EICConferenceObject: TGUID = '{661ABFE6-0523-11D2-8009-00A0C9A79E7C}';

type

{ Forward declarations: Interfaces }
  IEICConnection = interface;
  IEICConnectionDisp = dispinterface;
  IEICQueue = interface;
  IEICQueueDisp = dispinterface;
  IEICQueueWatcher = interface;
  IEICQueueWatcherDisp = dispinterface;
  IEICQueueObject = interface;
  IEICQueueObjectDisp = dispinterface;
  IEICQueueObjectWatcher = interface;
  IEICQueueObjectWatcherDisp = dispinterface;
  IEICCallObject = interface;
  IEICCallObjectDisp = dispinterface;
  IEICUser = interface;
  IEICUserDisp = dispinterface;
  IEICUserWatcher = interface;
  IEICUserWatcherDisp = dispinterface;
  IEICWorkgroup = interface;
  IEICWorkgroupDisp = dispinterface;
  IEICWorkgroupWatcher = interface;
  IEICWorkgroupWatcherDisp = dispinterface;
  IEICConferenceObject = interface;
  IEICConferenceObjectDisp = dispinterface;

{ Forward declarations: CoClasses }
  EICConnection = IEICConnection;
  EICQueue = IEICQueue;
  EICQueueWatcher = IEICQueueWatcher;
  EICQueueObject = IEICQueueObject;
  EICQueueObjectWatcher = IEICQueueObjectWatcher;
  EICCallObject = IEICCallObject;
  EICUser = IEICUser;
  EICUserWatcher = IEICUserWatcher;
  EICWorkgroup = IEICWorkgroup;
  EICWorkgroupWatcher = IEICWorkgroupWatcher;
  EICConferenceObject = IEICConferenceObject;

{ IEICConnection Interface }

  IEICConnection = interface(IDispatch)
    ['{DCC7AD42-F185-11D1-BFFE-00A0C9A79E7C}']
    procedure Connect(const p_App, p_Server, p_User, p_Password, p_Station: WideString; p_AutoDisconnect: WordBool); safecall;
    procedure Attach(const p_App, p_Server: WideString; p_AutoDisconnect: WordBool); safecall;
    procedure Disconnect(p_DisconnectUserOnly: WordBool); safecall;
    procedure ForceDisconnect(const p_User, p_Station: WideString; p_DisconnectUserOnly: WordBool); safecall;
    function Get_Server: WideString; safecall;
    function Get_User: WideString; safecall;
    function Get_Station: WideString; safecall;
    procedure PassiveConnect(const p_App, p_Server, p_User, p_Password: WideString; p_AutoDisconnect: WordBool); safecall;
    function Get_ConnectionValid: WordBool; safecall;
    property Server: WideString read Get_Server;
    property User: WideString read Get_User;
    property Station: WideString read Get_Station;
    property ConnectionValid: WordBool read Get_ConnectionValid;
  end;

{ DispInterface declaration for Dual Interface IEICConnection }

  IEICConnectionDisp = dispinterface
    ['{DCC7AD42-F185-11D1-BFFE-00A0C9A79E7C}']
    procedure Connect(const p_App, p_Server, p_User, p_Password, p_Station: WideString; p_AutoDisconnect: WordBool); dispid 1;
    procedure Attach(const p_App, p_Server: WideString; p_AutoDisconnect: WordBool); dispid 2;
    procedure Disconnect(p_DisconnectUserOnly: WordBool); dispid 3;
    procedure ForceDisconnect(const p_User, p_Station: WideString; p_DisconnectUserOnly: WordBool); dispid 4;
    property Server: WideString readonly dispid 5;
    property User: WideString readonly dispid 6;
    property Station: WideString readonly dispid 7;
    procedure PassiveConnect(const p_App, p_Server, p_User, p_Password: WideString; p_AutoDisconnect: WordBool); dispid 8;
    property ConnectionValid: WordBool readonly dispid 9;
  end;

{ IEICQueue Interface }

  IEICQueue = interface(IDispatch)
    ['{DCC7AD43-F185-11D1-BFFE-00A0C9A79E7C}']
    procedure Connect(p_Type: Integer; const p_Name: WideString); safecall;
    procedure SetChangeHandler(const p_Handler: IEICQueueWatcher); safecall;
    function Get_ActiveMonitor: WordBool; safecall;
    procedure Set_ActiveMonitor(Value: WordBool); safecall;
    function GetQueueObject(p_Type, p_Id: Integer): IEICQueueObject; safecall;
    function Get_Objects: OleVariant; safecall;
    function Get_Type_: Integer; safecall;
    function Get_Name: WideString; safecall;
    procedure StartObjectsList; safecall;
    procedure GetNextObject(out p_Type, p_Id: Integer); safecall;
    property ActiveMonitor: WordBool read Get_ActiveMonitor write Set_ActiveMonitor;
    property Objects: OleVariant read Get_Objects;
    property Type_: Integer read Get_Type_;
    property Name: WideString read Get_Name;
  end;

{ DispInterface declaration for Dual Interface IEICQueue }

  IEICQueueDisp = dispinterface
    ['{DCC7AD43-F185-11D1-BFFE-00A0C9A79E7C}']
    procedure Connect(p_Type: Integer; const p_Name: WideString); dispid 1;
    procedure SetChangeHandler(const p_Handler: IEICQueueWatcher); dispid 2;
    property ActiveMonitor: WordBool dispid 3;
    function GetQueueObject(p_Type, p_Id: Integer): IEICQueueObject; dispid 4;
    property Objects: OleVariant readonly dispid 5;
    property Type_: Integer readonly dispid 6;
    property Name: WideString readonly dispid 7;
    procedure StartObjectsList; dispid 8;
    procedure GetNextObject(out p_Type, p_Id: Integer); dispid 9;
  end;

{ IEICQueueWatcher Interface }

  IEICQueueWatcher = interface(IDispatch)
    ['{DCC7AD44-F185-11D1-BFFE-00A0C9A79E7C}']
    procedure ObjectAdded(p_Type, p_Id: Integer); safecall;
    procedure ObjectChanged(p_Type, p_Id: Integer); safecall;
    procedure ObjectRemoved(p_Type, p_Id: Integer); safecall;
  end;

{ DispInterface declaration for Dual Interface IEICQueueWatcher }

  IEICQueueWatcherDisp = dispinterface
    ['{DCC7AD44-F185-11D1-BFFE-00A0C9A79E7C}']
    procedure ObjectAdded(p_Type, p_Id: Integer); dispid 1;
    procedure ObjectChanged(p_Type, p_Id: Integer); dispid 2;
    procedure ObjectRemoved(p_Type, p_Id: Integer); dispid 3;
  end;

{ IEICQueueObject Interface }

  IEICQueueObject = interface(IDispatch)
    ['{DCC7AD45-F185-11D1-BFFE-00A0C9A79E7C}']
    function Get_State: Integer; safecall;
    function Get_StateString: WideString; safecall;
    procedure Set_StateString(const Value: WideString); safecall;
    procedure Pickup(const p_IfOnUserQueue: WideString); safecall;
    procedure Disconnect(const p_IfOnUserQueue: WideString); safecall;
    procedure SetChangeHandler(const p_Handler: IEICQueueObjectWatcher); safecall;
    function Get_Id: Integer; safecall;
    procedure Set_Id(Value: Integer); safecall;
    function Get_LocalName: WideString; safecall;
    function Get_LocalLocation: WideString; safecall;
    function Get_RemoteName: WideString; safecall;
    procedure Set_RemoteName(const Value: WideString); safecall;
    function Get_RemoteLocation: WideString; safecall;
    function Get_LocalId: WideString; safecall;
    function Get_RemoteId: WideString; safecall;
    function Get_CreationTime: TDateTime; safecall;
    procedure GetCreationTime(out hour, minute, second: Smallint); safecall;
    function Get_Direction: Smallint; safecall;
    function Get_NamedAttribute(const p_Name: WideString): WideString; safecall;
    procedure Set_NamedAttribute(const p_Name: WideString; const Value: WideString); safecall;
    procedure GetNamedAttribute(const p_Name: WideString; out p_Value: WideString); safecall;
    procedure SetNamedAttribute(const p_Name, p_Value: WideString); safecall;
    property State: Integer read Get_State;
    property StateString: WideString read Get_StateString write Set_StateString;
    property Id: Integer read Get_Id write Set_Id;
    property LocalName: WideString read Get_LocalName;
    property LocalLocation: WideString read Get_LocalLocation;
    property RemoteName: WideString read Get_RemoteName write Set_RemoteName;
    property RemoteLocation: WideString read Get_RemoteLocation;
    property LocalId: WideString read Get_LocalId;
    property RemoteId: WideString read Get_RemoteId;
    property CreationTime: TDateTime read Get_CreationTime;
    property Direction: Smallint read Get_Direction;
    property NamedAttribute[const p_Name: WideString]: WideString read Get_NamedAttribute write Set_NamedAttribute;
  end;

{ DispInterface declaration for Dual Interface IEICQueueObject }

  IEICQueueObjectDisp = dispinterface
    ['{DCC7AD45-F185-11D1-BFFE-00A0C9A79E7C}']
    property State: Integer readonly dispid 1;
    property StateString: WideString dispid 2;
    procedure Pickup(const p_IfOnUserQueue: WideString); dispid 3;
    procedure Disconnect(const p_IfOnUserQueue: WideString); dispid 4;
    procedure SetChangeHandler(const p_Handler: IEICQueueObjectWatcher); dispid 5;
    property Id: Integer dispid 6;
    property LocalName: WideString readonly dispid 7;
    property LocalLocation: WideString readonly dispid 8;
    property RemoteName: WideString dispid 9;
    property RemoteLocation: WideString readonly dispid 10;
    property LocalId: WideString readonly dispid 11;
    property RemoteId: WideString readonly dispid 12;
    property CreationTime: TDateTime readonly dispid 13;
    procedure GetCreationTime(out hour, minute, second: Smallint); dispid 14;
    property Direction: Smallint readonly dispid 15;
    property NamedAttribute[const p_Name: WideString]: WideString dispid 16;
    procedure GetNamedAttribute(const p_Name: WideString; out p_Value: WideString); dispid 17;
    procedure SetNamedAttribute(const p_Name, p_Value: WideString); dispid 18;
  end;

{ IEICQueueObjectWatcher Interface }

  IEICQueueObjectWatcher = interface(IDispatch)
    ['{B638F3B8-F4A4-11D1-BFFE-00A0C9A79E7C}']
    procedure StateChanged(p_NewState: Integer; const p_StateString: WideString); safecall;
    procedure ObjectSpecificChange; safecall;
    procedure ObjectDestroyed; safecall;
    procedure ObjectSpecificError(p_Error: Integer); safecall;
    procedure SubObjectChanged(p_Type, p_Id, p_Change: Integer); safecall;
  end;

{ DispInterface declaration for Dual Interface IEICQueueObjectWatcher }

  IEICQueueObjectWatcherDisp = dispinterface
    ['{B638F3B8-F4A4-11D1-BFFE-00A0C9A79E7C}']
    procedure StateChanged(p_NewState: Integer; const p_StateString: WideString); dispid 1;
    procedure ObjectSpecificChange; dispid 2;
    procedure ObjectDestroyed; dispid 3;
    procedure ObjectSpecificError(p_Error: Integer); dispid 4;
    procedure SubObjectChanged(p_Type, p_Id, p_Change: Integer); dispid 5;
  end;

{ IEICCallObject Interface }

  IEICCallObject = interface(IDispatch)
    ['{ED55B8B5-F4B0-11D1-BFFE-00A0C9A79E7C}']
    function Get_State: Integer; safecall;
    function Get_StateString: WideString; safecall;
    procedure Set_StateString(const Value: WideString); safecall;
    procedure Pickup(const p_IfOnUserQueue: WideString); safecall;
    procedure Disconnect(const p_IfOnUserQueue: WideString); safecall;
    procedure SetChangeHandler(const p_Handler: IEICQueueObjectWatcher); safecall;
    function Get_Id: Integer; safecall;
    procedure Set_Id(Value: Integer); safecall;
    function Get_LocalName: WideString; safecall;
    function Get_LocalLocation: WideString; safecall;
    function Get_RemoteName: WideString; safecall;
    procedure Set_RemoteName(const Value: WideString); safecall;
    function Get_RemoteLocation: WideString; safecall;
    function Get_LocalId: WideString; safecall;
    function Get_RemoteId: WideString; safecall;
    function Get_CreationTime: TDateTime; safecall;
    procedure GetCreationTime(out hour, minute, second: Smallint); safecall;
    function Get_Direction: Smallint; safecall;
    procedure GetNamedAttribute(const p_Name: WideString; out p_Value: WideString); safecall;
    procedure SetNamedAttribute(const p_Name, p_Value: WideString); safecall;
    procedure ExtendedDial(const p_Number: WideString; p_TimeoutSecs: Smallint; p_CallAnalysis, p_CallHandlerOnSuccess: WordBool); safecall;
    procedure Dial(const p_Number: WideString; p_CallHandlerOnSuccess: WordBool); safecall;
    procedure Listen(const p_IfOnUserQueue: WideString); safecall;
    procedure Record_(const p_IfOnUserQueue: WideString); safecall;
    procedure Pause; safecall;
    procedure Mute(const p_IfOnUserQueue: WideString); safecall;
    procedure Hold(const p_ToUserQueue, p_IfOnUserQueue: WideString); safecall;
    procedure Private_(const p_IfOnUserQueue: WideString); safecall;
    procedure BlindTransfer(const p_ToNumber, p_IfOnUserQueue: WideString); safecall;
    procedure ConsultTransfer(p_WithCall: Integer; const p_IfOnUserQueue: WideString); safecall;
    procedure SendToVoiceMail(const p_IfOnUserQueue: WideString); safecall;
    function Get_isHeld: WordBool; safecall;
    function Get_isRecording: WordBool; safecall;
    function Get_isPaused: WordBool; safecall;
    function Get_isMuted: WordBool; safecall;
    function Get_isPrivate: WordBool; safecall;
    function Get_isMonitored: WordBool; safecall;
    procedure PlayDigits(const p_StringOfDigits: WideString); safecall;
    function Get_isParty: WordBool; safecall;
    function Get_ConferenceId: Integer; safecall;
    property State: Integer read Get_State;
    property StateString: WideString read Get_StateString write Set_StateString;
    property Id: Integer read Get_Id write Set_Id;
    property LocalName: WideString read Get_LocalName;
    property LocalLocation: WideString read Get_LocalLocation;
    property RemoteName: WideString read Get_RemoteName write Set_RemoteName;
    property RemoteLocation: WideString read Get_RemoteLocation;
    property LocalId: WideString read Get_LocalId;
    property RemoteId: WideString read Get_RemoteId;
    property CreationTime: TDateTime read Get_CreationTime;
    property Direction: Smallint read Get_Direction;
    property isHeld: WordBool read Get_isHeld;
    property isRecording: WordBool read Get_isRecording;
    property isPaused: WordBool read Get_isPaused;
    property isMuted: WordBool read Get_isMuted;
    property isPrivate: WordBool read Get_isPrivate;
    property isMonitored: WordBool read Get_isMonitored;
    property isParty: WordBool read Get_isParty;
    property ConferenceId: Integer read Get_ConferenceId;
  end;

{ DispInterface declaration for Dual Interface IEICCallObject }

  IEICCallObjectDisp = dispinterface
    ['{ED55B8B5-F4B0-11D1-BFFE-00A0C9A79E7C}']
    property State: Integer readonly dispid 1;
    property StateString: WideString dispid 2;
    procedure Pickup(const p_IfOnUserQueue: WideString); dispid 3;
    procedure Disconnect(const p_IfOnUserQueue: WideString); dispid 4;
    procedure SetChangeHandler(const p_Handler: IEICQueueObjectWatcher); dispid 5;
    property Id: Integer dispid 6;
    property LocalName: WideString readonly dispid 7;
    property LocalLocation: WideString readonly dispid 8;
    property RemoteName: WideString dispid 9;
    property RemoteLocation: WideString readonly dispid 10;
    property LocalId: WideString readonly dispid 11;
    property RemoteId: WideString readonly dispid 12;
    property CreationTime: TDateTime readonly dispid 13;
    procedure GetCreationTime(out hour, minute, second: Smallint); dispid 14;
    property Direction: Smallint readonly dispid 15;
    procedure GetNamedAttribute(const p_Name: WideString; out p_Value: WideString); dispid 16;
    procedure SetNamedAttribute(const p_Name, p_Value: WideString); dispid 17;
    procedure ExtendedDial(const p_Number: WideString; p_TimeoutSecs: Smallint; p_CallAnalysis, p_CallHandlerOnSuccess: WordBool); dispid 101;
    procedure Dial(const p_Number: WideString; p_CallHandlerOnSuccess: WordBool); dispid 102;
    procedure Listen(const p_IfOnUserQueue: WideString); dispid 103;
    procedure Record_(const p_IfOnUserQueue: WideString); dispid 104;
    procedure Pause; dispid 105;
    procedure Mute(const p_IfOnUserQueue: WideString); dispid 106;
    procedure Hold(const p_ToUserQueue, p_IfOnUserQueue: WideString); dispid 107;
    procedure Private_(const p_IfOnUserQueue: WideString); dispid 108;
    procedure BlindTransfer(const p_ToNumber, p_IfOnUserQueue: WideString); dispid 109;
    procedure ConsultTransfer(p_WithCall: Integer; const p_IfOnUserQueue: WideString); dispid 110;
    procedure SendToVoiceMail(const p_IfOnUserQueue: WideString); dispid 111;
    property isHeld: WordBool readonly dispid 112;
    property isRecording: WordBool readonly dispid 113;
    property isPaused: WordBool readonly dispid 114;
    property isMuted: WordBool readonly dispid 115;
    property isPrivate: WordBool readonly dispid 116;
    property isMonitored: WordBool readonly dispid 117;
    procedure PlayDigits(const p_StringOfDigits: WideString); dispid 118;
    property isParty: WordBool readonly dispid 119;
    property ConferenceId: Integer readonly dispid 120;
  end;

{ IEICUser Interface }

  IEICUser = interface(IDispatch)
    ['{871962B3-FA2D-11D1-8001-00A0C9A79E7C}']
    function Get_Id: WideString; safecall;
    procedure Set_Id(const Value: WideString); safecall;
    function Get_Name: WideString; safecall;
    function Get_AvailableStatusMessages: OleVariant; safecall;
    function Get_StatusMessage: WideString; safecall;
    procedure Set_StatusMessage(const Value: WideString); safecall;
    function Get_isDND: WordBool; safecall;
    function Get_UntilDateTime: TDateTime; safecall;
    procedure Set_UntilDateTime(Value: TDateTime); safecall;
    procedure SetUntilDateTime(year, month, day, hour, minute: Smallint); safecall;
    procedure GetUntilDateTime(out year, month, day, hour, minute: Smallint); safecall;
    function Get_isOnPhone: WordBool; safecall;
    function Get_Extension: WideString; safecall;
    procedure SetChangeHandler(const p_Handler: IEICUserWatcher); safecall;
    procedure Call(out p_CallId: Integer); safecall;
    procedure Workgroups(out p_Workgroups: OleVariant); safecall;
    procedure ViewableWorkgroups(out p_Workgroups: OleVariant); safecall;
    procedure AccessibleQueues(out p_Queues: OleVariant); safecall;
    function Get_CanRecord: WordBool; safecall;
    function Get_CanListen: WordBool; safecall;
    function Get_CanMakePrivate: WordBool; safecall;
    procedure StartWorkgroupsList; safecall;
    procedure GetNextWorkgroup(out p_Name: WideString); safecall;
    procedure StartViewableWorkgroupsList; safecall;
    procedure GetNextViewableWorkgroup(out p_Name: WideString); safecall;
    procedure StartAccessibleQueuesList; safecall;
    procedure GetNextAccessibleQueues(out p_Name: WideString; out p_Type: Integer; out p_Modifiable: WordBool); safecall;
    property Id: WideString read Get_Id write Set_Id;
    property Name: WideString read Get_Name;
    property AvailableStatusMessages: OleVariant read Get_AvailableStatusMessages;
    property StatusMessage: WideString read Get_StatusMessage write Set_StatusMessage;
    property isDND: WordBool read Get_isDND;
    property UntilDateTime: TDateTime read Get_UntilDateTime write Set_UntilDateTime;
    property isOnPhone: WordBool read Get_isOnPhone;
    property Extension: WideString read Get_Extension;
    property CanRecord: WordBool read Get_CanRecord;
    property CanListen: WordBool read Get_CanListen;
    property CanMakePrivate: WordBool read Get_CanMakePrivate;
  end;

{ DispInterface declaration for Dual Interface IEICUser }

  IEICUserDisp = dispinterface
    ['{871962B3-FA2D-11D1-8001-00A0C9A79E7C}']
    property Id: WideString dispid 1;
    property Name: WideString readonly dispid 2;
    property AvailableStatusMessages: OleVariant readonly dispid 3;
    property StatusMessage: WideString dispid 4;
    property isDND: WordBool readonly dispid 5;
    property UntilDateTime: TDateTime dispid 6;
    procedure SetUntilDateTime(year, month, day, hour, minute: Smallint); dispid 7;
    procedure GetUntilDateTime(out year, month, day, hour, minute: Smallint); dispid 8;
    property isOnPhone: WordBool readonly dispid 9;
    property Extension: WideString readonly dispid 10;
    procedure SetChangeHandler(const p_Handler: IEICUserWatcher); dispid 11;
    procedure Call(out p_CallId: Integer); dispid 12;
    procedure Workgroups(out p_Workgroups: OleVariant); dispid 13;
    procedure ViewableWorkgroups(out p_Workgroups: OleVariant); dispid 14;
    procedure AccessibleQueues(out p_Queues: OleVariant); dispid 15;
    property CanRecord: WordBool readonly dispid 16;
    property CanListen: WordBool readonly dispid 17;
    property CanMakePrivate: WordBool readonly dispid 18;
    procedure StartWorkgroupsList; dispid 19;
    procedure GetNextWorkgroup(out p_Name: WideString); dispid 20;
    procedure StartViewableWorkgroupsList; dispid 21;
    procedure GetNextViewableWorkgroup(out p_Name: WideString); dispid 22;
    procedure StartAccessibleQueuesList; dispid 23;
    procedure GetNextAccessibleQueues(out p_Name: WideString; out p_Type: Integer; out p_Modifiable: WordBool); dispid 24;
  end;

{ IEICUserWatcher Interface }

  IEICUserWatcher = interface(IDispatch)
    ['{918EBE75-FA5D-11D1-8001-00A0C9A79E7C}']
    procedure StatusChanged(const p_NewStatus: WideString; p_UntilDateTime: TDateTime); safecall;
    procedure UserChanged; safecall;
  end;

{ DispInterface declaration for Dual Interface IEICUserWatcher }

  IEICUserWatcherDisp = dispinterface
    ['{918EBE75-FA5D-11D1-8001-00A0C9A79E7C}']
    procedure StatusChanged(const p_NewStatus: WideString; p_UntilDateTime: TDateTime); dispid 1;
    procedure UserChanged; dispid 2;
  end;

{ IEICWorkgroup Interface }

  IEICWorkgroup = interface(IDispatch)
    ['{C574F7B5-FEDE-11D1-8001-00A0C9A79E7C}']
    procedure GetWorkgroupMembers(out p_UserIds: OleVariant); safecall;
    procedure SetChangeHandler(const p_Handler: IEICWorkgroupWatcher; p_MonitorIndividuals: WordBool); safecall;
    function Get_Id: WideString; safecall;
    procedure Set_Id(const Value: WideString); safecall;
    function Get_Extension: WideString; safecall;
    procedure StartMembersList; safecall;
    procedure GetNextMember(out p_UserId: WideString); safecall;
    property Id: WideString read Get_Id write Set_Id;
    property Extension: WideString read Get_Extension;
  end;

{ DispInterface declaration for Dual Interface IEICWorkgroup }

  IEICWorkgroupDisp = dispinterface
    ['{C574F7B5-FEDE-11D1-8001-00A0C9A79E7C}']
    procedure GetWorkgroupMembers(out p_UserIds: OleVariant); dispid 1;
    procedure SetChangeHandler(const p_Handler: IEICWorkgroupWatcher; p_MonitorIndividuals: WordBool); dispid 2;
    property Id: WideString dispid 3;
    property Extension: WideString readonly dispid 4;
    procedure StartMembersList; dispid 5;
    procedure GetNextMember(out p_UserId: WideString); dispid 6;
  end;

{ IEICWorkgroupWatcher Interface }

  IEICWorkgroupWatcher = interface(IDispatch)
    ['{C574F7B7-FEDE-11D1-8001-00A0C9A79E7C}']
    procedure UserAdded(const p_UserId: WideString); safecall;
    procedure UserChanged(const p_UserId, p_Status: WideString; p_UntilDateTime: TDateTime); safecall;
    procedure UserRemoved(const p_UserId: WideString); safecall;
  end;

{ DispInterface declaration for Dual Interface IEICWorkgroupWatcher }

  IEICWorkgroupWatcherDisp = dispinterface
    ['{C574F7B7-FEDE-11D1-8001-00A0C9A79E7C}']
    procedure UserAdded(const p_UserId: WideString); dispid 1;
    procedure UserChanged(const p_UserId, p_Status: WideString; p_UntilDateTime: TDateTime); dispid 2;
    procedure UserRemoved(const p_UserId: WideString); dispid 3;
  end;

{ IEICConferenceObject Interface. Most of the Queue Object functions are not implemented in 1.0 }

  IEICConferenceObject = interface(IDispatch)
    ['{661ABFE5-0523-11D2-8009-00A0C9A79E7C}']
    procedure Create(const p_Call: IEICCallObject); safecall;
    procedure Add(const p_Call: IEICCallObject); safecall;
    procedure ListMembers(out p_ArrayOfCallIds: OleVariant); safecall;
    procedure SetChangeHandler(const p_Handler: IEICQueueObjectWatcher); safecall;
    procedure DisconnectParty(p_CallId: Integer); safecall;
    function Get_Id: Integer; safecall;
    procedure Set_Id(Value: Integer); safecall;
    procedure StartMembersList; safecall;
    procedure GetNextMember(out p_CallId: Integer); safecall;
    property Id: Integer read Get_Id write Set_Id;
  end;

{ DispInterface declaration for Dual Interface IEICConferenceObject }

  IEICConferenceObjectDisp = dispinterface
    ['{661ABFE5-0523-11D2-8009-00A0C9A79E7C}']
    procedure Create(const p_Call: IEICCallObject); dispid 1;
    procedure Add(const p_Call: IEICCallObject); dispid 2;
    procedure ListMembers(out p_ArrayOfCallIds: OleVariant); dispid 3;
    procedure SetChangeHandler(const p_Handler: IEICQueueObjectWatcher); dispid 4;
    procedure DisconnectParty(p_CallId: Integer); dispid 5;
    property Id: Integer dispid 6;
    procedure StartMembersList; dispid 7;
    procedure GetNextMember(out p_CallId: Integer); dispid 8;
  end;

{ EICConnection Class }

  CoEICConnection = class
    class function Create: IEICConnection;
    class function CreateRemote(const MachineName: string): IEICConnection;
  end;

{ EICQueue Class }

  CoEICQueue = class
    class function Create: IEICQueue;
    class function CreateRemote(const MachineName: string): IEICQueue;
  end;

{ EICQueueWatcher Class }

  CoEICQueueWatcher = class
    class function Create: IEICQueueWatcher;
    class function CreateRemote(const MachineName: string): IEICQueueWatcher;
  end;

{ EICQueueObject Class }

  CoEICQueueObject = class
    class function Create: IEICQueueObject;
    class function CreateRemote(const MachineName: string): IEICQueueObject;
  end;

{ EICQueueObjectWatcher Class }

  CoEICQueueObjectWatcher = class
    class function Create: IEICQueueObjectWatcher;
    class function CreateRemote(const MachineName: string): IEICQueueObjectWatcher;
  end;

{ EICCallObject Class }

  CoEICCallObject = class
    class function Create: IEICCallObject;
    class function CreateRemote(const MachineName: string): IEICCallObject;
  end;

{ EICUser Class }

  CoEICUser = class
    class function Create: IEICUser;
    class function CreateRemote(const MachineName: string): IEICUser;
  end;

{ EICUserWatcher Class }

  CoEICUserWatcher = class
    class function Create: IEICUserWatcher;
    class function CreateRemote(const MachineName: string): IEICUserWatcher;
  end;

{ EICWorkgroup Class }

  CoEICWorkgroup = class
    class function Create: IEICWorkgroup;
    class function CreateRemote(const MachineName: string): IEICWorkgroup;
  end;

{ EICWorkgroupWatcher Class }

  CoEICWorkgroupWatcher = class
    class function Create: IEICWorkgroupWatcher;
    class function CreateRemote(const MachineName: string): IEICWorkgroupWatcher;
  end;

{ EICConferenceObject Class }

  CoEICConferenceObject = class
    class function Create: IEICConferenceObject;
    class function CreateRemote(const MachineName: string): IEICConferenceObject;
  end;



implementation

uses ComObj;

class function CoEICConnection.Create: IEICConnection;
begin
  Result := CreateComObject(Class_EICConnection) as IEICConnection;
end;

class function CoEICConnection.CreateRemote(const MachineName: string): IEICConnection;
begin
  Result := CreateRemoteComObject(MachineName, Class_EICConnection) as IEICConnection;
end;

class function CoEICQueue.Create: IEICQueue;
begin
  Result := CreateComObject(Class_EICQueue) as IEICQueue;
end;

class function CoEICQueue.CreateRemote(const MachineName: string): IEICQueue;
begin
  Result := CreateRemoteComObject(MachineName, Class_EICQueue) as IEICQueue;
end;

class function CoEICQueueWatcher.Create: IEICQueueWatcher;
begin
  Result := CreateComObject(Class_EICQueueWatcher) as IEICQueueWatcher;
end;

class function CoEICQueueWatcher.CreateRemote(const MachineName: string): IEICQueueWatcher;
begin
  Result := CreateRemoteComObject(MachineName, Class_EICQueueWatcher) as IEICQueueWatcher;
end;

class function CoEICQueueObject.Create: IEICQueueObject;
begin
  Result := CreateComObject(Class_EICQueueObject) as IEICQueueObject;
end;

class function CoEICQueueObject.CreateRemote(const MachineName: string): IEICQueueObject;
begin
  Result := CreateRemoteComObject(MachineName, Class_EICQueueObject) as IEICQueueObject;
end;

class function CoEICQueueObjectWatcher.Create: IEICQueueObjectWatcher;
begin
  Result := CreateComObject(Class_EICQueueObjectWatcher) as IEICQueueObjectWatcher;
end;

class function CoEICQueueObjectWatcher.CreateRemote(const MachineName: string): IEICQueueObjectWatcher;
begin
  Result := CreateRemoteComObject(MachineName, Class_EICQueueObjectWatcher) as IEICQueueObjectWatcher;
end;

class function CoEICCallObject.Create: IEICCallObject;
begin
  Result := CreateComObject(Class_EICCallObject) as IEICCallObject;
end;

class function CoEICCallObject.CreateRemote(const MachineName: string): IEICCallObject;
begin
  Result := CreateRemoteComObject(MachineName, Class_EICCallObject) as IEICCallObject;
end;

class function CoEICUser.Create: IEICUser;
begin
  Result := CreateComObject(Class_EICUser) as IEICUser;
end;

class function CoEICUser.CreateRemote(const MachineName: string): IEICUser;
begin
  Result := CreateRemoteComObject(MachineName, Class_EICUser) as IEICUser;
end;

class function CoEICUserWatcher.Create: IEICUserWatcher;
begin
  Result := CreateComObject(Class_EICUserWatcher) as IEICUserWatcher;
end;

class function CoEICUserWatcher.CreateRemote(const MachineName: string): IEICUserWatcher;
begin
  Result := CreateRemoteComObject(MachineName, Class_EICUserWatcher) as IEICUserWatcher;
end;

class function CoEICWorkgroup.Create: IEICWorkgroup;
begin
  Result := CreateComObject(Class_EICWorkgroup) as IEICWorkgroup;
end;

class function CoEICWorkgroup.CreateRemote(const MachineName: string): IEICWorkgroup;
begin
  Result := CreateRemoteComObject(MachineName, Class_EICWorkgroup) as IEICWorkgroup;
end;

class function CoEICWorkgroupWatcher.Create: IEICWorkgroupWatcher;
begin
  Result := CreateComObject(Class_EICWorkgroupWatcher) as IEICWorkgroupWatcher;
end;

class function CoEICWorkgroupWatcher.CreateRemote(const MachineName: string): IEICWorkgroupWatcher;
begin
  Result := CreateRemoteComObject(MachineName, Class_EICWorkgroupWatcher) as IEICWorkgroupWatcher;
end;

class function CoEICConferenceObject.Create: IEICConferenceObject;
begin
  Result := CreateComObject(Class_EICConferenceObject) as IEICConferenceObject;
end;

class function CoEICConferenceObject.CreateRemote(const MachineName: string): IEICConferenceObject;
begin
  Result := CreateRemoteComObject(MachineName, Class_EICConferenceObject) as IEICConferenceObject;
end;


end.
0
 
LVL 20

Expert Comment

by:Madshi
ID: 1339792
loucks,

yes, you're using a factory now (it's the line in the initialization).
What is now your problem? It is that the window caption isn't drawed? I don't understand why that doesn't work because in your project is the line "Application.Run" (is always there). And this function IS a message loop. So your window should always be redrawed if necessary.
Perhaps your program is hanging around somewhere, but don't ask my where... I can't see that from your sources.
However, you should delete the "_Release" statements in Form.Destroy, because Delphi releases the interfaces for you. Delphi might get in trouble if you call "_Release". That's why there is a "_" before the "Release". But that cannot be the problem because it is in Form.Destroy...
Perhaps you should try to call Application.ProcessMessages after changing the caption of the form. Probably that would work. But that would only hide the real problem. The problem seems to be, that the application is hanging.
You could test if your application is still handling messages by adding a timer component and beeping in it's event handler.

Don't know what to say further...   :-(
Perhaps it helps a little bit.

Regards, Madshi.
0
 

Author Comment

by:loucks
ID: 1339793
It is weird.  When I have ShowMessage in there...  The beeping that is coming from the Timer event stops after a delay of 5 to 10 seconds after the handler is fired and showmessage should run...

Otherwise, if the ShowMessage isn't in there, it works fine, but the caption is not updated.  The beeping does work.  The caption only gets updated when I click on the form.  Then the caption is correct.
0
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 
LVL 20

Expert Comment

by:Madshi
ID: 1339794
Ahhh... I think I have it!

Try to use "windows.MessageBox" instead of ShowMessage. If that works then the problem is probably the following:
Delphi's VCL is not thread safe (this is the last really annoying Delphi problem). That means you can't use the VCL in other threads than the main thread. I think this 3rd party dll calls you in a way that the code of your program is executed in the context of another thread, not in the context of your main thread. I don't know why it should be this way (I don't know how COM works in detail) but the problems you have with ShowMessage and Form.Caption look like that.
If "windows.MessageBox" really works then please display in that MessageBox the two values "GetCurrentProcessID" and "GetCurrentThreadID". Furthermore in Form.Create display these values, too. If the values from Form.Create and the event handler differ, than you've a thread problem.

Regards, Madshi.
0
 

Author Comment

by:loucks
ID: 1339795
U have nailed it down...  Thread problem... The Process ID's were identical.  Thread ID's different....  Windows.MessageBox works fine.  

U have answered two questions so tell me how many points you want...  

How do I make this work now?  Is there any way to make it so I can update the form from this 'other' thread?   Something like the synchronize idea?
0
 
LVL 20

Accepted Solution

by:
Madshi earned 600 total points
ID: 1339796
loucks,

I suggest adding an event handler to the private part of your main form.

const CMsg_MySync = WM_USER+777;

type
  TForm1 = class(TForm)
    ...
  private
    ...
    procedure MySync(var Message: TMessage); message Msg_MySync;
  end;

procedure TForm1.MySync(var Message: TMessage);
var s1 : string;
begin
  if (Message.wParam=777) and (Message.lParam=777) and
     RegRdStr(HKEY_LOCAL_MACHINE,CYCsRegPath+'fileName',s1) then begin
    ShowMessage...
  end;
end;

and in the handler of that "alien" thread just call "PostMessage(Form1.handle,CMsg_MySync,777,777)" or "SendMessage(...)". I think now it should work. That's what the syncronize function of TThread does.

Don't know how many points this is worth. That's your decision!    :-)

Regards, Madshi.

(You can leave it with 200 points)
0
 

Author Comment

by:loucks
ID: 1339797
Good job! Just what I wanted... but I had to take out this part to get it to work  (I don't have RegRdStr or CYCsRegPath)

and RegRdStr(HKEY_LOCAL_MACHINE,CYCsRegPath+'fileName',s1)

do I need it?
0
 
LVL 20

Expert Comment

by:Madshi
ID: 1339798
No you don't need it. I copied these lines from another answer I posted a few minutes ago. I just forgot to delete this part of the sources...
0
 
LVL 20

Expert Comment

by:Madshi
ID: 1339799
Wow, 600 points? My best hiscore so far! Thanx...   :-)
0
 

Author Comment

by:loucks
ID: 1339800
Thanks so much for all your excellent help.  (And the three answers..)
0
 

Author Comment

by:loucks
ID: 1339801
Thanks so much for all your excellent help.  (And the three answers..)
0
 
LVL 20

Expert Comment

by:Madshi
ID: 1339802
I'm glad I could help you...
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

Suggested Solutions

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now