Example #1
0
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);
}
Example #2
0
/**
* 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;
}
Example #3
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();
}
Example #4
0
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;
}
Example #5
0
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;
}
Example #6
0
//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;
}
Example #7
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;
}
Example #8
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;
}