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; } TContainerData *p; switch (msg) { case WM_CREATE: for (int i=0; i < SIZEOF(_hotkeydescs); i++) { _hotkeydescs[i].cbSize = sizeof(HOTKEYDESC); Hotkey_Register(&_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 = (CLISTEVENT *)CallService(MS_CLIST_GETEVENT, (WPARAM)INVALID_HANDLE_VALUE, 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; 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((MCONTACT)dis->itemID); DWORD idle = 0; if (hWnd == NULL) { SESSION_INFO *si = SM_FindSessionByHCONTACT((MCONTACT)dis->itemID); hWnd = si ? si->hWnd : 0; } if (hWnd) dat = (TWindowData*)GetWindowLongPtr(hWnd, GWLP_USERDATA); if (dis->itemData >= 0) { HICON hIcon; if (dis->itemData > 0) hIcon = dis->itemData & 0x10000000 ? pci->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); return TRUE; } } } break; case DM_TRAYICONNOTIFY: 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) { BOOL iSelection = TrackPopupMenu(PluginConfig.g_hMenuTrayUnread, TPM_RETURNCMD, pt.x, pt.y, 0, hwndDlg, NULL); HandleMenuEntryFromhContact((MCONTACT)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: { if (wParam == 100) SetForegroundWindow(hwndDlg); int iCount = GetMenuItemCount(PluginConfig.g_hMenuTrayUnread); if (iCount > 0) { UINT uid = 0; MENUITEMINFOA mii = {0}; mii.fMask = MIIM_DATA; mii.cbSize = sizeof(mii); int i = iCount - 1; do { GetMenuItemInfoA(PluginConfig.g_hMenuTrayUnread, i, TRUE, &mii); if (mii.dwItemData > 0) { uid = GetMenuItemID(PluginConfig.g_hMenuTrayUnread, i); HandleMenuEntryFromhContact((MCONTACT)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); SetFocus(GetDlgItem(pLastActiveContainer->hwndActive, IDC_MESSAGE)); } else if (GetForegroundWindow() != pLastActiveContainer->hwnd) { SetForegroundWindow(pLastActiveContainer->hwnd); SetFocus(GetDlgItem(pLastActiveContainer->hwndActive, IDC_MESSAGE)); } 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)); BOOL 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((MCONTACT)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: for (p = pFirstContainer; p; p = p->pNext) ShowWindow(p->hwnd, SW_HIDE); break; case ID_TRAYCONTEXT_RESTOREALLMESSAGECONTAINERS: for (p = pFirstContainer; p; p = p->pNext) ShowWindow(p->hwnd, SW_SHOW); break; case ID_TRAYCONTEXT_BE: nen_options.iDisable = 1; nen_options.iNoSounds = 1; nen_options.iNoAutoPopup = 1; for (p = pFirstContainer; p; p = p->pNext) SendMessage(p->hwnd, WM_SYSCOMMAND, SC_MINIMIZE, 1); break; } } } if (wParam == 100) PostMessage(hwndDlg, WM_NULL, 0, 0); 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: // if lParam == NULL, don't consider clist events, just open the message tab if (lParam == 0) HandleMenuEntryFromhContact(wParam); else { CLISTEVENT *cle = (CLISTEVENT *)CallService(MS_CLIST_GETEVENT, wParam, 0); if (cle) { if (ServiceExists(cle->pszService)) { CallService(cle->pszService, 0, (LPARAM)cle); CallService(MS_CLIST_REMOVEEVENT, (WPARAM)cle->hContact, (LPARAM)cle->hDbEvent); } } // still, we got that message posted.. the event may be waiting in tabSRMMs tray... else HandleMenuEntryFromhContact(wParam); } break; case DM_DOCREATETAB: { HWND hWnd = M.FindWindow(lParam); if (hWnd && IsWindow(hWnd)) { 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((TContainerData*)wParam, lParam, 0, NULL, TRUE, TRUE, FALSE, 0); } } } break; case DM_DOCREATETAB_CHAT: { SESSION_INFO *si = SM_FindSessionByHWND((HWND)lParam); if (si && IsWindow(si->hWnd)) { 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((TContainerData*)wParam, si, TRUE, 0, 0); } } } break; case DM_SENDMESSAGECOMMANDW: SendMessageCommand_W(wParam, lParam); if (lParam) mir_free((void*)lParam); return 0; case DM_SENDMESSAGECOMMAND: SendMessageCommand(wParam, lParam); if (lParam) mir_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); db_event_markRead(wParam, (HANDLE)lParam); return 0; case DM_SETLOCALE: { HKL hkl = (HKL)lParam; MCONTACT hContact = wParam; HWND hWnd = M.FindWindow(hContact); if (hWnd) { TWindowData *dat = (TWindowData*)GetWindowLongPtr(hWnd, GWLP_USERDATA); if (dat) { if (hkl) { dat->hkl = hkl; PostMessage(dat->hwnd, DM_SETLOCALE, 0, 0); } DBVARIANT dbv; if (0 == db_get_ts(hContact, SRMSGMOD_T, "locale", &dbv)) { GetLocaleID(dat, dbv.ptszVal); db_free(&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); for (p = pFirstContainer; p; p = p->pNext) { if (fNewAero) SetAeroMargins(p); else { MARGINS m = {0}; if (M.m_pfnDwmExtendFrameIntoClientArea) M.m_pfnDwmExtendFrameIntoClientArea(p->hwnd, &m); } if (p->SideBar->isActive()) RedrawWindow(GetDlgItem(p->hwnd, 5000), NULL, NULL, RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW); // the container for the sidebar buttons RedrawWindow(p->hwnd, NULL, NULL, RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW|RDW_ALLCHILDREN); } } 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: M.getAeroState(); Skin->setupTabCloseBitmap(); CSkin::initAeroEffect(); PluginConfig.m_ncm.cbSize = sizeof(NONCLIENTMETRICS); SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &PluginConfig.m_ncm, 0); FreeTabConfig(); ReloadTabConfig(); for (p = pFirstContainer; p; p = p->pNext) { SendMessage(GetDlgItem(p->hwnd, IDC_MSGTABS), EM_THEMECHANGED, 0, 0); BroadCastContainer(p, EM_THEMECHANGED, 0, 0); } break; case DM_SPLITSENDACK: { SendJob *job = sendQueue->getJobByIndex((int)wParam); ACKDATA ack = {0}; 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: for (p = pFirstContainer; p; p = p->pNext) if (CSkin::m_skinEnabled) { // invalidate cached background DCs for skinned containers p->oldDCSize.cx = p->oldDCSize.cy = 0; SelectObject(p->cachedDC, p->oldHBM); DeleteObject(p->cachedHBM); DeleteDC(p->cachedDC); p->cachedDC = 0; RedrawWindow(p->hwnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_FRAME); } 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 container, they use this to update // dynamic content (i.e. local time in the info panel). for (p = pFirstContainer; p; p = p->pNext) SendMessage(p->hwnd, WM_TIMER, TIMERID_HEARTBEAT, 0); // 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); }
/** * New event was added into DB. */ static int MessageEventAdded(WPARAM wParam, LPARAM lParam) { MCONTACT hContact = wParam; HANDLE hDBEvent = (HANDLE)lParam; // is the message sender accepted for forwarding if (hForwardFrom != 0 && hForwardFrom != hContact) return 0; // is receiver specified if (hForwardTo == 0) return 0; // don't reply to receiver if (hForwardTo == hContact) return 0; // is current status acceptable int statMask; switch(CallService(MS_CLIST_GETSTATUSMODE, 0, 0)){ case ID_STATUS_OFFLINE: statMask = STATUS_OFFLINE ;break; case ID_STATUS_ONLINE: statMask = STATUS_ONLINE ;break; case ID_STATUS_AWAY: statMask = STATUS_AWAY ;break; case ID_STATUS_NA: statMask = STATUS_NA ;break; case ID_STATUS_OCCUPIED: statMask = STATUS_OCCUPIED ;break; case ID_STATUS_DND: statMask = STATUS_DND ;break; case ID_STATUS_FREECHAT: statMask = STATUS_FREECHAT ;break; case ID_STATUS_INVISIBLE:statMask = STATUS_INVISIBLE;break; } if ((iForwardOnStatus & statMask) == 0) return 0; // receive message from DB DBEVENTINFO dbei = { sizeof(dbei) }; dbei.cbBlob = db_event_getBlobSize(hDBEvent); if (dbei.cbBlob == -1) return 0; dbei.pBlob = (unsigned char*)alloca(dbei.cbBlob); db_event_get(hDBEvent, &dbei); if (dbei.flags & DBEF_SENT || dbei.flags & DBEF_READ || (dbei.eventType != EVENTTYPE_MESSAGE)) return 0; // get time and date time_t tTime = dbei.timestamp; tm *tm_time = gmtime(&tTime); // build a message Buffer<char> szUtfMsg; ptrA szTemplate( mir_utf8encodeT(tszForwardTemplate)); for (char *p = szTemplate; *p; p++) { if (*p != '%') { szUtfMsg.append(*p); continue; } TCHAR buf[100]; switch(*++p) { case 'u': case 'U': szUtfMsg.append( ptrA(mir_utf8encodeT(pcli->pfnGetContactDisplayName(hContact, 0)))); break; case 'i': case 'I': { // get sender's uin CONTACTINFO ci = { sizeof(ci) }; ci.dwFlag = CNF_UNIQUEID; if (CallService(MS_CONTACT_GETCONTACTINFO, 0, (long)&ci) == 0){ if (ci.type == CNFT_ASCIIZ) _tcsncpy_s(buf, ci.pszVal, SIZEOF(buf)); else if (ci.type == CNFT_BYTE) mir_sntprintf(buf, SIZEOF(buf), _T("%u"), ci.bVal); else if (ci.type == CNFT_WORD) mir_sntprintf(buf, SIZEOF(buf), _T("%u"), ci.wVal); else if (ci.type == CNFT_DWORD) mir_sntprintf(buf, SIZEOF(buf), _T("%u"), ci.dVal); } else mir_sntprintf(buf, SIZEOF(buf), _T("%p"), hContact); } szUtfMsg.append( ptrA(mir_utf8encodeT(buf))); break; case 't': case 'T': _tcsftime(buf, 10, _T("%H:%M"), tm_time); szUtfMsg.append( ptrA(mir_utf8encodeT(buf))); break; case 'd': case 'D': _tcsftime(buf, 12, _T("%d/%m/%Y"), tm_time); szUtfMsg.append( ptrA(mir_utf8encodeT(buf))); break; case 'm': case 'M': if (dbei.flags & DBEF_UTF) szUtfMsg.append((char*)dbei.pBlob, dbei.cbBlob); else szUtfMsg.append( ptrA(mir_utf8encode((char*)dbei.pBlob))); break; case '%': szUtfMsg.append('%'); break; } } int iPartCount = 1; size_t cbMsgSize = szUtfMsg.len, cbPortion = cbMsgSize; if (iSplit > 0) { iPartCount = min(iSendParts, int((szUtfMsg.len + iSplitMaxSize) / iSplitMaxSize)); cbPortion = iSplitMaxSize; } char *szBuf = szUtfMsg.str; for (int i=0; i < iPartCount; i++, szBuf += cbPortion) { char *szMsgPart = (char*)mir_alloc(cbPortion+1); strncpy(szMsgPart, szBuf, cbPortion); szMsgPart[cbPortion] = 0; HANDLE hMsgProc = (HANDLE)CallContactService(hForwardTo, PSS_MESSAGE, PREF_UTF, (LPARAM)szMsgPart); MESSAGE_PROC* msgProc = (MESSAGE_PROC*)mir_alloc(sizeof(MESSAGE_PROC)); msgProc->hProcess = hMsgProc; msgProc->msgText = szMsgPart; msgProc->retryCount = 0; arMessageProcs.insert(msgProc); } // mark message as 'read' if (iMarkRead > 0) db_event_markRead(hContact, hDBEvent); return 0; }
//mir_free() the return value static char* CreateRTFFromDbEvent(SrmmWindowData *dat, MCONTACT hContact, MEVENT hDbEvent, struct LogStreamData *streamData) { int showColon = 0; DBEVENTINFO dbei = { sizeof(dbei) }; dbei.cbBlob = db_event_getBlobSize(hDbEvent); if (dbei.cbBlob == -1) return NULL; dbei.pBlob = (PBYTE)mir_alloc(dbei.cbBlob); db_event_get(hDbEvent, &dbei); if (!DbEventIsShown(&dbei)) { mir_free(dbei.pBlob); return NULL; } if (!(dbei.flags & DBEF_SENT) && (dbei.eventType == EVENTTYPE_MESSAGE || DbEventIsForMsgWindow(&dbei))) { db_event_markRead(hContact, hDbEvent); pcli->pfnRemoveEvent(hContact, hDbEvent); } else if (dbei.eventType == EVENTTYPE_JABBER_CHATSTATES || dbei.eventType == EVENTTYPE_JABBER_PRESENCE) { db_event_markRead(hContact, hDbEvent); } CMStringA buffer; if (!dat->bIsAutoRTL && !streamData->isEmpty) buffer.Append("\\par"); if (dbei.flags & DBEF_RTL) { buffer.Append("\\rtlpar"); dat->bIsAutoRTL = TRUE; } else buffer.Append("\\ltrpar"); streamData->isEmpty = 0; if (dat->bIsAutoRTL) { if (dbei.flags & DBEF_RTL) buffer.Append("\\ltrch\\rtlch"); else buffer.Append("\\rtlch\\ltrch"); } if (g_dat.flags & SMF_SHOWICONS) { int i = ((dbei.eventType == EVENTTYPE_MESSAGE) ? ((dbei.flags & DBEF_SENT) ? LOGICON_MSG_OUT : LOGICON_MSG_IN): LOGICON_MSG_NOTICE); buffer.Append("\\f0\\fs14"); buffer.Append(pLogIconBmpBits[i]); } if (g_dat.flags & SMF_SHOWTIME) { const TCHAR* szFormat; TCHAR str[64]; if (g_dat.flags & SMF_SHOWSECS) szFormat = g_dat.flags & SMF_SHOWDATE ? _T("d s") : _T("s"); else szFormat = g_dat.flags & SMF_SHOWDATE ? _T("d t") : _T("t"); TimeZone_PrintTimeStamp(NULL, dbei.timestamp, szFormat, str, _countof(str), 0); buffer.AppendFormat(" %s ", SetToStyle(dbei.flags & DBEF_SENT ? MSGFONTID_MYTIME : MSGFONTID_YOURTIME)); AppendToBufferWithRTF(buffer, str); showColon = 1; } if (!(g_dat.flags & SMF_HIDENAMES) && dbei.eventType != EVENTTYPE_JABBER_CHATSTATES && dbei.eventType != EVENTTYPE_JABBER_PRESENCE) { TCHAR *szName; CONTACTINFO ci = { 0 }; if (dbei.flags & DBEF_SENT) { ci.cbSize = sizeof(ci); ci.szProto = dbei.szModule; ci.dwFlag = CNF_DISPLAY | CNF_TCHAR; if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM)&ci)) { // CNF_DISPLAY always returns a string type szName = ci.pszVal; } else // Shouldn't happen? szName = mir_tstrdup(TranslateT("Me")); } else szName = pcli->pfnGetContactDisplayName(hContact, 0); buffer.AppendFormat(" %s ", SetToStyle(dbei.flags & DBEF_SENT ? MSGFONTID_MYNAME : MSGFONTID_YOURNAME)); AppendToBufferWithRTF(buffer, szName); showColon = 1; if (ci.pszVal) mir_free(ci.pszVal); } if (showColon) buffer.AppendFormat("%s :", SetToStyle(dbei.flags & DBEF_SENT ? MSGFONTID_MYCOLON : MSGFONTID_YOURCOLON)); TCHAR *msg, *szName; switch (dbei.eventType) { case EVENTTYPE_JABBER_CHATSTATES: case EVENTTYPE_JABBER_PRESENCE: if (dbei.flags & DBEF_SENT) { CONTACTINFO ci = { sizeof(ci) }; ci.hContact = NULL; ci.szProto = dbei.szModule; ci.dwFlag = CNF_DISPLAY | CNF_TCHAR; // CNF_DISPLAY always returns a string type if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM)& ci)) szName = NEWTSTR_ALLOCA(ci.pszVal); else szName = _T(""); mir_free(ci.pszVal); } else szName = pcli->pfnGetContactDisplayName(hContact, 0); buffer.AppendFormat(" %s ", SetToStyle(MSGFONTID_NOTICE)); AppendToBufferWithRTF(buffer, szName); AppendToBufferWithRTF(buffer, _T(" ")); msg = DbGetEventTextT(&dbei, CP_ACP); if (msg) { AppendToBufferWithRTF(buffer, msg); mir_free(msg); } break; case EVENTTYPE_FILE: { char* filename = (char*)dbei.pBlob + sizeof(DWORD); char* descr = filename + mir_strlen(filename) + 1; ptrT ptszFileName(DbGetEventStringT(&dbei, filename)); buffer.AppendFormat(" %s ", SetToStyle(MSGFONTID_NOTICE)); AppendToBufferWithRTF(buffer, (dbei.flags & DBEF_SENT) ? TranslateT("File sent") : TranslateT("File received")); buffer.Append(": "); AppendToBufferWithRTF(buffer, ptszFileName); if (*descr != 0) { ptrT ptszDescr(DbGetEventStringT(&dbei, descr)); buffer.Append(" ("); AppendToBufferWithRTF(buffer, ptszDescr); buffer.Append(")"); } } break; case EVENTTYPE_MESSAGE: default: msg = DbGetEventTextT(&dbei, CP_ACP); buffer.AppendFormat(" %s ", SetToStyle((dbei.eventType == EVENTTYPE_MESSAGE) ? ((dbei.flags & DBEF_SENT) ? MSGFONTID_MYMSG : MSGFONTID_YOURMSG) : MSGFONTID_NOTICE)); AppendToBufferWithRTF(buffer, msg); mir_free(msg); } if (dat->bIsAutoRTL) buffer.Append("\\par"); mir_free(dbei.pBlob); return buffer.Detach(); }
INT_PTR CALLBACK DlgProcRecvFile(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { struct FileDlgData *dat; dat = (struct FileDlgData*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch (msg) { case WM_INITDIALOG: TranslateDialogDefault(hwndDlg); { TCHAR szPath[450]; CLISTEVENT* cle = (CLISTEVENT*)lParam; dat = (struct FileDlgData*)mir_calloc(sizeof(struct FileDlgData)); SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat); dat->hContact = cle->hContact; dat->hDbEvent = cle->hDbEvent; dat->hPreshutdownEvent = HookEventMessage(ME_SYSTEM_PRESHUTDOWN, hwndDlg, M_PRESHUTDOWN); dat->dwTicks = GetTickCount(); EnumChildWindows(hwndDlg, ClipSiblingsChildEnumProc, 0); Window_SetIcon_IcoLib(hwndDlg, SKINICON_EVENT_FILE); Button_SetIcon_IcoLib(hwndDlg, IDC_ADD, SKINICON_OTHER_ADDCONTACT, LPGEN("Add contact permanently to list")); Button_SetIcon_IcoLib(hwndDlg, IDC_DETAILS, SKINICON_OTHER_USERDETAILS, LPGEN("View user's details")); Button_SetIcon_IcoLib(hwndDlg, IDC_HISTORY, SKINICON_OTHER_HISTORY, LPGEN("View user's history")); Button_SetIcon_IcoLib(hwndDlg, IDC_USERMENU, SKINICON_OTHER_DOWNARROW, LPGEN("User menu")); TCHAR *contactName = pcli->pfnGetContactDisplayName(dat->hContact, 0); SetDlgItemText(hwndDlg, IDC_FROM, contactName); GetContactReceivedFilesDir(dat->hContact, szPath, SIZEOF(szPath), TRUE); SetDlgItemText(hwndDlg, IDC_FILEDIR, szPath); SHAutoComplete(GetWindow(GetDlgItem(hwndDlg, IDC_FILEDIR), GW_CHILD), 1); for (int i=0; i < MAX_MRU_DIRS; i++) { char idstr[32]; mir_snprintf(idstr, SIZEOF(idstr), "MruDir%d", i); DBVARIANT dbv; if (db_get_ts(NULL, "SRFile", idstr, &dbv)) break; SendDlgItemMessage(hwndDlg, IDC_FILEDIR, CB_ADDSTRING, 0, (LPARAM)dbv.ptszVal); db_free(&dbv); } db_event_markRead(dat->hContact, dat->hDbEvent); DBEVENTINFO dbei = { sizeof(dbei) }; dbei.cbBlob = db_event_getBlobSize(dat->hDbEvent); if (dbei.cbBlob > 4 && dbei.cbBlob <= 8196) { dbei.pBlob = (PBYTE)alloca(dbei.cbBlob + 1); db_event_get(dat->hDbEvent, &dbei); dbei.pBlob[dbei.cbBlob] = 0; dat->fs = cle->lParam ? (HANDLE)cle->lParam : (HANDLE)*(PDWORD)dbei.pBlob; char *str = (char*)dbei.pBlob + 4; ptrT ptszFileName( DbGetEventStringT(&dbei, str)); SetDlgItemText(hwndDlg, IDC_FILENAMES, ptszFileName); unsigned len = (unsigned)strlen(str) + 1; if (len + 4 < dbei.cbBlob) { str += len; ptrT ptszDescription( DbGetEventStringT(&dbei, str)); SetDlgItemText(hwndDlg, IDC_MSG, ptszDescription); } } else DestroyWindow(hwndDlg); TCHAR datetimestr[64]; tmi.printTimeStamp(NULL, dbei.timestamp, _T("t d"), datetimestr, SIZEOF(datetimestr), 0); SetDlgItemText(hwndDlg, IDC_DATE, datetimestr); char* szProto = GetContactProto(dat->hContact); if (szProto) { int hasName = 0; char buf[128]; CONTACTINFO ci = { 0 }; ci.cbSize = sizeof(ci); ci.hContact = dat->hContact; ci.szProto = szProto; ci.dwFlag = CNF_UNIQUEID; if ( !CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM)&ci)) { switch(ci.type) { case CNFT_ASCIIZ: hasName = 1; mir_snprintf(buf, SIZEOF(buf), "%s", ci.pszVal); mir_free(ci.pszVal); break; case CNFT_DWORD: hasName = 1; mir_snprintf(buf, SIZEOF(buf), "%u", ci.dVal); break; } } if (hasName) SetDlgItemTextA(hwndDlg, IDC_NAME, buf); else SetDlgItemText(hwndDlg, IDC_NAME, contactName); } if (db_get_b(dat->hContact, "CList", "NotOnList", 0)) { RECT rcBtn1, rcBtn2, rcDateCtrl; GetWindowRect(GetDlgItem(hwndDlg, IDC_ADD), &rcBtn1); GetWindowRect(GetDlgItem(hwndDlg, IDC_USERMENU), &rcBtn2); GetWindowRect(GetDlgItem(hwndDlg, IDC_DATE), &rcDateCtrl); SetWindowPos(GetDlgItem(hwndDlg, IDC_DATE), 0, 0, 0, rcDateCtrl.right-rcDateCtrl.left-(rcBtn2.left-rcBtn1.left), rcDateCtrl.bottom-rcDateCtrl.top, SWP_NOZORDER|SWP_NOMOVE); } else if (db_get_b(NULL, "SRFile", "AutoAccept", 0)) { //don't check auto-min here to fix BUG#647620 PostMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDOK, BN_CLICKED), (LPARAM)GetDlgItem(hwndDlg, IDOK)); } if ( !db_get_b(dat->hContact, "CList", "NotOnList", 0)) ShowWindow(GetDlgItem(hwndDlg, IDC_ADD), SW_HIDE); } return TRUE; case WM_MEASUREITEM: return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam); case WM_DRAWITEM: { LPDRAWITEMSTRUCT dis = (LPDRAWITEMSTRUCT)lParam; if (dis->hwndItem == GetDlgItem(hwndDlg, IDC_PROTOCOL)) { char *szProto = GetContactProto(dat->hContact); if (szProto) { HICON hIcon = (HICON)CallProtoService(szProto, PS_LOADICON, PLI_PROTOCOL|PLIF_SMALL, 0); if (hIcon) { DrawIconEx(dis->hDC, dis->rcItem.left, dis->rcItem.top, hIcon, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0, NULL, DI_NORMAL); DestroyIcon(hIcon); } } } } return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam); case WM_COMMAND: if (CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM)dat->hContact)) break; switch (LOWORD(wParam)) { case IDC_FILEDIRBROWSE: { TCHAR szDirName[MAX_PATH], szExistingDirName[MAX_PATH]; GetDlgItemText(hwndDlg, IDC_FILEDIR, szDirName, SIZEOF(szDirName)); GetLowestExistingDirName(szDirName, szExistingDirName, SIZEOF(szExistingDirName)); if (BrowseForFolder(hwndDlg, szExistingDirName)) SetDlgItemText(hwndDlg, IDC_FILEDIR, szExistingDirName); } break; case IDOK: { //most recently used directories TCHAR szRecvDir[MAX_PATH], szDefaultRecvDir[MAX_PATH]; GetDlgItemText(hwndDlg, IDC_FILEDIR, szRecvDir, SIZEOF(szRecvDir)); RemoveInvalidPathChars(szRecvDir); GetContactReceivedFilesDir(NULL, szDefaultRecvDir, SIZEOF(szDefaultRecvDir), TRUE); if (_tcsnicmp(szRecvDir, szDefaultRecvDir, lstrlen(szDefaultRecvDir))) { char idstr[32]; int i; DBVARIANT dbv; for (i = MAX_MRU_DIRS-2; i>=0; i--) { mir_snprintf(idstr, SIZEOF(idstr), "MruDir%d", i); if (db_get_ts(NULL, "SRFile", idstr, &dbv)) continue; mir_snprintf(idstr, SIZEOF(idstr), "MruDir%d", i+1); db_set_ts(NULL, "SRFile", idstr, dbv.ptszVal); db_free(&dbv); } db_set_ts(NULL, "SRFile", idstr, szRecvDir); } } EnableWindow(GetDlgItem(hwndDlg, IDC_FILENAMES), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_MSG), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_FILEDIR), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_FILEDIRBROWSE), FALSE); GetDlgItemText(hwndDlg, IDC_FILEDIR, dat->szSavePath, SIZEOF(dat->szSavePath)); GetDlgItemText(hwndDlg, IDC_FILE, dat->szFilenames, SIZEOF(dat->szFilenames)); GetDlgItemText(hwndDlg, IDC_MSG, dat->szMsg, SIZEOF(dat->szMsg)); dat->hwndTransfer = FtMgr_AddTransfer(dat); SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0); //check for auto-minimize here to fix BUG#647620 if (db_get_b(NULL, "SRFile", "AutoAccept", 0) && db_get_b(NULL, "SRFile", "AutoMin", 0)) { ShowWindow(hwndDlg, SW_HIDE); ShowWindow(hwndDlg, SW_SHOWMINNOACTIVE); } DestroyWindow(hwndDlg); break; case IDCANCEL: if (dat->fs) CallContactService(dat->hContact, PSS_FILEDENYT, (WPARAM)dat->fs, (LPARAM)TranslateT("Canceled")); dat->fs = NULL; /* the protocol will free the handle */ DestroyWindow(hwndDlg); break; case IDC_ADD: { ADDCONTACTSTRUCT acs = {0}; acs.handle = dat->hContact; acs.handleType = HANDLE_CONTACT; acs.szProto = ""; CallService(MS_ADDCONTACT_SHOW, (WPARAM)hwndDlg, (LPARAM)&acs); if ( !db_get_b(dat->hContact, "CList", "NotOnList", 0)) ShowWindow(GetDlgItem(hwndDlg, IDC_ADD), SW_HIDE); } break; case IDC_USERMENU: { RECT rc; HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM)dat->hContact, 0); GetWindowRect((HWND)lParam, &rc); TrackPopupMenu(hMenu, 0, rc.left, rc.bottom, 0, hwndDlg, NULL); DestroyMenu(hMenu); } break; case IDC_DETAILS: CallService(MS_USERINFO_SHOWDIALOG, (WPARAM)dat->hContact, 0); break; case IDC_HISTORY: CallService(MS_HISTORY_SHOWCONTACTHISTORY, (WPARAM)dat->hContact, 0); break; } break; case WM_DESTROY: Window_FreeIcon_IcoLib(hwndDlg); Button_FreeIcon_IcoLib(hwndDlg, IDC_ADD); Button_FreeIcon_IcoLib(hwndDlg, IDC_DETAILS); Button_FreeIcon_IcoLib(hwndDlg, IDC_HISTORY); Button_FreeIcon_IcoLib(hwndDlg, IDC_USERMENU); if (dat) FreeFileDlgData(dat); break; } return FALSE; }
INT_PTR CALLBACK RecvDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { TRecvContactsData *wndData = (TRecvContactsData*)GetWindowLongPtr(hwndDlg, DWLP_USER); MCONTACT hContact; switch (msg) { case WM_INITDIALOG: TranslateDialogDefault(hwndDlg); { CLISTEVENT *pcle = (CLISTEVENT*)lParam; WindowList_Add(ghRecvWindowList, hwndDlg, pcle->hContact); SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(hInst, MAKEINTRESOURCE(IDI_CONTACTS))); EnableDlgItem(hwndDlg, IDOK, FALSE); EnableDlgItem(hwndDlg, IDDETAILS, FALSE); wndData = new TRecvContactsData(pcle->hContact); SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)wndData); wndData->mhDbEvent = pcle->hDbEvent; /// initialized, pcle not needed anymore wndData->mhListIcon = ImageList_Create(GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),ILC_COLORDDB|ILC_MASK, 0, 1); wndData->mhPopup = LoadMenu(hInst, MAKEINTRESOURCE(IDR_CONTACTMENU)); TranslateMenu(wndData->mhPopup); wndData->hHook = HookEventMessage(ME_PROTO_ACK, hwndDlg, HM_EVENTSENT); char *szProto =GetContactProto(wndData->mhContact); HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); ListView_SetExtendedListViewStyle(hLV, LVS_EX_CHECKBOXES|LVS_EX_FULLROWSELECT); // add columns RecvListView_AddColumn(hLV, 120, _A2T((char*)CallProtoService(szProto, PS_GETCAPS, PFLAG_UNIQUEIDTEXT, 0)), 0); RecvListView_AddColumn(hLV, 100, TranslateT("Nick"), 1); RecvListView_AddColumn(hLV, 100, TranslateT("First Name"), 2); RecvListView_AddColumn(hLV, 100, TranslateT("Last Name"), 3); // fill in groups SendMessage(GetDlgItem(hwndDlg, IDC_ENABLEGROUPS), BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0); RebuildGroupCombo(hwndDlg); { // fill listview with received contacts DBEVENTINFO dbe = {0}; dbe.cbSize = sizeof(DBEVENTINFO); dbe.cbBlob = db_event_getBlobSize(wndData->mhDbEvent); if (dbe.cbBlob != -1) // this marks an invalid hDbEvent - all smashed anyway... dbe.pBlob = (PBYTE)_alloca(dbe.cbBlob); db_event_get(wndData->mhDbEvent, &dbe); char* pcBlob = (char*)dbe.pBlob; char* pcEnd = (char*)dbe.pBlob + dbe.cbBlob; HICON hiProto = LoadContactProtoIcon(wndData->mhContact); ImageList_AddIcon(wndData->mhListIcon, hiProto); DestroyIcon(hiProto); // imagelist copied the resource ListView_SetImageList(hLV, wndData->mhListIcon, LVSIL_SMALL); LVITEM lvi = {0}; lvi.iImage = 0; lvi.mask = LVIF_TEXT | LVIF_IMAGE; for (int nItem = 0; ; nItem++) { // Nick int strsize = (int)strlennull(pcBlob); TReceivedItem* pItem = wndData->AddReceivedItem(); if (dbe.flags & DBEF_UTF) pItem->mcaNick = mir_utf8decodeT(pcBlob); else pItem->mcaNick = mir_a2t(pcBlob); pcBlob += strsize + 1; // UIN strsize = (int)strlennull(pcBlob); pItem->mcaUIN = mir_a2t(pcBlob); pcBlob += strsize + 1; // add to listview lvi.iItem = nItem; lvi.pszText = pItem->mcaUIN; ListView_InsertItem(hLV, &lvi); // with image ListView_SetItemText(hLV, nItem, 1, pItem->mcaNick); // check for end of contacts if (pcBlob >= pcEnd) break; } } // new dlg init wndData->hIcons[0] = InitMButton(hwndDlg, IDC_ADD, MAKEINTRESOURCEA(IDI_ADDCONTACT), LPGEN("Add Contact Permanently to List")); wndData->hIcons[1] = InitMButton(hwndDlg, IDC_DETAILS, MAKEINTRESOURCEA(IDI_USERDETAILS), LPGEN("View User's Details")); wndData->hIcons[2] = InitMButton(hwndDlg, IDC_HISTORY, MAKEINTRESOURCEA(IDI_HISTORY), LPGEN("View User's History")); wndData->hIcons[3] = InitMButton(hwndDlg, IDC_USERMENU, MAKEINTRESOURCEA(IDI_DOWNARROW), LPGEN("User Menu")); SendMessage(hwndDlg,DM_UPDATETITLE,0,0); // new dialog init done Utils_RestoreWindowPosition(hwndDlg, NULL, MODULENAME, ""); return TRUE; } case WM_NOTIFY: if (((LPNMHDR)lParam)->idFrom == IDC_CONTACTS) { switch (((LPNMHDR)lParam)->code) { case NM_DBLCLK: { HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); if (ListView_GetSelectedCount(hLV) != 1) break; // if not clicking on item, bye wndData->iPopupItem = ListView_GetNextItem(hLV, -1, LVNI_ALL|LVNI_SELECTED); if (wndData->iPopupItem == -1) break; // if no item selected no user details available return SendMessage(hwndDlg, WM_COMMAND, ID_POPUP_USERDETAILS, 0); // show user details } case LVN_ITEMCHANGED: { LPNMLISTVIEW pNMLV = (LPNMLISTVIEW)lParam; HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); // optimisation, for FOR-Cycle bool bExistsCheckedItem = false; // there must be no checked items to disable "Add" button if (ListView_GetCheckState(hLV, pNMLV->iItem)) { // the user has checked this item bExistsCheckedItem = true; // enable "Add" button } else { // loop thru items and check if at least one is checked for (int i = 0; i < ListView_GetItemCount(hLV); i++) if (ListView_GetCheckState(hLV, i)) { // we found checked item, enable add, exit loop bExistsCheckedItem = true; break; } } EnableDlgItem(hwndDlg, IDOK, bExistsCheckedItem); EnableDlgItem(hwndDlg, IDDETAILS, ListView_GetSelectedCount(hLV) > 0); break; } } } break; case WM_COMMAND: { if (!lParam && CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM)wndData->mhContact)) break; switch(LOWORD(wParam)) { case IDOK: // "Add Selected" button click { // for each selected item, find its index in the hDbEvent // and after that add this item to the DB permanently HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); HWND hGroupsCombo = GetDlgItem(hwndDlg, IDC_GROUPS); HWND hGroupsCheck = GetDlgItem(hwndDlg, IDC_ENABLEGROUPS); int curs = SendMessage(hGroupsCombo, CB_GETCURSEL, 0, 0); TCHAR* caGroup = NULL; int nGroupId = -1; if (curs != CB_ERR && IsWindowEnabled(hGroupsCheck) && SendMessage(hGroupsCheck, BM_GETCHECK, 0, 0)) { //got groups, get the one selected in combo TCHAR* caGroup = (TCHAR*)_alloca((SendMessage(hGroupsCombo, CB_GETLBTEXTLEN, curs, 0) + 1) * sizeof(TCHAR)); SendMessage(hGroupsCombo, CB_GETLBTEXT, curs, (LPARAM)caGroup); nGroupId = SendMessage(hGroupsCombo, CB_GETITEMDATA, curs, 0); } for (int i = 0; i < ListView_GetItemCount(hLV); i++) if (ListView_GetCheckState(hLV, i)) { // found checked contact item, add it TCHAR *caUIN = ListView_GetItemTextEx(hLV, i, 0); for (int j = 0; j < wndData->cbReceived; j++) // determine item index in packet if (!lstrcmp(wndData->maReceived[j]->mcaUIN, caUIN)) { char *szProto =GetContactProto(wndData->mhContact); hContact = (MCONTACT)CallProtoService(szProto, PS_ADDTOLISTBYEVENT, MAKEWPARAM(0, j), (LPARAM)wndData->mhDbEvent); if (hContact && caGroup) { // use newest group API if available if (ServiceExists(MS_CLIST_CONTACTCHANGEGROUP)) CallService(MS_CLIST_CONTACTCHANGEGROUP, hContact, (LPARAM)nGroupId); else db_set_ts(hContact, "CList", "Group", caGroup); } break; } mir_free(caUIN); } // move to next item break; } case IDDETAILS: { // for each selected item, find its index in the hDbEvent // and after that add this item to the DB // finally, request Details window for this hContact HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); for (int i = 0; i < ListView_GetItemCount(hLV); i++) if (ListView_GetItemState(hLV, i, LVIS_SELECTED)) { hContact = CreateTemporaryContactForItem(hwndDlg, wndData, i); if (hContact) CallService(MS_USERINFO_SHOWDIALOG, hContact, 0); } } break; case IDCANCEL: SendMessage(hwndDlg, WM_CLOSE, 0, 0); break; case IDC_ENABLEGROUPS: EnableGroupCombo(hwndDlg); break; case IDC_GROUPS: // rebuild group list on popup if (HIWORD(wParam) == CBN_DROPDOWN) RebuildGroupCombo(hwndDlg); break; case ID_POPUP_ADDUSER: hContact = CreateTemporaryContactForItem(hwndDlg, wndData, wndData->iPopupItem); if (hContact) DialogAddContactExecute(hwndDlg, hContact); break; case ID_POPUP_USERDETAILS: hContact = CreateTemporaryContactForItem(hwndDlg, wndData, wndData->iPopupItem); if (hContact) CallService(MS_USERINFO_SHOWDIALOG, hContact, 0 ); break; case ID_POPUP_SENDMESSAGE: hContact = CreateTemporaryContactForItem(hwndDlg, wndData, wndData->iPopupItem); if (hContact) CallService(MS_MSG_SENDMESSAGE, hContact, 0); break; case IDC_USERMENU: { RECT rc; HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM)wndData->mhContact, 0); GetWindowRect(GetDlgItem(hwndDlg,IDC_USERMENU), &rc); TrackPopupMenu(hMenu, 0, rc.left, rc.bottom, 0, hwndDlg, NULL); DestroyMenu(hMenu); } break; case IDC_HISTORY: CallService(MS_HISTORY_SHOWCONTACTHISTORY,(WPARAM)wndData->mhContact,0); break; case IDC_DETAILS: CallService(MS_USERINFO_SHOWDIALOG,(WPARAM)wndData->mhContact,0); break; case IDC_ADD: DialogAddContactExecute(hwndDlg, wndData->mhContact); break; } } break; case WM_CONTEXTMENU: { HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); LVHITTESTINFO lvh; RECT rt; wndData->iPopupItem = -1; if ((HWND)wParam != hLV) break; // if not our ListView go away lvh.pt.x = LOWORD(lParam); lvh.pt.y = HIWORD(lParam); if (GetWindowRect(hLV, &rt)==0) return FALSE; // ?? why this, some check ?? ScreenToClient(hLV, &lvh.pt); // convert to ListView local coordinates int ci = ListView_HitTest(hLV, &lvh); if (ci==-1) break; // mouse is not over any item wndData->iPopupItem = ci; TrackPopupMenu(GetSubMenu(wndData->mhPopup, 0), TPM_LEFTALIGN|TPM_TOPALIGN, LOWORD(lParam), HIWORD(lParam), 0, hwndDlg, NULL); } break; case HM_EVENTSENT: { ACKDATA *ack = (ACKDATA*)lParam; if (ack->type != ACKTYPE_SEARCH) break; // not search ack, go away if (ack->hProcess != wndData->rhSearch) break; //not our search, go away if (ack->result == ACKRESULT_DATA) { HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); PROTOSEARCHRESULT *psr = (PROTOSEARCHRESULT*)ack->lParam; LVFINDINFO fi; fi.flags = LVFI_STRING; fi.psz = wndData->haUin; int iLPos = ListView_FindItem(hLV, -1, &fi); if (iLPos == -1) iLPos = 0; if (lstrcmp(psr->nick, _T("")) && psr->nick) ListView_SetItemText(hLV, iLPos, 1, psr->nick); ListView_SetItemText(hLV, iLPos, 2, psr->firstName); ListView_SetItemText(hLV, iLPos, 3, psr->lastName); break; } mir_free(wndData->haUin); } break; case WM_CLOSE: // user closed window, so destroy it WindowList_Remove(ghRecvWindowList, hwndDlg); DestroyWindow(hwndDlg); break; case WM_DESTROY: // last message received by this dialog, cleanup db_event_markRead(wndData->mhContact, wndData->mhDbEvent); Utils_SaveWindowPosition(hwndDlg, NULL, MODULENAME, ""); ImageList_Destroy(wndData->mhListIcon); UnhookEvent(wndData->hHook); DestroyMenu(wndData->mhPopup); { for (int i = 0; i < SIZEOF(wndData->hIcons); i++) DestroyIcon(wndData->hIcons[i]); } delete wndData; // automatically calls destructor break; case WM_MEASUREITEM: return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam); case WM_DRAWITEM: DrawProtocolIcon(hwndDlg, lParam, wndData->mhContact); return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam); case WM_SIZE: if (!IsIconic(hwndDlg)) { // make the dlg resizeable UTILRESIZEDIALOG urd = { sizeof(urd) }; urd.hInstance = hInst; urd.hwndDlg = hwndDlg; urd.lpTemplate = MAKEINTRESOURCEA(IDD_RECEIVE); urd.pfnResizer = RecvDlg_Resize; CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM) & urd); } break; case WM_GETMINMAXINFO: { MINMAXINFO* mmi=(MINMAXINFO*)lParam; mmi->ptMinTrackSize.x = 480+2*GetSystemMetrics(SM_CXSIZEFRAME); mmi->ptMinTrackSize.y = 130+2*GetSystemMetrics(SM_CYSIZEFRAME); } break; case DM_UPDATETITLE: UpdateDialogTitle(hwndDlg, wndData ? wndData->mhContact : NULL, LPGENT("Contacts from")); if (wndData) UpdateDialogAddButton(hwndDlg, wndData->mhContact); break; } return FALSE; }
//This function handles the ACK received from that hooked. int handleAckSMS(WPARAM wParam,LPARAM lParam) { if (lParam) if (((ACKDATA*)lParam)->type==ICQACKTYPE_SMS) { char szPhone[MAX_PHONE_LEN]={0}; TCHAR tszPhone[MAX_PHONE_LEN]={0}; LPSTR lpszXML=(LPSTR)((ACKDATA*)lParam)->lParam,lpszData,lpszPhone; SIZE_T dwXMLSize=lstrlenA(lpszXML),dwDataSize,dwPhoneSize; ACKDATA *ack=((ACKDATA*)lParam); if (GetXMLFieldEx(lpszXML,dwXMLSize,&lpszData,&dwDataSize,"sms_message","text",NULL)) { if (GetXMLFieldEx(lpszXML,dwXMLSize,&lpszPhone,&dwPhoneSize,"sms_message","sender",NULL)) { LPSTR lpszMessageUTF; SIZE_T dwBuffLen,dwMessageXMLEncodedSize,dwMessageXMLDecodedSize; HANDLE hContact; DBEVENTINFO dbei = { sizeof(dbei) }; dwBuffLen=(dwDataSize+MAX_PATH); dbei.pBlob=(LPBYTE)MEMALLOC((dwBuffLen+dwPhoneSize)); LPWSTR lpwszMessageXMLEncoded=(LPWSTR)MEMALLOC((dwBuffLen*sizeof(WCHAR))); LPWSTR lpwszMessageXMLDecoded=(LPWSTR)MEMALLOC((dwBuffLen*sizeof(WCHAR))); if (dbei.pBlob && lpwszMessageXMLEncoded && lpwszMessageXMLDecoded) { dwMessageXMLEncodedSize=MultiByteToWideChar(CP_UTF8,0,lpszData,dwDataSize,lpwszMessageXMLEncoded,dwBuffLen); DecodeXML(lpwszMessageXMLEncoded,dwMessageXMLEncodedSize,lpwszMessageXMLDecoded,dwBuffLen,&dwMessageXMLDecodedSize); lpszMessageUTF=(LPSTR)lpwszMessageXMLEncoded; WideCharToMultiByte(CP_UTF8,0,lpwszMessageXMLDecoded,dwMessageXMLDecodedSize,lpszMessageUTF,dwBuffLen,NULL,NULL); dwPhoneSize=CopyNumberA(szPhone,lpszPhone,dwPhoneSize); dwPhoneSize=MultiByteToWideChar(CP_UTF8,0,szPhone,dwPhoneSize,tszPhone,MAX_PHONE_LEN); hContact=HContactFromPhone(tszPhone,dwPhoneSize); dbei.szModule=GetModuleName(hContact); dbei.timestamp=time(NULL); dbei.flags=(DBEF_UTF); dbei.eventType=ICQEVENTTYPE_SMS; dbei.cbBlob=(mir_snprintf((LPSTR)dbei.pBlob,((dwBuffLen+dwPhoneSize)),"SMS From: +%s\r\n%s",szPhone,lpszMessageUTF)+sizeof(DWORD)); //dbei.pBlob=(LPBYTE)lpszBuff; (*((DWORD*)(dbei.pBlob+(dbei.cbBlob-sizeof(DWORD)))))=0; HANDLE hResult = db_event_add(hContact, &dbei); if (hContact==NULL) { if ( RecvSMSWindowAdd(NULL,ICQEVENTTYPE_SMS,tszPhone,dwPhoneSize,(LPSTR)dbei.pBlob,dbei.cbBlob)) { db_event_markRead(hContact, hResult); SkinPlaySound("RecvSMSMsg"); } } } MEMFREE(lpwszMessageXMLDecoded); MEMFREE(lpwszMessageXMLEncoded); MEMFREE(dbei.pBlob); } }else if (GetXMLFieldEx(lpszXML,dwXMLSize,&lpszData,&dwDataSize,"sms_delivery_receipt","delivered",NULL)) { if (GetXMLFieldEx(lpszXML,dwXMLSize,&lpszPhone,&dwPhoneSize,"sms_delivery_receipt","destination",NULL)) { dwPhoneSize=CopyNumberA(szPhone,lpszPhone,dwPhoneSize); dwPhoneSize=MultiByteToWideChar(CP_UTF8,0,szPhone,dwPhoneSize,tszPhone,MAX_PHONE_LEN); HANDLE hContact=HContactFromPhone(tszPhone,dwPhoneSize); DBEVENTINFO dbei={0}; dbei.cbSize=sizeof(dbei); dbei.szModule=GetModuleName(hContact); dbei.timestamp=time(NULL); dbei.eventType=ICQEVENTTYPE_SMSCONFIRMATION; if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpszData,dwDataSize,"yes",3)==CSTR_EQUAL) { dbei.cbBlob=(MAX_PHONE_LEN+MAX_PATH); dbei.pBlob=(PBYTE)MEMALLOC(dbei.cbBlob); if (dbei.pBlob) dbei.cbBlob=(mir_snprintf((LPSTR)dbei.pBlob,dbei.cbBlob,"SMS Confirmation From: +%s\r\nSMS was sent succesfully",szPhone)+4); }else{ if (GetXMLFieldEx(lpszXML,dwXMLSize,&lpszData,&dwDataSize,"sms_delivery_receipt","error","params","param",NULL)==FALSE) { lpszData=""; dwDataSize=0; } dbei.cbBlob=(MAX_PHONE_LEN+MAX_PATH+dwDataSize); dbei.pBlob=(PBYTE)MEMALLOC(dbei.cbBlob); if (dbei.pBlob) { dbei.cbBlob=mir_snprintf((LPSTR)dbei.pBlob,dbei.cbBlob,"SMS Confirmation From: +%s\r\nSMS was not sent succesfully: ",szPhone); CopyMemory((dbei.pBlob+dbei.cbBlob),lpszData,dwDataSize); dbei.cbBlob+=(dwDataSize+sizeof(DWORD)); (*((DWORD*)(dbei.pBlob+(dbei.cbBlob-sizeof(DWORD)))))=0; } } if (dbei.pBlob) { if (hContact) db_event_add(hContact, &dbei); else RecvSMSWindowAdd(NULL,ICQEVENTTYPE_SMSCONFIRMATION,tszPhone,dwPhoneSize,(LPSTR)dbei.pBlob,dbei.cbBlob); MEMFREE(dbei.pBlob); } } }else if ((ack->result==ACKRESULT_FAILED) || GetXMLFieldEx(lpszXML,dwXMLSize,&lpszData,&dwDataSize,"sms_response","deliverable",NULL)) { HWND hWndDlg=SendSMSWindowHwndByHProcessGet(ack->hProcess); if (hWndDlg) { char szNetwork[MAX_PATH]; KillTimer(hWndDlg,wParam); GetXMLFieldExBuff(lpszXML,dwXMLSize,szNetwork,sizeof(szNetwork),NULL,"sms_response","network",NULL); if (ack->result==ACKRESULT_FAILED || CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpszData,dwDataSize,"no",2)==CSTR_EQUAL) { char szBuff[1024]; TCHAR tszErrorMessage[1028]; LPSTR lpszErrorDescription; if (SendSMSWindowMultipleGet(hWndDlg)) { TVITEM tvi; tvi.mask=TVIF_TEXT; tvi.hItem=SendSMSWindowHItemSendGet(hWndDlg); tvi.pszText=tszPhone; tvi.cchTextMax=SIZEOF(tszPhone); TreeView_GetItem(GetDlgItem(hWndDlg,IDC_NUMBERSLIST),&tvi); } else GetDlgItemText(hWndDlg,IDC_ADDRESS,tszPhone,SIZEOF(szPhone)); if (ack->result == ACKRESULT_FAILED) lpszErrorDescription=lpszXML; else { lpszErrorDescription=szBuff; GetXMLFieldExBuff(lpszXML,dwXMLSize,szBuff,sizeof(szBuff),NULL,"sms_response","error","params","param",NULL); } mir_sntprintf(tszErrorMessage,SIZEOF(tszErrorMessage),TranslateT("SMS message didn't send by %S to %s because: %S"),szNetwork,tszPhone,lpszErrorDescription); ShowWindow(hWndDlg,SW_SHOWNORMAL); EnableWindow(hWndDlg,FALSE); HWND hwndTimeOut=CreateDialog(ssSMSSettings.hInstance,MAKEINTRESOURCE(IDD_SENDSMSTIMEDOUT),hWndDlg,SMSTimedOutDlgProc); SetDlgItemText(hwndTimeOut,IDC_STATUS,tszErrorMessage); } else { SendSMSWindowDBAdd(hWndDlg); if ( SendSMSWindowMultipleGet(hWndDlg)) { if ( SendSMSWindowNextHItemGet(hWndDlg,SendSMSWindowHItemSendGet(hWndDlg))) { SendSMSWindowAsSentSet(hWndDlg); SendSMSWindowHItemSendSet(hWndDlg,SendSMSWindowNextHItemGet(hWndDlg,SendSMSWindowHItemSendGet(hWndDlg))); SendSMSWindowNext(hWndDlg); } else SendSMSWindowRemove(hWndDlg); } else { if ( CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpszData,dwDataSize,"yes",3)==CSTR_EQUAL || CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpszData,dwDataSize,"smtp",4)==CSTR_EQUAL) { char szSource[MAX_PATH],szMessageID[MAX_PATH]; if (DB_SMS_GetByte(NULL,"ShowACK",SMS_DEFAULT_SHOWACK)) { HWND hwndAccepted=CreateDialog(ssSMSSettings.hInstance,MAKEINTRESOURCE(IDD_SENDSMSACCEPT),hWndDlg,SMSAcceptedDlgProc); if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpszData,dwDataSize,"yes",3)==CSTR_EQUAL) { GetXMLFieldExBuff(lpszXML,dwXMLSize,szSource,sizeof(szSource),NULL,"sms_response","source",NULL); GetXMLFieldExBuff(lpszXML,dwXMLSize,szMessageID,sizeof(szMessageID),NULL,"sms_response","message_id",NULL); } else { SetDlgItemText(hwndAccepted,IDC_ST_SOURCE,TranslateT("From:")); SetDlgItemText(hwndAccepted,IDC_ST_MESSAGEID,TranslateT("To:")); GetXMLFieldExBuff(lpszXML,dwXMLSize,szSource,sizeof(szSource),NULL,"sms_response","from",NULL); GetXMLFieldExBuff(lpszXML,dwXMLSize,szMessageID,sizeof(szMessageID),NULL,"sms_response","to",NULL); } SetDlgItemTextA(hwndAccepted,IDC_NETWORK,szNetwork); SetDlgItemTextA(hwndAccepted,IDC_SOURCE,szSource); SetDlgItemTextA(hwndAccepted,IDC_MESSAGEID,szMessageID); } else SendSMSWindowRemove(hWndDlg); } else SendSMSWindowRemove(hWndDlg); } } } } } return 0; }
//Handles new SMS messages added to the database int handleNewMessage(WPARAM wParam, LPARAM lParam) { char szServiceFunction[MAX_PATH], *pszServiceFunctionName; TCHAR szToolTip[MAX_PATH]; HANDLE hContact = (HANDLE)wParam, hDbEvent = (HANDLE)lParam; DBEVENTINFO dbei = { sizeof(dbei) }; if ((dbei.cbBlob = db_event_getBlobSize(hDbEvent)) != -1) { dbei.pBlob = (PBYTE)MEMALLOC(dbei.cbBlob); if (dbei.pBlob) { CopyMemory(szServiceFunction,PROTOCOL_NAMEA,PROTOCOL_NAME_SIZE); pszServiceFunctionName = szServiceFunction + PROTOCOL_NAME_LEN; if (db_event_get(hDbEvent, &dbei) == 0) if ((dbei.flags & DBEF_SENT) == 0) if (dbei.eventType == ICQEVENTTYPE_SMS) { if (dbei.cbBlob>MIN_SMS_DBEVENT_LEN) { SkinPlaySound("RecvSMSMsg"); if (DB_SMS_GetByte(NULL,"AutoPopup",0)) { if (RecvSMSWindowAdd(hContact,ICQEVENTTYPE_SMS,NULL,0,(LPSTR)dbei.pBlob,dbei.cbBlob)) db_event_markRead(hContact, hDbEvent); } else { CopyMemory(pszServiceFunctionName,SMS_READ,sizeof(SMS_READ)); mir_sntprintf(szToolTip,SIZEOF(szToolTip),TranslateT("SMS Message from %s"),GetContactNameW(hContact)); CLISTEVENT cle = { sizeof(cle) }; cle.flags = CLEF_TCHAR; cle.hContact = hContact; cle.hDbEvent = hDbEvent; cle.hIcon = LoadSkinnedIcon(SKINICON_OTHER_SMS); cle.pszService = szServiceFunction; cle.ptszTooltip = szToolTip; CallService(MS_CLIST_ADDEVENT,0,(LPARAM)&cle); } } } else if (dbei.eventType == ICQEVENTTYPE_SMSCONFIRMATION) { SkinPlaySound("RecvSMSConfirmation"); if (DB_SMS_GetByte(NULL, "AutoPopup", 0)) { if (RecvSMSWindowAdd(hContact,ICQEVENTTYPE_SMSCONFIRMATION,NULL,0,(LPSTR)dbei.pBlob,dbei.cbBlob)) db_event_delete(hContact, &dbei); } else { UINT iIcon; if (GetDataFromMessage((LPSTR)dbei.pBlob, dbei.cbBlob, NULL, NULL, 0, NULL, &iIcon)) { CopyMemory(pszServiceFunctionName,SMS_READ_ACK,sizeof(SMS_READ_ACK)); mir_sntprintf(szToolTip,SIZEOF(szToolTip),TranslateT("SMS Confirmation from %s"),GetContactNameW(hContact)); CLISTEVENT cle = { sizeof(cle) }; cle.flags = CLEF_TCHAR; cle.hContact = hContact; cle.hDbEvent = hDbEvent; cle.hIcon = (HICON)LoadImage(ssSMSSettings.hInstance,MAKEINTRESOURCE(iIcon),IMAGE_ICON,0,0,LR_SHARED); cle.pszService = szServiceFunction; cle.ptszTooltip = szToolTip; CallService(MS_CLIST_ADDEVENT,0,(LPARAM)&cle); } } } MEMFREE(dbei.pBlob); } } return 0; }
INT_PTR CALLBACK DlgProcUrlRecv(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { struct UrlRcvData *dat = (struct UrlRcvData *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch (msg) { case WM_INITDIALOG: TranslateDialogDefault(hwndDlg); Window_SetIcon_IcoLib(hwndDlg, SKINICON_EVENT_URL); Button_SetIcon_IcoLib(hwndDlg, IDC_ADD, SKINICON_OTHER_ADDCONTACT, LPGEN("Add contact permanently to list")); Button_SetIcon_IcoLib(hwndDlg, IDC_DETAILS, SKINICON_OTHER_USERDETAILS, LPGEN("View user's details")); Button_SetIcon_IcoLib(hwndDlg, IDC_HISTORY, SKINICON_OTHER_HISTORY, LPGEN("View user's history")); Button_SetIcon_IcoLib(hwndDlg, IDC_USERMENU, SKINICON_OTHER_DOWNARROW, LPGEN("User menu")); dat = (struct UrlRcvData*)mir_alloc(sizeof(struct UrlRcvData)); SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat); dat->hContact = ((CLISTEVENT*)lParam)->hContact; dat->hDbEvent = ((CLISTEVENT*)lParam)->hDbEvent; WindowList_Add(hUrlWindowList, hwndDlg, dat->hContact); { DBEVENTINFO dbei = { sizeof(dbei) }; dbei.cbBlob = db_event_getBlobSize(dat->hDbEvent); dbei.pBlob = (PBYTE)mir_alloc(dbei.cbBlob); db_event_get(dat->hDbEvent, &dbei); SetDlgItemTextA(hwndDlg, IDC_URL, (char*)dbei.pBlob); SetDlgItemTextA(hwndDlg, IDC_MSG, (char*)dbei.pBlob+lstrlenA((char*)dbei.pBlob)+1); mir_free(dbei.pBlob); db_event_markRead(dat->hContact, dat->hDbEvent); TCHAR *contactName = pcli->pfnGetContactDisplayName(dat->hContact, 0), msg[128]; mir_sntprintf(msg, SIZEOF(msg), TranslateT("URL from %s"), contactName); SetWindowText(hwndDlg, msg); SetDlgItemText(hwndDlg, IDC_FROM, contactName); SendDlgItemMessage(hwndDlg, IDOK, BUTTONSETARROW, 1, 0); TCHAR str[128]; tmi.printTimeStamp(NULL, dbei.timestamp, _T("t d"), str, SIZEOF(str), 0); SetDlgItemText(hwndDlg, IDC_DATE, str); } // From message dlg if ( !db_get_b(dat->hContact, "CList", "NotOnList", 0)) ShowWindow(GetDlgItem(hwndDlg, IDC_ADD), SW_HIDE); SendMessage(hwndDlg, DM_UPDATETITLE, 0, 0); // From message dlg end Utils_RestoreWindowPositionNoSize(hwndDlg, NULL, "SRUrl", "recv"); return TRUE; case WM_MEASUREITEM: return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam); case WM_DRAWITEM: { LPDRAWITEMSTRUCT dis = (LPDRAWITEMSTRUCT)lParam; if (dis->hwndItem == GetDlgItem(hwndDlg, IDC_PROTOCOL)) { char *szProto; szProto = GetContactProto(dat->hContact); if (szProto) { HICON hIcon; hIcon = (HICON)CallProtoService(szProto, PS_LOADICON, PLI_PROTOCOL|PLIF_SMALL, 0); if (hIcon) { DrawIconEx(dis->hDC, dis->rcItem.left, dis->rcItem.top, hIcon, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0, NULL, DI_NORMAL); DestroyIcon(hIcon); } } } } return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam); case DM_UPDATETITLE: sttUpdateTitle(hwndDlg, dat->hContact); break; case WM_COMMAND: if (dat) if (CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM)dat->hContact)) break; switch(LOWORD(wParam)) { case IDOK: { HMENU hMenu, hSubMenu; RECT rc; char url[256]; hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_CONTEXT)); hSubMenu = GetSubMenu(hMenu, 6); TranslateMenu(hSubMenu); GetWindowRect((HWND)lParam, &rc); GetDlgItemTextA(hwndDlg, IDC_URL, url, SIZEOF(url)); switch(TrackPopupMenu(hSubMenu, TPM_RETURNCMD, rc.left, rc.bottom, 0, hwndDlg, NULL)) { case IDM_OPENNEW: CallService(MS_UTILS_OPENURL, 1, (LPARAM)url); break; case IDM_OPENEXISTING: CallService(MS_UTILS_OPENURL, 0, (LPARAM)url); break; case IDM_COPYLINK: { HGLOBAL hData; if ( !OpenClipboard(hwndDlg)) break; EmptyClipboard(); hData = GlobalAlloc(GMEM_MOVEABLE, lstrlenA(url)+1); lstrcpyA((char*)GlobalLock(hData), url); GlobalUnlock(hData); SetClipboardData(CF_TEXT, hData); CloseClipboard(); break; } } DestroyMenu(hMenu); } return TRUE; case IDC_USERMENU: { RECT rc; HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM)dat->hContact, 0); GetWindowRect(GetDlgItem(hwndDlg, IDC_USERMENU), &rc); TrackPopupMenu(hMenu, 0, rc.left, rc.bottom, 0, hwndDlg, NULL); DestroyMenu(hMenu); } break; case IDC_HISTORY: CallService(MS_HISTORY_SHOWCONTACTHISTORY, (WPARAM)dat->hContact, 0); break; case IDC_DETAILS: CallService(MS_USERINFO_SHOWDIALOG, (WPARAM)dat->hContact, 0); break; case IDC_ADD: { ADDCONTACTSTRUCT acs = {0}; acs.hContact = dat->hContact; acs.handleType = HANDLE_CONTACT; CallService(MS_ADDCONTACT_SHOW, (WPARAM)hwndDlg, (LPARAM)&acs); } if ( !db_get_b(dat->hContact, "CList", "NotOnList", 0)) { ShowWindow(GetDlgItem(hwndDlg, IDC_ADD), FALSE); } break; case IDC_REPLY: CallService(MS_MSG_SENDMESSAGE, (WPARAM)dat->hContact, 0); //fall through case IDCANCEL: DestroyWindow(hwndDlg); return TRUE; } break; case WM_DESTROY: Window_FreeIcon_IcoLib(hwndDlg); Button_FreeIcon_IcoLib(hwndDlg, IDC_ADD); Button_FreeIcon_IcoLib(hwndDlg, IDC_DETAILS); Button_FreeIcon_IcoLib(hwndDlg, IDC_HISTORY); Button_FreeIcon_IcoLib(hwndDlg, IDC_USERMENU); WindowList_Remove(hUrlWindowList, hwndDlg); mir_free(dat); Utils_SaveWindowPosition(hwndDlg, NULL, "SRUrl", "recv"); break; } return FALSE; }