/** * obtain the UIN. This is only maintained for open message windows * it also run when the subcontact for a MC changes. */ bool CContactCache::updateUIN() { bool fChanged = false; if(m_Valid) { CONTACTINFO ci = {0}; ci.hContact = getActiveContact(); ci.szProto = const_cast<char *>(getActiveProto()); ci.cbSize = sizeof(ci); ci.dwFlag = CNF_DISPLAYUID | CNF_TCHAR; if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM) & ci)) { switch (ci.type) { case CNFT_ASCIIZ: mir_sntprintf(m_szUIN, safe_sizeof(m_szUIN), _T("%s"), reinterpret_cast<TCHAR *>(ci.pszVal)); mir_free((void *)ci.pszVal); break; case CNFT_DWORD: mir_sntprintf(m_szUIN, safe_sizeof(m_szUIN), _T("%u"), ci.dVal); break; default: m_szUIN[0] = 0; break; } } else m_szUIN[0] = 0; } else m_szUIN[0] = 0; return(fChanged); }
int CompareContacts(WPARAM wParam, LPARAM lParam) { HANDLE a = (HANDLE) wParam,b = (HANDLE) lParam; TCHAR namea[128], *nameb; int statusa, statusb; char *szProto1, *szProto2; int rc; szProto1 = (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) a, 0); szProto2 = (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) b, 0); statusa = DBGetContactSettingWord((HANDLE) a, SAFESTRING(szProto1), "Status", ID_STATUS_OFFLINE); statusb = DBGetContactSettingWord((HANDLE) b, SAFESTRING(szProto2), "Status", ID_STATUS_OFFLINE); if (sortByProto) { /* deal with statuses, online contacts have to go above offline */ if ((statusa == ID_STATUS_OFFLINE) != (statusb == ID_STATUS_OFFLINE)) { return 2 * (statusa == ID_STATUS_OFFLINE) - 1; } /* both are online, now check protocols */ rc = strcmp(SAFESTRING(szProto1), SAFESTRING(szProto2)); /* strcmp() doesn't like NULL so feed in "" as needed */ if (rc != 0 && (szProto1 != NULL && szProto2 != NULL)) return rc; /* protocols are the same, order by display name */ } if (sortByStatus) { int ordera, orderb; ordera = GetStatusModeOrdering(statusa); orderb = GetStatusModeOrdering(statusb); if (ordera != orderb) return ordera - orderb; } else { //one is offline: offline goes below online if ((statusa == ID_STATUS_OFFLINE) != (statusb == ID_STATUS_OFFLINE)) { return 2 * (statusa == ID_STATUS_OFFLINE) - 1; } } nameb = GetContactDisplayNameW(a, 0); _tcsncpy(namea, nameb, safe_sizeof(namea)); namea[safe_sizeof(namea) - 1] = 0; nameb = GetContactDisplayNameW(b, 0); //otherwise just compare names return CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, namea, -1, nameb, -1) - 2; //return _tcsicmp(namea,nameb); }
/** * extract the aero skin images from the DLL and store them in * the private data folder. * runs at every startup * * only overwrites the files when version number does not match or * one of the files is missing. */ void cfg::extractBaseSkin(bool fForceOverwrite) { wchar_t wszBasePath[MAX_PATH], wszTest[MAX_PATH]; bool fChecksPassed = true; HANDLE hFile; mir_sntprintf(wszBasePath, MAX_PATH, L"%s%s", szProfileDir, L"skin\\clng\\base\\"); mir_sntprintf(wszTest, MAX_PATH, L"%s%s", wszBasePath, L"base.cng"); /* * version check, also fails when the file is simply missing */ int uVersion = GetPrivateProfileInt(L"SkinInfo", L"Version", 0, wszTest); if(uVersion < SKIN_REQUIRED_VERSION) fChecksPassed = false; /* * version check passed, verify files are present */ if(fChecksPassed) { for(int i = 0; i < safe_sizeof(my_default_skin); i++) { mir_sntprintf(wszTest, MAX_PATH, L"%s%s", wszBasePath, my_default_skin[i].tszName); if((hFile = CreateFile(wszTest, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) == INVALID_HANDLE_VALUE) { fChecksPassed = false; break; } CloseHandle(hFile); } } // files are not present in skin dir, extract the default skin if(!fChecksPassed) { try { for(int i = 0; i < safe_sizeof(my_default_skin); i++) Utils::extractResource(g_hInst, my_default_skin[i].ulID, L"SKIN_GLYPH", wszBasePath, my_default_skin[i].tszName, true); fBaseSkinValid = true; } catch(CRTException& ex) { ex.display(); fBaseSkinValid = false; } } }
void TSAPI AddContactToFavorites(HANDLE hContact, const TCHAR *szNickname, const char *szProto, TCHAR *szStatus, WORD wStatus, HICON hIcon, BOOL mode, HMENU hMenu) { MENUITEMINFO mii = {0}; TCHAR szMenuEntry[80]; TCHAR szFinalNick[100]; if (szNickname == NULL) { mir_sntprintf(szFinalNick, safe_sizeof(szFinalNick), _T("%s"), (TCHAR *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR)); } else { _tcsncpy(szFinalNick, szNickname, 100); szFinalNick[99] = 0; } if (szProto == NULL) szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); if (szProto) { if (wStatus == 0) wStatus = DBGetContactSettingWord((HANDLE)hContact, szProto, "Status", ID_STATUS_OFFLINE); if (szStatus == NULL) szStatus = (TCHAR *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, wStatus, GSMDF_TCHAR); } else return; if (hIcon == 0) hIcon = LoadSkinnedProtoIcon(szProto, wStatus); PROTOACCOUNT *acc = (PROTOACCOUNT *)CallService(MS_PROTO_GETACCOUNT, (WPARAM)0, (LPARAM)szProto); if(acc && acc->tszAccountName) { mii.cbSize = sizeof(mii); mir_sntprintf(szMenuEntry, safe_sizeof(szMenuEntry), _T("%s: %s (%s)"), acc->tszAccountName, szFinalNick, szStatus); if (mode) { if (hMenu == PluginConfig.g_hMenuRecent) { if (CheckMenuItem(hMenu, (UINT_PTR)hContact, MF_BYCOMMAND | MF_UNCHECKED) == 0) { DeleteMenu(hMenu, (UINT_PTR)hContact, MF_BYCOMMAND); goto addnew; // move to the end of the menu... } if (GetMenuItemCount(PluginConfig.g_hMenuRecent) > nen_options.wMaxRecent) { // throw out oldest entry in the recent menu... UINT uid = GetMenuItemID(hMenu, 0); if (uid) { DeleteMenu(hMenu, (UINT_PTR)0, MF_BYPOSITION); M->WriteDword((HANDLE)uid, SRMSGMOD_T, "isRecent", 0); } } addnew: M->WriteDword(hContact, SRMSGMOD_T, "isRecent", time(NULL)); AppendMenu(hMenu, MF_BYCOMMAND, (UINT_PTR)hContact, szMenuEntry); } else if (hMenu == PluginConfig.g_hMenuFavorites) { // insert the item sorted... MENUITEMINFO mii2 = {0}; TCHAR szBuffer[142]; int i, c = GetMenuItemCount(PluginConfig.g_hMenuFavorites); mii2.fMask = MIIM_STRING; mii2.cbSize = sizeof(mii2); if (c == 0) InsertMenu(PluginConfig.g_hMenuFavorites, 0, MF_BYPOSITION, (UINT_PTR)hContact, szMenuEntry); else { for (i = 0; i <= c; i++) { mii2.cch = 0; mii2.dwTypeData = NULL; GetMenuItemInfo(PluginConfig.g_hMenuFavorites, i, TRUE, &mii2); mii2.cch++; mii2.dwTypeData = szBuffer; GetMenuItemInfo(PluginConfig.g_hMenuFavorites, i, TRUE, &mii2); if (_tcsncmp((TCHAR *)mii2.dwTypeData, szMenuEntry, 140) > 0 || i == c) { InsertMenu(PluginConfig.g_hMenuFavorites, i, MF_BYPOSITION, (UINT_PTR)hContact, szMenuEntry); break; } } } } } mii.fMask = MIIM_BITMAP | MIIM_DATA; if (!mode) { mii.fMask |= MIIM_STRING; mii.dwTypeData = (LPTSTR)szMenuEntry; mii.cch = lstrlen(szMenuEntry) + 1; } mii.hbmpItem = HBMMENU_CALLBACK; mii.dwItemData = (ULONG_PTR)hIcon; SetMenuItemInfo(hMenu, (UINT)hContact, FALSE, &mii); } }
LONG_PTR CALLBACK HotkeyHandlerDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static POINT ptLast; static int iMousedown; if (msg == WM_TASKBARCREATED) { CreateSystrayIcon(FALSE); if (nen_options.bTraySupport) CreateSystrayIcon(TRUE); return 0; } switch (msg) { case WM_CREATE: int i; for(i = 0; i < safe_sizeof(_hotkeydescs); i++) { _hotkeydescs[i].cbSize = sizeof(HOTKEYDESC); CallService(MS_HOTKEY_REGISTER, 0, (LPARAM)&_hotkeydescs[i]); } WM_TASKBARCREATED = RegisterWindowMessageA("TaskbarCreated"); ShowWindow(hwndDlg, SW_HIDE); hSvcHotkeyProcessor = CreateServiceFunction(MS_TABMSG_HOTKEYPROCESS, HotkeyProcessor); SetTimer(hwndDlg, TIMERID_SENDLATER, TIMEOUT_SENDLATER, NULL); break; case WM_HOTKEY: { CLISTEVENT *cli = 0; cli = (CLISTEVENT *)CallService(MS_CLIST_GETEVENT, (WPARAM)INVALID_HANDLE_VALUE, (LPARAM)0); if (cli != NULL) { if (strncmp(cli->pszService, "SRMsg/TypingMessage", strlen(cli->pszService))) { CallService(cli->pszService, 0, (LPARAM)cli); break; } } if (wParam == 0xc001) SendMessage(hwndDlg, DM_TRAYICONNOTIFY, 101, WM_MBUTTONDOWN); break; } /* * handle the popup menus (session list, favorites, recents... * just draw some icons, nothing more :) */ case WM_MEASUREITEM: { LPMEASUREITEMSTRUCT lpmi = (LPMEASUREITEMSTRUCT) lParam; lpmi->itemHeight = 0; lpmi->itemWidth = 6; return TRUE; } case WM_DRAWITEM: { LPDRAWITEMSTRUCT dis = (LPDRAWITEMSTRUCT) lParam; struct TWindowData *dat = 0; if (dis->CtlType == ODT_MENU && (dis->hwndItem == (HWND)PluginConfig.g_hMenuFavorites || dis->hwndItem == (HWND)PluginConfig.g_hMenuRecent)) { HICON hIcon = (HICON)dis->itemData; DrawMenuItem(dis, hIcon, 0); return TRUE; } else if (dis->CtlType == ODT_MENU) { HWND hWnd = M->FindWindow((HANDLE)dis->itemID); DWORD idle = 0; if (hWnd == NULL) { SESSION_INFO *si = SM_FindSessionByHCONTACT((HANDLE)dis->itemID); hWnd = si ? si->hWnd : 0; } if (hWnd) dat = (struct TWindowData *)GetWindowLongPtr(hWnd, GWLP_USERDATA); if (dis->itemData >= 0) { HICON hIcon; BOOL fNeedFree = FALSE; if (dis->itemData > 0) hIcon = dis->itemData & 0x10000000 ? hIcons[ICON_HIGHLIGHT] : PluginConfig.g_IconMsgEvent; else if (dat != NULL) { hIcon = MY_GetContactIcon(dat); idle = dat->idle; } else hIcon = PluginConfig.g_iconContainer; DrawMenuItem(dis, hIcon, idle); if (fNeedFree) DestroyIcon(hIcon); return TRUE; } } } break; case DM_TRAYICONNOTIFY: { int iSelection; if (wParam == 100 || wParam == 101) { switch (lParam) { case WM_LBUTTONUP: { POINT pt; GetCursorPos(&pt); if (wParam == 100) SetForegroundWindow(hwndDlg); if (GetMenuItemCount(PluginConfig.g_hMenuTrayUnread) > 0) { iSelection = TrackPopupMenu(PluginConfig.g_hMenuTrayUnread, TPM_RETURNCMD, pt.x, pt.y, 0, hwndDlg, NULL); HandleMenuEntryFromhContact(iSelection); } else TrackPopupMenu(GetSubMenu(PluginConfig.g_hMenuContext, 8), TPM_RETURNCMD, pt.x, pt.y, 0, hwndDlg, NULL); if (wParam == 100) PostMessage(hwndDlg, WM_NULL, 0, 0); break; } case WM_MBUTTONDOWN: { MENUITEMINFOA mii = {0}; int i, iCount = GetMenuItemCount(PluginConfig.g_hMenuTrayUnread); if (wParam == 100) SetForegroundWindow(hwndDlg); if (iCount > 0) { UINT uid = 0; mii.fMask = MIIM_DATA; mii.cbSize = sizeof(mii); i = iCount - 1; do { GetMenuItemInfoA(PluginConfig.g_hMenuTrayUnread, i, TRUE, &mii); if (mii.dwItemData > 0) { uid = GetMenuItemID(PluginConfig.g_hMenuTrayUnread, i); HandleMenuEntryFromhContact(uid); break; } } while (--i >= 0); if (uid == 0 && pLastActiveContainer != NULL) { // no session found, restore last active container if (IsIconic(pLastActiveContainer->hwnd) || !IsWindowVisible(pLastActiveContainer->hwnd)) { SendMessage(pLastActiveContainer->hwnd, WM_SYSCOMMAND, SC_RESTORE, 0); SetForegroundWindow(pLastActiveContainer->hwnd); } else { if(PluginConfig.m_HideOnClose) ShowWindow(pLastActiveContainer->hwnd, SW_HIDE); else SendMessage(pLastActiveContainer->hwnd, WM_SYSCOMMAND, SC_MINIMIZE, 0); } } } if (wParam == 100) PostMessage(hwndDlg, WM_NULL, 0, 0); break; } case WM_RBUTTONUP: { HMENU submenu = PluginConfig.g_hMenuTrayContext; POINT pt; if (wParam == 100) SetForegroundWindow(hwndDlg); GetCursorPos(&pt); CheckMenuItem(submenu, ID_TRAYCONTEXT_DISABLEALLPOPUPS, MF_BYCOMMAND | (nen_options.iDisable ? MF_CHECKED : MF_UNCHECKED)); CheckMenuItem(submenu, ID_TRAYCONTEXT_DON40223, MF_BYCOMMAND | (nen_options.iNoSounds ? MF_CHECKED : MF_UNCHECKED)); CheckMenuItem(submenu, ID_TRAYCONTEXT_DON, MF_BYCOMMAND | (nen_options.iNoAutoPopup ? MF_CHECKED : MF_UNCHECKED)); EnableMenuItem(submenu, ID_TRAYCONTEXT_HIDEALLMESSAGECONTAINERS, MF_BYCOMMAND | (nen_options.bTraySupport) ? MF_ENABLED : MF_GRAYED); CheckMenuItem(submenu, ID_TRAYCONTEXT_SHOWTHETRAYICON, MF_BYCOMMAND | (nen_options.bTraySupport ? MF_CHECKED : MF_UNCHECKED)); iSelection = TrackPopupMenu(submenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwndDlg, NULL); if (iSelection) { MENUITEMINFO mii = {0}; mii.cbSize = sizeof(mii); mii.fMask = MIIM_DATA | MIIM_ID; GetMenuItemInfo(submenu, (UINT_PTR)iSelection, FALSE, &mii); if (mii.dwItemData != 0) { // this must be an itm of the fav or recent menu HandleMenuEntryFromhContact(iSelection); } else { switch (iSelection) { case ID_TRAYCONTEXT_SHOWTHETRAYICON: nen_options.bTraySupport = !nen_options.bTraySupport; CreateSystrayIcon(nen_options.bTraySupport ? TRUE : FALSE); break; case ID_TRAYCONTEXT_DISABLEALLPOPUPS: nen_options.iDisable ^= 1; break; case ID_TRAYCONTEXT_DON40223: nen_options.iNoSounds ^= 1; break; case ID_TRAYCONTEXT_DON: nen_options.iNoAutoPopup ^= 1; break; case ID_TRAYCONTEXT_HIDEALLMESSAGECONTAINERS: { struct TContainerData *pContainer = pFirstContainer; while (pContainer) { ShowWindow(pContainer->hwnd, SW_HIDE); pContainer = pContainer->pNextContainer; } break; } case ID_TRAYCONTEXT_RESTOREALLMESSAGECONTAINERS: { struct TContainerData *pContainer = pFirstContainer; while (pContainer) { ShowWindow(pContainer->hwnd, SW_SHOW); pContainer = pContainer->pNextContainer; } break; } case ID_TRAYCONTEXT_BE: { struct TContainerData *pContainer = pFirstContainer; nen_options.iDisable = 1; nen_options.iNoSounds = 1; nen_options.iNoAutoPopup = 1; while (pContainer) { SendMessage(pContainer->hwnd, WM_SYSCOMMAND, SC_MINIMIZE, 1); pContainer = pContainer->pNextContainer; } break; } } } } if (wParam == 100) PostMessage(hwndDlg, WM_NULL, 0, 0); break; } default: break; } } break; } /* * handle an event from the popup module (mostly window activation). Since popups may run in different threads, the message * is posted to our invisible hotkey handler which does always run within the main thread. * wParam is the hContact * lParam the event handle */ case DM_HANDLECLISTEVENT: { CLISTEVENT *cle = (CLISTEVENT *)CallService(MS_CLIST_GETEVENT, wParam, 0); /* * if lParam == NULL, don't consider clist events, just open the message tab */ if(lParam == 0) { HandleMenuEntryFromhContact((int)wParam); break; } /* * first try, if the clist returned an event... */ if (cle) { if (ServiceExists(cle->pszService)) { CallService(cle->pszService, (WPARAM)NULL, (LPARAM)cle); CallService(MS_CLIST_REMOVEEVENT, (WPARAM)cle->hContact, (LPARAM)cle->hDbEvent); } } else { // still, we got that message posted.. the event may be waiting in tabSRMMs tray... HandleMenuEntryFromhContact((int)wParam); } break; } case DM_DOCREATETAB: { HWND hWnd = M->FindWindow((HANDLE)lParam); if (hWnd && IsWindow(hWnd)) { struct TContainerData *pContainer = 0; SendMessage(hWnd, DM_QUERYCONTAINER, 0, (LPARAM)&pContainer); if (pContainer) { int iTabs = TabCtrl_GetItemCount(GetDlgItem(pContainer->hwnd, IDC_MSGTABS)); if (iTabs == 1) SendMessage(pContainer->hwnd, WM_CLOSE, 0, 1); else SendMessage(hWnd, WM_CLOSE, 0, 1); CreateNewTabForContact((struct TContainerData *)wParam, (HANDLE)lParam, 0, NULL, TRUE, TRUE, FALSE, 0); } } break; } case DM_DOCREATETAB_CHAT: { SESSION_INFO *si = SM_FindSessionByHWND((HWND)lParam); if (si && IsWindow(si->hWnd)) { struct TContainerData *pContainer = 0; SendMessage(si->hWnd, DM_QUERYCONTAINER, 0, (LPARAM)&pContainer); if (pContainer) { int iTabs = TabCtrl_GetItemCount(GetDlgItem(pContainer->hwnd, 1159)); if (iTabs == 1) SendMessage(pContainer->hwnd, WM_CLOSE, 0, 1); else SendMessage(si->hWnd, WM_CLOSE, 0, 1); si->hWnd = CreateNewRoom((struct TContainerData *)wParam, si, TRUE, 0, 0); } } break; } case DM_SENDMESSAGECOMMANDW: SendMessageCommand_W(wParam, lParam); if (lParam) free((void *)lParam); return(0); case DM_SENDMESSAGECOMMAND: SendMessageCommand(wParam, lParam); if (lParam) free((void *)lParam); return(0); /* * sent from the popup to "dismiss" the event. we should do this in the main thread */ case DM_REMOVECLISTEVENT: CallService(MS_CLIST_REMOVEEVENT, wParam, lParam); CallService(MS_DB_EVENT_MARKREAD, wParam, lParam); return(0); case DM_SETLOCALE: { HKL hkl = (HKL)lParam; HANDLE hContact = (HANDLE)wParam; HWND hWnd = M->FindWindow(hContact); if(hWnd) { TWindowData *dat = (TWindowData *)GetWindowLongPtr(hWnd, GWLP_USERDATA); if(dat) { DBVARIANT dbv; if(hkl) { dat->hkl = hkl; PostMessage(dat->hwnd, DM_SETLOCALE, 0, 0); } if(0 == M->GetTString(hContact, SRMSGMOD_T, "locale", &dbv)) { GetLocaleID(dat, dbv.ptszVal); DBFreeVariant(&dbv); UpdateReadChars(dat); } } } return(0); } /* * react to changes in the desktop composition state * (enable/disable DWM, change to a non-aero visual style * or classic Windows theme */ case WM_DWMCOMPOSITIONCHANGED: { bool fNewAero = M->getAeroState(); // refresh dwm state SendMessage(hwndDlg, WM_THEMECHANGED, 0, 0); TContainerData *pContainer = pFirstContainer; while (pContainer) { if(fNewAero) SetAeroMargins(pContainer); else { MARGINS m = {0}; if(M->m_pfnDwmExtendFrameIntoClientArea) M->m_pfnDwmExtendFrameIntoClientArea(pContainer->hwnd, &m); } if(pContainer->SideBar->isActive()) RedrawWindow(GetDlgItem(pContainer->hwnd, 5000), NULL, NULL, RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW); // the container for the sidebar buttons RedrawWindow(pContainer->hwnd, NULL, NULL, RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW|RDW_ALLCHILDREN); pContainer = pContainer->pNextContainer; } M->BroadcastMessage(WM_DWMCOMPOSITIONCHANGED, 0, 0); break; } /* * this message is fired when the user changes desktop color * settings (Desktop->personalize) * the handler reconfigures the aero-related skin images for * tabs and buttons to match the new desktop color theme. */ case WM_DWMCOLORIZATIONCOLORCHANGED: { M->getAeroState(); Skin->setupAeroSkins(); CSkin::initAeroEffect(); break; } /* * user has changed the visual style or switched to/from * classic Windows theme */ case WM_THEMECHANGED: { struct TContainerData *pContainer = pFirstContainer; M->getAeroState(); Skin->setupTabCloseBitmap(); CSkin::initAeroEffect(); PluginConfig.m_ncm.cbSize = sizeof(NONCLIENTMETRICS); SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &PluginConfig.m_ncm, 0); FreeTabConfig(); ReloadTabConfig(); while (pContainer) { SendMessage(GetDlgItem(pContainer->hwnd, IDC_MSGTABS), EM_THEMECHANGED, 0, 0); BroadCastContainer(pContainer, EM_THEMECHANGED, 0, 0); pContainer = pContainer->pNextContainer; } break; } case DM_SPLITSENDACK: { ACKDATA ack = {0}; struct SendJob *job = sendQueue->getJobByIndex((int)wParam); ack.hContact = job->hOwner; ack.hProcess = job->hSendId; ack.type = ACKTYPE_MESSAGE; ack.result = ACKRESULT_SUCCESS; if (job->hOwner && job->iAcksNeeded && job->hOwner && job->iStatus == SendQueue::SQ_INPROGRESS) { if (IsWindow(job->hwndOwner)) ::SendMessage(job->hwndOwner, HM_EVENTSENT, (WPARAM)MAKELONG(wParam, 0), (LPARAM)&ack); else sendQueue->ackMessage(0, (WPARAM)MAKELONG(wParam, 0), (LPARAM)&ack); } return 0; } case DM_LOGSTATUSCHANGE: CGlobals::logStatusChange(wParam, reinterpret_cast<CContactCache *>(lParam)); return(0); case DM_MUCFLASHWORKER: { FLASH_PARAMS *p = reinterpret_cast<FLASH_PARAMS*>(lParam); if(1 == wParam) { CallService(MS_CLIST_CONTACTDOUBLECLICKED, (WPARAM)p->hContact, 1); p->bActiveTab = TRUE; p->bInactive = FALSE; p->bMustAutoswitch = p->bMustFlash = FALSE; } if(2 == wParam) { p->bActiveTab = TRUE; p->bInactive = FALSE; p->bMustAutoswitch = p->bMustFlash = FALSE; SendMessage(p->hWnd, DM_ACTIVATEME, 0, 0); } DoFlashAndSoundWorker(p); return(0); } case WM_POWERBROADCAST: case WM_DISPLAYCHANGE: { struct TContainerData *pContainer = pFirstContainer; while (pContainer) { if (CSkin::m_skinEnabled) { // invalidate cached background DCs for skinned containers pContainer->oldDCSize.cx = pContainer->oldDCSize.cy = 0; SelectObject(pContainer->cachedDC, pContainer->oldHBM); DeleteObject(pContainer->cachedHBM); DeleteDC(pContainer->cachedDC); pContainer->cachedDC = 0; RedrawWindow(pContainer->hwnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_FRAME); } pContainer = pContainer->pNextContainer; } break; } case WM_ACTIVATE: if (LOWORD(wParam) != WA_ACTIVE) SetWindowPos(hwndDlg, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE); return 0; case WM_CLOSE: return 0; case WM_TIMER: if(wParam == TIMERID_SENDLATER) { /* * send heartbeat to each open container (to manage autoclose * feature) */ TContainerData *pContainer = pFirstContainer; /* * send heartbeat to each container, they use this to update * dynamic content (i.e. local time in the info panel). */ while(pContainer) { SendMessage(pContainer->hwnd, WM_TIMER, TIMERID_HEARTBEAT, 0); pContainer = pContainer->pNextContainer; } /* * process send later contacts and jobs, if enough time has elapsed */ if(sendLater->isAvail() && !sendLater->isInteractive() && (time(0) - sendLater->lastProcessed()) > CSendLater::SENDLATER_PROCESS_INTERVAL) { sendLater->setLastProcessed(time(0)); /* * check the list of contacts that may have new send later jobs * (added on user's request) */ sendLater->processContacts(); /* * start processing the job list */ if(!sendLater->isJobListEmpty()) { KillTimer(hwndDlg, wParam); sendLater->startJobListProcess(); SetTimer(hwndDlg, TIMERID_SENDLATER_TICK, TIMEOUT_SENDLATER_TICK, 0); } } } /* * process one entry per tick (default: 200ms) * TODO better timings, possibly slow down when many jobs are in the * queue. */ else if(wParam == TIMERID_SENDLATER_TICK) { if(!sendLater->haveJobs()) { KillTimer(hwndDlg, wParam); SetTimer(hwndDlg, TIMERID_SENDLATER, TIMEOUT_SENDLATER, 0); sendLater->qMgrUpdate(true); } else sendLater->processCurrentJob(); } break; case WM_DESTROY: { KillTimer(hwndDlg, TIMERID_SENDLATER_TICK); KillTimer(hwndDlg, TIMERID_SENDLATER); DestroyServiceFunction(hSvcHotkeyProcessor); break; } } return(DefWindowProc(hwndDlg, msg, wParam, lParam)); }
/** * This just adds the message to the database for later delivery and * adds the contact to the list of contacts that have queued messages * * @param iJobIndex int: index of the send job * dat: Message window data * fAddHeader: add the "message was sent delayed" header (default = true) * hContact : contact to which the job should be added (default = hOwner of the send job) * * @return the index on success, -1 on failure */ int SendQueue::doSendLater(int iJobIndex, TWindowData *dat, HANDLE hContact, bool fIsSendLater) { bool fAvail = sendLater->isAvail(); const TCHAR *szNote = 0; if(fIsSendLater && dat) { if(fAvail) szNote = CTranslator::get(CTranslator::GEN_SQ_QUEUED_MESSAGE); else szNote = CTranslator::get(CTranslator::GEN_SQ_QUEUING_NOT_AVAIL); char *utfText = M->utf8_encodeT(szNote); DBEVENTINFO dbei; dbei.cbSize = sizeof(dbei); dbei.eventType = EVENTTYPE_MESSAGE; dbei.flags = DBEF_SENT | DBEF_UTF; dbei.szModule = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) dat->hContact, 0); dbei.timestamp = time(NULL); dbei.cbBlob = lstrlenA(utfText) + 1; dbei.pBlob = (PBYTE) utfText; StreamInEvents(dat->hwnd, 0, 1, 1, &dbei); if (dat->hDbEventFirst == NULL) SendMessage(dat->hwnd, DM_REMAKELOG, 0, 0); dat->cache->saveHistory(0, 0); EnableSendButton(dat, FALSE); if (dat->pContainer->hwndActive == dat->hwnd) UpdateReadChars(dat); SendDlgItemMessage(dat->hwnd, IDC_SAVE, BM_SETIMAGE, IMAGE_ICON, (LPARAM) PluginConfig.g_buttonBarIcons[ICON_BUTTON_CANCEL]); SendDlgItemMessage(dat->hwnd, IDC_SAVE, BUTTONADDTOOLTIP, (WPARAM)pszIDCSAVE_close, 0); dat->dwFlags &= ~MWF_SAVEBTN_SAV; mir_free(utfText); if(!fAvail) return(0); } if(iJobIndex >= 0 && iJobIndex < NR_SENDJOBS) { SendJob* job = &m_jobs[iJobIndex]; char szKeyName[20]; TCHAR tszTimestamp[30], tszHeader[150]; time_t now = time(0); if(fIsSendLater) { TCHAR *formatTime = _T("%Y.%m.%d - %H:%M"); _tcsftime(tszTimestamp, 30, formatTime, _localtime32((__time32_t *)&now)); tszTimestamp[29] = 0; mir_snprintf(szKeyName, 20, "S%d", now); mir_sntprintf(tszHeader, safe_sizeof(tszHeader), CTranslator::get(CTranslator::GEN_SQ_SENDLATER_HEADER), tszTimestamp); } else mir_sntprintf(tszHeader, safe_sizeof(tszHeader), _T("M%d|"), time(0)); if(job->dwFlags & PREF_UTF || !(job->dwFlags & PREF_UNICODE)) { char *utf_header = M->utf8_encodeT(tszHeader); UINT required = lstrlenA(utf_header) + lstrlenA(job->sendBuffer) + 10; char *tszMsg = reinterpret_cast<char *>(mir_alloc(required)); if(fIsSendLater) { mir_snprintf(tszMsg, required, "%s%s", job->sendBuffer, utf_header); DBWriteContactSettingString(hContact ? hContact : job->hOwner, "SendLater", szKeyName, tszMsg); } else { mir_snprintf(tszMsg, required, "%s%s", utf_header, job->sendBuffer); sendLater->addJob(tszMsg, (LPARAM)hContact); } mir_free(utf_header); mir_free(tszMsg); } else if(job->dwFlags & PREF_UNICODE) { int iLen = lstrlenA(job->sendBuffer); wchar_t *wszMsg = (wchar_t *)&job->sendBuffer[iLen + 1]; UINT required = sizeof(TCHAR) * (lstrlen(tszHeader) + lstrlenW(wszMsg) + 10); TCHAR *tszMsg = reinterpret_cast<TCHAR *>(mir_alloc(required)); if(fIsSendLater) mir_sntprintf(tszMsg, required, _T("%s%s"), wszMsg, tszHeader); else mir_sntprintf(tszMsg, required, _T("%s%s"), tszHeader, wszMsg); char *utf = M->utf8_encodeT(tszMsg); if(fIsSendLater) DBWriteContactSettingString(hContact ? hContact : job->hOwner, "SendLater", szKeyName, utf); else sendLater->addJob(utf, (LPARAM)hContact); mir_free(utf); mir_free(tszMsg); } if(fIsSendLater) { int iCount = M->GetDword(hContact ? hContact : job->hOwner, "SendLater", "count", 0); iCount++; M->WriteDword(hContact ? hContact : job->hOwner, "SendLater", "count", iCount); sendLater->addContact(hContact ? hContact : job->hOwner); } return(iJobIndex); } return(-1); }
int SendQueue::ackMessage(TWindowData *dat, WPARAM wParam, LPARAM lParam) { ACKDATA *ack = (ACKDATA *) lParam; DBEVENTINFO dbei = { 0}; HANDLE hNewEvent; int iFound = SendQueue::NR_SENDJOBS, iNextFailed; TContainerData *m_pContainer = 0; if (dat) m_pContainer = dat->pContainer; iFound = (int)(LOWORD(wParam)); //i = (int)(HIWORD(wParam)); if (m_jobs[iFound].iStatus == SQ_ERROR) { // received ack for a job which is already in error state... if (dat) { // window still open if (dat->iCurrentQueueError == iFound) { dat->iCurrentQueueError = -1; showErrorControls(dat, FALSE); } } /* * we must discard this job, because there is no message window open to handle the * error properly. But we display a tray notification to inform the user about the problem. */ else goto inform_and_discard; } // failed acks are only handled when the window is still open. with no window open, they will be *silently* discarded if (ack->result == ACKRESULT_FAILED) { if (dat) { /* * "hard" errors are handled differently in multisend. There is no option to retry - once failed, they * are discarded and the user is notified with a small log message. */ if (!nen_options.iNoSounds && !(m_pContainer->dwFlags & CNT_NOSOUND)) SkinPlaySound("SendError"); TCHAR *szAckMsg = mir_a2t((char *)ack->lParam); mir_sntprintf(m_jobs[iFound].szErrorMsg, safe_sizeof(m_jobs[iFound].szErrorMsg), CTranslator::get(CTranslator::GEN_MSG_DELIVERYFAILURE), szAckMsg); m_jobs[iFound].iStatus = SQ_ERROR; mir_free(szAckMsg); KillTimer(dat->hwnd, TIMERID_MSGSEND + iFound); if (!(dat->dwFlags & MWF_ERRORSTATE)) handleError(dat, iFound); return 0; } else { inform_and_discard: _DebugPopup(m_jobs[iFound].hOwner, CTranslator::get(CTranslator::GEN_SQ_DELIVERYFAILEDLATE)); clearJob(iFound); return 0; } } dbei.cbSize = sizeof(dbei); dbei.eventType = EVENTTYPE_MESSAGE; dbei.flags = DBEF_SENT; dbei.szModule = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) m_jobs[iFound].hOwner, 0); dbei.timestamp = time(NULL); dbei.cbBlob = lstrlenA(m_jobs[iFound].sendBuffer) + 1; if (dat) dat->cache->updateStats(TSessionStats::BYTES_SENT, dbei.cbBlob - 1); else { CContactCache *c = CContactCache::getContactCache(m_jobs[iFound].hOwner); if(c) c->updateStats(TSessionStats::BYTES_SENT, dbei.cbBlob - 1); } if (m_jobs[iFound].dwFlags & PREF_UNICODE) dbei.cbBlob *= sizeof(TCHAR) + 1; if (m_jobs[iFound].dwFlags & PREF_RTL) dbei.flags |= DBEF_RTL; if (m_jobs[iFound].dwFlags & PREF_UTF) dbei.flags |= DBEF_UTF; dbei.pBlob = (PBYTE) m_jobs[iFound].sendBuffer; hNewEvent = (HANDLE) CallService(MS_DB_EVENT_ADD, (WPARAM) m_jobs[iFound].hOwner, (LPARAM) & dbei); if (m_pContainer) { if (!nen_options.iNoSounds && !(m_pContainer->dwFlags & CNT_NOSOUND)) SkinPlaySound("SendMsg"); } if (dat && (m_jobs[iFound].hOwner == dat->hContact)) { if (dat->hDbEventFirst == NULL) { dat->hDbEventFirst = hNewEvent; SendMessage(dat->hwnd, DM_REMAKELOG, 0, 0); } } m_jobs[iFound].hSendId = NULL; m_jobs[iFound].iAcksNeeded--; if (m_jobs[iFound].iAcksNeeded == 0) { // everything sent //if (m_jobs[iFound].hOwner != 0 && dat) // EnableSending(dat, TRUE); clearJob(iFound); if (dat) { KillTimer(dat->hwnd, TIMERID_MSGSEND + iFound); dat->iOpenJobs--; } m_currentIndex--; } if (dat) { checkQueue(dat); if ((iNextFailed = findNextFailed(dat)) >= 0 && !(dat->dwFlags & MWF_ERRORSTATE)) handleError(dat, iNextFailed); //MAD: close on send mode else { if (M->GetByte("AutoClose", 0)) { if(M->GetByte("adv_AutoClose_2", 0)) SendMessage(dat->hwnd, WM_CLOSE, 0, 1); else SendMessage(dat->pContainer->hwnd, WM_CLOSE, 0, 0); } } //MAD_ } return 0; }
/** * dialog procedure for the user preferences dialog. Handles the top * level window (a tab control with 2 subpages) * * @params: like any Win32 window procedure * * @return LRESULT (ignored for dialog procs, use * DWLP_MSGRESULT) */ INT_PTR CALLBACK DlgProcUserPrefsFrame(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { HANDLE hContact = (HANDLE)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch(msg) { case WM_INITDIALOG: { TCITEM tci = {0}; RECT rcClient; TCHAR szBuffer[180]; hContact = (HANDLE)lParam; SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)hContact); WindowList_Add(PluginConfig.hUserPrefsWindowList, hwndDlg, hContact); TranslateDialogDefault(hwndDlg); GetClientRect(hwndDlg, &rcClient); mir_sntprintf(szBuffer, safe_sizeof(szBuffer), CTranslator::getOpt(CTranslator::OPT_UPREFS_TITLE), (TCHAR *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR)); SetWindowText(hwndDlg, szBuffer); tci.cchTextMax = 100; tci.mask = TCIF_PARAM | TCIF_TEXT; tci.lParam = (LPARAM)CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_USERPREFS), hwndDlg, DlgProcUserPrefs, (LPARAM)hContact); tci.pszText = const_cast<TCHAR *>(CTranslator::getOpt(CTranslator::OPT_UPREFS_GENERIC)); TabCtrl_InsertItem(GetDlgItem(hwndDlg, IDC_OPTIONSTAB), 0, &tci); MoveWindow((HWND)tci.lParam, 6, DPISCALEY_S(32), rcClient.right - 12, rcClient.bottom - DPISCALEY_S(80), 1); ShowWindow((HWND)tci.lParam, SW_SHOW); if (CMimAPI::m_pfnEnableThemeDialogTexture) CMimAPI::m_pfnEnableThemeDialogTexture((HWND)tci.lParam, ETDT_ENABLETAB); tci.lParam = (LPARAM)CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_USERPREFS1), hwndDlg, DlgProcUserPrefsLogOptions, (LPARAM)hContact); tci.pszText = const_cast<TCHAR *>(CTranslator::getOpt(CTranslator::OPT_UPREFS_MSGLOG)); TabCtrl_InsertItem(GetDlgItem(hwndDlg, IDC_OPTIONSTAB), 1, &tci); MoveWindow((HWND)tci.lParam, 6, DPISCALEY_S(32), rcClient.right - 12, rcClient.bottom - DPISCALEY_S(80), 1); ShowWindow((HWND)tci.lParam, SW_HIDE); if (CMimAPI::m_pfnEnableThemeDialogTexture) CMimAPI::m_pfnEnableThemeDialogTexture((HWND)tci.lParam, ETDT_ENABLETAB); TabCtrl_SetCurSel(GetDlgItem(hwndDlg, IDC_OPTIONSTAB), 0); ShowWindow(hwndDlg, SW_SHOW); return TRUE; } case WM_NOTIFY: switch (((LPNMHDR)lParam)->idFrom) { case IDC_OPTIONSTAB: switch (((LPNMHDR)lParam)->code) { case TCN_SELCHANGING: { TCITEM tci; tci.mask = TCIF_PARAM; TabCtrl_GetItem(GetDlgItem(hwndDlg, IDC_OPTIONSTAB), TabCtrl_GetCurSel(GetDlgItem(hwndDlg, IDC_OPTIONSTAB)), &tci); ShowWindow((HWND)tci.lParam, SW_HIDE); } break; case TCN_SELCHANGE: { TCITEM tci; tci.mask = TCIF_PARAM; TabCtrl_GetItem(GetDlgItem(hwndDlg, IDC_OPTIONSTAB), TabCtrl_GetCurSel(GetDlgItem(hwndDlg, IDC_OPTIONSTAB)), &tci); ShowWindow((HWND)tci.lParam, SW_SHOW); } break; } break; } break; case WM_COMMAND: { switch(LOWORD(wParam)) { case IDOK: { TCITEM tci; int i, count; DWORD dwActionToTake = 0; // child pages request which action to take HWND hwnd = M->FindWindow(hContact); tci.mask = TCIF_PARAM; count = TabCtrl_GetItemCount(GetDlgItem(hwndDlg, IDC_OPTIONSTAB)); for (i = 0;i < count;i++) { TabCtrl_GetItem(GetDlgItem(hwndDlg, IDC_OPTIONSTAB), i, &tci); SendMessage((HWND)tci.lParam, WM_COMMAND, WM_USER + 100, (LPARAM)&dwActionToTake); } if(hwnd) { struct TWindowData *dat = (struct TWindowData *)GetWindowLongPtr(hwnd, GWLP_USERDATA); if(dat) { DWORD dwOldFlags = (dat->dwFlags & MWF_LOG_ALL); SetDialogToType(hwnd); #if defined(__FEAT_DEPRECATED_DYNAMICSWITCHLOGVIEWER) if(dwActionToTake & UPREF_ACTION_SWITCHLOGVIEWER) { unsigned int mode = GetIEViewMode(hwndDlg, dat->hContact); SwitchMessageLog(dat, mode); } #endif LoadLocalFlags(hwnd, dat); if((dat->dwFlags & MWF_LOG_ALL) != dwOldFlags) { BOOL fShouldHide = TRUE; if(IsIconic(dat->pContainer->hwnd)) fShouldHide = FALSE; else ShowWindow(dat->pContainer->hwnd, SW_HIDE); SendMessage(hwnd, DM_OPTIONSAPPLIED, 0, 0); SendMessage(hwnd, DM_DEFERREDREMAKELOG, (WPARAM)hwnd, 0); if(fShouldHide) ShowWindow(dat->pContainer->hwnd, SW_SHOWNORMAL); } } } DestroyWindow(hwndDlg); break; } case IDCANCEL: DestroyWindow(hwndDlg); break; } break; } case WM_DESTROY: WindowList_Remove(PluginConfig.hUserPrefsWindowList, hwndDlg); break; } return FALSE; }
INT_PTR CALLBACK DlgProcTemplateEditor(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { struct TWindowData *dat = 0; TemplateEditorInfo *teInfo = 0; TTemplateSet *tSet; int i; dat = (struct TWindowData *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); /* * since this dialog needs a struct MessageWindowData * but has no container, we can store * the extended info struct in pContainer *) */ if (dat) { teInfo = (TemplateEditorInfo *)dat->pContainer; tSet = teInfo->rtl ? dat->pContainer->rtl_templates : dat->pContainer->ltr_templates; } switch (msg) { case WM_INITDIALOG: { TemplateEditorNew *teNew = (TemplateEditorNew *)lParam; COLORREF url_visited = RGB(128, 0, 128); COLORREF url_unvisited = RGB(0, 0, 255); dat = (struct TWindowData *) malloc(sizeof(struct TWindowData)); TranslateDialogDefault(hwndDlg); ZeroMemory((void *) dat, sizeof(struct TWindowData)); dat->pContainer = (struct TContainerData *)malloc(sizeof(struct TContainerData)); ZeroMemory((void *)dat->pContainer, sizeof(struct TContainerData)); teInfo = (TemplateEditorInfo *)dat->pContainer; ZeroMemory((void *)teInfo, sizeof(TemplateEditorInfo)); teInfo->hContact = teNew->hContact; teInfo->rtl = teNew->rtl; teInfo->hwndParent = teNew->hwndParent; LoadOverrideTheme(dat->pContainer); /* * set hContact to the first found contact so that we can use the Preview window properly * also, set other parameters needed by the streaming function to display events */ SendDlgItemMessage(hwndDlg, IDC_PREVIEW, EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS | ENM_LINK); SendDlgItemMessage(hwndDlg, IDC_PREVIEW, EM_SETEDITSTYLE, SES_EXTENDBACKCOLOR, SES_EXTENDBACKCOLOR); SendDlgItemMessage(hwndDlg, IDC_PREVIEW, EM_EXLIMITTEXT, 0, 0x80000000); dat->hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); dat->szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)dat->hContact, 0); while(dat->szProto == 0 && dat->hContact != 0) { dat->hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)dat->hContact, 0); dat->szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)dat->hContact, 0); } dat->dwFlags = dat->pContainer->theme.dwFlags; dat->cache = CContactCache::getContactCache(dat->hContact); dat->cache->updateState(); dat->cache->updateUIN(); dat->cache->updateStats(TSessionStats::INIT_TIMER); GetMYUIN(dat); SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) dat); ShowWindow(hwndDlg, SW_SHOW); SendDlgItemMessage(hwndDlg, IDC_EDITTEMPLATE, EM_LIMITTEXT, (WPARAM)TEMPLATE_LENGTH - 1, 0); SetWindowText(hwndDlg, CTranslator::getOpt(CTranslator::OPT_TEMP_TITLE)); Utils::enableDlgControl(hwndDlg, IDC_SAVETEMPLATE, FALSE); Utils::enableDlgControl(hwndDlg, IDC_REVERT, FALSE); Utils::enableDlgControl(hwndDlg, IDC_FORGET, FALSE); for (i = 0; i <= TMPL_ERRMSG; i++) { SendDlgItemMessageA(hwndDlg, IDC_TEMPLATELIST, LB_ADDSTRING, 0, (LPARAM)Translate(TemplateNames[i])); SendDlgItemMessage(hwndDlg, IDC_TEMPLATELIST, LB_SETITEMDATA, i, (LPARAM)i); } Utils::enableDlgControl(teInfo->hwndParent, IDC_MODIFY, FALSE); Utils::enableDlgControl(teInfo->hwndParent, IDC_RTLMODIFY, FALSE); SendDlgItemMessage(hwndDlg, IDC_COLOR1, CPM_SETCOLOUR, 0, M->GetDword("cc1", SRMSGDEFSET_BKGCOLOUR)); SendDlgItemMessage(hwndDlg, IDC_COLOR2, CPM_SETCOLOUR, 0, M->GetDword("cc2", SRMSGDEFSET_BKGCOLOUR)); SendDlgItemMessage(hwndDlg, IDC_COLOR3, CPM_SETCOLOUR, 0, M->GetDword("cc3", SRMSGDEFSET_BKGCOLOUR)); SendDlgItemMessage(hwndDlg, IDC_COLOR4, CPM_SETCOLOUR, 0, M->GetDword("cc4", SRMSGDEFSET_BKGCOLOUR)); SendDlgItemMessage(hwndDlg, IDC_COLOR5, CPM_SETCOLOUR, 0, M->GetDword("cc5", SRMSGDEFSET_BKGCOLOUR)); SendMessage(GetDlgItem(hwndDlg, IDC_EDITTEMPLATE), EM_SETREADONLY, TRUE, 0); return(TRUE); } case WM_COMMAND: switch (LOWORD(wParam)) { case IDCANCEL: DestroyWindow(hwndDlg); break; case IDC_RESETALLTEMPLATES: if (MessageBox(0, CTranslator::getOpt(CTranslator::OPT_TEMP_RESET), CTranslator::getOpt(CTranslator::OPT_TEMP_TITLE), MB_YESNO | MB_ICONQUESTION) == IDYES) { M->WriteByte(teInfo->rtl ? RTLTEMPLATES_MODULE : TEMPLATES_MODULE, "setup", 0); LoadDefaultTemplates(); MessageBox(0, CTranslator::getOpt(CTranslator::OPT_TEMP_WASRESET), CTranslator::getOpt(CTranslator::OPT_TEMP_TITLE), MB_OK); DestroyWindow(hwndDlg); } break; case IDC_TEMPLATELIST: switch (HIWORD(wParam)) { case LBN_DBLCLK: { LRESULT iIndex = SendDlgItemMessage(hwndDlg, IDC_TEMPLATELIST, LB_GETCURSEL, 0, 0); if (iIndex != LB_ERR) { SetDlgItemText(hwndDlg, IDC_EDITTEMPLATE, tSet->szTemplates[iIndex]); teInfo->inEdit = iIndex; teInfo->changed = FALSE; teInfo->selchanging = FALSE; SetFocus(GetDlgItem(hwndDlg, IDC_EDITTEMPLATE)); SendMessage(GetDlgItem(hwndDlg, IDC_EDITTEMPLATE), EM_SETREADONLY, FALSE, 0); } break; } case LBN_SELCHANGE: { LRESULT iIndex = SendDlgItemMessage(hwndDlg, IDC_TEMPLATELIST, LB_GETCURSEL, 0, 0); teInfo->selchanging = TRUE; if (iIndex != LB_ERR) { SetDlgItemText(hwndDlg, IDC_EDITTEMPLATE, tSet->szTemplates[iIndex]); teInfo->inEdit = iIndex; teInfo->changed = FALSE; } SendMessage(GetDlgItem(hwndDlg, IDC_EDITTEMPLATE), EM_SETREADONLY, TRUE, 0); break; } } break; case IDC_VARIABLESHELP: CallService(MS_UTILS_OPENURL, 0, (LPARAM)"http://wiki.miranda.or.at/TabSRMM/Templates"); break; case IDC_EDITTEMPLATE: if (HIWORD(wParam) == EN_CHANGE) { if (!teInfo->selchanging) { teInfo->changed = TRUE; teInfo->updateInfo[teInfo->inEdit] = TRUE; Utils::enableDlgControl(hwndDlg, IDC_SAVETEMPLATE, TRUE); Utils::enableDlgControl(hwndDlg, IDC_FORGET, TRUE); Utils::enableDlgControl(hwndDlg, IDC_TEMPLATELIST, FALSE); Utils::enableDlgControl(hwndDlg, IDC_REVERT, TRUE); } InvalidateRect(GetDlgItem(hwndDlg, IDC_TEMPLATELIST), NULL, FALSE); } break; case IDC_SAVETEMPLATE: { TCHAR newTemplate[TEMPLATE_LENGTH + 2]; GetWindowText(GetDlgItem(hwndDlg, IDC_EDITTEMPLATE), newTemplate, TEMPLATE_LENGTH); CopyMemory(tSet->szTemplates[teInfo->inEdit], newTemplate, sizeof(TCHAR) * TEMPLATE_LENGTH); teInfo->changed = FALSE; teInfo->updateInfo[teInfo->inEdit] = FALSE; Utils::enableDlgControl(hwndDlg, IDC_SAVETEMPLATE, FALSE); Utils::enableDlgControl(hwndDlg, IDC_FORGET, FALSE); Utils::enableDlgControl(hwndDlg, IDC_TEMPLATELIST, TRUE); Utils::enableDlgControl(hwndDlg, IDC_REVERT, FALSE); InvalidateRect(GetDlgItem(hwndDlg, IDC_TEMPLATELIST), NULL, FALSE); M->WriteTString(teInfo->hContact, teInfo->rtl ? RTLTEMPLATES_MODULE : TEMPLATES_MODULE, TemplateNames[teInfo->inEdit], newTemplate); SendMessage(GetDlgItem(hwndDlg, IDC_EDITTEMPLATE), EM_SETREADONLY, TRUE, 0); break; } case IDC_FORGET: { teInfo->changed = FALSE; teInfo->updateInfo[teInfo->inEdit] = FALSE; teInfo->selchanging = TRUE; SetDlgItemText(hwndDlg, IDC_EDITTEMPLATE, tSet->szTemplates[teInfo->inEdit]); SetFocus(GetDlgItem(hwndDlg, IDC_EDITTEMPLATE)); InvalidateRect(GetDlgItem(hwndDlg, IDC_TEMPLATELIST), NULL, FALSE); Utils::enableDlgControl(hwndDlg, IDC_SAVETEMPLATE, FALSE); Utils::enableDlgControl(hwndDlg, IDC_FORGET, FALSE); Utils::enableDlgControl(hwndDlg, IDC_TEMPLATELIST, TRUE); Utils::enableDlgControl(hwndDlg, IDC_REVERT, FALSE); teInfo->selchanging = FALSE; SendMessage(GetDlgItem(hwndDlg, IDC_EDITTEMPLATE), EM_SETREADONLY, TRUE, 0); break; } case IDC_REVERT: { teInfo->changed = FALSE; teInfo->updateInfo[teInfo->inEdit] = FALSE; teInfo->selchanging = TRUE; CopyMemory(tSet->szTemplates[teInfo->inEdit], LTR_Default.szTemplates[teInfo->inEdit], sizeof(TCHAR) * TEMPLATE_LENGTH); SetDlgItemText(hwndDlg, IDC_EDITTEMPLATE, tSet->szTemplates[teInfo->inEdit]); DBDeleteContactSetting(teInfo->hContact, teInfo->rtl ? RTLTEMPLATES_MODULE : TEMPLATES_MODULE, TemplateNames[teInfo->inEdit]); SetFocus(GetDlgItem(hwndDlg, IDC_EDITTEMPLATE)); InvalidateRect(GetDlgItem(hwndDlg, IDC_TEMPLATELIST), NULL, FALSE); teInfo->selchanging = FALSE; Utils::enableDlgControl(hwndDlg, IDC_SAVETEMPLATE, FALSE); Utils::enableDlgControl(hwndDlg, IDC_REVERT, FALSE); Utils::enableDlgControl(hwndDlg, IDC_FORGET, FALSE); Utils::enableDlgControl(hwndDlg, IDC_TEMPLATELIST, TRUE); SendMessage(GetDlgItem(hwndDlg, IDC_EDITTEMPLATE), EM_SETREADONLY, TRUE, 0); break; } case IDC_UPDATEPREVIEW: SendMessage(hwndDlg, DM_UPDATETEMPLATEPREVIEW, 0, 0); break; } break; case WM_DRAWITEM: { DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *) lParam; int iItem = dis->itemData; HBRUSH bkg, oldBkg; SetBkMode(dis->hDC, TRANSPARENT); FillRect(dis->hDC, &dis->rcItem, GetSysColorBrush(COLOR_WINDOW)); if (dis->itemState & ODS_SELECTED) { if (teInfo->updateInfo[iItem] == TRUE) { bkg = CreateSolidBrush(RGB(255, 0, 0)); oldBkg = (HBRUSH)SelectObject(dis->hDC, bkg); FillRect(dis->hDC, &dis->rcItem, bkg); SelectObject(dis->hDC, oldBkg); DeleteObject(bkg); } else FillRect(dis->hDC, &dis->rcItem, GetSysColorBrush(COLOR_HIGHLIGHT)); SetTextColor(dis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); } else { if (teInfo->updateInfo[iItem] == TRUE) SetTextColor(dis->hDC, RGB(255, 0, 0)); else SetTextColor(dis->hDC, GetSysColor(COLOR_WINDOWTEXT)); } char *pszName = Translate(TemplateNames[iItem]); TextOutA(dis->hDC, dis->rcItem.left, dis->rcItem.top, pszName, lstrlenA(pszName)); return(TRUE); } case DM_UPDATETEMPLATEPREVIEW: { DBEVENTINFO dbei = {0}; int iIndex = SendDlgItemMessage(hwndDlg, IDC_TEMPLATELIST, LB_GETCURSEL, 0, 0); TCHAR szTemp[TEMPLATE_LENGTH + 2]; if (teInfo->changed) { CopyMemory(szTemp, tSet->szTemplates[teInfo->inEdit], TEMPLATE_LENGTH * sizeof(TCHAR)); GetDlgItemText(hwndDlg, IDC_EDITTEMPLATE, tSet->szTemplates[teInfo->inEdit], TEMPLATE_LENGTH); } dbei.szModule = dat->szProto; dbei.timestamp = time(NULL); dbei.eventType = (iIndex == 6) ? EVENTTYPE_STATUSCHANGE : EVENTTYPE_MESSAGE; dbei.eventType = (iIndex == 7) ? EVENTTYPE_ERRMSG : dbei.eventType; if (dbei.eventType == EVENTTYPE_ERRMSG) dbei.szModule = "Sample error message"; dbei.cbSize = sizeof(dbei); dbei.pBlob = (iIndex == 6) ? (BYTE *)"is now offline (was online)" : (BYTE *)"The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog."; dbei.cbBlob = lstrlenA((char *)dbei.pBlob) + 1; dbei.flags = (iIndex == 1 || iIndex == 3 || iIndex == 5) ? DBEF_SENT : 0; dbei.flags |= (teInfo->rtl ? DBEF_RTL : 0); dat->lastEventTime = (iIndex == 4 || iIndex == 5) ? time(NULL) - 1 : 0; dat->iLastEventType = MAKELONG(dbei.flags, dbei.eventType); SetWindowText(GetDlgItem(hwndDlg, IDC_PREVIEW), _T("")); dat->dwFlags = MWF_LOG_ALL; dat->dwFlags = (teInfo->rtl ? dat->dwFlags | MWF_LOG_RTL : dat->dwFlags & ~MWF_LOG_RTL); dat->dwFlags = (iIndex == 0 || iIndex == 1) ? dat->dwFlags & ~MWF_LOG_GROUPMODE : dat->dwFlags | MWF_LOG_GROUPMODE; mir_sntprintf(dat->szMyNickname, safe_sizeof(dat->szMyNickname), _T("My Nickname")); StreamInEvents(hwndDlg, 0, 1, 1, &dbei); SendDlgItemMessage(hwndDlg, IDC_PREVIEW, EM_SETSEL, -1, -1); if (teInfo->changed) CopyMemory(tSet->szTemplates[teInfo->inEdit], szTemp, TEMPLATE_LENGTH * sizeof(TCHAR)); break; } case WM_DESTROY: Utils::enableDlgControl(teInfo->hwndParent, IDC_MODIFY, TRUE); Utils::enableDlgControl(teInfo->hwndParent, IDC_RTLMODIFY, TRUE); if (dat->pContainer) free(dat->pContainer); if (dat) free(dat); M->WriteDword(SRMSGMOD_T, "cc1", SendDlgItemMessage(hwndDlg, IDC_COLOR1, CPM_GETCOLOUR, 0, 0)); M->WriteDword(SRMSGMOD_T, "cc2", SendDlgItemMessage(hwndDlg, IDC_COLOR2, CPM_GETCOLOUR, 0, 0)); M->WriteDword(SRMSGMOD_T, "cc3", SendDlgItemMessage(hwndDlg, IDC_COLOR3, CPM_GETCOLOUR, 0, 0)); M->WriteDword(SRMSGMOD_T, "cc4", SendDlgItemMessage(hwndDlg, IDC_COLOR4, CPM_GETCOLOUR, 0, 0)); M->WriteDword(SRMSGMOD_T, "cc5", SendDlgItemMessage(hwndDlg, IDC_COLOR5, CPM_GETCOLOUR, 0, 0)); SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0); break; } return(FALSE); }
INT_PTR CALLBACK SelectContainerDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { HWND hwndMsgDlg = 0; hwndMsgDlg = (HWND) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch (msg) { case WM_INITDIALOG: { TCHAR szNewTitle[128]; RECT rc, rcParent; struct TContainerData *pContainer = 0; SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) lParam); hwndMsgDlg = (HWND) lParam; TranslateDialogDefault(hwndDlg); if (lParam) { struct TWindowData *dat = (struct TWindowData *)GetWindowLongPtr((HWND)lParam, GWLP_USERDATA); if (dat) { mir_sntprintf(szNewTitle, safe_sizeof(szNewTitle), CTranslator::get(CTranslator::CNT_SELECT_FOR), dat->cache->getNick()); SetWindowText(hwndDlg, szNewTitle); } } SendMessage(hwndDlg, DM_SC_BUILDLIST, 0, 0); SendDlgItemMessage(hwndDlg, IDC_NEWCONTAINERNAME, EM_LIMITTEXT, (WPARAM)CONTAINER_NAMELEN, 0); SendDlgItemMessage(hwndDlg, IDC_NEWCONTAINER, EM_LIMITTEXT, (WPARAM)CONTAINER_NAMELEN, 0); GetWindowRect(hwndDlg, &rc); GetWindowRect(GetParent(hwndDlg), &rcParent); SetWindowPos(hwndDlg, 0, (rcParent.left + rcParent.right - (rc.right - rc.left)) / 2, (rcParent.top + rcParent.bottom - (rc.bottom - rc.top)) / 2, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW); return TRUE; } case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: { TCHAR szName[CONTAINER_NAMELEN]; LRESULT iItem; if ((iItem = SendDlgItemMessage(hwndDlg, IDC_CNTLIST, LB_GETCURSEL, 0, 0)) != LB_ERR) { SendDlgItemMessage(hwndDlg, IDC_CNTLIST, LB_GETTEXT, (WPARAM) iItem, (LPARAM) szName); if (IsWindow(hwndMsgDlg)) SendMessage(hwndMsgDlg, DM_CONTAINERSELECTED, 0, (LPARAM) szName); } if (IsWindow(hwndDlg)) DestroyWindow(hwndDlg); break; } case IDCANCEL: DestroyWindow(hwndDlg); break; case IDC_DELETECONTAINER: { TCHAR szName[CONTAINER_NAMELEN + 1]; LRESULT iItem; if ((iItem = SendDlgItemMessage(hwndDlg, IDC_CNTLIST, LB_GETCURSEL, 0, 0)) != LB_ERR) { SendDlgItemMessage(hwndDlg, IDC_CNTLIST, LB_GETTEXT, (WPARAM) iItem, (LPARAM) szName); if (!_tcsncmp(szName, _T("default"), CONTAINER_NAMELEN) || !_tcsncmp(szName, CTranslator::get(CTranslator::GEN_DEFAULT_CONTAINER_NAME), CONTAINER_NAMELEN)) MessageBox(hwndDlg, CTranslator::get(CTranslator::CNT_SELECT_DELETEERROR), _T("Error"), MB_OK | MB_ICONERROR); else { int iIndex = SendDlgItemMessage(hwndDlg, IDC_CNTLIST, LB_GETITEMDATA, (WPARAM)iItem, 0); DeleteContainer(iIndex); SendDlgItemMessage(hwndDlg, IDC_CNTLIST, LB_RESETCONTENT, 0, 0); SendMessage(hwndDlg, DM_SC_BUILDLIST, 0, 0); BuildContainerMenu(); } } break; } case IDC_RENAMECONTAINER: { TCHAR szNewName[CONTAINER_NAMELEN], szName[CONTAINER_NAMELEN + 1]; int iLen, iItem; struct TContainerData *pCurrent = pFirstContainer; iLen = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_NEWCONTAINERNAME)); if (iLen) { GetWindowText(GetDlgItem(hwndDlg, IDC_NEWCONTAINERNAME), szNewName, CONTAINER_NAMELEN); if(!_tcsncmp(szNewName, CGlobals::m_default_container_name, CONTAINER_NAMELEN) || !_tcsncmp(szNewName, CTranslator::get(CTranslator::GEN_DEFAULT_CONTAINER_NAME), CONTAINER_NAMELEN)) { MessageBox(hwndDlg, CTranslator::get(CTranslator::CNT_SELECT_RENAMEERROR), _T("Error"), MB_OK | MB_ICONERROR); break; } iItem = SendDlgItemMessage(hwndDlg, IDC_CNTLIST, LB_FINDSTRING, (WPARAM) - 1, (LPARAM) szNewName); if (iItem != LB_ERR) { TCHAR szOldName[CONTAINER_NAMELEN + 1]; SendDlgItemMessage(hwndDlg, IDC_CNTLIST, LB_GETTEXT, (WPARAM) iItem, (LPARAM) szOldName); if (lstrlen(szOldName) == lstrlen(szNewName)) { MessageBox(0, CTranslator::get(CTranslator::CNT_SELECT_INUSE), _T("Error"), MB_OK | MB_ICONERROR); SetFocus(GetDlgItem(hwndDlg, IDC_NEWCONTAINERNAME)); break; } } if ((iItem = SendDlgItemMessage(hwndDlg, IDC_CNTLIST, LB_GETCURSEL, 0, 0)) != LB_ERR) { SendDlgItemMessage(hwndDlg, IDC_CNTLIST, LB_GETTEXT, (WPARAM) iItem, (LPARAM) szName); if (!_tcsncmp(szName, _T("default"), CONTAINER_NAMELEN) || !_tcsncmp(szName, CTranslator::get(CTranslator::GEN_DEFAULT_CONTAINER_NAME), CONTAINER_NAMELEN)) MessageBox(hwndDlg, CTranslator::get(CTranslator::CNT_SELECT_RENAMEERROR), _T("Error"), MB_OK | MB_ICONERROR); else { int iIndex = SendDlgItemMessage(hwndDlg, IDC_CNTLIST, LB_GETITEMDATA, (WPARAM)iItem, 0); RenameContainer(iIndex, szNewName); SendDlgItemMessage(hwndDlg, IDC_CNTLIST, LB_RESETCONTENT, 0, 0); while (pCurrent) { if (!_tcsncmp(pCurrent->szName, szName, CONTAINER_NAMELEN) && lstrlen(pCurrent->szName) == lstrlen(szName)) { _tcsncpy(pCurrent->szName, szNewName, CONTAINER_NAMELEN); SendMessage(pCurrent->hwnd, DM_CONFIGURECONTAINER, 0, 0); } pCurrent = pCurrent->pNextContainer; } SendMessage(hwndDlg, DM_SC_BUILDLIST, 0, 0); BuildContainerMenu(); } } } break; } case IDC_CREATENEW: { int iLen, iItem; TCHAR szNewName[CONTAINER_NAMELEN], szName[CONTAINER_NAMELEN + 1]; iLen = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_NEWCONTAINER)); if (iLen) { GetWindowText(GetDlgItem(hwndDlg, IDC_NEWCONTAINER), szNewName, CONTAINER_NAMELEN); iItem = SendDlgItemMessage(hwndDlg, IDC_CNTLIST, LB_FINDSTRING, (WPARAM) - 1, (LPARAM) szNewName); if (iItem != LB_ERR || !_tcsncmp(szNewName, CGlobals::m_default_container_name, CONTAINER_NAMELEN)) { SendDlgItemMessage(hwndDlg, IDC_CNTLIST, LB_GETTEXT, (WPARAM)iItem, (LPARAM)szName); if (lstrlen(szName) == lstrlen(szNewName) || !_tcsncmp(szNewName, CGlobals::m_default_container_name, CONTAINER_NAMELEN)) { MessageBox(0, CTranslator::get(CTranslator::CNT_SELECT_INUSE), _T("Error"), MB_OK | MB_ICONERROR); SetFocus(GetDlgItem(hwndDlg, IDC_NEWCONTAINER)); break; } } if (IsWindow(hwndMsgDlg)) { SendMessage(hwndMsgDlg, DM_CONTAINERSELECTED, 0, (LPARAM) szNewName); if (IsWindow(hwndDlg)) DestroyWindow(hwndDlg); } } break; } case IDC_CNTLIST: if (HIWORD(wParam) == LBN_DBLCLK) SendMessage(hwndDlg, WM_COMMAND, IDOK, 0); break; } break; /* * fill the list box... */ case DM_SC_BUILDLIST: { DBVARIANT dbv; int iCounter = 0, iItemNew; char *szKey = "TAB_ContainersW"; char szValue[10]; struct TContainerData *pContainer = 0; do { _snprintf(szValue, 8, "%d", iCounter); if (M->GetTString(NULL, szKey, szValue, &dbv)) break; // end of list if (dbv.type == DBVT_ASCIIZ || dbv.type == DBVT_WCHAR) { if (_tcsncmp(dbv.ptszVal, _T("**free**"), CONTAINER_NAMELEN)) { iItemNew = SendDlgItemMessage(hwndDlg, IDC_CNTLIST, LB_ADDSTRING, 0, (LPARAM)(!_tcscmp(dbv.ptszVal, _T("default")) ? CTranslator::get(CTranslator::GEN_DEFAULT_CONTAINER_NAME) : dbv.ptszVal)); if (iItemNew != LB_ERR) SendDlgItemMessage(hwndDlg, IDC_CNTLIST, LB_SETITEMDATA, (WPARAM)iItemNew, (LPARAM)iCounter); } DBFreeVariant(&dbv); } } while (++iCounter); /* * highlight the name of the container to which the message window currently is assigned */ SendMessage(hwndMsgDlg, DM_QUERYCONTAINER, 0, (LPARAM)&pContainer); if (pContainer) { LRESULT iItem; iItem = SendDlgItemMessage(hwndDlg, IDC_CNTLIST, LB_FINDSTRING, (WPARAM) - 1, (LPARAM)(!_tcscmp(pContainer->szName, _T("default")) ? CTranslator::get(CTranslator::GEN_DEFAULT_CONTAINER_NAME) : pContainer->szName)); if (iItem != LB_ERR) SendDlgItemMessage(hwndDlg, IDC_CNTLIST, LB_SETCURSEL, (WPARAM) iItem, 0); } } break; } return FALSE; }
int __fastcall CLVM_GetContactHiddenStatus(MCONTACT hContact, char *szProto, struct ClcData *dat) { int dbHidden = cfg::getByte(hContact, "CList", "Hidden", 0); // default hidden state, always respect it. int filterResult = 1; DBVARIANT dbv = {0}; char szTemp[64]; wchar_t szGroupMask[256]; DWORD dwLocalMask; // always hide subcontacts (but show them on embedded contact lists) if(cfg::dat.bMetaAvail && dat != NULL && dat->bHideSubcontacts && cfg::dat.bMetaEnabled && cfg::getByte(hContact, cfg::dat.szMetaName, "IsSubcontact", 0)) return 1; if(cfg::dat.bFilterEffective) { if (szProto == NULL) szProto = GetContactProto(hContact); // check stickies first (priority), only if we really have stickies defined (CLVM_STICKY_CONTACTS is set). if(cfg::dat.bFilterEffective & CLVM_STICKY_CONTACTS) { if((dwLocalMask = cfg::getDword(hContact, "CLVM", cfg::dat.current_viewmode, 0)) != 0) { if(cfg::dat.bFilterEffective & CLVM_FILTER_STICKYSTATUS) { WORD wStatus = cfg::getWord(hContact, szProto, "Status", ID_STATUS_OFFLINE); return !((1 << (wStatus - ID_STATUS_OFFLINE)) & HIWORD(dwLocalMask)); } return 0; } } // check the proto, use it as a base filter result for all further checks if(cfg::dat.bFilterEffective & CLVM_FILTER_PROTOS) { mir_snprintf(szTemp, sizeof(szTemp), "%s|", szProto); filterResult = strstr(cfg::dat.protoFilter, szTemp) ? 1 : 0; } if(cfg::dat.bFilterEffective & CLVM_FILTER_GROUPS) { if(!cfg::getTString(hContact, "CList", "Group", &dbv)) { _sntprintf(szGroupMask, safe_sizeof(szGroupMask), _T("%s|"), &dbv.ptszVal[1]); filterResult = (cfg::dat.filterFlags & CLVM_PROTOGROUP_OP) ? (filterResult | (_tcsstr(cfg::dat.groupFilter, szGroupMask) ? 1 : 0)) : (filterResult & (_tcsstr(cfg::dat.groupFilter, szGroupMask) ? 1 : 0)); mir_free(dbv.ptszVal); } else if(cfg::dat.filterFlags & CLVM_INCLUDED_UNGROUPED) filterResult = (cfg::dat.filterFlags & CLVM_PROTOGROUP_OP) ? filterResult : filterResult & 1; else filterResult = (cfg::dat.filterFlags & CLVM_PROTOGROUP_OP) ? filterResult : filterResult & 0; } if(cfg::dat.bFilterEffective & CLVM_FILTER_STATUS) { WORD wStatus = cfg::getWord(hContact, szProto, "Status", ID_STATUS_OFFLINE); filterResult = (cfg::dat.filterFlags & CLVM_GROUPSTATUS_OP) ? ((filterResult | ((1 << (wStatus - ID_STATUS_OFFLINE)) & cfg::dat.statusMaskFilter ? 1 : 0))) : (filterResult & ((1 << (wStatus - ID_STATUS_OFFLINE)) & cfg::dat.statusMaskFilter ? 1 : 0)); } if(cfg::dat.bFilterEffective & CLVM_FILTER_LASTMSG) { DWORD now; int iEntry = cfg::getCache(hContact, szProto); if(iEntry >= 0 && iEntry <= cfg::nextCacheEntry) { now = cfg::dat.t_now; now -= cfg::dat.lastMsgFilter; if(cfg::dat.bFilterEffective & CLVM_FILTER_LASTMSG_OLDERTHAN) filterResult = filterResult & (cfg::eCache[iEntry].dwLastMsgTime < now); else if(cfg::dat.bFilterEffective & CLVM_FILTER_LASTMSG_NEWERTHAN) filterResult = filterResult & (cfg::eCache[iEntry].dwLastMsgTime > now); } } return (dbHidden | !filterResult); } else return dbHidden; }