From a5ea1613d623ad8d7027ddd402632a842ba5f0af Mon Sep 17 00:00:00 2001 From: Alexander Lantsev Date: Tue, 2 Oct 2012 17:48:44 +0000 Subject: git-svn-id: http://svn.miranda-ng.org/main/trunk@1764 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/Skype/src/skype.h | 1 + protocols/Skype/src/skype_contacts.cpp | 186 +++++++++++++++++------------- protocols/Skype/src/skype_proto.cpp | 69 +++++------ protocols/Skype/src/skype_proto.h | 24 ++-- protocols/Skype/src/skype_settings.cpp | 16 +-- protocols/Skype/src/skype_subclassing.cpp | 22 ++-- protocols/Skype/src/skype_subclassing.h | 18 +-- 7 files changed, 193 insertions(+), 143 deletions(-) (limited to 'protocols/Skype') diff --git a/protocols/Skype/src/skype.h b/protocols/Skype/src/skype.h index 7a46bafec9..2382950b22 100644 --- a/protocols/Skype/src/skype.h +++ b/protocols/Skype/src/skype.h @@ -3,6 +3,7 @@ #define MIRANDA_VER 0x0A00 #include +#include //#pragma warning(push) //# pragma warning(disable:4312) diff --git a/protocols/Skype/src/skype_contacts.cpp b/protocols/Skype/src/skype_contacts.cpp index 2943e05e12..c5b4aeb513 100644 --- a/protocols/Skype/src/skype_contacts.cpp +++ b/protocols/Skype/src/skype_contacts.cpp @@ -5,100 +5,132 @@ void CSkypeProto::OnContactChanged(CContact* contact, int prop) { } -HANDLE CSkypeProto::GetContactBySkypeLogin(const char* skypeLogin) +bool CSkypeProto::IsSkypeContact(HANDLE hContact) { - for (HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); - hContact; - hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)) - { - //if(!IsMyContact(hContact)) - // continue; + return ::CallService(MS_PROTO_ISPROTOONCONTACT, (WPARAM)hContact, (LPARAM)this->m_szModuleName) > 0; +} - DBVARIANT dbv; - if( !DBGetContactSettingString(hContact, this->m_szModuleName, SKYPE_SETTINGS_LOGIN, &dbv)) +HANDLE CSkypeProto::GetContactBySkypeName(wchar_t* skypeName) +{ + HANDLE hContact = (HANDLE)::CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + while (hContact) + { + if (this->IsSkypeContact(hContact)) { - if(strcmp(skypeLogin, dbv.pszVal) == 0) - { - DBFreeVariant(&dbv); + if (::wcscmp(skypeName, this->GetSettingString(hContact, "SkypeName", L"")) == 0) return hContact; - } - else - DBFreeVariant(&dbv); } + + hContact = (HANDLE)::CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0); } return 0; } -void __cdecl CSkypeProto::LoadContactList(void*) +HANDLE CSkypeProto::AddContactBySkypeName(wchar_t* skypeName, wchar_t* displayName, DWORD flags) { - g_skype->GetHardwiredContactGroup(CContactGroup::ALL_KNOWN_CONTACTS, this->contactGroup); + HANDLE hContact = this->GetContactBySkypeName(skypeName); + if ( !hContact) + { + hContact = (HANDLE)::CallService(MS_DB_CONTACT_ADD, 0, 0); + ::CallService(MS_PROTO_ADDTOCONTACT, (WPARAM)hContact, (LPARAM)this->m_szModuleName); - this->contactGroup->GetContacts(this->contactGroup->ContactList); - fetch(this->contactGroup->ContactList); + this->SetSettingString(hContact, "SkypeName", skypeName); + this->SetSettingString(hContact, "DisplayName", displayName); + //::DBWriteContactSettingWString(hContact, "CList", "MyHandle", displayName); - for (unsigned int i = 0; i < this->contactGroup->ContactList.size(); i++) - { - SEString name; - SEString skypeLogin; + if (flags & PALF_TEMPORARY) + { + ::DBWriteContactSettingByte(hContact, "CList", "NotOnList", 1); + ::DBWriteContactSettingByte(hContact, "CList", "Hidden", 1); + } + } + else + { + if (!(flags & PALF_TEMPORARY)) + ::DBWriteContactSettingByte(hContact, "CList", "NotOnList", 1); + } - int status = ID_STATUS_OFFLINE; - CContact::AVAILABILITY availability = CContact::OFFLINE; + return hContact; +} - this->contactGroup->ContactList[i]->GetPropSkypename(skypeLogin); - printf("%3d. %s\n", i+1, (const char*)skypeLogin); +int CSkypeProto::SkypeToMirandaStatus(CContact::AVAILABILITY availability) +{ + int status = ID_STATUS_OFFLINE; - HANDLE hContact = this->GetContactBySkypeLogin(skypeLogin); - if (!hContact) - { - hContact = (HANDLE)CallService(MS_DB_CONTACT_ADD, 0, 0); - DBWriteContactSettingString(hContact, this->m_szModuleName, SKYPE_SETTINGS_LOGIN, skypeLogin); - } + switch (availability) + { + case CContact::ONLINE: + case CContact::ONLINE_FROM_MOBILE: + status = ID_STATUS_ONLINE; + break; + + case CContact::AWAY: + case CContact::AWAY_FROM_MOBILE: + status = ID_STATUS_AWAY; + break; + + case CContact::DO_NOT_DISTURB: + case CContact::DO_NOT_DISTURB_FROM_MOBILE: + status = ID_STATUS_DND; + break; + } - if (CallService(MS_PROTO_ADDTOCONTACT, (WPARAM)hContact, (LPARAM)this->m_szModuleName) == 0 ) - { + return status; +} - this->contactGroup->ContactList[i]->GetPropDisplayname(name); - this->contactGroup->ContactList[i]->GetPropAvailability(availability); - - switch (availability) - { - case CContact::ONLINE: - case CContact::ONLINE_FROM_MOBILE: - status = ID_STATUS_ONLINE; - break; - - case CContact::AWAY: - case CContact::AWAY_FROM_MOBILE: - status = ID_STATUS_AWAY; - break; - - case CContact::DO_NOT_DISTURB: - case CContact::DO_NOT_DISTURB_FROM_MOBILE: - status = ID_STATUS_DND; - break; - } - - DBDeleteContactSetting(hContact, "CList", "MyHandle"); - - /*DBVARIANT dbv; - if (!this->GetSettingString(this->m_szModuleName,FACEBOOK_KEY_DEF_GROUP,&dbv)) - { - DBWriteContactSettingTString(hContact,"CList","Group",dbv.ptszVal); - DBFreeVariant(&dbv); - }*/ - - DBWriteContactSettingString(hContact, this->m_szModuleName, SKYPE_SETTINGS_NAME, name); - DBWriteContactSettingWord(hContact, this->m_szModuleName, SKYPE_SETTINGS_STATUS, ID_STATUS_ONLINE); - DBWriteContactSettingString(hContact, this->m_szModuleName, SKYPE_SETTINGS_LOGIN, skypeLogin); - } - else - { - CallService(MS_DB_CONTACT_DELETE, (WPARAM)hContact, 0); - } +CContact::AVAILABILITY CSkypeProto::MirandaToSkypeStatus(int status) +{ + CContact::AVAILABILITY availability = CContact::UNKNOWN; + + switch(this->m_iStatus) + { + case ID_STATUS_ONLINE: + availability = CContact::ONLINE; + break; + + case ID_STATUS_AWAY: + availability = CContact::AWAY; + break; + + case ID_STATUS_DND: + availability = CContact::DO_NOT_DISTURB; + break; + + case ID_STATUS_INVISIBLE: + availability = CContact::INVISIBLE; + break; + } - //HANDLE hContact = AddToContactList(fbu, FACEBOOK_CONTACT_APPROVE, false, fbu->real_name.c_str()); - //DBWriteContactSettingByte(hContact, m_szModuleName, FACEBOOK_KEY_CONTACT_TYPE, FACEBOOK_CONTACT_APPROVE); + return availability; +} + +void __cdecl CSkypeProto::LoadContactList(void*) +{ + g_skype->GetHardwiredContactGroup(CContactGroup::ALL_KNOWN_CONTACTS, this->contactGroup); + + this->contactGroup->GetContacts(this->contactGroup->ContactList); + fetch(this->contactGroup->ContactList); + + for (unsigned int i = 0; i < this->contactGroup->ContactList.size(); i++) + { + //this->contactGroup->ContactList[i]->SetOnContactChangeCallback((OnContactChangeFunc)&CSkypeProto::OnContactChanged, this); + + //SEString sn; + //this->contactGroup->ContactList[i]->GetPropSkypename(sn); + wchar_t* skypeName = L"1";//::mir_a2u((const char*)sn); + + //SEString dn; + //this->contactGroup->ContactList[i]->GetPropDisplayname(dn); + wchar_t* displayName = L"1";//::mir_a2u((const char*)dn); + + //HANDLE hContact = this->GetContactBySkypeName(L"321"); + //if (!hContact) + HANDLE hContact = this->AddContactBySkypeName(skypeName, displayName, 0); + + CContact::AVAILABILITY availability; + this->contactGroup->ContactList[i]->GetPropAvailability(availability); + this->SetSettingWord(hContact, SKYPE_SETTINGS_STATUS, this->SkypeToMirandaStatus(availability)); } } @@ -108,9 +140,9 @@ void CSkypeProto::SetAllContactStatuses(int status) hContact; hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)) { - if (DBGetContactSettingWord(hContact, this->m_szModuleName, SKYPE_SETTINGS_STATUS, ID_STATUS_OFFLINE) == status) + if (this->GetSettingWord(hContact, SKYPE_SETTINGS_STATUS, ID_STATUS_OFFLINE) == status) continue; - DBWriteContactSettingWord(hContact, this->m_szModuleName, SKYPE_SETTINGS_STATUS, status); + this->SetSettingWord(hContact, SKYPE_SETTINGS_STATUS, status); } } \ No newline at end of file diff --git a/protocols/Skype/src/skype_proto.cpp b/protocols/Skype/src/skype_proto.cpp index 33bb6e7f9e..35920ac183 100644 --- a/protocols/Skype/src/skype_proto.cpp +++ b/protocols/Skype/src/skype_proto.cpp @@ -35,12 +35,34 @@ CSkypeProto::~CSkypeProto() HANDLE __cdecl CSkypeProto::AddToList(int flags, PROTOSEARCHRESULT* psr) { //if (psr->cbSize != sizeof(PROTOSEARCHRESULT)) - return 0; + // return 0; + // + //return this->AddContactBySkypeName(psr->id, psr->nick, flags); + return 0; +} - //return this->AddToListBySkypeLogin(psr->id, psr->nick, psr->firstName, psr->lastName, flags); +HANDLE __cdecl CSkypeProto::AddToListByEvent(int flags, int iContact, HANDLE hDbEvent) +{ + //DBEVENTINFO dbei = {0}; + //dbei.cbSize = sizeof(dbei); + + //if ((dbei.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hDbEvent, 0)) != -1) + //{ + // dbei.pBlob = (PBYTE)alloca(dbei.cbBlob); + // if (CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&dbei) == 0 && + // !strcmp(dbei.szModule, m_szModuleName) && + // (dbei.eventType == EVENTTYPE_AUTHREQUEST || dbei.eventType == EVENTTYPE_CONTACTS)) + // { + // char *nick = (char*)(dbei.pBlob + sizeof(DWORD) * 2); + // char *firstName = nick + strlen(nick) + 1; + // char *lastName = firstName + strlen(firstName) + 1; + // char *skypeName = lastName + strlen(lastName) + 1; + // return AddContactBySkypeName(::mir_a2u(skypeName), ::mir_a2u(nick), 0); + // } + //} + return 0; } -HANDLE __cdecl CSkypeProto::AddToListByEvent( int flags, int iContact, HANDLE hDbEvent ) { return 0; } int __cdecl CSkypeProto::Authorize( HANDLE hDbEvent ) { return 0; } int __cdecl CSkypeProto::AuthDeny( HANDLE hDbEvent, const TCHAR* szReason ) { return 0; } int __cdecl CSkypeProto::AuthRecv( HANDLE hContact, PROTORECVEVENT* ) { return 0; } @@ -66,9 +88,9 @@ DWORD_PTR __cdecl CSkypeProto:: GetCaps(int type, HANDLE hContact) return PF4_FORCEAUTH | PF4_FORCEADDED | PF4_SUPPORTTYPING | PF4_AVATARS | PF4_OFFLINEFILES | PF4_IMSENDUTF | PF4_IMSENDOFFLINE; case PFLAG_UNIQUEIDTEXT: - return (INT_PTR)Translate("Skype login"); + return (INT_PTR)Translate("Skype Name"); case PFLAG_UNIQUEIDSETTING: - return (INT_PTR) "SL"; + return (INT_PTR) L"SkypeName"; default: return 0; } @@ -116,7 +138,7 @@ int CSkypeProto::SetStatus(int new_status) { this->m_iStatus = new_status; //todo: set all status to offline - this->account->Logout(true); + this->account->Logout(); this->account->BlockWhileLoggingOut(); this->account->SetAvailability(CContact::OFFLINE); this->SetAllContactStatuses(ID_STATUS_OFFLINE); @@ -132,31 +154,12 @@ int CSkypeProto::SetStatus(int new_status) this->m_iStatus = ID_STATUS_CONNECTING; this->password = this->GetDecodeSettingString(SKYPE_SETTINGS_PASSWORD); - this->ForkThread(&CSkypeProto::SignIn, this); - //this->SignIn(this); + //this->ForkThread(&CSkypeProto::SignIn, this); + this->SignIn(this); } } - CContact::AVAILABILITY availability = CContact::UNKNOWN; - switch(this->m_iStatus) - { - case ID_STATUS_ONLINE: - availability = CContact::ONLINE; - break; - - case ID_STATUS_AWAY: - availability = CContact::AWAY; - break; - - case ID_STATUS_DND: - availability = CContact::DO_NOT_DISTURB; - break; - - case ID_STATUS_INVISIBLE: - availability = CContact::INVISIBLE; - break; - } - + CContact::AVAILABILITY availability = this->MirandaToSkypeStatus(this->m_iStatus); if(availability != CContact::UNKNOWN) this->account->SetAvailability(availability); } @@ -200,16 +203,16 @@ bool CSkypeProto::IsOffline() void __cdecl CSkypeProto::SignIn(void*) { - WaitForSingleObject(&this->signin_lock, INFINITE); + //WaitForSingleObject(&this->signin_lock, INFINITE); - this->account->LoginWithPassword(mir_u2a(this->password), false, false); + this->account->LoginWithPassword(::mir_u2a(this->password)); this->account->BlockWhileLoggingIn(); //CContact::Ref()->SetOnChangeCallback((OnContactChangeFunc)&CSkypeProto::OnContactChanged, this); this->SetStatus(this->m_iDesiredStatus); - this->ForkThread(&CSkypeProto::LoadContactList, this); - //this->LoadContactList(this); + //this->ForkThread(&CSkypeProto::LoadContactList, this); + this->LoadContactList(this); - ReleaseMutex(this->signin_lock); + //ReleaseMutex(this->signin_lock); } \ No newline at end of file diff --git a/protocols/Skype/src/skype_proto.h b/protocols/Skype/src/skype_proto.h index bb3a0bcebb..d9f2a4b634 100644 --- a/protocols/Skype/src/skype_proto.h +++ b/protocols/Skype/src/skype_proto.h @@ -84,8 +84,14 @@ protected: void __cdecl SignIn(void*); void __cdecl LoadContactList(void*); + // contacts void OnContactChanged(CContact* contact, int prop); - HANDLE GetContactBySkypeLogin(const char* skypeLogin); + + bool IsSkypeContact(HANDLE hContact); + HANDLE AddContactBySkypeName(wchar_t* skypeName, wchar_t* displayName, DWORD flags); + HANDLE GetContactBySkypeName(wchar_t* skypeName); + int SkypeToMirandaStatus(CContact::AVAILABILITY availability); + CContact::AVAILABILITY MirandaToSkypeStatus(int status); void SetAllContactStatuses(int status); // utils @@ -114,10 +120,10 @@ protected: WORD GetSettingWord(HANDLE hContact, const char *setting, WORD errorValue = 0); DWORD GetSettingDword(const char *setting, DWORD defVal = 0); DWORD GetSettingDword(HANDLE hContact, const char *setting, DWORD errorValue = 0); - TCHAR* GetSettingString(const char *setting, TCHAR* errorValue = NULL); - TCHAR* GetSettingString(HANDLE hContact, const char *setting, TCHAR* errorValue = NULL); - TCHAR* GetDecodeSettingString(const char *setting, TCHAR* errorValue = NULL); - TCHAR* GetDecodeSettingString(HANDLE hContact, const char *setting, TCHAR* errorValue = NULL); + wchar_t* GetSettingString(const char *setting, wchar_t* errorValue = NULL); + wchar_t* GetSettingString(HANDLE hContact, const char *setting, wchar_t* errorValue = NULL); + wchar_t* GetDecodeSettingString(const char *setting, wchar_t* errorValue = NULL); + wchar_t* GetDecodeSettingString(HANDLE hContact, const char *setting, wchar_t* errorValue = NULL); bool SetSettingByte(const char *setting, BYTE value = 0); bool SetSettingByte(HANDLE hContact, const char *setting, BYTE value = 0); @@ -125,10 +131,10 @@ protected: bool SetSettingWord(HANDLE hContact, const char *setting, WORD value = 0); bool SetSettingDword(const char *setting, DWORD value = 0); bool SetSettingDword(HANDLE hContact, const char *setting, DWORD value = 0); - bool SetSettingString(const char *setting, TCHAR* value = NULL); - bool SetSettingString(HANDLE hContact, const char *setting, TCHAR* value = NULL); - bool SetDecodeSettingString(const char *setting, TCHAR* value = NULL); - bool SetDecodeSettingString(HANDLE hContact, const char *setting, TCHAR* value = NULL); + bool SetSettingString(const char *setting, wchar_t* value = NULL); + bool SetSettingString(HANDLE hContact, const char *setting, wchar_t* value = NULL); + bool SetDecodeSettingString(const char *setting, wchar_t* value = NULL); + bool SetDecodeSettingString(HANDLE hContact, const char *setting, wchar_t* value = NULL); // dialog procs static INT_PTR CALLBACK SkypeAccountProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam); diff --git a/protocols/Skype/src/skype_settings.cpp b/protocols/Skype/src/skype_settings.cpp index 188274ae3c..e183e70fff 100644 --- a/protocols/Skype/src/skype_settings.cpp +++ b/protocols/Skype/src/skype_settings.cpp @@ -30,7 +30,7 @@ DWORD CSkypeProto::GetSettingDword(const char *setting, DWORD errorValue) return this->GetSettingDword(NULL, setting, errorValue); } -TCHAR* CSkypeProto::GetSettingString(HANDLE hContact, const char *setting, TCHAR* errorValue) +wchar_t* CSkypeProto::GetSettingString(HANDLE hContact, const char *setting, wchar_t* errorValue) { DBVARIANT dbv; TCHAR* result = NULL; @@ -44,12 +44,12 @@ TCHAR* CSkypeProto::GetSettingString(HANDLE hContact, const char *setting, TCHAR return result != NULL ? result : errorValue; } -TCHAR* CSkypeProto::GetSettingString(const char *setting, TCHAR* errorValue) +wchar_t* CSkypeProto::GetSettingString(const char *setting, wchar_t* errorValue) { return this->GetSettingString(NULL, setting, errorValue); } -TCHAR* CSkypeProto::GetDecodeSettingString(HANDLE hContact, const char *setting, TCHAR* errorValue) +wchar_t* CSkypeProto::GetDecodeSettingString(HANDLE hContact, const char *setting, wchar_t* errorValue) { TCHAR* result = this->GetSettingString(hContact, setting, errorValue); @@ -61,7 +61,7 @@ TCHAR* CSkypeProto::GetDecodeSettingString(HANDLE hContact, const char *setting, return result; } -TCHAR* CSkypeProto::GetDecodeSettingString(const char *setting, TCHAR* errorValue) +wchar_t* CSkypeProto::GetDecodeSettingString(const char *setting, wchar_t* errorValue) { return this->GetDecodeSettingString(NULL, setting, errorValue); } @@ -97,17 +97,17 @@ bool CSkypeProto::SetSettingDword(const char *setting, DWORD value) return this->SetSettingDword(NULL, setting, value); } -bool CSkypeProto::SetSettingString(HANDLE hContact, const char *szSetting, TCHAR* value) +bool CSkypeProto::SetSettingString(HANDLE hContact, const char *szSetting, wchar_t* value) { return !::DBWriteContactSettingWString(hContact, this->m_szModuleName, szSetting, value); } -bool CSkypeProto::SetSettingString(const char *szSetting, TCHAR* value) +bool CSkypeProto::SetSettingString(const char *szSetting, wchar_t* value) { return this->SetSettingString(NULL, szSetting, value); } -bool CSkypeProto::SetDecodeSettingString(HANDLE hContact, const char *setting, TCHAR* value) +bool CSkypeProto::SetDecodeSettingString(HANDLE hContact, const char *setting, wchar_t* value) { TCHAR* result = mir_wstrdup(value); CallService(MS_DB_CRYPT_ENCODESTRING, sizeof(result), reinterpret_cast(result)); @@ -115,7 +115,7 @@ bool CSkypeProto::SetDecodeSettingString(HANDLE hContact, const char *setting, T return !this->SetSettingString(hContact, setting, result); } -bool CSkypeProto::SetDecodeSettingString(const char *setting, TCHAR* value) +bool CSkypeProto::SetDecodeSettingString(const char *setting, wchar_t* value) { return this->SetDecodeSettingString(NULL, setting, value); } \ No newline at end of file diff --git a/protocols/Skype/src/skype_subclassing.cpp b/protocols/Skype/src/skype_subclassing.cpp index 0a0ebd5a0f..c206f65ef5 100644 --- a/protocols/Skype/src/skype_subclassing.cpp +++ b/protocols/Skype/src/skype_subclassing.cpp @@ -40,7 +40,13 @@ void CAccount::OnChange(int prop) } } } - //(proto->*callback)(this, prop); + +} + +void CContact::SetOnContactChangeCallback(OnContactChangeFunc callback, CSkypeProto* proto) +{ + this->proto = proto; + this->callback = callback; } void CAccount::BlockWhileLoggingIn() @@ -68,13 +74,15 @@ CContact::CContact(unsigned int oid, SERootObject* root) : Contact(oid, root) { } -void CAccount::SetOnChangeCallback(OnContactChangeFunc callback, CSkypeProto* proto) -{ - this->proto = proto; - this->callback = callback; -} +//void CAccount::SetOnChangeCallback(OnContactChangeFunc callback, CSkypeProto* proto) +//{ +// this->proto = proto; +// this->callback = callback; +//} void CContact::OnChange(int prop) { - //(proto->*callback)(this, prop); + //SEString identity; + //this->GetIdentity(identity); + (proto->*callback)(this, prop); } \ No newline at end of file diff --git a/protocols/Skype/src/skype_subclassing.h b/protocols/Skype/src/skype_subclassing.h index 044c825b68..a4ea9a1264 100644 --- a/protocols/Skype/src/skype_subclassing.h +++ b/protocols/Skype/src/skype_subclassing.h @@ -8,7 +8,7 @@ class CContact; struct CSkypeProto; -typedef void (__cdecl CSkypeProto::* OnContactChangeFunc)(CContact*, int); +typedef void (CSkypeProto::* OnContactChangeFunc)(CContact* contact, int); class CContact : public Contact { @@ -17,8 +17,14 @@ public: typedef DRefs Refs; CContact(unsigned int oid, SERootObject* root); + + void SetOnContactChangeCallback(OnContactChangeFunc callback, CSkypeProto* proto); private: + CSkypeProto* proto; + + OnContactChangeFunc callback; + void OnChange(int prop); }; @@ -47,14 +53,8 @@ public: void BlockWhileLoggingIn(); void BlockWhileLoggingOut(); - - - void SetOnChangeCallback(OnContactChangeFunc callback, CSkypeProto* proto); - -private: - CSkypeProto* proto; - OnContactChangeFunc callback; - + +private: void OnChange(int prop); }; -- cgit v1.2.3