// ---------------------------------------------------------------------------80 // ICQ plugin for Miranda Instant Messenger // ________________________________________ // // Copyright © 2000,2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede // Copyright © 2001,2002 Jon Keating, Richard Hughes // Copyright © 2002,2003,2004 Martin Öberg, Sam Kothari, Robert Rainwater // Copyright © 2004,2005,2006 Joe Kucera // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // // ----------------------------------------------------------------------------- // // File name : $Source: /cvsroot/miranda/miranda/protocols/IcqOscarJ/UI/userinfotab.c,v $ // Revision : $Revision: 1.38 $ // Last change on : $Date: 2006/04/23 11:57:14 $ // Last change by : $Author: jokusoftware $ // // DESCRIPTION: // // Code for User details ICQ specific pages // // ----------------------------------------------------------------------------- #include "icqoscar.h" #include "m_flash.h" // icqj magic id #define FA_MAGIC_ID 0x4943516A extern WORD wListenPort; extern char* calcMD5Hash(char* szFile); extern char* MirandaVersionToString(char* szStr, int v, int m); extern char* nameXStatus[29]; static BOOL CALLBACK IcqDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); static BOOL CALLBACK AvatarDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); static BYTE SetValue(HWND hwndDlg, int idCtrl, HANDLE hContact, char *szModule, char *szSetting, WORD type); #define SVS_NORMAL 0 #define SVS_ZEROISUNSPEC 2 #define SVS_IP 3 #define SVS_SIGNED 6 #define SVS_ICQVERSION 8 #define SVS_TIMESTAMP 9 #define SVS_STATUSID 10 #define SVS_FLAGS 0xFF #define SVSF_GRAYED 0x100 #define SVSF_NORMAL 0x200 int OnDetailsInit(WPARAM wParam, LPARAM lParam) { OPTIONSDIALOGPAGE odp = {0}; if ((!IsICQContact((HANDLE)lParam)) && lParam) return 0; odp.cbSize = sizeof(odp); odp.hIcon = NULL; odp.hInstance = hInst; odp.pfnDlgProc = IcqDlgProc; odp.position = -1900000000; odp.pszTemplate = MAKEINTRESOURCE(IDD_INFO_ICQ); AddUserInfoPageUtf(&odp, wParam, gpszICQProtoName); if (((lParam != 0) && gbAvatarsEnabled) || (gbSsiEnabled && gbAvatarsEnabled)) { DWORD dwUin; uid_str dwUid; if (!ICQGetContactSettingUID((HANDLE)lParam, &dwUin, &dwUid)) { // Avatar page only for valid contacts char *szAvtTitle; odp.pfnDlgProc = AvatarDlgProc; odp.position = -1899999998; odp.pszTemplate = MAKEINTRESOURCE(IDD_INFO_AVATAR); if (lParam) szAvtTitle = "Avatar"; else szAvtTitle = "%s Avatar"; AddUserInfoPageUtf(&odp, wParam, szAvtTitle); } } InitChangeDetails(wParam, lParam); return 0; } #define HM_DBCHANGE (WM_USER+200) #define HM_PROTOACK (WM_USER+201) #define TIMERID 1 #define TIMEOUT_IGNORE 2 //#define TIMEOUT_CAPS 3 #define TIMEOUT_IP 4 typedef struct infoflag_s { char *Descr; char *szSetting; DWORD mask; } infoflag; struct UserData { HANDLE hContact; DWORD dwUin; HANDLE hEventDbSettingChange; int nTimer; HANDLE hProtoAck; DWORD dwCookie; }; static infoflag infoflags[] = { {"Hidden", NULL, WAS_FOUND}, {"WebAware", "WebAware", 0}, {"Auth", "AddAuth", 0}, {"UTF", NULL, CAPF_UTF}, {"MTN", NULL, CAPF_TYPING}, {"Xtraz", NULL, CAPF_XTRAZ}, {"ServerRelay", NULL, CAPF_SRV_RELAY}, {"AIMFile", NULL, CAPF_AIM_FILE}, {"Push2Talk", NULL, CAPF_PUSH2TALK}, {"ICQLite", NULL, CAPF_ICQ_LITE}, {"RTF", NULL, CAPF_RTF}, {"XTrazChat", NULL, CAPF_XTRAZ_CHAT}, {"VoiceChat", NULL, CAPF_VOICE_CHAT}, {"ICQDevil", NULL, CAPF_ICQ_DEVIL}, {"DirectConnect", NULL, CAPF_DIRECT}, }; static BOOL CALLBACK IcqDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { struct UserData *dat=(struct UserData*)GetWindowLong(hwndDlg,GWL_USERDATA); switch (msg) { case WM_INITDIALOG: ICQTranslateDialog(hwndDlg); dat=(struct UserData*)malloc(sizeof(struct UserData)); SetWindowLong(hwndDlg,GWL_USERDATA,(LONG)dat); dat->hEventDbSettingChange=HookEventMessage(ME_DB_CONTACT_SETTINGCHANGED,hwndDlg,HM_DBCHANGE); dat->hContact=(HANDLE)lParam; dat->nTimer=0; dat->dwUin=ICQGetContactSettingDword(dat->hContact, UNIQUEIDSETTING, 0); dat->hProtoAck=NULL; dat->dwCookie=0; if ((HANDLE)lParam == NULL) { ShowWindow(GetDlgItem(hwndDlg, IDC_FLAGS), SW_HIDE); ShowWindow(GetDlgItem(hwndDlg, IDC_FLAGSTEXT), SW_HIDE); } return TRUE; case WM_NOTIFY: { switch (((LPNMHDR)lParam)->idFrom) { case 0: { switch (((LPNMHDR)lParam)->code) { case PSN_INFOCHANGED: { HANDLE hContact = dat->hContact; WORD flag = SVSF_NORMAL; int was_found = 0; char szUin[20]; char szStatus[64]; mir_snprintf(szUin, 20, "%u", dat->dwUin); if (hContact == NULL) { SetValue(hwndDlg, IDC_SYSTEMUPTIME, NULL, gpszICQProtoName, "MemberTS", (icqOnline)?SVS_TIMESTAMP|SVSF_NORMAL:SVS_TIMESTAMP|SVSF_GRAYED); _snprintf(szStatus, sizeof(szStatus), MirandaStatusToString(gnCurrentStatus)); SetDlgItemText(hwndDlg, IDC_STATUS, szStatus); } else { WORD wStatus = ICQGetContactSettingWord(hContact, "Status", 0); char str[128] = {0}; int i; SetValue(hwndDlg, IDC_STATUS, hContact, gpszICQProtoName, "Status", SVS_STATUSID); ShowWindow(GetDlgItem(hwndDlg,IDC_GETSTATUS),(ASD)?SW_SHOW:SW_HIDE); //ShowWindow(GetDlgItem(hwndDlg,IDC_GETCAPS),(wStatus != ID_STATUS_OFFLINE)?SW_SHOW:SW_HIDE); ShowWindow(GetDlgItem(hwndDlg,IDC_RETRIEVE),(wStatus != ID_STATUS_OFFLINE)?SW_SHOW:SW_HIDE); ShowWindow(GetDlgItem(hwndDlg,IDC_IGNORECHECK),(wStatus != ID_STATUS_OFFLINE)?SW_SHOW:SW_HIDE); // Subnets //DBGetStaticString(hContact, gpszICQProtoName, "SubNets", str, sizeof(str)); // Set flags for (i=0; i < sizeof(infoflags)/sizeof(infoflags[0]); i++) { if ((infoflags[i].szSetting && ICQGetContactSettingByte(hContact, infoflags[i].szSetting,0)) || (infoflags[i].szSetting == NULL && CheckContactCapabilities(hContact, infoflags[i].mask))) mir_snprintf(str, sizeof(str), (str[0]==0)?"%s%s":"%s, %s", str, Translate(infoflags[i].Descr)); } EnableWindow(GetDlgItem(hwndDlg, IDC_FLAGSTEXT), (str[0] != 0)); if (str[0]==0) SetDlgItemText(hwndDlg, IDC_FLAGSTEXT, ICQTranslate("")); else SetDlgItemText(hwndDlg, IDC_FLAGSTEXT, str); // Gray flags if miranda offline SetWindowLong(GetDlgItem(hwndDlg, IDC_FLAGSTEXT), GWL_USERDATA, (!icqOnline && str[0] != 0)); } //SetValue(hwndDlg, IDC_UIN, hContact, gpszICQProtoName, UNIQUEIDSETTING, 0); SetDlgItemText(hwndDlg, IDC_UIN, szUin); // Client version SetValue(hwndDlg, IDC_MIRVER, hContact, gpszICQProtoName, "MirVer", SVS_ZEROISUNSPEC|flag); // Proto version. if (!SetValue(hwndDlg, IDC_VERSION, hContact, gpszICQProtoName, "Version", SVS_ZEROISUNSPEC|SVSF_NORMAL)) SetValue(hwndDlg, IDC_VERSION, hContact, gpszICQProtoName, "OldVersion", SVS_ZEROISUNSPEC|SVSF_GRAYED); // IP if (!SetValue(hwndDlg, IDC_IP, hContact, gpszICQProtoName, "IP", SVS_IP|SVSF_NORMAL)) SetValue(hwndDlg, IDC_IP, hContact, gpszICQProtoName, "OldIP", SVS_IP|SVSF_GRAYED); // Real IP if (!SetValue(hwndDlg, IDC_REALIP, hContact, gpszICQProtoName, "RealIP", SVS_IP|SVSF_NORMAL)) SetValue(hwndDlg, IDC_REALIP, hContact, gpszICQProtoName, "OldRealIP", SVS_IP|SVSF_GRAYED); // Port if (!SetValue(hwndDlg, IDC_PORT, hContact, gpszICQProtoName, "UserPort", SVS_ZEROISUNSPEC|SVSF_NORMAL)) SetValue(hwndDlg, IDC_PORT, hContact, gpszICQProtoName, "OldUserPort", SVS_ZEROISUNSPEC|SVSF_GRAYED); // Online since time if (!SetValue(hwndDlg, IDC_ONLINESINCE, hContact, gpszICQProtoName, "LogonTS", SVS_TIMESTAMP|SVSF_NORMAL)) SetValue(hwndDlg, IDC_ONLINESINCE, hContact, gpszICQProtoName, "OldLogonTS", SVS_TIMESTAMP|SVSF_GRAYED); // Idle time if (was_found) SetValue(hwndDlg, IDC_IDLETIME, hContact, NULL, NULL, 0); else if (!SetValue(hwndDlg, IDC_IDLETIME, hContact, gpszICQProtoName, "IdleTS", SVS_TIMESTAMP|SVSF_NORMAL)) SetValue(hwndDlg, IDC_IDLETIME, hContact, gpszICQProtoName, "OldIdleTS", SVS_TIMESTAMP|SVSF_GRAYED); if (ICQGetContactSettingByte(hContact, "ClientID", 0) == 1) SetValue(hwndDlg, IDC_SYSTEMUPTIME, hContact, NULL, "TickTS", SVS_TIMESTAMP); else SetValue(hwndDlg, IDC_SYSTEMUPTIME, hContact, gpszICQProtoName, "TickTS", SVS_TIMESTAMP); } break; } } break; } } break; case WM_COMMAND: switch(LOWORD(wParam)) { case IDCANCEL: SendMessage(GetParent(hwndDlg),msg,wParam,lParam); break; case IDC_GETSTATUS: if (icqOnline) icq_GetUserStatus(dat->hContact, 1); break; case IDC_RETRIEVE: if (icqOnline && dat->dwUin) { int wMessageType = 0; switch(ICQGetContactSettingWord(dat->hContact, "Status",ID_STATUS_OFFLINE)) { case ID_STATUS_OFFLINE: break; case ID_STATUS_NA: wMessageType = MTYPE_AUTONA; break; case ID_STATUS_OCCUPIED: wMessageType = MTYPE_AUTOBUSY; break; case ID_STATUS_DND: wMessageType = MTYPE_AUTODND; break; case ID_STATUS_FREECHAT: wMessageType = MTYPE_AUTOFFC; break; case ID_STATUS_AWAY: default: wMessageType = MTYPE_AUTOAWAY; break; } icq_sendGetAwayMsgServ(dat->dwUin, wMessageType, (WORD)(ICQGetContactSettingWord(dat->hContact, "Version", 0)==9?9:ICQ_VERSION)); EnableWindow(GetDlgItem(hwndDlg, IDC_RETRIEVE), FALSE); SetTimer(hwndDlg, TIMEOUT_IP, 10000, NULL); } break; case IDC_IGNORECHECK: if (icqOnline && ICQGetContactSettingWord(dat->hContact, "Status", 0) != ID_STATUS_OFFLINE) { message_cookie_data* pCookieData; if (!dat->hProtoAck) dat->hProtoAck = HookEventMessage(ME_PROTO_ACK, hwndDlg, HM_PROTOACK); SetDlgItemText(hwndDlg, IDC_IGNORE, Translate("Checking...")); pCookieData = malloc(sizeof(message_cookie_data)); pCookieData->bMessageType = MTYPE_PLAIN; pCookieData->nAckType = ACKTYPE_SERVER; dat->dwCookie = icq_SendChannel4Message(dat->dwUin, 0, 0, "", pCookieData); EnableWindow(GetDlgItem(hwndDlg, IDC_IGNORECHECK), FALSE); SetTimer(hwndDlg, TIMEOUT_IGNORE, 10000, NULL); } break; } break; case HM_DBCHANGE: { DBCONTACTWRITESETTING *cws=(DBCONTACTWRITESETTING*)lParam; if (!dat->nTimer && (cws->szModule != NULL) && (dat->hContact == (HANDLE)wParam) && !strcmp(cws->szModule, gpszICQProtoName)) { dat->nTimer = 1; SetTimer(hwndDlg, TIMERID, 1000, NULL); } } break; case HM_PROTOACK: { ACKDATA *ack = (ACKDATA*)lParam; if (!ack || !ack->szModule || ack->hProcess != (HANDLE)dat->dwCookie || ack->hContact != dat->hContact || strcmp(ack->szModule, gpszICQProtoName)) break; if (dat->hProtoAck) { UnhookEvent(dat->hProtoAck); dat->hProtoAck = NULL; } if (ack->result == ACKRESULT_SUCCESS) { SetDlgItemText(hwndDlg, IDC_IGNORE, Translate("Msg Accepted!")); Netlib_Logf(ghServerNetlibUser, "User %u accepts your messages", dat->dwUin); } else if (ack->result == ACKRESULT_FAILED) { SetDlgItemText(hwndDlg, IDC_IGNORE, Translate("Msg Ignored!")); Netlib_Logf(ghServerNetlibUser, "User %u ignores your messages", dat->dwUin); } } break; case WM_TIMER: if (wParam==TIMERID) { PSHNOTIFY pshn; pshn.hdr.code=PSN_INFOCHANGED; pshn.hdr.hwndFrom=hwndDlg; pshn.hdr.idFrom=0; pshn.lParam=(LPARAM)wParam; KillTimer(hwndDlg, TIMERID); dat->nTimer = 0; SendMessage(hwndDlg,WM_NOTIFY,0,(LPARAM)&pshn); } else if (wParam==TIMEOUT_IGNORE) { KillTimer(hwndDlg, TIMEOUT_IGNORE); EnableWindow(GetDlgItem(hwndDlg, IDC_IGNORECHECK), TRUE); } else if (wParam==TIMEOUT_IP) { KillTimer(hwndDlg, TIMEOUT_IP); EnableWindow(GetDlgItem(hwndDlg, IDC_RETRIEVE), TRUE); } break; case WM_DESTROY: if (dat->hEventDbSettingChange) UnhookEvent(dat->hEventDbSettingChange); if (dat->nTimer) KillTimer(hwndDlg, TIMERID); if (dat->hProtoAck) UnhookEvent(dat->hProtoAck); free(dat); break; } return FALSE; } typedef struct AvtDlgProcData_t { HANDLE hContact; HANDLE hEventHook; HWND hFlashAvatar; } AvtDlgProcData; #define HM_REBIND_AVATAR (WM_USER + 1024) static char* ChooseAvatarFileName() { char* szDest = (char*)SAFE_MALLOC(MAX_PATH+0x10); char str[MAX_PATH]; char szFilter[512]; OPENFILENAME ofn = {0}; str[0] = 0; CallService(MS_UTILS_GETBITMAPFILTERSTRINGS,sizeof(szFilter),(LPARAM)szFilter); if (ServiceExists(MS_FAVATAR_GETINFO)) //Flash avatars are supported { char * allimages; char b2[255]; int l,i; char flashfilt[520]={0}; allimages=szFilter+strlen(szFilter)+1; l=sizeof(szFilter)-strlen(szFilter)-1; sprintf(flashfilt,"%s (%s;*.XML)",Translate("All Bitmaps"),allimages); memcpy(flashfilt+strlen(flashfilt)+1,"*.XML;",6); memcpy(flashfilt+6+strlen(flashfilt)+1,allimages,l-(6+strlen(flashfilt)+1)); { int z0=0,z1=0; for (i=0;i0) z0=z1; z1=i; } if (flashfilt[i]=='\0' && flashfilt[i+1]=='\0') { sprintf(b2,"%s (*.xml)",Translate("flash avatars")); memcpy(flashfilt+z0+1,b2,strlen(b2)+1); z0=z0+strlen(b2)+1; memcpy(flashfilt+z0+1,"*.XML\0",6); z0+=6; sprintf(b2,"%s(*.*)",Translate("All files")); memcpy(flashfilt+z0+1,b2,strlen(b2)+1); z0=z0+strlen(b2)+1; memcpy(flashfilt+z0+1,"*\0\0",4); memcpy(szFilter,flashfilt,sizeof(szFilter)); break; } } } } ofn.lStructSize = sizeof(OPENFILENAME); ofn.lpstrFilter = szFilter; ofn.lpstrFile = szDest; ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; ofn.nMaxFile = MAX_PATH; ofn.nMaxFileTitle = MAX_PATH; ofn.lpstrDefExt = "jpg"; if (!GetOpenFileName(&ofn)) { SAFE_FREE(&szDest); return NULL; } return szDest; } static void PrepareFlashAvatar(HWND hwndDlg, AvtDlgProcData* pData) { FLASHAVATAR fa = {0}; fa.hContact = pData->hContact; fa.id = FA_MAGIC_ID; CallService(MS_FAVATAR_GETINFO, (WPARAM)&fa, 0); if (fa.hWindow) { pData->hFlashAvatar = fa.hWindow; SetParent(fa.hWindow, GetDlgItem(hwndDlg, IDC_AVATAR)); } else { fa.hParentWindow = GetDlgItem(hwndDlg, IDC_AVATAR); CallService(MS_FAVATAR_MAKE, (WPARAM)&fa, 0); if (fa.hWindow) pData->hFlashAvatar = fa.hWindow; } } static void ReleaseFlashAvatar(AvtDlgProcData* pData) { if (pData->hFlashAvatar) { // release expired flash avatar object FLASHAVATAR fa; fa.hContact = pData->hContact; fa.id = FA_MAGIC_ID; // icqj magic id CallService(MS_FAVATAR_DESTROY, (WPARAM)&fa, 0); pData->hFlashAvatar = NULL; } } static BOOL CALLBACK AvatarDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_INITDIALOG: ICQTranslateDialog(hwndDlg); { DBVARIANT dbvHash; AvtDlgProcData* pData = (AvtDlgProcData*)SAFE_MALLOC(sizeof(AvtDlgProcData)); DWORD dwUIN; uid_str szUID; char szAvatar[MAX_PATH]; DWORD dwPaFormat; int bValid = 0; pData->hContact = (HANDLE)lParam; if (pData->hContact) pData->hEventHook = HookEventMessage(ME_PROTO_ACK, hwndDlg, HM_REBIND_AVATAR); else { ShowWindow(GetDlgItem(hwndDlg, IDC_SETAVATAR), SW_SHOW); ShowWindow(GetDlgItem(hwndDlg, IDC_DELETEAVATAR), SW_SHOW); ShowWindow(GetDlgItem(hwndDlg, -1), SW_SHOW); if (!icqOnline) { EnableDlgItem(hwndDlg, IDC_SETAVATAR, FALSE); EnableDlgItem(hwndDlg, IDC_DELETEAVATAR, FALSE); } } SetWindowLong(hwndDlg, GWL_USERDATA, (LONG)pData); if (!ICQGetContactSettingUID((HANDLE)lParam, &dwUIN, &szUID)) { if (!ICQGetContactSetting((HANDLE)lParam, "AvatarHash", &dbvHash)) { dwPaFormat = ICQGetContactSettingByte((HANDLE)lParam, "AvatarType", PA_FORMAT_UNKNOWN); if (!pData->hContact || (dwPaFormat != PA_FORMAT_UNKNOWN)) { // we do not know avatar format, so neither filename is known, not valid if (pData->hContact) GetFullAvatarFileName(dwUIN, szUID, dwPaFormat, szAvatar, 255); else { // owner's avatar char* file = loadMyAvatarFileName(); if (file) { strcpy(szAvatar, file); SAFE_FREE(&file); if (dbvHash.pbVal[1] == 8) // we do this by hand, as owner's format is not saved dwPaFormat = PA_FORMAT_XML; } else szAvatar[0] = '\0'; } if (!pData->hContact || !IsAvatarSaved((HANDLE)lParam, dbvHash.pbVal)) { // if the file exists, we know we have the current avatar if (!access(szAvatar, 0)) bValid = 1; } } } else return TRUE; if (bValid) { //load avatar if ((dwPaFormat == PA_FORMAT_XML || dwPaFormat == PA_FORMAT_SWF) && ServiceExists(MS_FAVATAR_GETINFO)) { // flash avatar and we have FlashAvatars installed, init flash avatar PrepareFlashAvatar(hwndDlg, pData); } else { // static avatar processing HBITMAP avt = (HBITMAP)CallService(MS_UTILS_LOADBITMAP, 0, (WPARAM)szAvatar); if (avt) SendDlgItemMessage(hwndDlg, IDC_AVATAR, STM_SETIMAGE, IMAGE_BITMAP, (WPARAM)avt); } } else if (pData->hContact) // only retrieve users avatars { GetAvatarFileName(dwUIN, szUID, szAvatar, 255); GetAvatarData((HANDLE)lParam, dwUIN, szUID, dbvHash.pbVal, 0x14, szAvatar); } } ICQFreeVariant(&dbvHash); } return TRUE; case HM_REBIND_AVATAR: { AvtDlgProcData* pData = (AvtDlgProcData*)GetWindowLong(hwndDlg, GWL_USERDATA); ACKDATA* ack = (ACKDATA*)lParam; if (!pData->hContact) break; // we do not use this for us if (ack->type == ACKTYPE_AVATAR && ack->hContact == pData->hContact) { if (ack->result == ACKRESULT_SUCCESS) { // load avatar PROTO_AVATAR_INFORMATION* AI = (PROTO_AVATAR_INFORMATION*)ack->hProcess; HBITMAP avt = NULL; ReleaseFlashAvatar(pData); if ((AI->format == PA_FORMAT_XML || AI->format == PA_FORMAT_SWF) && ServiceExists(MS_FAVATAR_GETINFO)) { // flash avatar and we have FlashAvatars installed, init flash avatar PrepareFlashAvatar(hwndDlg, pData); } else { avt = (HBITMAP)CallService(MS_UTILS_LOADBITMAP, 0, (WPARAM)AI->filename); } if (avt) avt = (HBITMAP)SendDlgItemMessage(hwndDlg, IDC_AVATAR, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)avt); if (avt) DeleteObject(avt); // we release old avatar if any } else if (ack->result == ACKRESULT_STATUS) { // contact has changed avatar DWORD dwUIN; uid_str szUID; DBVARIANT dbvHash; if (!ICQGetContactSettingUID(pData->hContact, &dwUIN, &szUID)) { if (!ICQGetContactSetting(pData->hContact, "AvatarHash", &dbvHash)) { char szAvatar[MAX_PATH]; GetAvatarFileName(dwUIN, szUID, szAvatar, 255); GetAvatarData(pData->hContact, dwUIN, szUID, dbvHash.pbVal, 0x14, szAvatar); } ICQFreeVariant(&dbvHash); } } } } break; case WM_COMMAND: switch(LOWORD(wParam)) { case IDC_SETAVATAR: { char* szFile; AvtDlgProcData* pData = (AvtDlgProcData*)GetWindowLong(hwndDlg, GWL_USERDATA); if (szFile = ChooseAvatarFileName()) { // user selected file for his avatar DWORD dwPaFormat = DetectAvatarFormat(szFile); if (dwPaFormat == PA_FORMAT_XML || dwPaFormat == PA_FORMAT_JPEG || dwPaFormat == PA_FORMAT_GIF || dwPaFormat == PA_FORMAT_BMP) { // a valid file HBITMAP avt = NULL; if (dwPaFormat != PA_FORMAT_XML || !ServiceExists(MS_FAVATAR_GETINFO)) avt = (HBITMAP)CallService(MS_UTILS_LOADBITMAP, 0, (WPARAM)szFile); if (!IcqSetMyAvatar(0, (LPARAM)szFile)) // set avatar { ReleaseFlashAvatar(pData); if (dwPaFormat != PA_FORMAT_XML || !ServiceExists(MS_FAVATAR_GETINFO)) { // it is not flash, release possible previous avt = (HBITMAP)SendDlgItemMessage(hwndDlg, IDC_AVATAR, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)avt); } else { // is is flash load it PrepareFlashAvatar(hwndDlg, pData); } } if (avt) DeleteObject(avt); // we release old avatar if any } SAFE_FREE(&szFile); } } break; case IDC_DELETEAVATAR: { HBITMAP avt; AvtDlgProcData* pData = (AvtDlgProcData*)GetWindowLong(hwndDlg, GWL_USERDATA); avt = (HBITMAP)SendDlgItemMessage(hwndDlg, IDC_AVATAR, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)NULL); RedrawWindow(GetDlgItem(hwndDlg, IDC_AVATAR), NULL, NULL, RDW_INVALIDATE); if (avt) DeleteObject(avt); // we release old avatar if any ReleaseFlashAvatar(pData); IcqSetMyAvatar(0, 0); // clear hash on server } break; } break; case WM_DESTROY: { AvtDlgProcData* pData = (AvtDlgProcData*)GetWindowLong(hwndDlg, GWL_USERDATA); if (pData->hContact) UnhookEvent(pData->hEventHook); ReleaseFlashAvatar(pData); SetWindowLong(hwndDlg, GWL_USERDATA, (LONG)0); SAFE_FREE(&pData); } break; } return FALSE; } static BYTE SetValue(HWND hwndDlg, int idCtrl, HANDLE hContact, char* szModule, char* szSetting, WORD type) { DBVARIANT dbv = {0}; char str[MAX_PATH]; char* pstr = NULL; int unspecified = 0; int special = type & SVS_FLAGS; int bUtf = 0, bDbv = 0, bAlloc = 0; dbv.type = DBVT_DELETED; if ((hContact == NULL) && ((int)szModule<0x100)) { dbv.type = (BYTE)szModule; switch((int)szModule) { case DBVT_BYTE: dbv.cVal = (BYTE)szSetting; break; case DBVT_WORD: dbv.wVal = (WORD)szSetting; break; case DBVT_DWORD: dbv.dVal = (DWORD)szSetting; break; case DBVT_ASCIIZ: dbv.pszVal = pstr = szSetting; break; default: unspecified = 1; dbv.type = DBVT_DELETED; } } else { if (szModule == NULL) unspecified = 1; else { unspecified = DBGetContactSetting(hContact, szModule, szSetting, &dbv); bDbv = 1; } } if (!unspecified) { switch (dbv.type) { case DBVT_BYTE: unspecified = (special == SVS_ZEROISUNSPEC && dbv.bVal == 0); pstr = itoa(special == SVS_SIGNED ? dbv.cVal:dbv.bVal, str, 10); break; case DBVT_WORD: if (special == SVS_ICQVERSION) { if (dbv.wVal != 0) { char szExtra[80]; null_snprintf(str, 250, "%d", dbv.wVal); pstr = str; if (hContact && IsDirectConnectionOpen(hContact, DIRECTCONN_STANDARD)) { ICQTranslateUtfStatic(" (DC Established)", szExtra); strcat(str, szExtra); bUtf = 1; } } else unspecified = 1; } else if (special == SVS_STATUSID) { char* pXName; char* pszStatus; BYTE bXStatus = ICQGetContactSettingByte(hContact, DBSETTING_XSTATUSID, 0); pszStatus = MirandaStatusToStringUtf(dbv.wVal); if (bXStatus) { pXName = ICQGetContactSettingUtf(hContact, DBSETTING_XSTATUSNAME, ""); if (!strlennull(pXName)) { // give default name pXName = ICQTranslateUtf(nameXStatus[bXStatus-1]); } null_snprintf(str, sizeof(str), "%s (%s)", pszStatus, pXName); SAFE_FREE(&pXName); } else null_snprintf(str, sizeof(str), pszStatus); bUtf = 1; SAFE_FREE(&pszStatus); pstr = str; unspecified = 0; } else { unspecified = (special == SVS_ZEROISUNSPEC && dbv.wVal == 0); pstr = itoa(special == SVS_SIGNED ? dbv.sVal:dbv.wVal, str, 10); } break; case DBVT_DWORD: unspecified = (special == SVS_ZEROISUNSPEC && dbv.dVal == 0); if (special == SVS_IP) { struct in_addr ia; ia.S_un.S_addr = htonl(dbv.dVal); pstr = inet_ntoa(ia); if (dbv.dVal == 0) unspecified=1; } else if (special == SVS_TIMESTAMP) { if (dbv.dVal == 0) unspecified = 1; else { pstr = asctime(localtime(&dbv.dVal)); pstr[24] = '\0'; // Remove newline } } else pstr = itoa(special == SVS_SIGNED ? dbv.lVal:dbv.dVal, str, 10); break; case DBVT_ASCIIZ: unspecified = (special == SVS_ZEROISUNSPEC && dbv.pszVal[0] == '\0'); if (!unspecified && pstr != szSetting) { pstr = UniGetContactSettingUtf(hContact, szModule, szSetting, NULL); bUtf = 1; bAlloc = 1; } if (idCtrl == IDC_UIN) SetDlgItemTextUtf(hwndDlg, IDC_UINSTATIC, ICQTranslateUtfStatic("ScreenName:", str)); break; default: pstr = str; lstrcpy(str,"???"); break; } } EnableDlgItem(hwndDlg, idCtrl, !unspecified); if (unspecified) SetDlgItemTextUtf(hwndDlg, idCtrl, ICQTranslateUtfStatic("", str)); else if (bUtf) SetDlgItemTextUtf(hwndDlg, idCtrl, pstr); else SetDlgItemText(hwndDlg, idCtrl, pstr); if (bDbv) ICQFreeVariant(&dbv); if (bAlloc) SAFE_FREE(&pstr); if (type > SVS_FLAGS) { EnableWindow(GetDlgItem(hwndDlg, idCtrl), !(type & SVSF_GRAYED)); } return !unspecified; }