我的 SKYPE API程序的二次开发

我是从SKYPE 0.几版本就开始进行SKYPE的二次开发的,那个时候SKYPE 还没有开放SDK出来,只能是通过 钩子和模拟按键 的方式做到对 来电去电的控制。哪个时候很苦闷,也很没有底气,毕竟都是类似于hacker的操作。但是老板就是老板,他要求什么功能我就得想方设法实现它,谁叫我不是老板呢,赫赫。后来,SKYPE出了论坛,再后来有了SDK,我终于舒服了,一切都变得那么Easy,虽然它SDK提供得功能是一步一步枝繁叶茂的。

到现在,通过SKYPE SDK对skype的控制已经很完整了,当然这是指Windows下的版本,因为Windows 的版本的SDK 协议已经到了protocol 7了,而且SKYPE 3.2出来后又增加了很多新的控制(不知道protocol 版本升级了没有);而Linux下的SDK 虽然到了protocol 5,但是其实很多命令发过去,它都没有反映(它没有报错,没有报错就表示它能理解该命令,但是却没有反映,如果它无法理解它会返回错误信息)。

我用的linux的发行版是Fedora Core 4,SKYPE的版本是最新的FC4下的版本(才1.3.几,对比windows用户,真的很惨), API程序是用QT3.3写的界面。我感觉Fedora Core 4下对 USB Phone这类高耗电设备的支持还是有很大的问题,在不运行我的AP的情况下,插拔几次(次数不确定)设备,电脑就可能当机;我试过几台电脑,都有一样的问题。而且,如果开机的时候设备是连着的,第一次连我的API程序,铁定连不上,插拔一次就可以了(我的AP可以不退出),这个问题我一直没办法理解。同时USB Phone的麦克风在Fedora Core4下也很容易出问题,情况是 出问题后用户根本没办法控制麦克风,当然也没有声音,重启几次后就好了,同时声音也出来了。

如果我有什么理解错误,希望大家指出来,不要让我冷场了。如果有什么问题,也可以根贴提出来。谢谢。



并贴上SKYPE官方提供的Windows下API调用例程的源代码。

// tab size: 2
// following special commands are recognized and handled by this client
// #quit
// #exit
// terminate client
// #dbgon
// turn on debug printing of windows messages
// #dbgoff
// turn off debug printing of windows messages
// #connect
// discover skype api
// #disconnect
// terminate connection to skype api
// all other commands are sent "as is" directly to Skype
// (no UTF-8 translation is done at present)

#include
#include
#include
#include

#include
#include

HWND hInit_MainWindowHandle;
HINSTANCE hInit_ProcessHandle;
char acInit_WindowClassName[128];
HANDLE hGlobal_ThreadShutdownEvent;
bool volatile fGlobal_ThreadRunning=true;
UINT uiGlobal_MsgID_SkypeControlAPIAttach;
UINT uiGlobal_MsgID_SkypeControlAPIDiscover;
HWND hGlobal_SkypeAPIWindowHandle=NULL;
#if defined(_DEBUG)
bool volatile fGlobal_DumpWindowsMessages=true;
#else
bool volatile fGlobal_DumpWindowsMessages=false;
#endif
DWORD ulGlobal_PromptConsoleMode=0;
HANDLE volatile hGlobal_PromptConsoleHandle=NULL;

enum {
SKYPECONTROLAPI_ATTACH_SUCCESS=0, // Client is successfully attached and API window handle can be found in wParam parameter
SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION=1, // 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
SKYPECONTROLAPI_ATTACH_REFUSED=2, // User has explicitly denied access to client
SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE=3, // 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.
SKYPECONTROLAPI_ATTACH_API_AVAILABLE=0x8001
};

bool Global_Console_ReadRow( char *pacPromptBuffer, unsigned int uiMaxLength)
{
HANDLE hConsoleHandle, hDuplicatedConsoleHandle;
DWORD ulCharactersRead, ulConsoleMode;
unsigned int uiNewLength;
BOOL fReadConsoleResult;
bool fReturnStatus;
char cCharacter;

fReturnStatus=false;
while((hConsoleHandle=GetStdHandle(STD_INPUT_HANDLE))!=INVALID_HANDLE_VALUE)
{
if( DuplicateHandle( GetCurrentProcess(), hConsoleHandle,
GetCurrentProcess(), &hDuplicatedConsoleHandle, 0, FALSE,
DUPLICATE_SAME_ACCESS)==FALSE )
break;
GetConsoleMode( hDuplicatedConsoleHandle, &ulConsoleMode);
SetConsoleMode( hDuplicatedConsoleHandle, ENABLE_LINE_INPUT|ENABLE_PROCESSED_INPUT|ENABLE_ECHO_INPUT);
hGlobal_PromptConsoleHandle=hDuplicatedConsoleHandle;
ulGlobal_PromptConsoleMode=ulConsoleMode;
fReadConsoleResult=ReadConsole( hGlobal_PromptConsoleHandle,
(LPVOID)pacPromptBuffer, uiMaxLength, &ulCharactersRead, (LPVOID)0);
if( hGlobal_PromptConsoleHandle==(HANDLE)0 )
break;
hGlobal_PromptConsoleHandle=(HANDLE)0;
SetConsoleMode( hDuplicatedConsoleHandle, ulConsoleMode);
CloseHandle(hDuplicatedConsoleHandle);
if( fReadConsoleResult==FALSE || ulCharactersRead>uiMaxLength )
break;
pacPromptBuffer[ulCharactersRead]=0;
uiNewLength=ulCharactersRead;
while(uiNewLength!=0)
{
cCharacter=pacPromptBuffer[uiNewLength-1];
if( cCharacter!='r' && cCharacter!='n' )
break;
uiNewLength--;
}
pacPromptBuffer[uiNewLength]=0;
fReturnStatus=true;
break;
}
if( fReturnStatus==false )
pacPromptBuffer[0]=0;
return(fReturnStatus);
}

void Global_Console_CancelReadRow(void)
{
if( hGlobal_PromptConsoleHandle!=(HANDLE)0 )
{
SetConsoleMode( hGlobal_PromptConsoleHandle, ulGlobal_PromptConsoleMode);
CloseHandle(hGlobal_PromptConsoleHandle);
hGlobal_PromptConsoleHandle=(HANDLE)0;
}
}

static LRESULT APIENTRY SkypeAPITest_Windows_WindowProc(
HWND hWindow, UINT uiMessage, WPARAM uiParam, LPARAM ulParam)
{
LRESULT lReturnCode;
bool fIssueDefProc;

lReturnCode=0;
fIssueDefProc=false;
switch(uiMessage)
{
case WM_DESTROY:
hInit_MainWindowHandle=NULL;
PostQuitMessage(0);
break;
case WM_COPYDATA:
if( hGlobal_SkypeAPIWindowHandle==(HWND)uiParam )
{
PCOPYDATASTRUCT poCopyData=(PCOPYDATASTRUCT)ulParam;
printf( "Message from Skype(%u): %.*sn", poCopyData->dwData, poCopyData->cbData, poCopyData->lpData);
lReturnCode=1;
}
break;
default:
if( uiMessage==uiGlobal_MsgID_SkypeControlAPIAttach )
{
switch(ulParam)
{
case SKYPECONTROLAPI_ATTACH_SUCCESS:
printf("!!! Connected; to terminate issue #disconnectn");
hGlobal_SkypeAPIWindowHandle=(HWND)uiParam;
break;
case SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION:
printf("!!! Pending authorizationn");
break;
case SKYPECONTROLAPI_ATTACH_REFUSED:
printf("!!! Connection refusedn");
break;
case SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE:
printf("!!! Skype API not availablen");
break;
case SKYPECONTROLAPI_ATTACH_API_AVAILABLE:
printf("!!! Try connect now (API available); issue #connectn");
break;
}
lReturnCode=1;
break;
}
fIssueDefProc=true;
break;
}
if( fIssueDefProc )
lReturnCode=DefWindowProc( hWindow, uiMessage, uiParam, ulParam);
if( fGlobal_DumpWindowsMessages )
{
printf( "WindowProc: hWindow=0x%08X, MainWindow=0x%08X, Message=%5u, WParam=0x%08X, LParam=0x%08X; Return=%ld%sn",
hWindow, hInit_MainWindowHandle, uiMessage, uiParam, ulParam, lReturnCode, fIssueDefProc? " (default)":"");
}
return(lReturnCode);
}

bool Initialize_CreateWindowClass(void)
{
unsigned char *paucUUIDString;
RPC_STATUS lUUIDResult;
bool fReturnStatus;
UUID oUUID;

fReturnStatus=false;
lUUIDResult=UuidCreate(&oUUID);
hInit_ProcessHandle=(HINSTANCE)OpenProcess( PROCESS_DUP_HANDLE, FALSE, GetCurrentProcessId());
if( hInit_ProcessHandle!=NULL && (lUUIDResult==RPC_S_OK || lUUIDResult==RPC_S_UUID_LOCAL_ONLY) )
{
if( UuidToString( &oUUID, &paucUUIDString)==RPC_S_OK )
{
WNDCLASS oWindowClass;

strcpy( acInit_WindowClassName, "Skype-API-Test-");
strcat( acInit_WindowClassName, (char *)paucUUIDString);

oWindowClass.style=CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS;
oWindowClass.lpfnWndProc=(WNDPROC)&SkypeAPITest_Windows_WindowProc;
oWindowClass.cbClsExtra=0;
oWindowClass.cbWndExtra=0;
oWindowClass.hInstance=hInit_ProcessHandle;
oWindowClass.hIcon=NULL;
oWindowClass.hCursor=NULL;
oWindowClass.hbrBackground=NULL;
oWindowClass.lpszMenuName=NULL;
oWindowClass.lpszClassName=acInit_WindowClassName;

if( RegisterClass(&oWindowClass)!=0 )
fReturnStatus=true;

RpcStringFree(&paucUUIDString);
}
}
if( fReturnStatus==false )
CloseHandle(hInit_ProcessHandle),hInit_ProcessHandle=NULL;
return(fReturnStatus);
}

void DeInitialize_DestroyWindowClass(void)
{
UnregisterClass( acInit_WindowClassName, hInit_ProcessHandle);
CloseHandle(hInit_ProcessHandle),hInit_ProcessHandle=NULL;
}

bool Initialize_CreateMainWindow(void)
{
hInit_MainWindowHandle=CreateWindowEx( WS_EX_APPWINDOW|WS_EX_WINDOWEDGE,
acInit_WindowClassName, "", WS_BORDER|WS_SYSMENU|WS_MINIMIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT, 128, 128, NULL, 0, hInit_ProcessHandle, 0);
return(hInit_MainWindowHandle!=NULL? true:false);
}

void DeInitialize_DestroyMainWindow(void)
{
if( hInit_MainWindowHandle!=NULL )
DestroyWindow(hInit_MainWindowHandle),hInit_MainWindowHandle=NULL;
}

void Global_MessageLoop(void)
{
MSG oMessage;

while(GetMessage( &oMessage, 0, 0, 0)!=FALSE)
{
TranslateMessage(&oMessage);
DispatchMessage(&oMessage);
}
}

void __cdecl Global_InputProcessingThread(void *)
{
static char acInputRow[1024];
bool fProcessed;

if( SendMessage( HWND_BROADCAST, uiGlobal_MsgID_SkypeControlAPIDiscover, (WPARAM)hInit_MainWindowHandle, 0)!=0 )
{
while(Global_Console_ReadRow( acInputRow, sizeof(acInputRow)-1))
{
if( stricmp( acInputRow, "#quit")==0 ||
stricmp( acInputRow, "#exit")==0 )
break;
fProcessed=false;
if( stricmp( acInputRow, "#dbgon")==0 )
{
printf( "SkypeControlAPIAttach=%u, SkypeControlAPIDiscover=%u, hInit_MainWindowHandle=0x%08lXn",
uiGlobal_MsgID_SkypeControlAPIAttach, uiGlobal_MsgID_SkypeControlAPIDiscover, hInit_MainWindowHandle);
fGlobal_DumpWindowsMessages=true,fProcessed=true;
}
if( stricmp( acInputRow, "#dbgoff")==0 )
fGlobal_DumpWindowsMessages=false,fProcessed=true;
if( stricmp( acInputRow, "#connect")==0 )
{
SendMessage( HWND_BROADCAST, uiGlobal_MsgID_SkypeControlAPIDiscover, (WPARAM)hInit_MainWindowHandle, 0);
fProcessed=true;
}
if( stricmp( acInputRow, "#disconnect")==0 )
{
hGlobal_SkypeAPIWindowHandle=NULL;
printf("!!! Disconnectedn");
fProcessed=true;
}
if( fProcessed==false && hGlobal_SkypeAPIWindowHandle!=NULL )
{
COPYDATASTRUCT oCopyData;

// send command to skype
oCopyData.dwData=0;
oCopyData.lpData=acInputRow;
oCopyData.cbData=strlen(acInputRow)+1;
if( oCopyData.cbData!=1 )
{
if( SendMessage( hGlobal_SkypeAPIWindowHandle, WM_COPYDATA, (WPARAM)hInit_MainWindowHandle, (LPARAM)&oCopyData)==FALSE )
{
hGlobal_SkypeAPIWindowHandle=NULL;
printf("!!! Disconnectedn");
}
}
}
}
}
PostMessage( hInit_MainWindowHandle, WM_CLOSE, 0, 0);
SetEvent(hGlobal_ThreadShutdownEvent);
fGlobal_ThreadRunning=false;
}

void main(void)
{
// create window class
// create dummy/hidden window for processing messages
// run message loop thread
// do application control until exit
// exit: send QUIT message to our own window
// wait until thred terminates
// destroy main window
// destroy window class
uiGlobal_MsgID_SkypeControlAPIAttach=RegisterWindowMessage("SkypeControlAPIAttach");
uiGlobal_MsgID_SkypeControlAPIDiscover=RegisterWindowMessage("SkypeControlAPIDiscover");
if( uiGlobal_MsgID_SkypeControlAPIAttach!=0 && uiGlobal_MsgID_SkypeControlAPIDiscover!=0 )
{
if( Initialize_CreateWindowClass() )
{
if( Initialize_CreateMainWindow() )
{
hGlobal_ThreadShutdownEvent=CreateEvent( NULL, TRUE, FALSE, NULL);
if( hGlobal_ThreadShutdownEvent!=NULL )
{
if( _beginthread( &Global_InputProcessingThread, 64*1024, NULL)!=(unsigned long)-1 )
{
Global_MessageLoop();
Global_Console_CancelReadRow();
WaitForSingleObject( hGlobal_ThreadShutdownEvent, INFINITE);
}
CloseHandle(hGlobal_ThreadShutdownEvent);
}
DeInitialize_DestroyMainWindow();
}
DeInitialize_DestroyWindowClass();
}
}
}

[@more@]

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/9838355/viewspace-914398/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/9838355/viewspace-914398/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值