使用过MSN的人应该知道,目前有针对MSN的外壳程序MSNShell。使用Skype4Com API你也可以轻松的开发一个SKYPEShell程序。
Skype也是世界上最开放,最具创新意识的IM工具,他提供了Skype API, Skype4COM, Skype4Java几种形式的开发接口给Skype爱好者编写Skype的交互程序或者Skype的插件。
Skype中文官网:http://skype.tom.com/
Skype全球官网:http://www.skype.com/
Skype全球开发者社区:http://developer.skype.com/
SkypeShell下载链接:
http://download.csdn.net/down/236631/lin_bei
我们可以使用任何熟悉的语言,比如C/C++,VB, C#,Delphi,Java甚至PHP,VBScript来操作Skype客户端。
关于如何使用Skype API结合Windows SDK API来编外壳程序,请参考我同事陈敏的那篇:你也可以玩转Skype -- 基于Skype API开发外壳程序入门
这篇文章讨论的是使用Skype4Com API来编写外壳程序。
下一篇blog是介绍如何使用Skype4Java API。
SkypeShell是一个Skype的外壳增强插件。这个程序是独立的EXE程序,它连接Skype API成为Skype的监听者。实现了三个功能,1:显示Skype的状态信息;2:当Skype用户离开时有消息自动回复的功能;3:设置可以滚动显示多个签名档。
SkypeShell是在VC6下开发的一个MFC程序,它通过Skype4COM组件连接Skype。虽然VC也能支持直接使用这类COM组件,但是要更灵活地使用它,最好通过VC Class
Wizard生成一个"包裹"类(wrapper)。具体方法如下:
1.下载Skype4COM.dll,注册到Windows系统中。命令为regsvr32 Skype4COM.dll
2.在VC的资源视图中,打开对话框界面,在对话框中点击右键菜单“Insert ActvieX Control”,选择“Skype Class”加入到对话框中。
3.修改Skype控件的ID为ID_SKYPE,按Ctrl+W打开Class Wizard,选择“Member Variables”,双击ID_SKYPE, 此时弹出对话框提示是否自动生成Wrapper Classes。点击是,并关联这个控件到CSkype对象即可使用。
接下来,要跟Skype建立连接,就可以调用CSkype对象的Attach方法,它有两个参数:协议版本号与连接方式,我们使用的是Attach(6,FALSE),即协议版本号为6,施行的是异步的连接方式,即非阻塞的,程序可以继续往前执行不用等待连接成功后才继续往前执行。
<shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"></path><lock v:ext="edit" aspectratio="t"></lock></shapetype><shape id="_x0000_i1025" style="WIDTH: 416.25pt; HEIGHT: 364.5pt" type="#_x0000_t75" o:ole=""><imagedata src="file:///C:%5CDOCUME~1%5CGAOLIN~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image001.emz" o:title=""></imagedata></shape>图1 与Skype建立连接的过程各种事件的函数调用
如上图1所示,首先①,调用Attach 方法:m_ctrlSkype.Attach(6, FALSE),接下来整个过程是这样的,在Skype客户端弹出一个对话框提示是否允许本程序操作Skype, 这时候会激发一个事件AttachmentStatus,程序可以调用它的处理函数:OnAttachmentStatusSkype,我们可以取得它的Satus: apiAttachPendingAuthorization = 1,表示本程序正等待客户的允许对它的使用,这时候我们可以针对这个回调函数进行编程,即如下代码所示:
//客户端程序与Skype连接情况的回调函数
void CSkypeShellDlg::OnAttachmentStatusSkype(long Status)
{
//获取父窗口的句柄从而改变标题
CWnd * pOwnerWnd = GetParent();
switch(Status)
{
/*
apiAttachUnknown = -1,
apiAttachSuccess = 0,
apiAttachPendingAuthorization = 1,
apiAttachRefused = 2,
apiAttachNotAvailable = 3,
apiAttachAvailable = 4
*/
case 1:
pOwnerWnd->SetWindowText("SkypeShell 与Skype正建立连接...");
break;
case 2:
……
}
}
当Skype用户允许本程序对其使用时,进入2.1,由于允许外部程序跟Skype建立连接,这时候必须检测当前的Skype用户状态,所以会激发UserStatus事件,调用其回调函数:OnUserStatusSkype,发现这时候的Status为cusOffline = 0,即用户为离线状态,虽然是离线,本程序跟Skype程序却已经成功建立了连接,这时候又激发了OnAttachmentStatusSkype回调函数,查看Stauts,可以知道apiAttachSuccess = 0,即成功建立了连接。
在本程序里,获得Skype程序的状态,主要是通过下面的回调函数:
与Skype成功连接后如果用户的状态有所改变将会激发UserStatus事件,从而调用此回调函数
void CSkypeShellDlg::OnUserStatusSkype(long Status)
{
/*
enum {
cusUnknown = -1,
cusOffline = 0, //离线
cusOnline = 1, //在线
cusAway = 2, //离开
cusNotAvailable = 3, //没空
cusDoNotDisturb = 4, //请勿打扰
cusInvisible = 5, //隐身
cusLoggedOut = 6, //退出
cusSkypeMe = 7 //使用SkypeMe
} TUserStatus;
*/
CWnd* pOwnerWnd = GetParent();
switch(Status) {
//离线
case 0:
{
pOwnerWnd->SetWindowText("SkypeShell
已连接Skype("+m_ctrlSkype.GetVersion()+")"+m_ctrlSkype.GetCurrentUser().GetFullName()+" 离线");
//更改与Skype的连接状态为已连接上
theConfig.m_bIsConnectSuccess = TRUE;
break;
}
……
}
以上是有关本程序在操作Skype之前如何跟它建立连接,及它的状态改变时如何调用
各种回调函数的一个过程。
在成功与Skype建立连接,及始终保持连接的前提下,外部程序可以操作Skype的各各信息,因为Skype4COM API,封装了Skype API,我们使用起来很方便,比如说,本外壳程序的滚动个性签名功能,就是简单的使用了Skype4COM API:
//滚动个性签名集合中的个性签名
m_ctrlSkype.GetCurrentUserProfile().SetMoodText(theConfig.m_cMoods[m_nCurMoodIndex].m_strContent.c_str());
m_ctrlSkype是封装成的类CSkype对象,用来表示模拟Skype的各种功能,如上面的,改变用户个性签名。查看Skype4COM API的说明文档,我们可以找到其它功能都是如何模拟及使用的。
除此之外,本外壳程序还用到了另外一个Skype4COM AP中其它类对象,如CChat,它是来模拟一个聊天会话,在这里我们主要是用来实现当Skype用户处于离开状态是留言自动回复的功能。
//Skype的回调函数,当用户收到或者发送消息时都会激活MessageStatus事件调
//用这个函数
void CSkypeShellDlg::OnMessageStatusSkype(LPDISPATCH pMessage, long Status)
{
/*
enum {
cusUnknown = -1,
cusOffline = 0,
cusOnline = 1,
cusAway = 2,
cusNotAvailable = 3,
cusDoNotDisturb = 4,
cusInvisible = 5,
cusLoggedOut = 6,
cusSkypeMe = 7
} TUserStatus;
*/
//获取当前自己的Skype的状态
long m_lStatus = m_ctrlSkype.GetCurrentUser().GetOnlineStatus();
//如果用户启动了自动回复功能
if (theConfig.m_bIsAutoAnswer)
{
//表示当前用户是处于离线状态
if (m_lStatus == 2)
{
//2表示有消息到来了
if(Status == 2)
{
CChatMessage cChatMessage;
cChatMessage.AttachDispatch(pMessage);
CString strHandle = cChatMessage.GetFromHandle();
CChat cChat = cChatMessage.GetChat();
CUserCollection cUserCollection = cChat.GetMembers();
int nMembers = cUserCollection.GetCount();
CUser cUser = m_ctrlSkype.GetUser(strHandle);
//如果对方是处于离开状态什么都不做并且必须不是来自群组消息
if(cUser.GetOnlineStatus() != 2 && nMembers == 1)
{
CChat cChat = cChatMessage.GetChat();
//发送用户选择的留言
cChat.SendMessage(theConfig.m_strSelectedAnswer.c_str());
cChatMessage.DetachDispatch();
}
}
}
}
}