About two years I first attempted to create a caller ID app in PB (http://www.powerbasic.com/support/pb...ad.php?t=14238). After a few weeks I had to move on to other projects. Well now I am back on this project and still searching for success. The same requirements apply:
1. No specialized external hardware allowed
2. No third party dll's or controls allowed
3. Win 9x-Vista support
I have tried to adapt Mike Trader's example at (http://www.powerbasic.com/support/pb...ad.php?t=24743) to display caller ID information. Here is the entire adapted example:
I changed the privileges to be %LINECALLPRIVILEGE_MONITOR instead of %LINECALLPRIVILEGE_NONE. I click on the "listen" button and it opens the line. When a call comes in, the LINECALLBACKFUNC is never executed. Am I missing some step? I have tried numerous things and nothing has worked. I don't know what else to try at this point.
To make sure that the phone is connect, the modem is giving caller ID info, etc, etc. I tried a nice shareware app called PHONETRAY FREE. This program will alert when an incoming call comes in and work fine. The *strange* thing is that when Phonetray is running, the callback function in my program is executed and work perfectly. Somehow this other app must initialize or unlock something somewhere. Does anybody have any clue what to check for?
Thanks for your effort.
1. No specialized external hardware allowed
2. No third party dll's or controls allowed
3. Win 9x-Vista support
I have tried to adapt Mike Trader's example at (http://www.powerbasic.com/support/pb...ad.php?t=24743) to display caller ID information. Here is the entire adapted example:
Code:
#COMPILE EXE "TAPI09.exe" #DIM ALL %TAPI_CURRENT_VERSION = &h00020000 ' Version 2.0 #IF %TAPI_CURRENT_VERSION >= &h000020000 ' for completeness ' These constants are mutually exclusive - there's no way to specify more ' than one AT a time (AND it doesn't make sense, either) so they're ordinal rather than bits. %LINEINITIALIZEEXOPTION_USEHIDDENWINDOW = &h00000001 ' TAPI v2.0 %LINEINITIALIZEEXOPTION_USEEVENT = &h00000002 ' TAPI v2.0 %LINEINITIALIZEEXOPTION_USECOMPLETIONPORT = &h00000003 ' TAPI v2.0 #ENDIF #INCLUDE "c:\pbwin80\winapi\WIN32API.INC" #INCLUDE "TAPI32.INC" DECLARE FUNCTION CreateConnection( sTitle AS STRING, TotDev AS DWORD ) AS STRING DECLARE FUNCTION NegotiateAPIversions( TotDev AS DWORD, AppAPIver AS DWORD ) AS STRING DECLARE FUNCTION GetLineDevCaps( TotDev AS DWORD ) AS STRING DECLARE FUNCTION GetTAPIStructString( BYVAL ptrTapistruct AS LONG, BYVAL offset AS LONG, BYVAL length AS LONG ) AS STRING DECLARE FUNCTION DeviceInfo( Dev AS LONG ) AS STRING DECLARE FUNCTION DeviceConfigDialog( BYVAL Dev AS LONG, BYVAL OwnerHwnd AS LONG ) AS STRING DECLARE FUNCTION DialingPropertiesDialog( BYVAL Dev AS LONG, BYVAL OwnerHwnd AS LONG, AppAPIver AS DWORD ) AS STRING DECLARE FUNCTION OpenLine( Dev AS LONG ) AS STRING DECLARE FUNCTION ProcessCanonical( hLineApp AS LONG, Dev AS LONG ) AS STRING DECLARE FUNCTION MakeCallAsynch( zNumToDial AS ASCIIZ*%MAX_PATH ) AS STRING DECLARE FUNCTION DropCallAsynch( ) AS STRING DECLARE FUNCTION DeallocateCall( ) AS STRING DECLARE FUNCTION CloseLine( ) AS STRING DECLARE FUNCTION ShutdownLine( ) AS STRING DECLARE FUNCTION PaintDevIcon( BYVAL Dev AS LONG, hIcon AS LONG ) AS STRING DECLARE FUNCTION ShowText( sTxt AS STRING ) AS LONG DECLARE FUNCTION lineCallbackFunc( BYVAL hDevice AS DWORD, BYVAL dwMsg AS DWORD, BYVAL dwCallbackInstance AS DWORD, _ BYVAL dwParam1 AS DWORD,BYVAL dwParam2 AS DWORD,BYVAL dwParam3 AS DWORD ) AS LONG TYPE TapiLineTYPE zLineName AS ASCIIZ*%MAX_PATH ' dwLineNameOffset, dwLineNameSize) zProviderInfo AS ASCIIZ*%MAX_PATH ' dwProviderInfoOffset, dwProviderInfoSize) zSwitchInfo AS ASCIIZ*%MAX_PATH ' dwSwitchInfoOffset, dwSwitchInfoSize) CurrentLineID AS DWORD ' Device Number PermanentLineID AS DWORD ' dwPermanentLineID StringFormat AS DWORD ' dwStringFormat numAddresses AS DWORD ' dwNumAddresses maxDataRate AS DWORD ' dwMaxRate BearerModes AS DWORD ' dwBearerModes AddressModes AS DWORD ' dwAddressModes MediaModes AS DWORD ' dwMediaModes GenerateToneMaxNumFreq AS DWORD ' dwGenerateToneMaxNumFreq GenerateToneModes AS DWORD ' dwGenerateToneModes numTerminals AS DWORD ' dwNumTerminals NegAPIver AS DWORD ' Negotiated API Version ExtAPIver AS LINEEXTENSIONID ' Extension API versions LineSupportsVoiceCalls AS LONG ' Can make a voice call zNumToDial AS ASCIIZ*%MAX_PATH ' Number user wants to dial zDialableString AS ASCIIZ*%MAX_PATH ' Contains all info zDisplayableString AS ASCIIZ*%MAX_PATH ' Does not display Credit card info CurrentCountry AS DWORD ' Country/region code configured in CurrentLocation DestCountry AS DWORD ' Destination country/region code of the translated address TranslateResults AS DWORD ' Code to string contents TranslateDefn AS STRING*48 ' Explanation of Translation Result END TYPE GLOBAL TapiLine() AS TapiLineTYPE GLOBAL RequestingCall, DroppingCall AS LONG ' Global call state flags GLOBAL hDbg, hDlg, hCall, hLine, hLineApp, Done AS LONG GLOBAL lpfnCallback AS DWORD ' pointer to the function callback %LoAPI = &H10003 ' default TAPI 1.3 (&H00010003) ' %EARLY_TAPI_VERSION %HiAPI = &H30000 ' default TAPI 3.0 (&H00030000) ' %TAPI_CURRENT_VERSION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ FUNCTION CreateConnection( sTitle AS STRING, TotDev AS DWORD ) AS STRING LOCAL RetVal, hInstance AS LONG LOCAL lpNumDevs AS DWORD LOCAL zTemp AS ASCIIZ * 255 LOCAL lpfnCallBack AS LONG PTR LOCAL lip AS LINEINITIALIZEEXPARAMS FUNCTION = "" ' no problems ShowText "Initializing TAPI & Enumerating Lines" zTemp = sTitle ' hInstance = 0 lip.dwTotalSize = LEN(lip) 'init params lip.dwOptions = %LINEINITIALIZEEXOPTION_USEHIDDENWINDOW ' What is important to notice regarding lineInitializeEx is that ' you can SELECT one OF two mechanisms by which TAPI will NOTIFY the ' application OF telephony events: Hidden Window OR Event HANDLE. ' In this example we are using Hidden Window. ' When the hidden window method of notification is used in a TAPI application, TAPI creates a hidden ' window for the application in the context of the thread that called lineInitializeEx. If the thread that ' calls lineInitializeEx does not retrieve and dispatch windows messages, the hidden window does not ' receive Windows messages, and in turn, the callback function registered by the TAPI application is not called. ' Calling lineInitialize is equivalent to calling lineInitializeEx with the LINEINITIALIZEEXOPTION_USEHIDDENWINDOW ' option, so using lineInitialize instead of lineInitializeEx results in the same behavior. ' Make sure the thread that calls lineInitializeEx contains a message loop that retrieves and ' dispatches messages for the hidden window. msgbox "lineInitializeEx within create connection" lpfnCallBack = CODEPTR(lineCallbackFunc) ' Pointer to Callback Function RetVal = lineInitializeEx( hLineApp, _ ' LPHLINEAPP lphLineApp - HANDLE used in all TAPI functions calls hInstance, _ ' HINSTANCE hInstance - EXEorDLL instance HANDLE BYVAL lpfnCallBack, _ ' LINECALLBACK lpfnCallback - CALLBACK FUNCTION TO return asynchronous notifications zTemp, _ ' LPCWSTR lpszFriendlyAppName - NAME TO indicate who is calling TAPI lpNumDevs, _ ' LPDWORD lpdwNumDevs - Number of available TAPI devices, 0 to dwNumDevices-1 %HiAPI, _ ' LPDWORD lpdwAPIVersion - Negotiate TAPI Version lip) ' LPLINEINITIALIZEEXPARAMS lip - Hidden Window OR Event HANDLE ' Returns 0 if successful IF RetVal <> 0 THEN SELECT CASE CDWD(RetVal) CASE %LINEERR_INVALAPPNAME : FUNCTION = "Invalid application name" CASE %LINEERR_OPERATIONFAILED : FUNCTION = "the operation failed" CASE %LINEERR_INIFILECORRUPT : FUNCTION = "the INI file is corrupted" CASE %LINEERR_INVALPOINTER : FUNCTION = "Invalid pointer" CASE %LINEERR_REINIT : FUNCTION = "the application attempted to initialize TAPI twice" CASE %LINEERR_NOMEM : FUNCTION = "No memory available" CASE %LINEERR_INVALPARAM : FUNCTION = "Invalid parameter" CASE ELSE : FUNCTION = "Undefined Error"+STR$(RetVal) + " = &H" + HEX$(RetVal) END SELECT EXIT FUNCTION END IF '================================ IF lpNumDevs = 0 THEN FUNCTION = "No TAPI Devices found" 'no lines! TotDev = 0 ELSE TotDev = lpNumDevs-1 END IF '================================ END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ FUNCTION NegotiateAPIversions( TotDev AS DWORD, AppAPIver AS DWORD ) AS STRING LOCAL RetVal AS LONG LOCAL Dev AS DWORD LOCAL lxid AS LINEEXTENSIONID FUNCTION = "" ' no problems ShowText "Negotiating API ver for lines" REDIM TapiLine(TotDev) FOR Dev = 0 TO TotDev ' negotiate and cache API versions for each line RetVal = lineNegotiateAPIVersion( hLineApp, Dev, %LoAPI, %HiAPI, TapiLine(Dev).NegAPIver, lxid) ' Returns a LONG 'PRINT #hDbg, STR$(Dev) + ", Negotiated API ver=" + STR$(HI(WORD,TapiLine(Dev).NegAPIver)) + "." + STR$(Lo(WORD,TapiLine(Dev).NegAPIver)) IF RetVal <> 0 THEN SELECT CASE CDWD(RetVal) CASE %LINEERR_BADDEVICEID : FUNCTION = "the device identifier provided is incorrect" CASE %LINEERR_NODRIVER : FUNCTION = "No driver was found" CASE %LINEERR_INCOMPATIBLEAPIVERSION : FUNCTION = "the API version is incompatible" CASE %LINEERR_OPERATIONFAILED : FUNCTION = "the operation failed" CASE %LINEERR_INVALAPPHANDLE : FUNCTION = "the Application handle was invalid" CASE %LINEERR_RESOURCEUNAVAIL : FUNCTION = "the resource is unavailable" CASE %LINEERR_INVALPOINTER : FUNCTION = "the pointer is invalid" CASE %LINEERR_UNINITIALIZED : FUNCTION = "the parameter is uninitialized" CASE %LINEERR_NOMEM : FUNCTION = "No memory is available" CASE %LINEERR_OPERATIONUNAVAIL : FUNCTION = "the operation is unavailable" CASE %LINEERR_NODEVICE : TapiLine(Dev).zLineName = "Device not found" : ITERATE ' Handle this differently CASE ELSE : FUNCTION = "Undefined Error"+STR$(RetVal) END SELECT ' "Device not Found" can occur on a laptop with PCMCIA card coming out of hibernation. TapiLine(Dev).NegAPIver = 0 'no compatible API negotiated for this line EXIT FUNCTION ELSE ' PRINT #hDbg, "ExtAPIversions=" + STR$(lxid.dwExtensionID0) + STR$(lxid.dwExtensionID1) + STR$(lxid.dwExtensionID2) + STR$(lxid.dwExtensionID3) ' If the service provider for the specified dwDeviceID parameter supports provider-specific extensions, ' then, upon a successful negotiation, this structure is filled with the extension identifier of ' these extensions. This structure contains all zeros if the line provides no extensions. An application ' can ignore the returned parameter if it does not use extensions. TapiLine(Dev).ExtAPIver.dwExtensionID0 = lxid.dwExtensionID0 ' Save extension version (dev-specific features) if available TapiLine(Dev).ExtAPIver.dwExtensionID1 = lxid.dwExtensionID1 TapiLine(Dev).ExtAPIver.dwExtensionID2 = lxid.dwExtensionID2 TapiLine(Dev).ExtAPIver.dwExtensionID3 = lxid.dwExtensionID3 IF TapiLine(Dev).NegAPIver > AppAPIver THEN AppAPIver = TapiLine(Dev).NegAPIver ' highest ver found END IF NEXT END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ FUNCTION GetLineDevCaps( TotDev AS DWORD ) AS STRING ' This function queries a specified line device to determine its telephony capabilities. ' the returned data is valid for all addresses on the line device ' lineGetDevCaps(BYVAL hLineApp AS DWORD, BYVAL dwDeviceID AS DWORD, BYVAL dwAPIVersion AS DWORD, BYVAL dwExtVersion AS DWORD, lpLineDevCaps AS LINEDEVCAPS) LOCAL RetVal, lpData, NumElem AS LONG LOCAL Dev AS DWORD LOCAL LineCaps() AS LINEDEVCAPS ' variable-length structures that TAPI may throw at you FUNCTION = "" ' no problems ShowText "Getting Line Device Info" ' NOTE: dwNeededSize will return zero if the memory size is too small to start with hence ' the test for %LINEERR_STRUCTURETOOSMALL right after the function call. This test alone ' is not sufficient as the function may not return this error when the TotalSize is still ' less than the NeededSize! Hence the test for both. ' RetVal is a LONG variable yet the Constant is defined as a DWORD in tapi32.inc hence ' the need to convert RetVal to a DWORD. Of course none of this is in MSDN.... NumElem = 1 ' Starting memory size DIM LineCaps(NumElem-1) ' First attempt LineCaps(0).dwTotalSize = SIZEOF(LINEDEVCAPS) * NumElem ' Size of the UDT FOR Dev = 0 TO TotDev IF TapiLine(Dev).NegAPIver = 0 THEN ITERATE ' not found in API negotiation DO RetVal = lineGetDevCaps( hLineApp, Dev, TapiLine(Dev).NegAPIver, 0, LineCaps(0) ) 'request TAPI to fill UDT with info IF CDWD(RetVal) = %LINEERR_STRUCTURETOOSMALL OR LineCaps(0).dwTotalSize < LineCaps(0).dwNeededSize THEN ' increase buffer size 'PRINT #hDbg, STR$(Dev) + ", NumElem=" + STR$(NumElem) + ", TotalSize=" + STR$(LineCaps(0).dwTotalSize) + ", NeededSize=" + STR$(LineCaps(0).dwNeededSize) INCR NumElem ' Once increased, just leave it that size for next device IF NumElem > 20 THEN ' Something else is wrong FUNCTION = "Memory increased x"+STR$(NumElem)+" and still not big enough for LineCaps!" EXIT FUNCTION END IF ' REDIM LineCaps(NumElem-1) ' assign more memory LineCaps(0).dwTotalSize = SIZEOF(LINEDEVCAPS) * NumElem ELSE ' PRINT #hDbg, STR$(Dev) + ", NumElem=" + STR$(NumElem) + ", TotalSize=" + STR$(LineCaps(0).dwTotalSize) + ", NeededSize=" + STR$(LineCaps(0).dwNeededSize) EXIT LOOP END IF LOOP '================================ IF RetVal <> 0 THEN SELECT CASE CDWD(RetVal) CASE %LINEERR_STRUCTURETOOSMALL : FUNCTION = "the structure is too small" ' buffer size is too small CASE %LINEERR_BADDEVICEID : FUNCTION = "Bad device id provided" CASE %LINEERR_NOMEM : FUNCTION = "No memory is available" CASE %LINEERR_INCOMPATIBLEAPIVERSION : FUNCTION = "API version is incompatible" CASE %LINEERR_OPERATIONFAILED : FUNCTION = "the operation failed" CASE %LINEERR_INCOMPATIBLEEXTVERSION : FUNCTION = "Extension version is incompatible" CASE %LINEERR_RESOURCEUNAVAIL : FUNCTION = "the resource is unavailable" CASE %LINEERR_INVALAPPHANDLE : FUNCTION = "the Application Handle is invalid" CASE %LINEERR_INVALPOINTER : FUNCTION = "Invalid pointer" CASE %LINEERR_UNINITIALIZED : FUNCTION = "the parameter is uninitialized" CASE %LINEERR_NODRIVER : FUNCTION = "No driver was found" CASE %LINEERR_OPERATIONUNAVAIL : FUNCTION = "the operation is unavailable" CASE %LINEERR_NODEVICE : FUNCTION = "No device was found" CASE ELSE : FUNCTION = "Undefined Error"+STR$(RetVal) END SELECT EXIT FUNCTION END IF '================================ 'store UDT info in class local variables TapiLine(Dev).CurrentLineID = Dev TapiLine(Dev).zLineName = GetTAPIStructString(VARPTR(LineCaps(0)), LineCaps(0).dwLineNameOffset, LineCaps(0).dwLineNameSize) TapiLine(Dev).zProviderInfo = GetTAPIStructString(VARPTR(LineCaps(0)), LineCaps(0).dwProviderInfoOffset, LineCaps(0).dwProviderInfoSize) TapiLine(Dev).zSwitchInfo = GetTAPIStructString(VARPTR(LineCaps(0)), LineCaps(0).dwSwitchInfoOffset, LineCaps(0).dwSwitchInfoSize) TapiLine(Dev).PermanentLineID = LineCaps(0).dwPermanentLineID TapiLine(Dev).StringFormat = LineCaps(0).dwStringFormat TapiLine(Dev).numAddresses = LineCaps(0).dwNumAddresses TapiLine(Dev).maxDataRate = LineCaps(0).dwMaxRate TapiLine(Dev).BearerModes = LineCaps(0).dwBearerModes TapiLine(Dev).AddressModes = LineCaps(0).dwAddressModes TapiLine(Dev).MediaModes = LineCaps(0).dwMediaModes TapiLine(Dev).GenerateToneMaxNumFreq = LineCaps(0).dwGenerateToneMaxNumFreq TapiLine(Dev).GenerateToneModes = LineCaps(0).dwGenerateToneModes TapiLine(Dev).numTerminals = LineCaps(0).dwNumTerminals '================================ IF %LINEBEARERMODE_VOICE AND TapiLine(Dev).BearerModes THEN 'check if line supports making voice calls IF %LINEMEDIAMODE_INTERACTIVEVOICE AND TapiLine(Dev).mediamodes THEN TapiLine(Dev).LineSupportsVoiceCalls = 1 END IF END IF '================================ COMBOBOX ADD hDlg, 98, STR$(Dev) + " - " + TRIM$(TapiLine(Dev).zLineName) ' add the device to the combobox '================================ NEXT END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ FUNCTION GetTAPIStructString(BYVAL ptrTapistruct AS LONG, BYVAL offset AS LONG, BYVAL length AS LONG) AS STRING LOCAL sTemp AS STRING FUNCTION = "" IF length THEN ' handle erroneous input IF offset THEN ' sTemp = SPACE$(length) CopyMemory BYVAL STRPTR(sTemp), BYVAL ptrTapistruct+offset, length FUNCTION = sTemp END IF END IF '================================ END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ FUNCTION DeviceInfo( Dev AS LONG ) AS STRING LOCAL sTemp, sMsg AS STRING sMsg = "" sMsg = sMsg + "TAPI LINE NAME: " + TapiLine(Dev).zLineName + $CRLF sMsg = sMsg + "TAPI LINE: #" + STR$(TapiLine(Dev).CurrentLineID) + $CRLF ' sMsg = sMsg + "TAPI PROVIDER INFO: " + TapiLine(Dev).zProviderInfo + $CRLF sMsg = sMsg + "TAPI SWITCH INFO: " + TapiLine(Dev).zSwitchInfo + $CRLF sMsg = sMsg + $CRLF + "Permanent Line ID: " + STR$(TapiLine(Dev).PermanentLineID) + $CRLF SELECT CASE TapiLine(Dev).StringFormat CASE %STRINGFORMAT_ASCII sMsg = sMsg + "String Format: STRINGFORMAT_ASCII" + $CRLF CASE %STRINGFORMAT_DBCS sMsg = sMsg + "String Format: STRINGFORMAT_DBCS" + $CRLF CASE %STRINGFORMAT_UNICODE sMsg = sMsg + "String Format: STRINGFORMAT_UNICODE" + $CRLF CASE %STRINGFORMAT_BINARY sMsg = sMsg + "String Format: STRINGFORMAT_BINARY" + $CRLF CASE ELSE END SELECT sMsg = sMsg + "Number of addresses associated with this line: " + STR$(TapiLine(Dev).numAddresses) + $CRLF sMsg = sMsg + "Max data rate: " + STR$(TapiLine(Dev).maxDataRate) + $CRLF sMsg = sMsg + $CRLF + "Bearer Modes supported:" + $CRLF IF %LINEBEARERMODE_VOICE AND TapiLine(Dev).BearerModes THEN sMsg = sMsg + $TAB + "LINEBEARERMODE_VOICE" + $CRLF IF %LINEBEARERMODE_SPEECH AND TapiLine(Dev).BearerModes THEN sMsg = sMsg + $TAB + "LINEBEARERMODE_SPEECH" + $CRLF IF %LINEBEARERMODE_DATA AND TapiLine(Dev).BearerModes THEN sMsg = sMsg + $TAB + "LINEBEARERMODE_DATA" + $CRLF IF %LINEBEARERMODE_ALTSPEECHDATA AND TapiLine(Dev).BearerModes THEN sMsg = sMsg + $TAB + "LINEBEARERMODE_ALTSPEECHDATA" + $CRLF IF %LINEBEARERMODE_MULTIUSE AND TapiLine(Dev).BearerModes THEN sMsg = sMsg + $TAB + "LINEBEARERMODE_MULTIUSE" + $CRLF IF %LINEBEARERMODE_NONCALLSIGNALING AND TapiLine(Dev).BearerModes THEN sMsg = sMsg + $TAB + "LINEBEARERMODE_NONCALLSIGNALING" + $CRLF sMsg = sMsg + $CRLF + "Address Modes supported:" + $CRLF IF TapiLine(Dev).AddressModes AND %LINEADDRESSMODE_ADDRESSID THEN sMsg = sMsg + $TAB + "LINEADDRESSMODE_ADDRESSID" + $CRLF IF TapiLine(Dev).AddressModes AND %LINEADDRESSMODE_DIALABLEADDR THEN sMsg = sMsg + $TAB + "LINEADDRESSMODE_DIALABLEADDR" + $CRLF sMsg = sMsg + $CRLF + "Media Modes supported:" + $CRLF IF %LINEMEDIAMODE_ADSI AND TapiLine(Dev).mediamodes THEN sMsg = sMsg + $TAB + "LINEMEDIAMODE_ADSI" + $CRLF IF %LINEMEDIAMODE_AUTOMATEDVOICE AND TapiLine(Dev).mediamodes THEN sMsg = sMsg + $TAB + "LINEMEDIAMODE_AUTOMATEDVOICE" + $CRLF IF %LINEMEDIAMODE_DATAMODEM AND TapiLine(Dev).mediamodes THEN sMsg = sMsg + $TAB + "LINEMEDIAMODE_DATAMODEM" + $CRLF IF %LINEMEDIAMODE_DIGITALDATA AND TapiLine(Dev).mediamodes THEN sMsg = sMsg + $TAB + "LINEMEDIAMODE_DIGITALDATA" + $CRLF IF %LINEMEDIAMODE_G3FAX AND TapiLine(Dev).mediamodes THEN sMsg = sMsg + $TAB + "LINEMEDIAMODE_G3FAX" + $CRLF IF %LINEMEDIAMODE_G4FAX AND TapiLine(Dev).mediamodes THEN sMsg = sMsg + $TAB + "LINEMEDIAMODE_G4FAX" + $CRLF IF %LINEMEDIAMODE_INTERACTIVEVOICE AND TapiLine(Dev).mediamodes THEN sMsg = sMsg + $TAB + "LINEMEDIAMODE_INTERACTIVEVOICE" + $CRLF IF %LINEMEDIAMODE_MIXED AND TapiLine(Dev).mediamodes THEN sMsg = sMsg + $TAB + "LINEMEDIAMODE_MIXED" + $CRLF IF %LINEMEDIAMODE_TDD AND TapiLine(Dev).mediamodes THEN sMsg = sMsg + $TAB + "LINEMEDIAMODE_TDD" + $CRLF IF %LINEMEDIAMODE_TELETEX AND TapiLine(Dev).mediamodes THEN sMsg = sMsg + $TAB + "LINEMEDIAMODE_TELETEX" + $CRLF IF %LINEMEDIAMODE_TELEX AND TapiLine(Dev).mediamodes THEN sMsg = sMsg + $TAB + "LINEMEDIAMODE_TELEX" + $CRLF IF %LINEMEDIAMODE_UNKNOWN AND TapiLine(Dev).mediamodes THEN sMsg = sMsg + $TAB + "LINEMEDIAMODE_UNKNOWN" + $CRLF IF %LINEMEDIAMODE_VIDEOTEX AND TapiLine(Dev).mediamodes THEN sMsg = sMsg + $TAB + "LINEMEDIAMODE_VIDEOTEX" + $CRLF sMsg = sMsg + $CRLF + "Line Tone Generation supported: " + STR$(TapiLine(Dev).GenerateToneMaxNumFreq) + $CRLF IF TapiLine(Dev).GenerateToneMaxNumFreq THEN 'show if tone generation is supported IF %LINETONEMODE_BEEP AND TapiLine(Dev).GenerateToneModes THEN sMsg = sMsg + $TAB + "LINETONEMODE_BEEP" + $CRLF IF %LINETONEMODE_BILLING AND TapiLine(Dev).GenerateToneModes THEN sMsg = sMsg + $TAB + "LINETONEMODE_BILLING" + $CRLF IF %LINETONEMODE_BUSY AND TapiLine(Dev).GenerateToneModes THEN sMsg = sMsg + $TAB + "LINETONEMODE_BUSY" + $CRLF IF %LINETONEMODE_CUSTOM AND TapiLine(Dev).GenerateToneModes THEN sMsg = sMsg + $TAB + "LINETONEMODE_CUSTOM" + $CRLF IF %LINETONEMODE_RINGBACK AND TapiLine(Dev).GenerateToneModes THEN sMsg = sMsg + $TAB + "LINETONEMODE_RINGBACK" + $CRLF END IF sMsg = sMsg + "Number of terminals for this line: " + STR$(TapiLine(Dev).numTerminals) + $CRLF FUNCTION = sMsg ' END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ FUNCTION DeviceConfigDialog( BYVAL Dev AS LONG, BYVAL OwnerHwnd AS LONG ) AS STRING LOCAL zTemp AS ASCIIZ*255 LOCAL RetVal AS LONG FUNCTION = "" ' no problems zTemp = "" ' Highest level of config available RetVal = lineConfigDialog( TapiLine(Dev).CurrentLineID, OwnerHwnd, zTemp) IF RetVal <> 0 THEN SELECT CASE CDWD(RetVal) CASE %LINEERR_BADDEVICEID : FUNCTION = "the device id is incorrect" CASE %LINEERR_NOMEM : FUNCTION = "not enough memory is available" CASE %LINEERR_INUSE : FUNCTION = "the line is in use" CASE %LINEERR_OPERATIONFAILED : FUNCTION = "the operation failed" CASE %LINEERR_INVALDEVICECLASS : FUNCTION = "the device class is invalid" CASE %LINEERR_RESOURCEUNAVAIL : FUNCTION = "the resource is unavailable" CASE %LINEERR_INVALPARAM : FUNCTION = "the parameter is invalid" CASE %LINEERR_UNINITIALIZED : FUNCTION = "the parameter is uninitialized" CASE %LINEERR_INVALPOINTER : FUNCTION = "the pointer is invalid" CASE %LINEERR_OPERATIONUNAVAIL : FUNCTION = "the operation is unavailable" CASE %LINEERR_NODEVICE : FUNCTION = "the device was not found" CASE ELSE : FUNCTION = "Undefined Error"+STR$(RetVal) + " = &H" + HEX$(RetVal) END SELECT END IF '================================ END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ FUNCTION DialingPropertiesDialog(BYVAL Dev AS LONG, BYVAL OwnerHwnd AS LONG, AppAPIver AS DWORD ) AS STRING LOCAL RetVal AS LONG FUNCTION = "" ' no problems RetVal = lineTranslateDialog(hLineApp, TapiLine(Dev).CurrentLineID, AppAPIver, OwnerHwnd, TapiLine(Dev).zNumToDial) IF RetVal <> 0 THEN SELECT CASE CDWD(RetVal) CASE %LINEERR_BADDEVICEID : FUNCTION = "the device id is incorrect" CASE %LINEERR_INVALPARAM : FUNCTION = "the parameter is invalid" CASE %LINEERR_INCOMPATIBLEAPIVERSION : FUNCTION = "the API version is incompatible" CASE %LINEERR_INVALPOINTER : FUNCTION = "the pointer is invalid" CASE %LINEERR_INIFILECORRUPT : FUNCTION = "the INI file is corrupt" CASE %LINEERR_NODRIVER : FUNCTION = "the driver was not found" CASE %LINEERR_INUSE : FUNCTION = "the line is in use" CASE %LINEERR_NOMEM : FUNCTION = "not enough memory is available" CASE %LINEERR_INVALADDRESS : FUNCTION = "the Address is invalid" CASE %LINEERR_INVALAPPHANDLE : FUNCTION = "the application handle is invalid" CASE %LINEERR_OPERATIONFAILED : FUNCTION = "the operation failed" CASE ELSE : FUNCTION = "Unknown Return Value=" + STR$(RetVal) + " = &H" + HEX$(RetVal) END SELECT END IF '================================ END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ FUNCTION OpenLine( Dev AS LONG ) AS STRING ' hLine is GLOBAL LOCAL privileges, mediamodes AS LONG LOCAL RetVal AS LONG LOCAL dwfnCallBack AS DWORD PTR ' dwPrivileges defines which privileges your application is ' interested in obtaining. Possible values are LINECALLPRIVILEGE_NONE, ' LINECALLPRIVILEGE_MONITOR, and LINECALLPRIVILEGE_OWNER. If you do not need ' any stuff on incoming calls, simply put LINECALLPRIVILEGE_NONE there. In ' case you really want to deal with incoming/outgoing calls, specify the ' appropriate privilege level. the dwMediaModes parameter is used only if ' LINECALLPRIVILEGE_OWNER is set. It declares which media modes are of ' interest for your application. 'privileges = %LINECALLPRIVILEGE_NONE privileges = %LINECALLPRIVILEGE_MONITOR 'mediamodes = %LINEMEDIAMODE_INTERACTIVEVOICE mediamodes =%LINEMEDIAMODE_UNKNOWN OR _ %LINEMEDIAMODE_INTERACTIVEVOICE OR _ %LINEMEDIAMODE_AUTOMATEDVOICE OR _ %LINEMEDIAMODE_DATAMODEM OR _ %LINEMEDIAMODE_G3FAX OR _ %LINEMEDIAMODE_TDD OR _ %LINEMEDIAMODE_G4FAX OR _ %LINEMEDIAMODE_DIGITALDATA OR _ %LINEMEDIAMODE_TELETEX OR _' %LINEMEDIAMODE_VIDEOTEX OR _ %LINEMEDIAMODE_TELEX OR _ %LINEMEDIAMODE_MIXED OR _ %LINEMEDIAMODE_ADSI OR _ %LINEMEDIAMODE_VOICEVIEW '================================ FUNCTION = "" ' no problems ShowText "Opening Line #" + STR$(Dev) IF hLine <> 0 THEN ' Check Line is not allready open FUNCTION = "Line allready open on this device" EXIT FUNCTION END IF '================================ dwfnCallBack = CODEPTR(lineCallbackFunc) ' Pointer to Callback Function '================================ 'N.B. You should pass the pointer to lineCallbackFunc in lineInitializeEx and 0 in lineOpen. ' the dwCallbackInstance parameter is not a pointer to a callback function, ' but user-instance data. Apparently, the VB code is using it to pass a ' pointer to a class and then doing some tweaking to be able to call the ' members of the class using a dotted syntax. RetVal = lineOpen( hLineApp, _ ' Dev, _ ' DWORD dwDeviceID hLine, _ ' LPHLINE lphLine - line handle for the corresponding opened line device TapiLine(Dev).NegAPIver, _ ' DWORD dwAPIVersion BYVAL 0, _ ' DWORD dwExtVersion BYVAL 0, _ ' DWORD_PTR dwCallbackInstance - User Instance Data privileges, _ ' DWORD dwPrivileges mediamodes, _ ' DWORD dwMediaModes BYVAL 0& ) ' LPLINECALLPARAMS const lpCallParams, Usually set to NULL '================================ IF RetVal < 0 THEN ' Zero indicates success. A negative error number indicates that an error occurred SELECT CASE CDWD(RetVal) CASE %LINEERR_ALLOCATED : FUNCTION = "the line cannot be opened, serial port may be in use" CASE %LINEERR_LINEMAPPERFAILED : FUNCTION = "no lines found matching requirements specified in lpCallParams" CASE %LINEERR_BADDEVICEID : FUNCTION = "the device id is incorrect" CASE %LINEERR_NODRIVER : FUNCTION = "the driver was not found" CASE %LINEERR_INCOMPATIBLEAPIVERSION : FUNCTION = "the API version is incompatible" CASE %LINEERR_NOMEM : FUNCTION = "not enough memory is available" CASE %LINEERR_OPERATIONFAILED : FUNCTION = "the operation failed" CASE %LINEERR_INVALAPPHANDLE : FUNCTION = "the application handle is invalid" CASE %LINEERR_RESOURCEUNAVAIL : FUNCTION = "he resource is unavailable" CASE %LINEERR_INVALMEDIAMODE : FUNCTION = "the Media Mode is invalid" CASE %LINEERR_STRUCTURETOOSMALL : FUNCTION = "the structure is too small" CASE %LINEERR_INVALPOINTER : FUNCTION = "the pointer is invalid" CASE %LINEERR_UNINITIALIZED : FUNCTION = "Lthe parameter is uninitialized" CASE %LINEERR_INVALPRIVSELECT : FUNCTION = "the Priviledges are invalid" CASE %LINEERR_REINIT : FUNCTION = "the application attempted to initialize TAPI twice" CASE %LINEERR_NODEVICE : FUNCTION = "the device was not found" CASE %LINEERR_OPERATIONUNAVAIL : FUNCTION = "the operation is unavailable" CASE ELSE : FUNCTION = "Unknown Return Value=" + STR$(RetVal) + " = &H" + HEX$(RetVal) END SELECT END IF ' PRINT #hDbg, "lineopen() RetVal="+STR$(RetVal)+"(Zero indicates success), TAPIver="+STR$(TapiLine(Dev).NegAPIver) '================================ END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ FUNCTION ProcessCanonical( hLineApp AS LONG, Dev AS LONG ) AS STRING ' hLine is GLOBAL 'A common practice is that phone numbers are stored in canonical format, 'which includes international the dialing code, area code, and so forth. An 'actual call may use a modified form of this number depending on current 'location, local or long distance call, and so forth. Therefore, the 'initial phone number should be translated into a dialable form. To proceed 'with this task, you need to call lineTranslateAddress. Similar to 'lineGetDevCaps, you might be required to call this function several times 'until a correctly sized memory block is passed to keep its output. 'the canonical address format is: ' + Country/RegionCode ( AreaCode ) SubscriberNumber 'For example, this is how you would enter a US number in canonical address format: '+1 (425) 555-0100 LOCAL RetVal, NumElem AS LONG LOCAL TrnsAdd() AS LINETRANSLATEOUTPUT FUNCTION = "" ' no problems ShowText "Processing Canonical number" IF TapiLine(Dev).NegAPIver = 0 THEN ' not found in API negotiation FUNCTION = "This Device cannot be found" EXIT FUNCTION END IF '================================ 'LONG WINAPI lineTranslateAddress( 'HLINEAPP hLineApp , 'DWORD dwDeviceID , 'DWORD dwAPIVersion , 'LPCSTR lpszAddressIn , 'DWORD dwCard , 'DWORD dwTranslateOptions , 'LPLINETRANSLATEOUTPUT lpTranslateOutput NumElem = 1 ' Starting memory size DIM TrnsAdd(NumElem-1) ' First attempt TrnsAdd(0).dwTotalSize = SIZEOF(LINETRANSLATEOUTPUT) * NumElem ' Size of the UDT DO RetVal = lineTranslateAddress( hLineApp, Dev, TapiLine(Dev).NegAPIver, TapiLine(Dev).zNumToDial, 0, 0, TrnsAdd(0) ) ' Translate IF CDWD(RetVal) = %LINEERR_STRUCTURETOOSMALL OR TrnsAdd(0).dwTotalSize < TrnsAdd(0).dwNeededSize THEN ' increase buffer size 'PRINT #hDbg, STR$(Dev) + ", NumElem=" + STR$(NumElem) + ", TotalSize=" + STR$(TrnsAdd(0).dwTotalSize) + ", NeededSize=" + STR$(TrnsAdd(0).dwNeededSize) INCR NumElem IF NumElem > 20 THEN ' Something else is wrong FUNCTION = "Memory increased x"+STR$(NumElem)+" and still not big enough for TrnsAdd!" EXIT FUNCTION END IF ' REDIM TrnsAdd(NumElem-1) ' assign more memory TrnsAdd(0).dwTotalSize = SIZEOF(LINETRANSLATEOUTPUT) * NumElem ELSE ' PRINT #hDbg, STR$(Dev) + ", NumElem=" + STR$(NumElem) + ", TotalSize=" + STR$(TrnsAdd(0).dwTotalSize) + ", NeededSize=" + STR$(TrnsAdd(0).dwNeededSize) EXIT LOOP END IF LOOP '================================ IF RetVal <> 0 THEN SELECT CASE CDWD(RetVal) CASE %LINEERR_BADDEVICEID : FUNCTION = "the device id is incorrect" CASE %LINEERR_INVALPOINTER : FUNCTION = "the pointer is invalid" CASE %LINEERR_INCOMPATIBLEAPIVERSION : FUNCTION = "the API version is incompatible" CASE %LINEERR_NODRIVER : FUNCTION = "the driver was not found" CASE %LINEERR_INIFILECORRUPT : FUNCTION = "the INI file is corrupted" CASE %LINEERR_NOMEM : FUNCTION = "not enough memory is available" CASE %LINEERR_INVALADDRESS : FUNCTION = "the address is invalid" CASE %LINEERR_OPERATIONFAILED : FUNCTION = "the operation failed" CASE %LINEERR_INVALAPPHANDLE : FUNCTION = "the application handle is invalid" CASE %LINEERR_RESOURCEUNAVAIL : FUNCTION = "the resource is unavailable" CASE %LINEERR_INVALCARD : FUNCTION = "the card is invalid" CASE %LINEERR_STRUCTURETOOSMALL : FUNCTION = "the structure is too small" CASE %LINEERR_INVALPARAM : FUNCTION = "the parameter is invalid" CASE ELSE : FUNCTION = "Unknown Return Value=" + STR$(RetVal) + " = &H" + HEX$(RetVal) END SELECT EXIT FUNCTION END IF '================================ 'store UDT info in class local variables TapiLine(Dev).zDialableString = GetTAPIStructString(VARPTR(TrnsAdd(0)), TrnsAdd(0).dwDialableStringOffset, TrnsAdd(0).dwDialableStringSize) ' the output is always a null-terminated ASCII string (NULL is accounted for in Size). ' Ancillary fields such as name and subaddress are included in this output string if they ' were in the input string. This string may contain private data such as calling card numbers. ' It should not be displayed to the user, to prevent inadvertent visibility to unauthorized persons. TapiLine(Dev).zDisplayableString = GetTAPIStructString(VARPTR(TrnsAdd(0)), TrnsAdd(0).dwDisplayableStringOffset, TrnsAdd(0).dwDisplayableStringSize) ' Contain the translated output that can be displayed to the user for confirmation. It is identical to ' DialableString, except that calling card digits are replaced with the friendly name of the card enclosed ' within bracket characters, and ancillary fields such as name and subaddress are removed. It should ' normally be safe to display this string in call-status dialog boxes without exposing private data to ' unauthorized persons. This data is also appropriate to include in call logs. ] TapiLine(Dev).CurrentCountry = TrnsAdd(0).dwCurrentCountry ' Country/region code configured in CurrentLocation. This value may be used to control the ' display by the application of certain user interface elements, for local call progress tone detection, ' and for other purposes. TapiLine(Dev).DestCountry = TrnsAdd(0).dwDestCountry ' Destination country/region code of the translated address. This value may be passed ' to the dwCountryCode parameter of lineMakeCall and other dialing functions (so that ' the call progress tones of the destination country/region such as a busy signal are ' properly detected). This field is set to zero if the destination address passed to the ' lineTranslateAddress function is not in canonical format. TapiLine(Dev).TranslateResults = TrnsAdd(0).dwTranslateResults ' Value that indicates the data derived from the translation process, which may assist ' the application in presenting user-interface elements '================================ SELECT CASE TapiLine(Dev).TranslateResults CASE 0 : TapiLine(Dev).TranslateDefn = "input string was not in valid canonical form" ' This function has essentailly failed CASE %LINETRANSLATERESULT_CANONICAL : TapiLine(Dev).TranslateDefn = "input string was in valid canonical form" CASE %LINETRANSLATERESULT_INTERNATIONAL : TapiLine(Dev).TranslateDefn = "call treated as an international call" CASE %LINETRANSLATERESULT_LONGDISTANCE : TapiLine(Dev).TranslateDefn = "area code is different from current location" CASE %LINETRANSLATERESULT_LOCAL : TapiLine(Dev).TranslateDefn = "Local Call" CASE %LINETRANSLATERESULT_INTOLLLIST : TapiLine(Dev).TranslateDefn = "call is being dialed as long distance" CASE %LINETRANSLATERESULT_NOTINTOLLLIST : TapiLine(Dev).TranslateDefn = "prefix not in TollPrefixList" CASE %LINETRANSLATERESULT_DIALBILLING : TapiLine(Dev).TranslateDefn = "returned address contains a $" CASE %LINETRANSLATERESULT_DIALQUIET : TapiLine(Dev).TranslateDefn = "returned address contains a @" CASE %LINETRANSLATERESULT_DIALDIALTONE : TapiLine(Dev).TranslateDefn = "returned address contains a W" CASE %LINETRANSLATERESULT_DIALPROMPT : TapiLine(Dev).TranslateDefn = "returned address contains a ?" CASE %LINETRANSLATERESULT_VOICEDETECT : TapiLine(Dev).TranslateDefn = "LPause until a voice prompt is detected" CASE ELSE : TapiLine(Dev).TranslateDefn = "Unknown Translate Result Code=" + STR$(RetVal) + " = &H" + HEX$(RetVal) END SELECT '================================ 'PRINT #hDbg, "Dev=" + STR$(Dev) + ", zNumToDial=" + TRIM$(TapiLine(Dev).zNumToDial) 'PRINT #hDbg, "TranslateResults=" + STR$(TapiLine(Dev).TranslateResults) + _ ' ", Defn=" + TapiLine(Dev).TranslateDefn 'PRINT #hDbg, "zDialableString=" + TRIM$(TapiLine(Dev).zDialableString) + _ ' ", DisplayableString=" + TRIM$(TapiLine(Dev).zDisplayableString) 'PRINT #hDbg, ", CurrentCountry=" + STR$(TapiLine(Dev).CurrentCountry) + _ ' ", DestCountry=" + STR$(TapiLine(Dev).DestCountry) END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ FUNCTION MakeCallAsynch( zNumToDial AS ASCIIZ*%MAX_PATH ) AS STRING ' hCall, hLine are GLOBAL, zDialableString is in the TYPE 'lineMakeCall operates asynchronously; in other words, it will return 'control before dialing is completed. the application will receive 'notifications on different stages of this process via supported a callback 'function. you can look at the CeDialer sample in the SDK for more details. LOCAL RetVal AS LONG FUNCTION = "" ' no problems ShowText "Dialing: " + TRIM$(zNumToDial) IF hLine = 0 THEN FUNCTION = "Line not open" EXIT FUNCTION END IF '================================ 'if zNumToDial = "" then it will just get a dial tone RetVal = lineMakeCall(hLine, hCall, zNumToDial, 0&, BYVAL 0&) 'dial a number ' Returns a positive request identifier if the function is completed asynchronously, or a negative ' error number if an error occurs. the dwParam2 parameter of the corresponding LINE_REPLY ' message is zero if the function succeeds or it is a negative error number if an error occurs. ' the following table shows the return values for this function. ' After lineMakeCall returns a success reply message (>0) to the application, a LINE_CALLSTATE message ' is sent to the application to indicate the current state of the call. This state is not necessarily ' LINECALLSTATE_DIALTONE. ' PRINT #hDbg, "lineMakeCall() handle="+STR$(RetVal)+", hLine="+STR$(hLine)+", NumToDial="+TRIM$(zNumToDial) IF RetVal > 0 THEN 'now placing call - completion will be signalled by a LINE_REPLY event in the callback 'store positive request identifier in class member variable for use in the callback handler RequestingCall = RetVal ELSE ' RetVal < 0 SELECT CASE CDWD(RetVal) CASE %LINEERR_ADDRESSBLOCKED : FUNCTION = "the address is blocked" CASE %LINEERR_INVALLINEHANDLE : FUNCTION = "the line handle is invalid" CASE %LINEERR_BEARERMODEUNAVAIL : FUNCTION = "bearer mode specified not valid/available" ' in LINECALLPARAMS CASE %LINEERR_INVALLINESTATE : FUNCTION = "the line is not in a valid state" CASE %LINEERR_CALLUNAVAIL : FUNCTION = "the call is unavailable" CASE %LINEERR_INVALMEDIAMODE : FUNCTION = "the media mode is invalid" CASE %LINEERR_DIALBILLING : FUNCTION = "Billing control chars cannot be processed by service provider" CASE %LINEERR_INVALPARAM : FUNCTION = "the parameters are invalid" CASE %LINEERR_DIALDIALTONE : FUNCTION = "Dialing control chars cannot be processed by service provider" CASE %LINEERR_INVALPOINTER : FUNCTION = "the pointer is invalid" CASE %LINEERR_DIALPROMPT : FUNCTION = "Prompt control chars cannot be processed by service provider" CASE %LINEERR_INVALRATE : FUNCTION = "the rate is invalid" CASE %LINEERR_DIALQUIET : FUNCTION = "Quiet control chars cannot be processed by service provider" CASE %LINEERR_NOMEM : FUNCTION = "Out of memory" CASE %LINEERR_INUSE : FUNCTION = "the line is in use" CASE %LINEERR_OPERATIONFAILED : FUNCTION = "the operation failed" CASE %LINEERR_INVALADDRESS : FUNCTION = "the address is invalid" CASE %LINEERR_OPERATIONUNAVAIL : FUNCTION = "the operation is unavailable" CASE %LINEERR_INVALADDRESSID : FUNCTION = "the address id is invalid" CASE %LINEERR_RATEUNAVAIL : FUNCTION = "the rate is unavailable" CASE %LINEERR_INVALADDRESSMODE : FUNCTION = "the address mode is invalid" CASE %LINEERR_RESOURCEUNAVAIL : FUNCTION = "the resource is unavailable" CASE %LINEERR_INVALBEARERMODE : FUNCTION = "the bearer mode is invalid" CASE %LINEERR_STRUCTURETOOSMALL : FUNCTION = "the structure is too small" CASE %LINEERR_INVALCALLPARAMS : FUNCTION = "Invalid parameters used for this call" CASE %LINEERR_UNINITIALIZED : FUNCTION = "the parameter is uninitialized" CASE %LINEERR_INVALCOUNTRYCODE : FUNCTION = "the country/region code provided was invalid" CASE %LINEERR_USERUSERINFOTOOBIG : FUNCTION = "the users information is too large" CASE ELSE : FUNCTION = "Unknown Return Value=" + STR$(RetVal) + " = &H" + HEX$(RetVal) END SELECT END IF '================================ 'now placing call - completion will be signalled by a LINE_REPLY event in the callback 'store positive request identifier in class member variable for use in the callback handler END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ FUNCTION DropCallAsynch( ) AS STRING ' hCall is global 'Finally, after all requested operations are performed on the line device, 'you should close it and release all allocated resources. You also should 'clean up the resources in response to errors that occurred. If you have 'made a call, you should use the following two APIs: 'LONG lineDrop( HCALL hCall, LPCTSTR lpsUserUserInfo, DWORD dwSize ); 'LONG lineDeallocateCall( HCALL hCall ); LOCAL RetVal AS LONG LOCAL zTemp AS ASCIIZ*255 FUNCTION = "" ' no problems ShowText "Dropping Call" If hCall = 0 Then FUNCTION = "No Call to Drop" EXIT FUNCTION END IF '================================ RetVal = lineDrop( hCall, zTemp, 0& ) ' ' Returns a positive request identifier if the function is completed asynchronously ' or a negative error number if an error occurs. IF RetVal > 0 THEN ' dropping call DroppingCall = RetVal ELSE ' RetVal < 0 SELECT CASE CDWD(RetVal) CASE %LINEERR_INVALCALLHANDLE : FUNCTION = "the Call handle is invalid" CASE %LINEERR_OPERATIONUNAVAIL : FUNCTION = "the operation is unavailable" CASE %LINEERR_NOMEM : FUNCTION = "Out of memory" CASE %LINEERR_OPERATIONFAILED : FUNCTION = "the operation failed" CASE %LINEERR_NOTOWNER : FUNCTION = "This application is not the owner of the call" CASE %LINEERR_RESOURCEUNAVAIL : FUNCTION = "the resource is unavailable" CASE %LINEERR_INVALPOINTER : FUNCTION = "the pointer is invalid" CASE %LINEERR_USERUSERINFOTOOBIG : FUNCTION = "the users information is too large" CASE %LINEERR_INVALCALLSTATE : FUNCTION = "Invalid call state" CASE %LINEERR_UNINITIALIZED : FUNCTION = "the parameter is uninitialized" CASE ELSE : FUNCTION = "Unknown Return Value=" + STR$(RetVal) + " = &H" + HEX$(RetVal) END SELECT END IF '================================ END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ FUNCTION DeallocateCall( ) AS STRING ' hCall is global ' the deallocation does not affect the call state of the physical call. It does, however, ' release internal resources related to the call LOCAL RetVal AS LONG FUNCTION = "" ' no problems ShowText "Deallocating Call" CALL lineDeallocateCall( hCall ) IF RetVal < 0 THEN SELECT CASE CDWD(RetVal) CASE %LINEERR_INVALCALLHANDLE : FUNCTION = "the Call Handle is invalid" CASE %LINEERR_OPERATIONFAILED : FUNCTION = "the operation failed" CASE %LINEERR_INVALCALLSTATE : FUNCTION = "Invalid call state" CASE %LINEERR_RESOURCEUNAVAIL : FUNCTION = "the resource is unavailable" CASE %LINEERR_NOMEM : FUNCTION = "not enough memory is available" CASE %LINEERR_UNINITIALIZED : FUNCTION = "the parameter is uninitialized" CASE ELSE : FUNCTION = "Unknown Return Value=" + STR$(RetVal) + " = &H" + HEX$(RetVal) END SELECT EXIT FUNCTION END IF '================================ hCall = 0 END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ FUNCTION CloseLine( ) AS STRING ' hLine is GLOBAL ' Handle to the open line device to be closed. After the line has been successfully closed, ' this handle is no longer valid. ' If an application calls lineClose while it still has active calls on the opened line, the application's ' ownership of these calls is revoked. If the application was the sole owner of these calls, the calls ' are dropped as well. It is good programming practice for an application to dispose of the calls it ' owns on an opened line by explicitly relinquishing ownership and/or by dropping these calls prior ' to closing the line. LOCAL RetVal AS LONG FUNCTION = "" ' no problems ShowText "Closing Line" '================================ IF hLine = 0 THEN FUNCTION = "No Line to Close" EXIT FUNCTION END IF '================================ RetVal = lineClose( hLine ) IF RetVal < 0 THEN SELECT CASE CDWD(RetVal) CASE %LINEERR_INVALLINEHANDLE : FUNCTION = "the Line Handle is Invalid" CASE %LINEERR_RESOURCEUNAVAIL : FUNCTION = "the resource is unavailable" CASE %LINEERR_NOMEM : FUNCTION = "not enough memory is available" CASE %LINEERR_UNINITIALIZED : FUNCTION = "the parameter is uninitialized" CASE %LINEERR_OPERATIONFAILED : FUNCTION = "the operation failed" CASE %LINEERR_OPERATIONUNAVAIL : FUNCTION = "the operation is unavailable" CASE ELSE : FUNCTION = "Unknown Return Value=" + STR$(RetVal) + " = &H" + HEX$(RetVal) END SELECT EXIT FUNCTION END IF '================================ hLine = 0 ' Handle freed up END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ FUNCTION ShutdownLine( ) AS STRING ' hLine is GLOBAL ' the lineShutdown function shuts down the application's usage of the line abstraction of the API. ' If this function is called when the application has lines open or calls active, the call handles are ' deleted and TAPI automatically performs the equivalent of a lineClose on each open line. However, ' it is recommended that applications explicitly close all open lines before invoking lineShutdown. ' If shutdown is performed while asynchronous requests are outstanding, those requests are canceled. LOCAL RetVal AS LONG FUNCTION = "" ' no problems ShowText "Shutting Down Line" IF hLine = 0 THEN FUNCTION = "No Line to Close" EXIT FUNCTION END IF '================================ PRINT #hDbg, "hLine=" + STR$(hLine) RetVal = lineShutdown( hLine ) IF RetVal < 0 THEN SELECT CASE CDWD(RetVal) CASE %LINEERR_INVALAPPHANDLE : FUNCTION = "the application handle is invalid" CASE %LINEERR_NOMEM : FUNCTION = "not enough memory is available" CASE %LINEERR_RESOURCEUNAVAIL : FUNCTION = "the resource is unavailable" CASE %LINEERR_UNINITIALIZED : FUNCTION = "the parameter is uninitialized" CASE ELSE : FUNCTION = "Unknown Return Value=" + STR$(RetVal) + " = &H" + HEX$(RetVal) END SELECT END IF '================================ END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ FUNCTION ShowText( sTxt AS STRING ) AS LONG 'PRINT #hDbg, sTxt ' For debugging 'PRINT #hDbg, "" sTxt = sTxt + $CRLF CONTROL SEND hDlg, 401, %EM_REPLACESEL, 0, STRPTR(sTxt) ' Add text to the end FUNCTION = 1 END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ FUNCTION lineCallbackFunc( BYVAL hDevice AS DWORD, _ ' Handle callbacks here BYVAL dwMsg AS DWORD, _ ' the callback instance supplied when opening the call's line BYVAL dwCallbackInstance AS DWORD, _ ' user-instance value BYVAL dwParam1 AS DWORD, _ ' Request Identifier Code BYVAL dwParam2 AS DWORD, _ ' Reply Code BYVAL dwParam3 AS DWORD) AS LONG ' dwCallbackInstance is a user-instance value that you can pass in the lineOpen function and that ' the VB programmer is using to pass a pointer to his class and then converting to an object variable ' to be able to use the dotted syntax. This parameter can be any dword value that you will find useful or 0. msgbox "inside callback" ' the Line Callback function is used by TAPI to inform your application about ' various events that happen during the TAPI session. ' the first parameter is a handle either of a line device or a call on which ' TAPI is informing your application. More interesting parameters are dwMsg ' and dwParamN. They describe fired message and its specific data. You can ' find a complete list of TAPI messages in the SDK documentation with a ' detailed description of each message parameter. To avoid odd duplication ' of existing documentation, I would simply like to redirect you to a ' well-commented SDK sample called CEDialer. It contains a sample ' implementation of lineCallbackFunc with gorgeous explanations of many TAPI messages. ' LINE_REPLY messages: ' Functions that operate asynchronously return a positive request identifier value to the application. ' This request identifier is returned with the reply message to identify the request that was completed. ' the other parameter for the LINE_REPLY message carries the success or failure indication. ' Possible errors are the same as those defined by the corresponding function. ' In some cases, an application may fail to receive the LINE_REPLY message corresponding to ' a call to an asynchronous function. This occurs if the corresponding call handle is deallocated ' before the message has been received. ' Note: When an application invokes any asynchronous operation that writes data back into ' application memory, the application must keep that memory available for writing until a ' LINE_REPLY or LINE_GATHERDIGITS message is received. ' If hWnd is NULL, GetMessage retrieves messages for any window that belongs to the ' calling thread and thread messages posted to the calling thread by means of PostThreadMessage. STATIC sTemp AS STRING ' PRINT #hDbg, "Entering LineProcHandler" SELECT CASE dwMsg CASE %LINE_REPLY ' Functions that operate asynchronously return a positive request identifier value to the application ' PRINT #hDbg, "%LINE_REPLY: dwParam1=" + STR$(dwParam1) + ", dwParam2=" + STR$(dwParam2) + ", dwParam3=" + STR$(dwParam3) IF dwParam1 = RequestingCall THEN ' the request identifier for which this is the reply RequestingCall = -1 ' Requester from lineMakeCall() don't need ID anymore - it matched IF dwParam2 = 0 THEN ' Zero indicates success, negative number indicates an error ShowText "TAPI MSG: LINE_REPLY - DIALING" ELSE ' Possible errors are the same as those defined by the corresponding function SELECT CASE dwParam2 CASE %LINEERR_ADDRESSBLOCKED : sTemp = "the address is blocked" CASE %LINEERR_INVALLINEHANDLE : sTemp = "the line handle is invalid" CASE %LINEERR_BEARERMODEUNAVAIL : sTemp = "bearer mode specified not valid/available" ' in LINECALLPARAMS CASE %LINEERR_INVALLINESTATE : sTemp = "the line is not in a valid state" CASE %LINEERR_CALLUNAVAIL : sTemp = "the call is unavailable" CASE %LINEERR_INVALMEDIAMODE : sTemp = "the media mode is invalid" CASE %LINEERR_DIALBILLING : sTemp = "Billing control chars cannot be processed by service provider" CASE %LINEERR_INVALPARAM : sTemp = "the parameters are invalid" CASE %LINEERR_DIALDIALTONE : sTemp = "Dialing control chars cannot be processed by service provider" CASE %LINEERR_INVALPOINTER : sTemp = "the pointer is invalid" CASE %LINEERR_DIALPROMPT : sTemp = "Prompt control chars cannot be processed by service provider" CASE %LINEERR_INVALRATE : sTemp = "the rate is invalid" CASE %LINEERR_DIALQUIET : sTemp = "Quiet control chars cannot be processed by service provider" CASE %LINEERR_NOMEM : sTemp = "Out of memory" CASE %LINEERR_INUSE : sTemp = "the line is in use" CASE %LINEERR_OPERATIONFAILED : sTemp = "the operation failed" CASE %LINEERR_INVALADDRESS : sTemp = "the address is invalid" CASE %LINEERR_OPERATIONUNAVAIL : sTemp = "the operation is unavailable" CASE %LINEERR_INVALADDRESSID : sTemp = "the address id is invalid" CASE %LINEERR_RATEUNAVAIL : sTemp = "the rate is unavailable" CASE %LINEERR_INVALADDRESSMODE : sTemp = "the address mode is invalid" CASE %LINEERR_RESOURCEUNAVAIL : sTemp = "the resource is unavailable" CASE %LINEERR_INVALBEARERMODE : sTemp = "the bearer mode is invalid" CASE %LINEERR_STRUCTURETOOSMALL : sTemp = "the structure is too small" CASE %LINEERR_INVALCALLPARAMS : sTemp = "Invalid parameters used for this call" CASE %LINEERR_UNINITIALIZED : sTemp = "the parameter is uninitialized" CASE %LINEERR_INVALCOUNTRYCODE : sTemp = "the country/region code provided was invalid" CASE %LINEERR_USERUSERINFOTOOBIG : sTemp = "the users information is too large" CASE ELSE : sTemp = "Unknown Return Value=" + STR$(dwParam2) + " = &H" + HEX$(dwParam2) END SELECT ShowText "TAPI MSG: LINE_REPLY - " + sTemp sTemp = CloseLine( ) IF LEN(sTemp) THEN ShowText "CloseLine() Error: " + sTemp ' if it was an error make sure the line is closed END IF ELSEIF dwParam1 = DroppingCall THEN ' asynch reply to lineDrop() call DroppingCall = -1 ' Requester from lineDrop() IF dwParam2 = 0 THEN ShowText "TAPI MSG: LINE_REPLY - CALL DROPPED" ELSE ' Possible errors are the same as those defined by the corresponding function SELECT CASE dwParam2 CASE %LINEERR_INVALCALLHANDLE : sTemp = "the Call handle is invalid" CASE %LINEERR_OPERATIONUNAVAIL : sTemp = "the operation is unavailable" CASE %LINEERR_NOMEM : sTemp = "Out of memory" CASE %LINEERR_OPERATIONFAILED : sTemp = "the operation failed" CASE %LINEERR_NOTOWNER : sTemp = "This application is not the owner of the call" CASE %LINEERR_RESOURCEUNAVAIL : sTemp = "the resource is unavailable" CASE %LINEERR_INVALPOINTER : sTemp = "the pointer is invalid" CASE %LINEERR_USERUSERINFOTOOBIG : sTemp = "the users information is too large" CASE %LINEERR_INVALCALLSTATE : sTemp = "Invalid call state" CASE %LINEERR_UNINITIALIZED : sTemp = "the parameter is uninitialized" CASE ELSE : sTemp = "Unknown Return Value=" + STR$(dwParam2) + " = &H" + HEX$(dwParam2) END SELECT ShowText "TAPI MSG: LINE_REPLY - " + sTemp END IF ELSE ShowText "TAPI MSG: Unknown LINE_REPLY - " + STR$(dwParam1) + " = &H" + HEX$(dwParam1) END IF CASE %LINE_CALLSTATE ' status of the specified call has changed ' PRINT #hDbg, "%LINE_CALLSTATE: dwParam1=" + STR$(dwParam1) + ", dwParam2=" + STR$(dwParam2) + ", dwParam3=" + STR$(dwParam3) ' the TAPI LINE_CALLSTATE message is sent when the status of the specified call has changed. ' Typically, several such messages are received during the lifetime of a call. ' Applications are notified of new incoming calls with this message; the new call is in the offering state. ' the application can use lineGetCallStatus to retrieve more detailed information about the current status of the call. msgbox "line_callstate" SELECT CASE dwParam1 ' the new call state, dwParam2 ' Call-state-dependent information CASE %LINECALLSTATE_DISCONNECTED ' remote party has disconnected from the call SELECT CASE dwParam2 CASE %LINEDISCONNECTMODE_BADADDRESS : sTemp = "the destination address is invalid" CASE %LINEDISCONNECTMODE_BLOCKED : sTemp = "calls from the origination address are not being accepted" CASE %LINEDISCONNECTMODE_BUSY : sTemp = "the remote users station is busy" CASE %LINEDISCONNECTMODE_CANCELLED : sTemp = "the call was cancelled" CASE %LINEDISCONNECTMODE_CONGESTION : sTemp = "the network is congested" CASE %LINEDISCONNECTMODE_DONOTDISTURB : sTemp = "destination has invoked the Do not Disturb feature" CASE %LINEDISCONNECTMODE_FORWARDED : sTemp = "the call was forwarded by the switch" CASE %LINEDISCONNECTMODE_INCOMPATIBLE : sTemp = "the remote users station equipment is incompatible" CASE %LINEDISCONNECTMODE_NOANSWER : sTemp = "the remote users station does not answer" CASE %LINEDISCONNECTMODE_NODIALTONE : sTemp = "a dial tone was not detected within a service-provider defined timeout" CASE %LINEDISCONNECTMODE_NORMAL : sTemp = "the call was terminated normally" CASE %LINEDISCONNECTMODE_NUMBERCHANGED : sTemp = "destination number has been changed" CASE %LINEDISCONNECTMODE_OUTOFORDER : sTemp = "destination device is out of order (hardware failure)" CASE %LINEDISCONNECTMODE_PICKUP : sTemp = "the call was picked up from elsewhere" CASE %LINEDISCONNECTMODE_QOSUNAVAIL : sTemp = "minimum quality of service could not be obtained or sustained" CASE %LINEDISCONNECTMODE_REJECT : sTemp = "the remote user has rejected the call" CASE %LINEDISCONNECTMODE_TEMPFAILURE : sTemp = "temporary failure in the network" CASE %LINEDISCONNECTMODE_UNAVAIL : sTemp = "the reason for the disconnect is unavailable and will not become known later" CASE %LINEDISCONNECTMODE_UNKNOWN : sTemp = "the reason for the disconnect request is unknown but may become known later" CASE %LINEDISCONNECTMODE_UNREACHABLE : sTemp = "the remote user could not be reached" END SELECT ShowText "TAPI MSG: LINECALLSTATE_DISCONNECTED - " + sTemp CASE %LINECALLSTATE_IDLE ' no call exists - the line is idle ' the call exists but has not been connected. No activity exists on the call, which means that no call ' is currently active. A call can never transition out of the idle state. ShowText "TAPI MSG: LINECALLSTATE_IDLE" IF hCall <> 0 THEN ' Free up the resources sTemp = DeallocateCall() ' Line Go Idle IF LEN(sTemp) THEN ShowText "DeallocateCall() Error: " + sTemp : EXIT FUNCTION END IF IF hLine <> 0 THEN ' Free up the line sTemp = CloseLine() IF LEN(sTemp) THEN ShowText "CloseLine() Error: " + sTemp : EXIT FUNCTION ' if it was an error make sure the line is closed END IF CONTROL DISABLE hDlg, 307 ' Disable Hang Up CONTROL ENABLE hDlg, 305 ' Enable Dial CASE %LINECALLSTATE_CONNECTED ' dwParam2 details about connected mode - LINECONNECTEDMODE_ constants SELECT CASE dwParam2 ' If the call state mode is ZERO, the application should assume that the value is "active" CASE 0 : sTemp = "the call is ASSUMED to be connected" CASE %LINEDISCONNECTMODE_BADADDRESS : sTemp = "the destination address is invalid" CASE %LINECONNECTEDMODE_ACTIVE : sTemp = "the call IS connected at the current station" CASE %LINECONNECTEDMODE_ACTIVEHELD : sTemp = "remote party has placed the call on hold" CASE %LINECONNECTEDMODE_CONFIRMED : sTemp = "service provider received notification that the call is connected" CASE %LINECONNECTEDMODE_INACTIVE : sTemp = "the current station is not a participant in the call" CASE %LINECONNECTEDMODE_INACTIVEHELD : sTemp = "the remote party has placed the call on hold" END SELECT ShowText "TAPI MSG: LINECALLSTATE_CONNECTED - " + sTemp 'RaiseEvent Connected CASE %LINECALLSTATE_BUSY ' dwParam2 details about busy mode - LINEBUSYMODE_ constants SELECT CASE dwParam2 CASE %LINEBUSYMODE_STATION : sTemp = "the called party's station is busy" CASE %LINEBUSYMODE_TRUNK : sTemp = "trunk or circuit is busy" CASE %LINEBUSYMODE_UNKNOWN : sTemp = "busy signal's specific mode is currently unknown" CASE %LINEBUSYMODE_UNAVAIL : sTemp = "signal's specific mode is unavailable" END SELECT ShowText "TAPI MSG: LINECALLSTATE_BUSY - " + sTemp CASE %LINECALLSTATE_DIALTONE ' dwParam2 details about dial tone mode - LINEDIALTONEMODE_ constants SELECT CASE dwParam2 CASE %LINEDIALTONEMODE_EXTERNAL : sTemp = "This is an external (public network) dial tone" CASE %LINEDIALTONEMODE_INTERNAL : sTemp = "This is an internal dial tone, as within a PBX" CASE %LINEDIALTONEMODE_NORMAL : sTemp = "This is a normal dial tone, which typically is a continuous tone" CASE %LINEDIALTONEMODE_SPECIAL : sTemp = "This is a special dial tone" CASE %LINEDIALTONEMODE_UNAVAIL : sTemp = "the dial tone mode is unavailable and will not become known" CASE %LINEDIALTONEMODE_UNKNOWN : sTemp = "the dial tone mode is not currently known but may become known later" END SELECT ShowText "TAPI MSG: LINECALLSTATE_DIALTONE - " + sTemp 'switch is ready to receive a dialed number CASE %LINECALLSTATE_SPECIALINFO ' dwParam2 details about special information mode - LINESPECIALINFO_ constants SELECT CASE dwParam2 CASE %LINESPECIALINFO_CUSTIRREG : sTemp = "a vacant number, AIS, Centrex number change and nonworking station..." CASE %LINESPECIALINFO_NOCIRCUIT : sTemp = "no circuit or an emergency announcement (trunk blockage category)" CASE %LINESPECIALINFO_REORDER : sTemp = "reorder announcement (equipment irregularity category)" CASE %LINESPECIALINFO_UNAVAIL : sTemp = "Specifics are unavailable and will not become known" CASE %LINESPECIALINFO_UNKNOWN : sTemp = "Specifics are currently unknown but may become known later" END SELECT ShowText "TAPI MSG: LINECALLSTATE_SPECIALINFO - " + sTemp 'network error occured CASE %LINECALLSTATE_OFFERING ' dwParam2 details about connected mode - LINEOFFERINGMODE_ constants msgbox "offering" SELECT CASE dwParam2 ' describe different substates OF an offering CALL CASE %LINEOFFERINGMODE_ACTIVE : sTemp = "call is alerting at the current station" CASE %LINEOFFERINGMODE_INACTIVE : sTemp = "Indicates that the call is being offered at more than one station" END SELECT ShowText "TAPI MSG: LINECALLSTATE_OFFERING - " + sTemp CASE %LINECALLSTATE_RINGBACK ' the station to be called has been reached, and the destination's switch is generating a ring tone ' back to the originator. A ringback means that the destination address is being alerted to the call. ShowText "TAPI MSG: LINECALLSTATE_RINGBACK" 'the other station has been reached and is being alerted (ringing) CASE %LINECALLSTATE_DIALING ' the originator is dialing digits on the call. the dialed digits are collected by the switch. ShowText "TAPI MSG: LINECALLSTATE_DIALING" CASE %LINECALLSTATE_PROCEEDING ' ' Dialing has completed and the call is proceeding through the switch or telephone network. ' This occurs after dialing is complete and before the call reaches the dialed party, ' as indicated by ringback, busy, or answer. ShowText "TAPI MSG: LINECALLSTATE_PROCEEDING" CASE ELSE ' an unknown message is sent only if lineCompleteTransfer causes calls to be resolved into a three-way conference ShowText "TAPI MSG: Unknown LINE_CALLSTATE - " + STR$(dwParam1) + " = &H" + HEX$(dwParam1) END SELECT CASE %LINE_ADDRESSSTATE : ShowText "TAPI MSG: LINE_ADDRESSSTATE, the status of an address changes on a line that is currently open" CASE %LINE_APPNEWCALL : ShowText "TAPI MSG: LINE_APPNEWCALL, a new call handle has been spontaneously created on its behalf" ' CASE %LINE_APPNEWCALLHUB : ShowText "TAPI MSG: LINE_APPNEWCALLHUB, a new call hub has been created" CASE %LINE_CALLINFO : ShowText "TAPI MSG: LINE_CALLINFO, call information about the specified call has changed" ' CASE %LINE_CALLHUBCLOSE : ShowText "TAPI MSG: LINE_CALLHUBCLOSE, a call hub has been closed" CASE %LINE_CLOSE : ShowText "TAPI MSG: LINE_CLOSE, the specified line device has been forcibly closed" CASE %LINE_CREATE : ShowText "TAPI MSG: LINE_CREATE, creation of a new line device" CASE %LINE_DEVSPECIFIC : ShowText "TAPI MSG: LINE_DEVSPECIFIC, device-specific events occurring on a line, address, or call" ' CASE %LINE_DEVSPECIFICEX : ShowText "TAPI MSG: LINE_DEVSPECIFICEX, device-specific events occurring on a line, address, or call" CASE %LINE_DEVSPECIFICFEATURE : ShowText "TAPI MSG: LINE_DEVSPECIFICFEATURE, device-specific events occurring on a line, address, or call" CASE %LINE_GATHERDIGITS : ShowText "TAPI MSG: LINE_GATHERDIGITS, current buffered digit-gathering request has terminated or is canceled" CASE %LINE_GENERATE : ShowText "TAPI MSG: LINE_GENERATE, current digit or tone generation has terminated" CASE %LINE_LINEDEVSTATE : ShowText "TAPI MSG: LINE_LINEDEVSTATE, the state of a line device has changed" CASE %LINE_MONITORDIGITS : ShowText "TAPI MSG: LINE_MONITORDIGITS, a digit is detected" CASE %LINE_MONITORMEDIA : ShowText "TAPI MSG: LINE_MONITORMEDIA, a change in the calls media type is detected" CASE %LINE_MONITORTONE : ShowText "TAPI MSG: LINE_MONITORTONE, a tone is detected" CASE %LINE_REMOVE : ShowText "TAPI MSG: LINE_REMOVE, removal of a line device" CASE %LINE_REQUEST : ShowText "TAPI MSG: LINE_REQUEST, the arrival OF a NEW request FROM another application" CASE ELSE : ShowText "TAPI MSG: Unknown Message - " + STR$(dwMsg) + " = &H" + HEX$(dwMsg) END SELECT msgbox "end callback" END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ FUNCTION PaintDevIcon( BYVAL Dev AS LONG, hIcon AS LONG ) AS STRING LOCAL zTemp AS ASCIIZ*255 LOCAL RetVal AS LONG ' LONG WINAPI lineGetIcon( DWORD dwDeviceID , LPCSTR lpszDeviceClass, LPHICON lphIcon ) 'dwDeviceID 'Identifier of the line device whose icon is requested. 'lpszDeviceClass 'Pointer to a null-terminated string that identifies a device class name. This device class allows the 'application to select a specific sub-icon applicable to that device class. This parameter is optional 'and can be left NULL or empty, in which case the highest-level icon associated with the line device 'rather than a specified media stream device would be selected. 'lphIcon 'Pointer to a memory location in which the handle to the icon is returned. FUNCTION = "" ' no problems zTemp = "tapi/line" ' Substitute Generic icon if none is available RetVal = lineGetIcon( TapiLine(Dev).CurrentLineID, zTemp, hIcon ) IF RetVal <> 0 THEN SELECT CASE CDWD(RetVal) CASE %LINEERR_BADDEVICEID : FUNCTION = "Bad device id provided" CASE %LINEERR_OPERATIONFAILED : FUNCTION = "the operation failed" CASE %LINEERR_INVALPOINTER : FUNCTION = "Invalid pointer" CASE %LINEERR_RESOURCEUNAVAIL : FUNCTION = "the resource is unavailable" CASE %LINEERR_INVALDEVICECLASS : FUNCTION = "Invalid Device Class" CASE %LINEERR_UNINITIALIZED : FUNCTION = "the parameter is uninitialized" CASE %LINEERR_NOMEM : FUNCTION = "No memory is available" CASE %LINEERR_NODEVICE : FUNCTION = "No device was found" CASE %LINEERR_OPERATIONUNAVAIL : FUNCTION = "Operation Unavailable" CASE ELSE : FUNCTION = "Undefined Error"+STR$(RetVal) + " = &H" + HEX$(RetVal) END SELECT END IF '================================ ' For applications using an API version earlier than 2.0, if the provider does not ' return an icon (whether because the given device class is invalid or the provider ' does not support icons), TAPI substitutes a generic Telephony line device icon. ' For applications using API version 2.0 or later, TAPI substitutes the default line ' icon only if the lpszDeviceClass parameter is "tapi/line", "" or NULL. For any other ' device class, if the given device class is not valid or the provider does not support ' icons for the class, lineGetIcon returns LINEERR_INVALDEVICECLASS. END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤' CALLBACK FUNCTION TapiCallback() AS LONG ' Operational Flow: ' * the first thing you must do with TAPI is line initialization ' * Version negotiation is used to reach agreement between TAPI, service provider & this application. ' * Get information about each Device with lineGetDevCaps ' * open a device line with lineOpen ' * lineTranslateAddress is used to transtalate the phone number to canonical form ' * lineMakeCall is doing the actual job for you, communicating to your application via provided callback function ' * Finally, lineDrop, lineDeallocateCall, and lineClose will be called to make all required cleanup STATIC AppAPIver AS DWORD ' some TAPI calls need this instead of negotiated API version STATIC TotDev AS DWORD ' Total number of TAPI devices STATIC DevSelected AS DWORD ' Current TAPI device LOCAL ps AS paintstruct STATIC rc AS RECT STATIC hIcon AS LONG LOCAL FieldFlag, hDC, RetVal AS LONG ' for TAPI icon LOCAL d AS DWORD LOCAL sTemp, sNumToDial AS STRING SELECT CASE CBMSG CASE %WM_INITDIALOG CONTROL DISABLE hDlg, 301 ' Dialing Options CONTROL DISABLE hDlg, 303 ' Line Config CONTROL DISABLE hDlg, 305 ' Disable Dial CONTROL DISABLE hDlg, 307 ' Disable Hang Up DIM TapiLine( 0 ) ' Keep the Compiler happy msgbox "create connection" sTemp = CreateConnection( "MyApp", TotDev ) ' MSGBOX STR$(TotDev),,"TotDev" IF LEN(sTemp) THEN ShowText "Error in CreateConnection()" DIALOG END CBHNDL EXIT FUNCTION END IF AppAPIver = %LoAPI ' Starting Version sTemp = NegotiateAPIversions( TotDev, AppAPIver ) ' MSGBOX STR$(TotDev),,"TotDev" IF LEN(sTemp) THEN ShowText "NegotiateAPIversions()" DIALOG END CBHNDL EXIT FUNCTION END IF sTemp = GetLineDevCaps( TotDev ) IF LEN(sTemp) THEN ShowText "Error in GetLineDevCaps()" DIALOG END CBHNDL EXIT FUNCTION END IF DevSelected = 0 ' TotDev ' Show the last Device COMBOBOX SELECT CBHNDL, 98, DevSelected+1 ' Set MsgBox to first Item ShowText TRIM$(TapiLine(DevSelected).zLineName) IF TapiLine(DevSelected).LineSupportsVoiceCalls THEN CONTROL ENABLE hDlg, 305 'if Device supports voice CONTROL ENABLE hDlg, 303 ' Line Config CONTROL ENABLE hDlg, 305 ' Dial CONTROL ENABLE hDlg, 301 ' Dialing Options DroppingCall = -1 ' Anything except zero or a +ve number RequestingCall = -1 GetClientRect CBHNDL, rc ' For redrawing the Icon sTemp = PaintDevIcon( DevSelected, hIcon ) ' Get a handle to the Icon IF LEN(sTemp) THEN ShowText "PaintDevIcon() Error: " + sTemp InvalidateRect CBHNDL, rc, 1 ' Draw the Icon CASE %WM_PAINT hDC = BeginPaint(CBHNDL, ps) RetVal = DrawIconEx(hDc, 260, 8, hIcon, 32, 32, 0, 0, %DI_NORMAL) ' Draw the TAPI Icon ReleaseDC CBHNDL, hDC EndPaint CBHNDL, ps CASE %WM_COMMAND SELECT CASE CBCTL CASE 301 ' Dial Properties TapiLine(DevSelected).zNumToDial = "555-1212" sTemp = DialingPropertiesDialog( DevSelected, hDlg, AppAPIver ) IF LEN(sTemp) THEN ShowText "Error in DialingPropertiesDialog()" : sTemp = "" CASE 303 ' Line Config sTemp = DeviceConfigDialog( DevSelected, hDlg ) ' DWORD IF LEN(sTemp) THEN ShowText "Error in DeviceConfigDialog()" : sTemp = "" CASE 305 ' Dial CONTROL DISABLE hDlg, 305 ' Disable Dial sTemp = OpenLine( DevSelected ) ' Returns hLine IF LEN(sTemp) THEN ShowText "OpenLine() Error: " + sTemp : EXIT FUNCTION CONTROL GET TEXT hDlg, 403 TO sTemp ' get the user supplied phone number TapiLine(DevSelected).zNumToDial = sTemp ' sTemp = ProcessCanonical( hLineApp, DevSelected ) ' IF LEN(sTemp) THEN ShowText "ProcessCanonical() Error: " + sTemp : EXIT FUNCTION CONTROL ENABLE hDlg, 307 ' Enable Hang Up sTemp = MakeCallAsynch( TapiLine(DevSelected).zNumToDial ) ' zDialableString/zNumToDial IF LEN(sTemp) THEN ShowText "MakeCallAsynch() Error: " + sTemp : EXIT FUNCTION '****start of caller ID addition case 777'listen to phone line local mylpCallStatus as LINECALLSTATUS local lret as long local myLINECALLLIST as LINECALLLIST local theaddress as dword local cnt as long local mydwLineStates as dword local mydwAddressStates as dword cnt=0 stemp = openline( devselected ) ' returns hline IF LEN(sTemp) THEN ShowText "OpenLine() Error: " + sTemp : EXIT FUNCTION mydwLineStates = %LINEDEVSTATE_OTHER OR %LINEDEVSTATE_RINGING OR %LINEDEVSTATE_CONNECTED OR %LINEDEVSTATE_DISCONNECTED OR _ %LINEDEVSTATE_MSGWAITON OR %LINEDEVSTATE_MSGWAITOFF OR %LINEDEVSTATE_INSERVICE OR %LINEDEVSTATE_OUTOFSERVICE OR _ %LINEDEVSTATE_MAINTENANCE OR %LINEDEVSTATE_OPEN OR %LINEDEVSTATE_CLOSE OR %LINEDEVSTATE_NUMCALLS OR _ %LINEDEVSTATE_NUMCOMPLETIONS OR %LINEDEVSTATE_TERMINALS OR %LINEDEVSTATE_ROAMMODE OR %LINEDEVSTATE_BATTERY OR _ %LINEDEVSTATE_SIGNAL OR %LINEDEVSTATE_DEVSPECIFIC OR %LINEDEVSTATE_REINIT OR %LINEDEVSTATE_LOCK OR _ %LINEDEVSTATE_CAPSCHANGE OR %LINEDEVSTATE_CONFIGCHANGE OR %LINEDEVSTATE_TRANSLATECHANGE OR _ %LINEDEVSTATE_COMPLCANCEL OR %LINEDEVSTATE_REMOVED mydwAddressStates = %LINEADDRESSSTATE_OTHER OR %LINEADDRESSSTATE_DEVSPECIFIC OR %LINEADDRESSSTATE_INUSEZERO OR %LINEADDRESSSTATE_INUSEONE OR _ %LINEADDRESSSTATE_INUSEMANY OR %LINEADDRESSSTATE_NUMCALLS OR %LINEADDRESSSTATE_FORWARD OR _ %LINEADDRESSSTATE_TERMINALS OR %LINEADDRESSSTATE_CAPSCHANGE lineSetStatusMessages(hline,mydwLineStates ,mydwAddressStates) ' while 0 ' INCR CNT ' if CNT = 300 then exit function ' sleep 1 ' lret = lineGetAddressID(hline, theaddress, ,,sizeof()) ' myLINECALLLIST.dwTotalSize = len(LINECALLLIST) ' lret = lineGetNewCalls(hline, theaddress ,%LINECALLSELECT_ADDRESS ,myLINECALLLIST) ' lret = lineGetLineDevStatus(hcall, mylpCallStatus ) ' if mylpCallStatus.dwCallState = %LINECALLSTATE_OFFERING then ' msgbox "offering" ' exit function ' end if ' WEND '****** End of Caller ID addition CASE 307 ' Hang Up IF hCall <> 0 THEN sTemp = DropCallAsynch( ) IF LEN(sTemp) THEN ShowText "DropCallAsynch() Error: " + sTemp END IF CASE 98 ' select a device IF LOWRD(CBCTLMSG) = %CBN_SELENDOK THEN COMBOBOX GET TEXT hDlg, 98 TO sTemp DevSelected = VAL(sTemp) CONTROL DISABLE hDlg, 305 ' Disable Dial if Device does not support voice IF TapiLine(DevSelected).LineSupportsVoiceCalls THEN CONTROL ENABLE hDlg, 305 ShowText TRIM$(TapiLine(DevSelected).zLineName) sTemp = PaintDevIcon( DevSelected, hIcon ) ' Get a handle to the Icon IF LEN(sTemp) THEN ShowText "PaintDevIcon() Error: " + sTemp InvalidateRect CBHNDL, rc, 1 ' Draw the Icon sTemp = DeviceInfo( DevSelected ) MSGBOX sTemp,64,"TAPI info for Device " + STR$(DevSelected) END IF END SELECT CASE %WM_SYSCOMMAND ' User closes window with X IF (CBWPARAM AND &HFFF0) = %SC_CLOSE THEN ' CLOSE hDbg ' hDbgf IF hLine THEN sTemp = ShutdownLine( ) IF LEN(sTemp) THEN MSGBOX sTemp,64, "ShutdownLine() Error" END IF SendMessage CBHNDL, %WM_CLOSE, 0, 0 ' Close main window END IF END SELECT END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ FUNCTION PBMAIN 'OPEN "TAPIDbg.txt" FOR OUTPUT AS hDbg ' for debuggin PRINT #hDbg, "File Open" DIALOG NEW 0, "TAPI Test", 100, 10, 398, 268, %WS_SYSMENU TO hDlg CONTROL ADD COMBOBOX, hDlg, 98, , 218, 008, 160, 260, %CBS_DROPDOWNLIST CONTROL ADD BUTTON, hDlg, 305, "Dial", 008, 008, 050, 12 CONTROL ADD BUTTON, hDlg, 307, "HangUp", 008, 022, 050, 12 CONTROL ADD BUTTON, hDlg, 777, "listen", 008, 045, 050, 12 CONTROL ADD BUTTON, hDlg, 301, "Options", 008, 068, 050, 12 CONTROL ADD BUTTON, hDlg, 303, "LineCfg", 008, 088, 050, 12 CONTROL ADD TEXTBOX, hDlg, 403, "13105551212", 068, 008, 60, 12 CONTROL ADD TEXTBOX, hDlg, 401, "", 068, 032, 310, 200, _ %WS_VISIBLE OR %ES_MULTILINE OR %ES_WANTRETURN OR %ES_LEFT OR %ES_AUTOVSCROLL OR %WS_VSCROLL OR %WS_TABSTOP, %WS_EX_CLIENTEDGE DIALOG SHOW MODAL hDlg CALL TapiCallback 'CLOSE hDbg ' hDbgf END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
To make sure that the phone is connect, the modem is giving caller ID info, etc, etc. I tried a nice shareware app called PHONETRAY FREE. This program will alert when an incoming call comes in and work fine. The *strange* thing is that when Phonetray is running, the callback function in my program is executed and work perfectly. Somehow this other app must initialize or unlock something somewhere. Does anybody have any clue what to check for?
Thanks for your effort.
Comment