Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Can I control Skype from VFP?

Voip - Voice Over IP

Can I control Skype from VFP?

by  wgcs  Posted    (Edited  )
Oh, yeah. Skype is great with VFP9: We now can hook windows events, so we don't need any intermediate ActiveX skype API wrapper.

Drop this control on a form, and call THISFORM.aasSkype1.Connect to connect to skype.
Put code in the events this control exposes, and call THISFORM.sendskypemsg( Skype Message ) to control the Skype phone. Read the Skype API docs to see what the Messages are.

Code:
**************************************************
*-- Class:        aasskype (c:\source\msgctr\msgctr.vcx)
*-- Author:       William GC Steinford
*-- Date:         Feb 25, 2005
*

*// Client is successfully attached and API window handle can be found in wParam parameter
#DEFINE SKYPECONTROLAPI_ATTACH_SUCCESS               0
*// Skype has acknowledged connection request and is waiting for confirmation from the user.
*// The client is not yet attached and should wait for SKYPECONTROLAPI_ATTACH_SUCCESS message														
#DEFINE SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION 1
*// User has explicitly denied access to client
#DEFINE SKYPECONTROLAPI_ATTACH_REFUSED               2						
*// API is not available at the moment. For example, this happens when no user is currently logged in.
*// Client should wait for SKYPECONTROLAPI_ATTACH_API_AVAILABLE broadcast before making any further
*// connection attempts.
#DEFINE SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE         3
#DEFINE SKYPECONTROLAPI_ATTACH_API_AVAILABLE         0x8001
#define WM_COPYDATA                     0x004A

DEFINE CLASS aasskype AS container


	Width = 78
	Height = 22
	msgid_skypecontrolapiattach = 0
	msgid_skypecontrolapidiscover = 0
	skypeapiwindowhandle = 0
	Name = "aasskype"


	ADD OBJECT label1 AS label WITH ;
		AutoSize = .F., ;
		Caption = "Skype API", ;
		Height = 17, ;
		Left = 3, ;
		Top = 1, ;
		Width = 56, ;
		Name = "Label1"

	PROCEDURE Init
		DECLARE LONG RegisterWindowMessage IN WIN32API STRING @ LPCTSTR_lpString
		  
		THIS.MsgID_SkypeControlAPIAttach   = RegisterWindowMessage("SkypeControlAPIAttach")
		*THISFORM.addmsg(' Window Message "SkypeControlAPIAttach" registered as '+TRANSFORM(THISFORM.MsgID_SkypeControlAPIAttach) )
		THIS.MsgID_SkypeControlAPIDiscover = RegisterWindowMessage("SkypeControlAPIDiscover")
		*THISFORM.addmsg(' Window Message "SkypeControlAPIDiscover" registered as '+TRANSFORM(THISFORM.MsgID_SkypeControlAPIDiscover ) )

		BINDEVENT( _VFP.hWnd, THIS.MsgID_SkypeControlAPIAttach,   THIS,  'Evt_SkypeControlAPIAttach' )
		BINDEVENT( _VFP.hWnd, THIS.MsgID_SkypeControlAPIDiscover, THIS,  'Evt_SkypeControlAPIDiscover')
		BINDEVENT( _VFP.hWnd, WM_COPYDATA,                        THIS,  'Evt_CopyData' )
	ENDPROC

	PROCEDURE evt_skypecontrolapiattach
		LPARAMETERS HWND_hWindow, UINT_uiMessage, WPARAM_uiParam, LPARAM_ulParam
		*THIS.addmsg('ATTACH Msg')
		IF UINT_uiMessage = THIS.MsgID_SkypeControlAPIAttach
		  DO CASE
		    CASE LPARAM_ulParam = SKYPECONTROLAPI_ATTACH_SUCCESS
		      THIS.SkypeAPIWindowHandle = WPARAM_uiParam
		      RAISEEVENT(THIS,'Connected')
		      *THIS.AddMsg("!!! Connected; to terminate issue #disconnect")
		      
		    CASE LPARAM_ulParam = SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION
		      RAISEEVENT(THIS,'ConnectError','PENDING')
		      *THIS.AddMsg("!!! Pending authorization")
		      
		    CASE LPARAM_ulParam = SKYPECONTROLAPI_ATTACH_REFUSED
		      RAISEEVENT(THIS,'ConnectError','REFUSED')
		      *THISFORM.AddMsg("!!! Connection refused")
		      
		    CASE LPARAM_ulParam = SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE
		      RAISEEVENT(THIS,'ConnectError','API NOT AVAILABLE')
		      *THISFORM.AddMsg("!!! Skype API not available")
		      
		    CASE LPARAM_ulParam = SKYPECONTROLAPI_ATTACH_API_AVAILABLE
		      RAISEEVENT(THIS,'ConnectError','API NOW AVAILABLE')
		      *THISFORM.AddMsg("!!! Try connect now (API available); issue #connect")
		      *SendMessage( 0xffff, THISFORM.MsgID_SkypeControlAPIDiscover, ;
		                   _VFP.hwnd, 0)      
		  ENDCASE 

		ENDIF

		RETURN 1
	ENDPROC


	PROCEDURE evt_copydata
		LPARAMETERS HWND_hWindow, UINT_uiMessage, WPARAM_uiParam, LPARAM_ulParam
		*THISFORM.addmsg(' Window Message "WM_COPYDATA" Received' )

		IF WPARAM_uiParam = THIS.skypeapiwindowhandle
		  *THISFORM.addmsg( '<< Received Message from Skype: '+TRANSFORM(UINT_uiMessage);
		    +','+TRANSFORM(WPARAM_uiParam,'@0');
		    +','+TRANSFORM(LPARAM_ulParam,'@0') )
		  *THISFORM.addmsg( ;
		     ' HWND='+TRANSFORM(HWND_hWindow,'@0') ;
		    +' Skype_HWND='+TRANSFORM(THISFORM.skypeapiwindowhandle,'@0') ;
		    +' THISFORM.HWND='+TRANSFORM(THISFORM.HWND,'@0') ;
		    +' _vfp.HWND='+TRANSFORM(_vfp.HWND,'@0') ;
		     )
		     
		*    oCopyData = BINTOC( 0,            '4Rs' ) ;
		*              + BINTOC( LEN(tcMsg)+1, '4Rs' ) ;
		*              + BINTOC( lnCBData_Hnd, '4Rs' ) 
		  * Retrieve the COPYDATA structure:
		  lnLen = 16 
		  Declare LONG RtlMoveMemory IN "kernel32" ;
		        STRING @ cIntoHere, LONG ptrFromHere, LONG cb
		  lcRet = SPACE(lnLen)
		  RtlMoveMemory(@lcRet,LPARAM_ulParam,lnLen)  
		  * Extract the length and the string pointer
		  *lc1 = SUBSTR(lcRet,1,4)
		  lc2 = SUBSTR(lcRet,5,4)
		  lc3 = SUBSTR(lcRet,9,4)
		   
		  lnLen = CTOBIN(lc2,'4RS')
		  lp3   = CTOBIN(lc3,'4RS')
		   
		  IF lnLen>0
		    * Retrieve the pointed-to string:
		    lcStr = SPACE(lnLen)
		    RtlMoveMemory(@lcStr,lp3,lnLen)
		    lcStr = LEFT(lcStr, AT(CHR(0),lcStr) )
		    * THISFORM.addmsg( '  '+lcStr)
		        
		    DO CASE 
		      CASE lcStr='ERROR '
		        RAISEEVENT( THIS, 'SkypeError', SUBSTR(lcStr,7) )
		      OTHERWISE
		        RAISEEVENT( THIS, 'SkypeMessageIn', lcStr )    
		    ENDCASE     
		  ENDIF 
		ENDIF
		RETURN 1
	ENDPROC


	PROCEDURE skypemessagein
		LPARAMETERS tcSkypeMsg
	ENDPROC


	PROCEDURE sendskypemsg
		LPARAMETERS tcMsg
		LOCAL lnRes, oCopyData, lnCBData_Hnd
		DO CASE 
		  CASE UPPER(tcMsg)='#CONNECT'
		    THIS.Connect
		    
		  CASE LEN(tcMsg)>0 AND THIS.SkypeAPIWindowHandle>0
		    *THISFORM.addmsg('>> '+tcMsg)
		    
		    Declare LONG GlobalAlloc IN "kernel32" LONG wFlags, LONG dwBytes
		    Declare LONG RtlMoveMemory IN "kernel32" ;
		            LONG ptrIntoHere, STRING @ cFromHere, LONG cb
		    Declare LONG GlobalFree IN "kernel32" LONG hmem
		              
		    * len(tcMsg)+1 is used to include the 0x00 char.
		    tcMsg = ALLTRIM(tcMsg) + CHR(0)
		    lnCBData_Hnd = GlobalAlloc( 0, len(tcMsg) )
		    RtlMoveMemory( lnCBData_Hnd, @tcMsg, len(tcMsg) )
		    
		    *!*	typedef struct tagCOPYDATASTRUCT {
		    *!*	    DWORD dwData;
		    *!*	    DWORD cbData;
		    *!*	    PVOID lpData;
		    *!*	} COPYDATASTRUCT, *PCOPYDATASTRUCT;
		    *!*	COPYDATASTRUCT oCopyData;
		    
		    *// send command to skype
		    *!*	oCopyData.dwData=0
		    *!*	oCopyData.cbData = len(tcMsg)+1
		    *!*	oCopyData.lpData = acInputRow
		    oCopyData = BINTOC( 0,            '4Rs' ) ;
		              + BINTOC( LEN(tcMsg)+1, '4Rs' ) ;
		              + BINTOC( lnCBData_Hnd, '4Rs' ) 

		    DECLARE LONG SendMessage IN WIN32API ;
		      LONG HWND_hWnd, ;
		      LONG UINT_Msg,  ;
		      LONG WPARAM_wParam, ;
		      STRING @ LPARAM_lParam
		    
		    IF 0=SendMessage( THIS.Skypeapiwindowhandle, WM_COPYDATA, ;
		                      _VFP.hwnd, @oCopyData )
		       THIS.SkypeAPIWindowHandle = 0
		       RAISEEVENT(THIS,'Disconnected')
		       *THIS.AddMsg("!!! Disconnected")
		    ENDIF
		    GlobalFree(lnCBData_Hnd)
		ENDCASE 
	ENDPROC


	PROCEDURE connect
		DECLARE LONG SendMessage IN WIN32API ;
		        LONG    HWND_hWnd, ;
		        INTEGER UINT_Msg,  ;
		        INTEGER WPARAM_wParam, ;
		        LONG    LPARAM_lParam
		      
		*THISFORM.addmsg('Connecting to Skype...')
		* #define HWND_BROADCAST  ((HWND)0xffff)

		* if( SendMessage( HWND_BROADCAST, uiGlobal_MsgID_SkypeControlAPIDiscover, (WPARAM)hInit_MainWindowHandle, 0)!=0 )
		lnRes = SendMessage( 0xffff, THIS.MsgID_SkypeControlAPIDiscover, _VFP.hwnd, 0)
		* THISFORM.addmsg('Returned '+TRANSFORM(lnRes))

		RETURN lnRes
	ENDPROC

	PROCEDURE evt_skypecontrolapidiscover
		LPARAMETERS HWND_hWindow, UINT_uiMessage, WPARAM_uiParam, LPARAM_ulParam
		RETURN 1
	ENDPROC

	PROCEDURE disconnect
		THIS.SkypeAPIWindowHandle = 0
		RAISEEVENT(THIS,'Disconnected')
	ENDPROC

	PROCEDURE connecterror
		LPARAMETERS tcErrorDescription
	ENDPROC

	PROCEDURE skypeerror
		LPARAMETERS tcErrorNumber_and_Desc
	ENDPROC

	PROCEDURE connected
	ENDPROC

	PROCEDURE disconnected
	ENDPROC

ENDDEFINE
*
*-- EndDefine: aasskype
**************************************************
Register to rate this FAQ  : BAD 1 2 3 4 5 6 7 8 9 10 GOOD
Please Note: 1 is Bad, 10 is Good :-)

Part and Inventory Search

Back
Top