WCHAR* multiReplaceW(const WCHAR *value, const WCHAR *search, const WCHAR *replace, int cs) { int slen = (int)mir_wstrlen(search); int rlen = (int)mir_wstrlen(replace); int vlen = (int)mir_wstrlen(value); int ci = slen ? cs : 1; // on empty string strstr() returns full string while StrStrI() returns NULL // let's try to calculate maximum length for result string int newlen = (!slen) ? rlen + 1 : ( ( rlen <= slen ) ? vlen + 1 : vlen * rlen / slen + 1 ); WCHAR *head; WCHAR *in = (WCHAR*)value; WCHAR *out = (WCHAR*)mir_alloc(newlen * sizeof(WCHAR)); out[0] = 0; while (head = ci ? wcsstr(in, search) : StrStrIW(in, search)) { if (head != in) mir_wstrncat(out, in, head - in + 1); in = head + slen; mir_wstrcat(out, replace); } mir_wstrcat(out, in); return out; }
void GetStatusText(MCONTACT hContact, WORD newStatus, WORD oldStatus, wchar_t *stzStatusText) { if (opt.UseAlternativeText) { switch (GetGender(hContact)) { case GENDER_MALE: wcsncpy(stzStatusText, StatusList[Index(newStatus)].lpzMStatusText, MAX_STATUSTEXT); break; case GENDER_FEMALE: wcsncpy(stzStatusText, StatusList[Index(newStatus)].lpzFStatusText, MAX_STATUSTEXT); break; case GENDER_UNSPECIFIED: wcsncpy(stzStatusText, StatusList[Index(newStatus)].lpzUStatusText, MAX_STATUSTEXT); break; } } else wcsncpy(stzStatusText, StatusList[Index(newStatus)].lpzStandardText, MAX_STATUSTEXT); if (opt.ShowPreviousStatus) { wchar_t buff[MAX_STATUSTEXT]; mir_snwprintf(buff, TranslateW(STRING_SHOWPREVIOUSSTATUS), StatusList[Index(oldStatus)].lpzStandardText); mir_wstrcat(mir_wstrcat(stzStatusText, L" "), buff); } }
int ProcessStatusMessage(DBCONTACTWRITESETTING *cws, MCONTACT hContact) { STATUSMSGINFO smi; bool bEnablePopup = true, bEnableSound = true; char *szProto = GetContactProto(hContact); smi.proto = szProto; smi.hContact = hContact; smi.compare = CompareStatusMsg(&smi, cws, "LastStatusMsg"); if (smi.compare == COMPARE_SAME) goto skip_notify; if (cws->value.type == DBVT_DELETED) db_unset(hContact, "UserOnline", "LastStatusMsg"); else db_set(hContact, "UserOnline", "LastStatusMsg", &cws->value); //don't show popup when mradio connecting and disconnecting if (_stricmp(szProto, "mRadio") == 0 && !cws->value.type == DBVT_DELETED) { wchar_t buf[MAX_PATH]; mir_snwprintf(buf, L" (%s)", TranslateT("connecting")); T2Utf pszUtf(buf); mir_snwprintf(buf, L" (%s)", TranslateT("aborting")); T2Utf pszUtf2(buf); mir_snwprintf(buf, L" (%s)", TranslateT("playing")); T2Utf pszUtf3(buf); if (_stricmp(cws->value.pszVal, pszUtf) == 0 || _stricmp(cws->value.pszVal, pszUtf2) == 0 || _stricmp(cws->value.pszVal, pszUtf3) == 0) goto skip_notify; } // check per-contact ignored events if (db_get_b(hContact, MODULE, "EnableSMsgNotify", 1) == 0) bEnableSound = bEnablePopup = false; // we're offline or just connecting int myStatus = Proto_GetStatus(szProto); if (myStatus == ID_STATUS_OFFLINE) goto skip_notify; char dbSetting[64]; mir_snprintf(dbSetting, "%s_enabled", szProto); // this proto is not set for status message notifications if (db_get_b(NULL, MODULE, dbSetting, 1) == 0) goto skip_notify; mir_snprintf(dbSetting, "%d", IDC_CHK_STATUS_MESSAGE); // status message change notifications are disabled if (db_get_b(NULL, MODULE, dbSetting, 1) == 0) goto skip_notify; if (SkipHiddenContact(hContact)) goto skip_notify; // check if our status isn't on autodisable list if (opt.AutoDisable) { char statusIDs[12], statusIDp[12]; mir_snprintf(statusIDs, "s%d", myStatus); mir_snprintf(statusIDp, "p%d", myStatus); bEnableSound = db_get_b(0, MODULE, statusIDs, 1) ? FALSE : bEnableSound; bEnablePopup = db_get_b(0, MODULE, statusIDp, 1) ? FALSE : bEnablePopup; } // check flags if ((!(templates.PopupSMsgFlags & NOTIFY_REMOVE_MESSAGE) && (smi.compare == COMPARE_DEL)) || (!(templates.PopupSMsgFlags & NOTIFY_NEW_MESSAGE) && (smi.compare == COMPARE_DIFF))) bEnablePopup = false; if (db_get_b(0, MODULE, szProto, 1) == 0 && !opt.PSMsgOnConnect) bEnablePopup = false; if (bEnablePopup && db_get_b(hContact, MODULE, "EnablePopups", 1) && !opt.TempDisabled) { // cut message if needed wchar_t *copyText = nullptr; if (opt.PSMsgTruncate && (opt.PSMsgLen > 0) && smi.newstatusmsg && (mir_wstrlen(smi.newstatusmsg) > opt.PSMsgLen)) { wchar_t buff[MAX_TEXT_LEN + 3]; copyText = mir_wstrdup(smi.newstatusmsg); wcsncpy(buff, smi.newstatusmsg, opt.PSMsgLen); buff[opt.PSMsgLen] = 0; mir_wstrcat(buff, L"..."); replaceStrW(smi.newstatusmsg, buff); } wchar_t *str; if (smi.compare == COMPARE_DEL) { char protoname[MAX_PATH]; mir_snprintf(protoname, "%s_TPopupSMsgRemoved", szProto); DBVARIANT dbVar = { 0 }; if (db_get_ws(NULL, MODULE, protoname, &dbVar)) { str = GetStr(&smi, DEFAULT_POPUP_SMSGREMOVED); } else { str = GetStr(&smi, dbVar.ptszVal); db_free(&dbVar); } } else { char protoname[MAX_PATH]; mir_snprintf(protoname, "%s_TPopupSMsgChanged", szProto); DBVARIANT dbVar = { 0 }; if (db_get_ws(NULL, MODULE, protoname, &dbVar)) { str = GetStr(&smi, DEFAULT_POPUP_SMSGCHANGED); } else { str = GetStr(&smi, dbVar.ptszVal); db_free(&dbVar); } } ShowChangePopup(hContact, Skin_LoadProtoIcon(szProto, db_get_w(hContact, szProto, "Status", ID_STATUS_ONLINE)), ID_STATUS_STATUSMSG, str); mir_free(str); if (copyText) { mir_free(smi.newstatusmsg); smi.newstatusmsg = copyText; } } if (opt.BlinkIcon && opt.BlinkIcon_ForMsgs && !opt.TempDisabled) { HICON hIcon = opt.BlinkIcon_Status ? Skin_LoadProtoIcon(szProto, db_get_w(hContact, szProto, "Status", ID_STATUS_ONLINE)) : Skin_LoadIcon(SKINICON_OTHER_USERONLINE); wchar_t str[256]; mir_snwprintf(str, TranslateT("%s changed status message to %s"), Clist_GetContactDisplayName(hContact), smi.newstatusmsg); BlinkIcon(hContact, hIcon, str); } if (bEnableSound && db_get_b(0, "Skin", "UseSound", TRUE) && db_get_b(hContact, MODULE, "EnableSounds", 1) && !opt.TempDisabled) { if (smi.compare == COMPARE_DEL) PlayChangeSound(hContact, StatusListEx[ID_STATUS_SMSGREMOVED].lpzSkinSoundName); else PlayChangeSound(hContact, StatusListEx[ID_STATUS_SMSGCHANGED].lpzSkinSoundName); } BOOL bEnableLog = opt.SMsgLogToDB && db_get_b(hContact, MODULE, "EnableSMsgLogging", 1); if (bEnableLog && (!opt.SMsgLogToDB_WinOpen || CheckMsgWnd(hContact))) LogSMsgToDB(&smi, smi.compare == COMPARE_DEL ? templates.LogSMsgRemoved : templates.LogSMsgChanged); if (opt.SMsgLogToFile && db_get_b(hContact, MODULE, "EnableSMsgLogging", 1)) { wchar_t stzDate[MAX_STATUSTEXT], stzTime[MAX_STATUSTEXT], stzText[MAX_TEXT_LEN]; GetTimeFormat(LOCALE_USER_DEFAULT, 0, nullptr, L"HH':'mm", stzTime, _countof(stzTime)); GetDateFormat(LOCALE_USER_DEFAULT, 0, nullptr, L"dd/MM/yyyy", stzDate, _countof(stzDate)); wchar_t *str; if (smi.compare == COMPARE_DEL) str = GetStr(&smi, templates.LogSMsgRemoved); else str = GetStr(&smi, templates.LogSMsgChanged); mir_snwprintf(stzText, L"%s, %s. %s %s\r\n", stzDate, stzTime, Clist_GetContactDisplayName(hContact), str); LogToFile(stzText); mir_free(str); } skip_notify: replaceStrW(smi.newstatusmsg, nullptr); replaceStrW(smi.oldstatusmsg, nullptr); return 1; }
int ChangeLayout(HWND hTextWnd, BYTE TextOperation, BOOL CurrentWord) { HKL hklCurLay = nullptr, hklToLay = nullptr; ptrW ptszInText; CHARRANGE crSelection = { 0 }, crTemp = { 0 }; DWORD dwStartWord, dwEndWord; int i, iRes; BYTE WindowType = WTYPE_Unknown; BOOL WindowIsReadOnly, TwoWay; if (hTextWnd == nullptr) hTextWnd = GetFocus(); if (hTextWnd == nullptr) return 0; //--------------Определяем тип окна----------------- IEVIEWEVENT ieEvent = { 0 }; ieEvent.cbSize = sizeof(IEVIEWEVENT); ieEvent.iType = IEE_GET_SELECTION; if (ServiceExists(MS_HPP_EG_EVENT)) { // То же самое для History++ ieEvent.hwnd = hTextWnd; ptszInText = (wchar_t*)CallService(MS_HPP_EG_EVENT, 0, (LPARAM)&ieEvent); if (!IsBadStringPtr(ptszInText, MaxTextSize)) WindowType = WTYPE_HistoryPP; } if ((WindowType == WTYPE_Unknown) && (ServiceExists(MS_IEVIEW_EVENT))) { // Извращенное определение хэндла IEView ieEvent.hwnd = GetParent(GetParent(hTextWnd)); ptszInText = (wchar_t*)CallService(MS_IEVIEW_EVENT, 0, (LPARAM)&ieEvent); if (!IsBadStringPtr(ptszInText, MaxTextSize)) WindowType = WTYPE_IEView; } if (WindowType == WTYPE_Unknown) { ptrW ptszTemp((LPTSTR)mir_alloc(255 * sizeof(wchar_t))); i = GetClassName(hTextWnd, ptszTemp, 255); ptszTemp[i] = 0; if (wcsstr(CharUpper(ptszTemp), L"RICHEDIT") != nullptr) { WindowType = WTYPE_RichEdit; SendMessage(hTextWnd, EM_EXGETSEL, 0, (LPARAM)&crSelection); } } if (WindowType == WTYPE_Unknown) { SendMessage(hTextWnd, EM_GETSEL, (WPARAM)&crSelection.cpMin, (LPARAM)&crSelection.cpMax); if ((SendMessage(hTextWnd, WM_GETDLGCODE, 0, 0)&(DLGC_HASSETSEL)) && (crSelection.cpMin >= 0)) WindowType = WTYPE_Edit; } // Получим текст из Рича или обычного Едита if (WindowType == WTYPE_RichEdit || WindowType == WTYPE_Edit) { dwStartWord = dwEndWord = -1; SendMessage(hTextWnd, WM_SETREDRAW, FALSE, 0); // Бэкап выделения crTemp = crSelection; // Если имеется выделенный текст, то получим его if (crSelection.cpMin != crSelection.cpMax) { if (WindowType == WTYPE_RichEdit) { EditStreamData esdData; EDITSTREAM esStream = { 0 }; esStream.dwCookie = (DWORD_PTR)&esdData; esStream.pfnCallback = EditStreamOutRtf; if (SendMessage(hTextWnd, EM_STREAMOUT, SF_TEXT | SF_UNICODE | SFF_SELECTION, (LPARAM)&esStream) > 0) ptszInText = GeTStringFromStreamData(&esdData); else { SendMessage(hTextWnd, EM_EXSETSEL, 0, (LPARAM)&crSelection); SendMessage(hTextWnd, WM_SETREDRAW, TRUE, 0); InvalidateRect(hTextWnd, nullptr, FALSE); return 1; } } if (WindowType == WTYPE_Edit) { ptrW ptszTemp((LPTSTR)mir_alloc(MaxTextSize*sizeof(wchar_t))); ptszInText = (LPTSTR)mir_alloc(MaxTextSize*sizeof(wchar_t)); iRes = GetWindowText(hTextWnd, ptszTemp, MaxTextSize); if (!IsBadStringPtr(ptszInText, MaxTextSize) && (iRes > 0)) { wcsncpy(ptszInText, &ptszTemp[crSelection.cpMin], crSelection.cpMax - crSelection.cpMin); ptszInText[crSelection.cpMax - crSelection.cpMin] = 0; } else { SendMessage(hTextWnd, EM_EXSETSEL, 0, (LPARAM)&crSelection); SendMessage(hTextWnd, WM_SETREDRAW, TRUE, 0); InvalidateRect(hTextWnd, nullptr, FALSE); return 1; } } } // Если выделения нет, то получим нужный текст else { // Получаем весь текст в поле if (WindowType == WTYPE_RichEdit) { crTemp.cpMin = 0; crTemp.cpMax = -1; SendMessage(hTextWnd, EM_EXSETSEL, 0, (LPARAM)&crTemp); EditStreamData esdData; EDITSTREAM esStream = { 0 }; esStream.dwCookie = (DWORD_PTR)&esdData; esStream.pfnCallback = EditStreamOutRtf; if (SendMessage(hTextWnd, EM_STREAMOUT, SF_TEXT | SF_UNICODE | SFF_SELECTION, (LPARAM)&esStream) != 0) ptszInText = GeTStringFromStreamData(&esdData); else { SendMessage(hTextWnd, EM_EXSETSEL, 0, (LPARAM)&crSelection); SendMessage(hTextWnd, WM_SETREDRAW, TRUE, 0); InvalidateRect(hTextWnd, nullptr, FALSE); return 1; } } if (WindowType == WTYPE_Edit) { ptszInText = (LPTSTR)mir_alloc(MaxTextSize*sizeof(wchar_t)); iRes = GetWindowText(hTextWnd, ptszInText, MaxTextSize); if (!IsBadStringPtr(ptszInText, MaxTextSize) && (iRes > 0)) { crTemp.cpMin = 0; crTemp.cpMax = (int)mir_wstrlen(ptszInText); } else { SendMessage(hTextWnd, EM_EXSETSEL, 0, (LPARAM)&crSelection); SendMessage(hTextWnd, WM_SETREDRAW, TRUE, 0); InvalidateRect(hTextWnd, nullptr, FALSE); return 1; } } // Получаем текущее слово if (CurrentWord) { for (dwStartWord = crSelection.cpMin; (dwStartWord > 0) && (wcschr(ptszSeparators, ptszInText[dwStartWord - 1]) == nullptr); dwStartWord--); for (dwEndWord = crSelection.cpMin; (dwEndWord < (mir_wstrlen(ptszInText))) && (wcschr(ptszSeparators, ptszInText[dwEndWord]) == nullptr); dwEndWord++); crTemp.cpMin = dwStartWord; crTemp.cpMax = dwEndWord; if (WindowType == WTYPE_RichEdit) { SendMessage(hTextWnd, EM_EXSETSEL, 0, (LPARAM)&crTemp); EditStreamData esdData; EDITSTREAM esStream = { 0 }; esStream.dwCookie = (DWORD_PTR)&esdData; esStream.pfnCallback = EditStreamOutRtf; if (SendMessage(hTextWnd, EM_STREAMOUT, SF_TEXT | SF_UNICODE | SFF_SELECTION, (LPARAM)&esStream) != 0) ptszInText = GeTStringFromStreamData(&esdData); else { SendMessage(hTextWnd, EM_EXSETSEL, 0, (LPARAM)&crSelection); SendMessage(hTextWnd, WM_SETREDRAW, TRUE, 0); InvalidateRect(hTextWnd, nullptr, FALSE); return 1; } } if (WindowType == WTYPE_Edit) { ptrW ptszTemp((LPTSTR)mir_alloc(MaxTextSize*sizeof(wchar_t))); wcsncpy(ptszTemp, &ptszInText[crTemp.cpMin], crTemp.cpMax - crTemp.cpMin); ptszTemp[crTemp.cpMax - crTemp.cpMin] = 0; mir_wstrcpy(ptszInText, ptszTemp); if (mir_wstrlen(ptszInText) == 0) { SendMessage(hTextWnd, EM_EXSETSEL, 0, (LPARAM)&crSelection); SendMessage(hTextWnd, WM_SETREDRAW, TRUE, 0); InvalidateRect(hTextWnd, nullptr, FALSE); return 1; } } } } } //---------------Выдаем результаты-------------------- WindowIsReadOnly = FALSE; if (WindowType == WTYPE_IEView || WindowType == WTYPE_HistoryPP) WindowIsReadOnly = TRUE; // if ((SendMessage(hTextWnd, EM_GETOPTIONS, 0, 0)&ECO_READONLY)) if (WindowType == WTYPE_RichEdit || WindowType == WTYPE_Edit) if (GetWindowLongPtr(hTextWnd, GWL_STYLE) & ES_READONLY) WindowIsReadOnly = TRUE; // Лог Иевью и ХисториПП в режиме эмуляции Иевью и поля только для чтения. if (WindowType != WTYPE_Unknown && !IsBadStringPtr(ptszInText, MaxTextSize)) if (WindowIsReadOnly) { ptrW ptszMBox((LPTSTR)mir_alloc(MaxTextSize*sizeof(wchar_t))); ptszMBox[0] = 0; if (TextOperation == TOT_Layout) { hklCurLay = GetLayoutOfText(ptszInText); hklToLay = GetNextLayout(hklCurLay); TwoWay = (moOptions.TwoWay) && (bLayNum == 2); if (bLayNum == 2) ptszMBox = ChangeTextLayout(ptszInText, hklCurLay, hklToLay, TwoWay); else { for (i = 0; i < bLayNum; i++) if (hklLayouts[i] != hklCurLay) { if (mir_wstrlen(ptszMBox) != 0) mir_wstrcat(ptszMBox, L"\n\n"); ptrW ptszTemp(GetShortNameOfLayout(hklLayouts[i])); mir_wstrcat(ptszMBox, ptszTemp); mir_wstrcat(ptszMBox, L":\n"); ptrW ptszOutText(ChangeTextLayout(ptszInText, hklCurLay, hklLayouts[i], FALSE)); mir_wstrcat(ptszMBox, ptszOutText); } } } else if (TextOperation == TOT_Case) ptszMBox = ChangeTextCase(ptszInText); if ((WindowType == WTYPE_Edit) || (WindowType == WTYPE_RichEdit)) { SendMessage(hTextWnd, EM_EXSETSEL, 0, (LPARAM)&crSelection); SendMessage(hTextWnd, WM_SETREDRAW, TRUE, 0); InvalidateRect(hTextWnd, nullptr, FALSE); } if (TextOperation == TOT_Layout) Skin_PlaySound(SND_ChangeLayout); else if (TextOperation == TOT_Case) Skin_PlaySound(SND_ChangeCase); if (moOptions.CopyToClipboard) CopyTextToClipboard(ptszMBox); //-------------------------------Покажем попапы------------------------------------------ if (moOptions.ShowPopup) { LPTSTR ptszPopupText = (LPTSTR)mir_alloc(MaxTextSize*sizeof(wchar_t)); mir_wstrcpy(ptszPopupText, ptszMBox); POPUPDATAT_V2 pdtData = { 0 }; pdtData.cbSize = sizeof(pdtData); wcsncpy(pdtData.lptzContactName, TranslateT(MODULENAME), MAX_CONTACTNAME); wcsncpy(pdtData.lptzText, ptszPopupText, MAX_SECONDLINE); switch (poOptions.bColourType) { case PPC_POPUP: pdtData.colorBack = pdtData.colorText = 0; break; case PPC_WINDOWS: pdtData.colorBack = GetSysColor(COLOR_BTNFACE); pdtData.colorText = GetSysColor(COLOR_WINDOWTEXT); break; case PPC_CUSTOM: pdtData.colorBack = poOptions.crBackColour; pdtData.colorText = poOptions.crTextColour; break; } switch (poOptions.bTimeoutType) { case PPT_POPUP: pdtData.iSeconds = 0; break; case PPT_PERMANENT: pdtData.iSeconds = -1; break; case PPC_CUSTOM: pdtData.iSeconds = poOptions.bTimeout; break; } pdtData.PluginData = ptszPopupText; pdtData.PluginWindowProc = (WNDPROC)CKLPopupDlgProc; pdtData.lchIcon = hPopupIcon; poOptions.paActions[0].lchIcon = hCopyIcon; pdtData.lpActions = poOptions.paActions; pdtData.actionCount = 1; if (CallService(MS_POPUP_ADDPOPUPT, (WPARAM)&pdtData, APF_NEWDATA) < 0) { mir_free(ptszPopupText); MessageBox(nullptr, ptszMBox, TranslateT(MODULENAME), MB_ICONINFORMATION); } } } //------------------Редактируемые поля ---------------------------- else { ptrW ptszOutText; if (TextOperation == TOT_Layout) { hklCurLay = GetLayoutOfText(ptszInText); hklToLay = GetNextLayout(hklCurLay); TwoWay = (moOptions.TwoWay) && (bLayNum == 2); ptszOutText = ChangeTextLayout(ptszInText, hklCurLay, hklToLay, TwoWay); } else if (TextOperation == TOT_Case) ptszOutText = ChangeTextCase(ptszInText); if (WindowType == WTYPE_RichEdit) { SendMessage(hTextWnd, EM_EXSETSEL, 0, (LPARAM)&crTemp); SendMessage(hTextWnd, EM_REPLACESEL, FALSE, (LPARAM)ptszOutText); SendMessage(hTextWnd, EM_EXSETSEL, 0, (LPARAM)&crSelection); } else { ptrW ptszTemp((LPTSTR)mir_alloc(MaxTextSize*sizeof(wchar_t))); GetWindowText(hTextWnd, ptszTemp, MaxTextSize); for (i = crTemp.cpMin; i < crTemp.cpMax; i++) ptszTemp[i] = ptszOutText[i - crTemp.cpMin]; SetWindowText(hTextWnd, ptszTemp); SendMessage(hTextWnd, EM_SETSEL, crSelection.cpMin, crSelection.cpMax); } // Переключим раскладку или изменим состояние Caps Lock if (TextOperation == TOT_Layout && hklToLay != nullptr && moOptions.ChangeSystemLayout) ActivateKeyboardLayout(hklToLay, KLF_SETFORPROCESS); else if (TextOperation == TOT_Case) { // Если нужно инвертнуть if (moOptions.bCaseOperations == 0) { keybd_event(VK_CAPITAL, 0x45, 0, 0); keybd_event(VK_CAPITAL, 0x45, KEYEVENTF_KEYUP, 0); } // Если нужно отключить else if (moOptions.bCaseOperations == 1) { if (GetKeyState(VK_CAPITAL) & 0x0001) { keybd_event(VK_CAPITAL, 0x45, 0, 0); keybd_event(VK_CAPITAL, 0x45, KEYEVENTF_KEYUP, 0); } } } SendMessage(hTextWnd, WM_SETREDRAW, TRUE, 0); InvalidateRect(hTextWnd, nullptr, FALSE); if (TextOperation == TOT_Layout) Skin_PlaySound(SND_ChangeLayout); else if (TextOperation == TOT_Case) Skin_PlaySound(SND_ChangeCase); } return 0; }
static INT_PTR GetContactInfo(WPARAM, LPARAM lParam) { DBVARIANT dbv; CONTACTINFO *ci = (CONTACTINFO*)lParam; if (ci == NULL) return 1; if (ci->szProto == NULL) ci->szProto = Proto_GetBaseAccountName(ci->hContact); if (ci->szProto == NULL) return 1; ci->type = 0; switch (ci->dwFlag & 0x7F) { case CNF_FIRSTNAME: return ProcessDatabaseValueDefault(ci, "FirstName"); case CNF_LASTNAME: return ProcessDatabaseValueDefault(ci, "LastName"); case CNF_NICK: return ProcessDatabaseValueDefault(ci, "Nick"); case CNF_EMAIL: return ProcessDatabaseValueDefault(ci, "e-mail"); case CNF_CITY: return ProcessDatabaseValueDefault(ci, "City"); case CNF_STATE: return ProcessDatabaseValueDefault(ci, "State"); case CNF_PHONE: return ProcessDatabaseValueDefault(ci, "Phone"); case CNF_HOMEPAGE: return ProcessDatabaseValueDefault(ci, "Homepage"); case CNF_ABOUT: return ProcessDatabaseValueDefault(ci, "About"); case CNF_AGE: return ProcessDatabaseValueDefault(ci, "Age"); case CNF_GENDER: return ProcessDatabaseValueDefault(ci, "Gender"); case CNF_FAX: return ProcessDatabaseValueDefault(ci, "Fax"); case CNF_CELLULAR: return ProcessDatabaseValueDefault(ci, "Cellular"); case CNF_BIRTHDAY: return ProcessDatabaseValueDefault(ci, "BirthDay"); case CNF_BIRTHMONTH: return ProcessDatabaseValueDefault(ci, "BirthMonth"); case CNF_BIRTHYEAR: return ProcessDatabaseValueDefault(ci, "BirthYear"); case CNF_STREET: return ProcessDatabaseValueDefault(ci, "Street"); case CNF_ZIP: return ProcessDatabaseValueDefault(ci, "ZIP"); case CNF_LANGUAGE1: return ProcessDatabaseValueDefault(ci, "Language1"); case CNF_LANGUAGE2: return ProcessDatabaseValueDefault(ci, "Language2"); case CNF_LANGUAGE3: return ProcessDatabaseValueDefault(ci, "Language3"); case CNF_CONAME: return ProcessDatabaseValueDefault(ci, "Company"); case CNF_CODEPT: return ProcessDatabaseValueDefault(ci, "CompanyDepartment"); case CNF_COPOSITION: return ProcessDatabaseValueDefault(ci, "CompanyPosition"); case CNF_COSTREET: return ProcessDatabaseValueDefault(ci, "CompanyStreet"); case CNF_COCITY: return ProcessDatabaseValueDefault(ci, "CompanyCity"); case CNF_COSTATE: return ProcessDatabaseValueDefault(ci, "CompanyState"); case CNF_COZIP: return ProcessDatabaseValueDefault(ci, "CompanyZIP"); case CNF_COHOMEPAGE: return ProcessDatabaseValueDefault(ci, "CompanyHomepage"); case CNF_CUSTOMNICK: { char* saveProto = ci->szProto; ci->szProto = "CList"; if (ci->hContact != NULL && !ProcessDatabaseValueDefault(ci, "MyHandle")) { ci->szProto = saveProto; return 0; } ci->szProto = saveProto; } break; case CNF_COUNTRY: case CNF_COCOUNTRY: if (!GetDatabaseString(ci, (ci->dwFlag & 0x7F) == CNF_COUNTRY ? "CountryName" : "CompanyCountryName", &dbv)) return 0; if (!db_get(ci->hContact, ci->szProto, (ci->dwFlag & 0x7F) == CNF_COUNTRY ? "Country" : "CompanyCountry", &dbv)) { if (dbv.type == DBVT_WORD) { int i, countryCount; struct CountryListEntry *countries; CallService(MS_UTILS_GETCOUNTRYLIST, (WPARAM)&countryCount, (LPARAM)&countries); for (i = 0; i < countryCount; i++) { if (countries[i].id != dbv.wVal) continue; if (ci->dwFlag & CNF_UNICODE) { int cbLen = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)countries[i].szName, -1, NULL, 0); WCHAR* buf = (WCHAR*)mir_alloc(sizeof(WCHAR)*(cbLen + 1)); if (buf != NULL) MultiByteToWideChar(CP_ACP, 0, (LPCSTR)countries[i].szName, -1, buf, cbLen); ci->pszVal = (TCHAR*)buf; } else ci->pszVal = (TCHAR*)mir_strdup(countries[i].szName); ci->type = CNFT_ASCIIZ; db_free(&dbv); return 0; } } else return ProcessDatabaseValueDefault(ci, (ci->dwFlag & 0x7F) == CNF_COUNTRY ? "Country" : "CompanyCountry"); db_free(&dbv); } break; case CNF_FIRSTLAST: if (!GetDatabaseString(ci, "FirstName", &dbv)) { DBVARIANT dbv2; if (!GetDatabaseString(ci, "LastName", &dbv2)) { ci->type = CNFT_ASCIIZ; if (ci->dwFlag & CNF_UNICODE) { size_t len = mir_wstrlen(dbv.pwszVal) + mir_wstrlen(dbv2.pwszVal) + 2; WCHAR* buf = (WCHAR*)mir_alloc(sizeof(WCHAR)*len); if (buf != NULL) mir_wstrcat(mir_wstrcat(mir_wstrcpy(buf, dbv.pwszVal), L" "), dbv2.pwszVal); ci->pszVal = (TCHAR*)buf; } else { size_t len = mir_strlen(dbv.pszVal) + mir_strlen(dbv2.pszVal) + 2; char* buf = (char*)mir_alloc(len); if (buf != NULL) mir_strcat(mir_strcat(mir_strcpy(buf, dbv.pszVal), " "), dbv2.pszVal); ci->pszVal = (TCHAR*)buf; } db_free(&dbv); db_free(&dbv2); return 0; } db_free(&dbv); } break; case CNF_UNIQUEID: { if (db_mc_isMeta(ci->hContact)) { TCHAR buf[40]; _itot(ci->hContact, buf, 10); ci->pszVal = mir_tstrdup(buf); ci->type = CNFT_ASCIIZ; return 0; } char *uid = (char*)CallProtoService(ci->szProto, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0); if ((INT_PTR)uid != CALLSERVICE_NOTFOUND && uid) if (!ProcessDatabaseValueDefault(ci, uid)) return 0; } break; case CNF_DISPLAYUID: { if (!ProcessDatabaseValueDefault(ci, "display_uid")) return 0; char *uid = (char*)CallProtoService(ci->szProto, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0); if ((INT_PTR)uid != CALLSERVICE_NOTFOUND && uid) if (!ProcessDatabaseValueDefault(ci, uid)) return 0; } break; case CNF_DISPLAYNC: case CNF_DISPLAY: for (int i = 0; i < NAMEORDERCOUNT; i++) { switch (nameOrder[i]) { case 0: // custom name // make sure we aren't in CNF_DISPLAYNC mode // don't get custom name for NULL contact { char *saveProto = ci->szProto; ci->szProto = "CList"; if (ci->hContact != NULL && (ci->dwFlag & 0x7F) == CNF_DISPLAY && !ProcessDatabaseValueDefault(ci, "MyHandle")) { ci->szProto = saveProto; return 0; } ci->szProto = saveProto; } break; case 1: if (!ProcessDatabaseValueDefault(ci, "Nick")) // nick return 0; break; case 2: if (!ProcessDatabaseValueDefault(ci, "FirstName")) // First Name return 0; break; case 3: if (!ProcessDatabaseValueDefault(ci, "e-mail")) // E-mail return 0; break; case 4: if (!ProcessDatabaseValueDefault(ci, "LastName")) // Last Name return 0; break; case 5: // Unique id { // protocol must define a PFLAG_UNIQUEIDSETTING char *uid = (char*)CallProtoService(ci->szProto, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0); if ((INT_PTR)uid != CALLSERVICE_NOTFOUND && uid) { if (!GetDatabaseString(ci, uid, &dbv)) { if (dbv.type == DBVT_BYTE || dbv.type == DBVT_WORD || dbv.type == DBVT_DWORD) { long value = (dbv.type == DBVT_BYTE) ? dbv.bVal : (dbv.type == DBVT_WORD ? dbv.wVal : dbv.dVal); if (ci->dwFlag & CNF_UNICODE) { WCHAR buf[40]; _ltow(value, buf, 10); ci->pszVal = (TCHAR*)mir_wstrdup(buf); } else { char buf[40]; _ltoa(value, buf, 10); ci->pszVal = (TCHAR*)mir_strdup(buf); } ci->type = CNFT_ASCIIZ; return 0; } if (dbv.type == DBVT_ASCIIZ && !(ci->dwFlag & CNF_UNICODE)) { ci->type = CNFT_ASCIIZ; ci->pszVal = dbv.ptszVal; return 0; } if (dbv.type == DBVT_WCHAR && (ci->dwFlag & CNF_UNICODE)) { ci->type = CNFT_ASCIIZ; ci->pszVal = dbv.ptszVal; return 0; } } } } break; case 6: // first + last name case 7: // last + first name if (!GetDatabaseString(ci, nameOrder[i] == 6 ? "FirstName" : "LastName", &dbv)) { DBVARIANT dbv2; if (!GetDatabaseString(ci, nameOrder[i] == 6 ? "LastName" : "FirstName", &dbv2)) { ci->type = CNFT_ASCIIZ; if (ci->dwFlag & CNF_UNICODE) { size_t len = mir_wstrlen(dbv.pwszVal) + mir_wstrlen(dbv2.pwszVal) + 2; WCHAR* buf = (WCHAR*)mir_alloc(sizeof(WCHAR)*len); if (buf != NULL) mir_wstrcat(mir_wstrcat(mir_wstrcpy(buf, dbv.pwszVal), L" "), dbv2.pwszVal); ci->pszVal = (TCHAR*)buf; } else { size_t len = mir_strlen(dbv.pszVal) + mir_strlen(dbv2.pszVal) + 2; char* buf = (char*)mir_alloc(len); if (buf != NULL) mir_strcat(mir_strcat(mir_strcpy(buf, dbv.pszVal), " "), dbv2.pszVal); ci->pszVal = (TCHAR*)buf; } db_free(&dbv); db_free(&dbv2); return 0; } db_free(&dbv); } break; case 8: if (ci->dwFlag & CNF_UNICODE) ci->pszVal = (TCHAR*)mir_wstrdup(TranslateW(L"'(Unknown contact)'")); else ci->pszVal = (TCHAR*)mir_strdup(Translate("'(Unknown contact)'")); ci->type = CNFT_ASCIIZ; return 0; } } break; case CNF_TIMEZONE: { HANDLE hTz = TimeZone_CreateByContact(ci->hContact, 0, TZF_KNOWNONLY); if (hTz) { LPTIME_ZONE_INFORMATION tzi = TimeZone_GetInfo(hTz); int offset = tzi->Bias + tzi->StandardBias; char str[80]; mir_snprintf(str, offset ? "UTC%+d:%02d" : "UTC", offset / -60, abs(offset % 60)); ci->pszVal = ci->dwFlag & CNF_UNICODE ? (TCHAR*)mir_a2u(str) : (TCHAR*)mir_strdup(str); ci->type = CNFT_ASCIIZ; return 0; } } break; case CNF_MYNOTES: char* saveProto = ci->szProto; ci->szProto = "UserInfo"; if (!ProcessDatabaseValueDefault(ci, "MyNotes")) { ci->szProto = saveProto; return 0; } ci->szProto = saveProto; break; } return 1; }
LRESULT CALLBACK BadConnectPopupProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) { DWORD PluginParam; switch(msg) { case WM_COMMAND: // if clicked and it's new mail popup window if ((HIWORD(wParam)==STN_CLICKED) && (CallService(MS_POPUP_GETPLUGINDATA, (WPARAM)hWnd, (LPARAM)&PluginParam))) { PROCESS_INFORMATION pi; STARTUPINFOW si; memset(&si, 0, sizeof(si)); si.cb=sizeof(si); HACCOUNT ActualAccount = (HACCOUNT)CallService(MS_POPUP_GETPLUGINDATA, (WPARAM)hWnd, 0); #ifdef DEBUG_SYNCHRO DebugLog(SynchroFile,"PopupProc:LEFTCLICK:ActualAccountSO-read wait\n"); #endif if (WAIT_OBJECT_0==WaitToReadFcn(ActualAccount->AccountAccessSO)) { #ifdef DEBUG_SYNCHRO DebugLog(SynchroFile,"PopupProc:LEFTCLICK:ActualAccountSO-read enter\n"); #endif if (ActualAccount->BadConnectN.App != NULL) { WCHAR *Command; if (ActualAccount->BadConnectN.AppParam != NULL) Command = new WCHAR[wcslen(ActualAccount->BadConnectN.App)+wcslen(ActualAccount->BadConnectN.AppParam)+6]; else Command = new WCHAR[wcslen(ActualAccount->BadConnectN.App)+6]; if (Command != NULL) { mir_wstrcpy(Command,L"\""); mir_wstrcat(Command,ActualAccount->BadConnectN.App); mir_wstrcat(Command,L"\" "); if (ActualAccount->BadConnectN.AppParam != NULL) mir_wstrcat(Command,ActualAccount->BadConnectN.AppParam); CreateProcessW(NULL,Command,NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi); delete[] Command; } } #ifdef DEBUG_SYNCHRO DebugLog(SynchroFile,"PopupProc:LEFTCLICK:ActualAccountSO-read done\n"); #endif ReadDoneFcn(ActualAccount->AccountAccessSO); } #ifdef DEBUG_SYNCHRO else DebugLog(SynchroFile,"PopupProc:LEFTCLICK:ActualAccountSO-read enter failed\n"); #endif SendMessage(hWnd,UM_DESTROYPOPUP,0,0); } break; case UM_FREEPLUGINDATA: //Here we'd free our own data, if we had it. return FALSE; case UM_INITPOPUP: //This is the equivalent to WM_INITDIALOG you'd get if you were the maker of dialog popups. break; case WM_CONTEXTMENU: SendMessage(hWnd,UM_DESTROYPOPUP,0,0); break; } return DefWindowProc(hWnd,msg,wParam,lParam); }