基於Skype 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,施行的是異步的連接方式,即非阻塞的,程序可以繼續往前執行不用等待連接成功後才繼續往前執行。

 
圖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();
             }
                }
         }
  }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章