INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Jobs

Voip - Voice Over IP

Can I control Skype from VFP? by wgcs
Posted: 11 Mar 05

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
**************************************************

Back to Microsoft: Visual FoxPro FAQ Index
Back to Microsoft: Visual FoxPro Forum

My Archive

Resources

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close