473,385 Members | 1,602 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

TAPI 3 and C# -- Has anyone gotten it to work??

I'm rewriting a C++ TAPI app I wrote a while ago in C#. Everything
works fine for the first call. Unfortunately, all subsequent calls are
completely ignored by TAPI until I restart the app again.

I remember running into this same problem with my original C++ code and
it was being caused by my failure to release all call related tapi
resources. As a point of reference the C++ app has been running quite
well for over a year.

Anyway, I beleive I'm releasing all the tapi interfaces when I'm done
with them but nothing I've done has solved the problem. I'm at a
complete loss as to what might be causing the problem. Any thoughts
would be greatly appreciated.

Here's the code:
========================

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Runtime.InteropServices;

using TAPI3Lib;

namespace CallManager
{
/// <summary>
/// Summary description for TapiMsgWindow.
/// </summary>
public class TapiMsgWindow : System.Windows.Forms.Form
{
public delegate void TapiInitializationDelegate(object sender, bool
success);
public event TapiInitializationDelegate TapiInitialization;

public delegate void CallNotificationDelegate(object sender);
public event CallNotificationDelegate CallNotification;

public delegate void CallStateDelegate(object sender,
TAPI3Lib.CALL_STATE callState);
public event CallStateDelegate CallState;

public delegate void CallInfoDelegate(object sender,
CALLINFOCHANGE_CAUSE cic);
public event CallInfoDelegate CallInfo;

public delegate void CallerIDEventDelegate(object sender,
CallerIDInfo cidInfo);
public event CallerIDEventDelegate CallerIDEvent;

public enum MEDIATYPE
{
MediaAudio = 8,
MediaModem = 16,
MediaFax = 32,
MediaVideo = 32768,
}

private MainForm _ParentForm = null;
private TAPI3Lib.TAPIClass _TAPI = null;
private ITAddress ListenAddress = null;
private ITBasicCallControl Call = null;
private int RegEventsResult = -1;
private int mediaTypes = 0;

private bool IsNewCall = false;
private int CurrentRingCount = 0;

/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;

public TapiMsgWindow()
{
InitializeComponent();
}

public TapiMsgWindow(MainForm parentForm) : this()
{
_ParentForm = parentForm;
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
_TAPI.UnregisterNotifications(RegEventsResult);
_TAPI.Shutdown();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.Size = new System.Drawing.Size(300,300);
this.Text = "TapiMsgWindow";
}
#endregion

public bool InitTAPI()
{
bool result = false;
_TAPI = new TAPI3Lib.TAPIClass();

try
{
_TAPI.Initialize();
_TAPI.Event += new
ITTAPIDispatchEventNotification_EventEventHandler( OnTapiEvent);
result = SelectAddress();
}

catch(Exception ex)
{
MessageBox.Show(ex.Message);
result = false;
}

if(TapiInitialization != null)
TapiInitialization(this, result);

return result;
}

private bool SelectAddress()
{
bool result = false;
ITCollection addresses = (ITCollection)_TAPI.Addresses;
ITAddress curAddress = null;
ListenAddress = null;

//Careful here. The array is 1 based NOT 0 based;
for(int i = 1; i <= addresses.Count; i++)
{
curAddress = (ITAddress)addresses[i];

if(curAddress.State == ADDRESS_STATE.AS_INSERVICE)
{
ITMediaSupport mediaSupport = (ITMediaSupport)curAddress;

// Get the supported media types...
mediaTypes = mediaSupport.MediaTypes;
mediaSupport = null;

if((mediaTypes & (int)MEDIATYPE.MediaAudio) ==
(int)MEDIATYPE.MediaAudio)
{
ListenAddress = curAddress;
break;
}
}
}

// Did we find the address we were looking for?
if(ListenAddress != null)
{
RegEventsResult = _TAPI.RegisterCallNotifications(ListenAddress,
true, true, mediaTypes, 1);

_TAPI.EventFilter = (int)(
TAPI_EVENT.TE_CALLNOTIFICATION |
TAPI_EVENT.TE_CALLSTATE |
TAPI_EVENT.TE_DIGITEVENT |
TAPI_EVENT.TE_CALLINFOCHANGE |
TAPI_EVENT.TE_ADDRESS
);
}

else
{
MessageBox.Show("No TAPI address selected");
result = false;
}

result = true;
return result;
}

private void OnTapiEvent(TAPI_EVENT TapiEvent, object pEvent)
{
switch(TapiEvent)
{
case TAPI_EVENT.TE_CALLSTATE:
{
OnCallStateEvent((ITCallStateEvent)pEvent);
break;
}

case TAPI_EVENT.TE_ADDRESS:
{
OnAddressEvent((ITAddressEvent)pEvent);
break;
}

case TAPI_EVENT.TE_CALLNOTIFICATION:
{
OnCallNotifyEvent((ITCallNotificationEvent)pEvent) ;
break;
}

case TAPI_EVENT.TE_CALLINFOCHANGE:
{
OnCallInfoEvent((ITCallInfoChangeEvent)pEvent);
break;
}

case TAPI_EVENT.TE_PHONEEVENT:
{
Marshal.ReleaseComObject(pEvent);
break;
}

case TAPI_EVENT.TE_DIGITEVENT:
{
OnDigitEvent((ITDigitDetectionEvent)pEvent);
break;
}

case TAPI_EVENT.TE_GATHERDIGITS:
{
OnGatherDigits((ITDigitsGatheredEvent)pEvent);
break;
}

case TAPI_EVENT.TE_CALLMEDIA:
{
OnCallMediaChanged((ITCallMediaEvent)pEvent);
break;
}

case TAPI_EVENT.TE_TONEEVENT:
{
OnCallToneEvent((ITToneDetectionEvent)pEvent);
break;
}

default:
{
Marshal.ReleaseComObject(pEvent);
break;
}
}
}

private void OnCallInfoEvent(ITCallInfoChangeEvent pEvent)
{
Console.WriteLine("CallInfoEvent:");
Console.WriteLine(pEvent.Cause.ToString());

if(CallInfo != null)
CallInfo(this, pEvent.Cause);

try
{
if(pEvent.Cause == CALLINFOCHANGE_CAUSE.CIC_CALLERID)
{
if(CurrentRingCount >= 2)
{
string callerIDName =
pEvent.Call.get_CallInfoString(CALLINFO_STRING.CIS _CALLERIDNAME);
string callerIDNumber =
pEvent.Call.get_CallInfoString(CALLINFO_STRING.CIS _CALLERIDNUMBER);
CallerIDInfo cidInfo = new CallerIDInfo(callerIDNumber,
callerIDName);

if(CallerIDEvent != null)
CallerIDEvent(this, cidInfo);
}

}
}

catch(Exception ex)
{
MessageBox.Show(string.Format("CallInfoEvent failed with the
following exception:{0}", ex.Message));
}

finally
{
Marshal.ReleaseComObject(pEvent);
}
}

private void OnDigitEvent(ITDigitDetectionEvent pEvent)
{
try
{
byte digit = pEvent.Digit;
int digitMode = pEvent.DigitMode;
}

finally
{
Marshal.ReleaseComObject(pEvent);
}
}

private void OnGatherDigits(ITDigitsGatheredEvent pEvent)
{
try
{
}

finally
{
Marshal.ReleaseComObject(pEvent);
}
}

private void OnCallMediaChanged(ITCallMediaEvent pEvent)
{
try
{
}

finally
{
Marshal.ReleaseComObject(pEvent);
}
}

private void OnCallToneEvent(ITToneDetectionEvent pEvent)
{
try
{
}

finally
{
Marshal.ReleaseComObject(pEvent);
}
}

private void OnAddressEvent(ITAddressEvent pEvent)
{
ADDRESS_EVENT addressEvent = pEvent.Event;
Marshal.ReleaseComObject(pEvent);

switch(addressEvent)
{
case ADDRESS_EVENT.AE_RINGING:
{
CurrentRingCount++;
break;
}
}
}

private void OnCallNotifyEvent(ITCallNotificationEvent pEvent)
{
CALL_NOTIFICATION_EVENT callEvent = pEvent.Event;

if(Call != null)
{
Marshal.ReleaseComObject(Call);
Call = null;
}

Call = (ITBasicCallControl)(object)pEvent.Call;
IsNewCall = true;

Marshal.ReleaseComObject(pEvent);

switch(callEvent)
{
case CALL_NOTIFICATION_EVENT.CNE_MONITOR:
{
break;
}

case CALL_NOTIFICATION_EVENT.CNE_OWNER:
{
break;
}
}

if(CallNotification != null)
CallNotification(this);
}

private void OnCallStateEvent(ITCallStateEvent pEvent)
{
CALL_STATE state = pEvent.State;
Marshal.ReleaseComObject(pEvent);

if(CallState != null)
CallState(this, state);

switch(state)
{
case CALL_STATE.CS_IDLE:
{
break;
}

case CALL_STATE.CS_INPROGRESS:
{
break;
}
case CALL_STATE.CS_OFFERING:
{
break;
}

case CALL_STATE.CS_CONNECTED:
{
break;
}

case CALL_STATE.CS_QUEUED:
{
break;
}

case CALL_STATE.CS_HOLD:
{
break;
}

case CALL_STATE.CS_DISCONNECTED:
{
CurrentRingCount = 0;
DisconnectTheCall();
ReleaseTheCall();

IsNewCall = false;
break;
}
}
}

private void DisconnectTheCall()
{
Call.Disconnect(DISCONNECT_CODE.DC_NORMAL);
}

private void ReleaseTheCall()
{
Marshal.ReleaseComObject(Call);
Call = null;
}
}
}

Nov 17 '05 #1
7 18702
Well, I got it working by releasing TAPIClass and ITAddress objects and
re-initializing these objects after each call. It's working ok but
this seems a little strange that I would need to go to this extreme.

Thoughts, comments, and suggestions appreciated.

SteveV

Nov 17 '05 #2
No one :(

Nov 17 '05 #3
Per MS it can't work reliably:

http://support.microsoft.com/default...b;en-us;841712

However, Helen Warn has written a nice wrapper which you may want to look
at:

http://www.gotdotnet.com/Community/U...2-b90bf6932414
--
Grant Schenck
<St**********@hotmail.com> wrote in message
news:11*********************@f14g2000cwb.googlegro ups.com...
No one :(

Nov 17 '05 #4
Thanks for the links. I had completely missed the MS kb article. I
had seen Helen's TAPI sample but it's TAPI2 and I was hoping to use my
existing TAPI3 c++ app as a model to minimize the amount of code
rewrite required to convert it to C#. Bummer.

Thanks again,
Steve

Nov 17 '05 #5
Steven
I'm using Tapi with C#. The difference is that i wrote a dll and call it by
C# (everythings, C# just call the functions).

Best regards,
Vuong
Tran xuan

"St**********@hotmail.com" wrote:
Thanks for the links. I had completely missed the MS kb article. I
had seen Helen's TAPI sample but it's TAPI2 and I was hoping to use my
existing TAPI3 c++ app as a model to minimize the amount of code
rewrite required to convert it to C#. Bummer.

Thanks again,
Steve

Nov 17 '05 #6
Hi Steven,
I am starting my first steps in tapi using c #, i find it difficult but I
think your code gives me a good starting point.
Trying to run your code gave errors like :
* The type or namespace name 'MainForm' could not be found (are you missing
a using directive or an assembly reference?)
I tried to solve it by making new windows form of midi type with name
MainForm in namspace CallManger.
* The type or namespace name 'CallerIDInfo' could not be found (are you
missing a using directive or an assembly reference?)
Which i coul not find or solve.

So i will appreciate if you gave a hint how to make it work . or send me a
demo code.
It will be amazing to see working c# code for tapi Applications.
Thanks
Dr.Sameh Ali
dr***********@hotmail.com
"St**********@hotmail.com" wrote:
I'm rewriting a C++ TAPI app I wrote a while ago in C#. Everything
works fine for the first call. Unfortunately, all subsequent calls are
completely ignored by TAPI until I restart the app again.

I remember running into this same problem with my original C++ code and
it was being caused by my failure to release all call related tapi
resources. As a point of reference the C++ app has been running quite
well for over a year.

Anyway, I beleive I'm releasing all the tapi interfaces when I'm done
with them but nothing I've done has solved the problem. I'm at a
complete loss as to what might be causing the problem. Any thoughts
would be greatly appreciated.

Here's the code:
========================

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Runtime.InteropServices;

using TAPI3Lib;

namespace CallManager
{
/// <summary>
/// Summary description for TapiMsgWindow.
/// </summary>
public class TapiMsgWindow : System.Windows.Forms.Form
{
public delegate void TapiInitializationDelegate(object sender, bool
success);
public event TapiInitializationDelegate TapiInitialization;

public delegate void CallNotificationDelegate(object sender);
public event CallNotificationDelegate CallNotification;

public delegate void CallStateDelegate(object sender,
TAPI3Lib.CALL_STATE callState);
public event CallStateDelegate CallState;

public delegate void CallInfoDelegate(object sender,
CALLINFOCHANGE_CAUSE cic);
public event CallInfoDelegate CallInfo;

public delegate void CallerIDEventDelegate(object sender,
CallerIDInfo cidInfo);
public event CallerIDEventDelegate CallerIDEvent;

public enum MEDIATYPE
{
MediaAudio = 8,
MediaModem = 16,
MediaFax = 32,
MediaVideo = 32768,
}

private MainForm _ParentForm = null;
private TAPI3Lib.TAPIClass _TAPI = null;
private ITAddress ListenAddress = null;
private ITBasicCallControl Call = null;
private int RegEventsResult = -1;
private int mediaTypes = 0;

private bool IsNewCall = false;
private int CurrentRingCount = 0;

/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;

public TapiMsgWindow()
{
InitializeComponent();
}

public TapiMsgWindow(MainForm parentForm) : this()
{
_ParentForm = parentForm;
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
_TAPI.UnregisterNotifications(RegEventsResult);
_TAPI.Shutdown();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.Size = new System.Drawing.Size(300,300);
this.Text = "TapiMsgWindow";
}
#endregion

public bool InitTAPI()
{
bool result = false;
_TAPI = new TAPI3Lib.TAPIClass();

try
{
_TAPI.Initialize();
_TAPI.Event += new
ITTAPIDispatchEventNotification_EventEventHandler( OnTapiEvent);
result = SelectAddress();
}

catch(Exception ex)
{
MessageBox.Show(ex.Message);
result = false;
}

if(TapiInitialization != null)
TapiInitialization(this, result);

return result;
}

private bool SelectAddress()
{
bool result = false;
ITCollection addresses = (ITCollection)_TAPI.Addresses;
ITAddress curAddress = null;
ListenAddress = null;

//Careful here. The array is 1 based NOT 0 based;
for(int i = 1; i <= addresses.Count; i++)
{
curAddress = (ITAddress)addresses[i];

if(curAddress.State == ADDRESS_STATE.AS_INSERVICE)
{
ITMediaSupport mediaSupport = (ITMediaSupport)curAddress;

// Get the supported media types...
mediaTypes = mediaSupport.MediaTypes;
mediaSupport = null;

if((mediaTypes & (int)MEDIATYPE.MediaAudio) ==
(int)MEDIATYPE.MediaAudio)
{
ListenAddress = curAddress;
break;
}
}
}

// Did we find the address we were looking for?
if(ListenAddress != null)
{
RegEventsResult = _TAPI.RegisterCallNotifications(ListenAddress,
true, true, mediaTypes, 1);

_TAPI.EventFilter = (int)(
TAPI_EVENT.TE_CALLNOTIFICATION |
TAPI_EVENT.TE_CALLSTATE |
TAPI_EVENT.TE_DIGITEVENT |
TAPI_EVENT.TE_CALLINFOCHANGE |
TAPI_EVENT.TE_ADDRESS
);
}

else
{
MessageBox.Show("No TAPI address selected");
result = false;
}

result = true;
return result;
}

private void OnTapiEvent(TAPI_EVENT TapiEvent, object pEvent)
{
switch(TapiEvent)
{
case TAPI_EVENT.TE_CALLSTATE:
{
OnCallStateEvent((ITCallStateEvent)pEvent);
break;
}

case TAPI_EVENT.TE_ADDRESS:
{
OnAddressEvent((ITAddressEvent)pEvent);
break;
}

case TAPI_EVENT.TE_CALLNOTIFICATION:
{
OnCallNotifyEvent((ITCallNotificationEvent)pEvent) ;
break;
}

case TAPI_EVENT.TE_CALLINFOCHANGE:
{
OnCallInfoEvent((ITCallInfoChangeEvent)pEvent);
break;
}

case TAPI_EVENT.TE_PHONEEVENT:
{
Marshal.ReleaseComObject(pEvent);
break;
}

case TAPI_EVENT.TE_DIGITEVENT:
{
OnDigitEvent((ITDigitDetectionEvent)pEvent);
break;
}

case TAPI_EVENT.TE_GATHERDIGITS:
{
OnGatherDigits((ITDigitsGatheredEvent)pEvent);
break;
}

case TAPI_EVENT.TE_CALLMEDIA:
{
OnCallMediaChanged((ITCallMediaEvent)pEvent);
break;
}

case TAPI_EVENT.TE_TONEEVENT:
{
OnCallToneEvent((ITToneDetectionEvent)pEvent);
break;
}

default:
{
Marshal.ReleaseComObject(pEvent);
break;
}
}
}

private void OnCallInfoEvent(ITCallInfoChangeEvent pEvent)
{
Console.WriteLine("CallInfoEvent:");
Console.WriteLine(pEvent.Cause.ToString());

if(CallInfo != null)
CallInfo(this, pEvent.Cause);

try
{
if(pEvent.Cause == CALLINFOCHANGE_CAUSE.CIC_CALLERID)
{
if(CurrentRingCount >= 2)
{
string callerIDName =
pEvent.Call.get_CallInfoString(CALLINFO_STRING.CIS _CALLERIDNAME);
string callerIDNumber =
pEvent.Call.get_CallInfoString(CALLINFO_STRING.CIS _CALLERIDNUMBER);
CallerIDInfo cidInfo = new CallerIDInfo(callerIDNumber,
callerIDName);

if(CallerIDEvent != null)
CallerIDEvent(this, cidInfo);
}

}
}

catch(Exception ex)
{
MessageBox.Show(string.Format("CallInfoEvent failed with the
following exception:{0}", ex.Message));
}

finally
{
Marshal.ReleaseComObject(pEvent);
}

Nov 17 '05 #7
hala dr. sameh

i quick-checked that code...mainform is just the parent form...and that
calledidinfo is just used for even triggereing as i understood...u can remove
them all and/or rewrite some parts of the code...

or just use/learn from my code in the other thread...

salam...
Dec 25 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: j_mckitrick | last post by:
I've been looking all over for this solution, but I cannot find it. I cannot get even the simple demos for BLT to work. At the first use of any Pmw.Blt.* call, I get this error: ...
1
by: Brian | last post by:
When using this: import parallel p = parallel.Parallel() #open LPT1 p.setData(0x55) I get this:
0
by: BizTalk Architect | last post by:
Hello, C# + TAPI Anyone know a routine which will query the local TAPI provider for all available telephone numbers for a call to be transfered to? Thanks....
1
by: Dr.Sameh Ali | last post by:
I am trying to build IVR system using c# . i know that .net wrapper for tapi does not work well. but it seems that many made it work. So my question: Is there any hope to find a working code that...
10
by: Tommy Vercetti | last post by:
With Visual Studio .NET 2003, I create a new project -> C++ -> Class library (.NET). The instant I include a C++ header file such as: #include <string> or any other standard C++ header I...
4
by: peteh | last post by:
Hi All; I am trying to test the web services consumer example on a DB2 v9 ESE Windows server. I have tried 2 methods which both return the same error:...
3
by: PW | last post by:
Hi, I just bought a SanDisk Cruzer 4GB "U3" thumb drive. Is it possible to run an Access 2003 MDE off of one, complete with data? If so, what would I have to do to get it to work? Just...
5
by: Soren S. Jorgensen | last post by:
Hi, I'm trying to read some messages (native structs) from a kernel mode mini-filter driver. I'm using my own implementation of IAsyncResult to pack/unpack the NativeOverlapped structure, and...
5
by: RSL101 | last post by:
Dear DBAs. I am wondering if anyone gotten good results leaving the, Monitor health of instance and databases (HEALTH_MON) = ON I find the default ON setting causes more problem than its...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.