Пример #1
0
LRESULT CALLBACK PopupDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	PLUGINDATA *pdp = NULL;

	switch(message) {
	case WM_MEASUREITEM: //Needed by the contact's context menu
		return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam);

	case WM_DRAWITEM: //Needed by the contact's context menu
		return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam);

	case WM_COMMAND:
		//This one returns TRUE if it processed the menu command, and FALSE if it did not process it.
		if (CallServiceSync(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM)PUGetContact(hwnd)))
			break;

		PopupAction(hwnd, opt.LeftClickAction);
		break;

	case WM_CONTEXTMENU:
		PopupAction(hwnd, opt.RightClickAction);
		break;

	case UM_FREEPLUGINDATA:
		pdp = (PLUGINDATA *)PUGetPluginData(hwnd);
		if (pdp != NULL) {
			if (pdp->hAwayMsgHook != NULL) {
				UnhookEvent(pdp->hAwayMsgHook);
				pdp->hAwayMsgHook = NULL;
			}

			mir_free(pdp);
		}
		return FALSE;

	case UM_INITPOPUP:
		pdp = (PLUGINDATA *)PUGetPluginData(hwnd);
		if (pdp != NULL) {
			char *szProto = GetContactProto( PUGetContact(hwnd));
			if (szProto && opt.ReadAwayMsg && StatusHasAwayMessage(szProto, pdp->newStatus)) {
				WORD myStatus = (WORD)CallProtoService(szProto, PS_GETSTATUS, 0, 0);
				if (myStatus != ID_STATUS_INVISIBLE)
					QueryAwayMessage(hwnd, pdp);
			}
		}

		return FALSE;
	}

	return DefWindowProc(hwnd, message, wParam, lParam);
}
Пример #2
0
int ContactStatusChanged(MCONTACT hContact, WORD oldStatus, WORD newStatus)
{
	if (opt.LogToDB && (!opt.LogToDB_WinOpen || CheckMsgWnd(hContact))) {
		wchar_t stzStatusText[MAX_SECONDLINE] = { 0 };
		GetStatusText(hContact, newStatus, oldStatus, stzStatusText);
		T2Utf blob(stzStatusText);

		DBEVENTINFO dbei = {};
		dbei.cbBlob = (DWORD)mir_strlen(blob) + 1;
		dbei.pBlob = (PBYTE)blob;
		dbei.eventType = EVENTTYPE_STATUSCHANGE;
		dbei.flags = DBEF_READ | DBEF_UTF;

		dbei.timestamp = (DWORD)time(0);
		dbei.szModule = MODULE;
		MEVENT hDBEvent = db_event_add(hContact, &dbei);

		if (opt.LogToDB_WinOpen && opt.LogToDB_Remove) {
			DBEVENT *dbevent = (DBEVENT *)mir_alloc(sizeof(DBEVENT));
			dbevent->hContact = hContact;
			dbevent->hDBEvent = hDBEvent;
			eventListStatus.insert(dbevent);
		}
	}

	bool bEnablePopup = true, bEnableSound = true;
	char *szProto = GetContactProto(hContact);
	int myStatus = Proto_GetStatus(szProto);

	if (!mir_strcmp(szProto, META_PROTO)) { //this contact is Meta
		MCONTACT hSubContact = db_mc_getMostOnline(hContact);
		char *szSubProto = GetContactProto(hSubContact);
		if (szSubProto == nullptr)
			return 0;

		if (newStatus == ID_STATUS_OFFLINE) {
			// read last online proto for metacontact if exists,
			// to avoid notifying when meta went offline but default contact's proto still online
			DBVARIANT dbv;
			if (!db_get_s(hContact, szProto, "LastOnline", &dbv)) {
				szSubProto = NEWSTR_ALLOCA(dbv.pszVal);
				db_free(&dbv);
			}
		}
		else
			db_set_s(hContact, szProto, "LastOnline", szSubProto);

		if (db_get_b(0, MODULE, szSubProto, 1) == 0)
			return 0;

		szProto = szSubProto;
	}
	else {
		if (myStatus == ID_STATUS_OFFLINE || db_get_b(0, MODULE, szProto, 1) == 0)
			return 0;
	}

	if (!opt.FromOffline || oldStatus != ID_STATUS_OFFLINE) { // Either it wasn't a change from Offline or we didn't enable that.
		char buff[8];
		mir_snprintf(buff, "%d", newStatus);
		if (db_get_b(0, MODULE, buff, 1) == 0)
			return 0; // "Notify when a contact changes to one of..." is unchecked
	}

	if (SkipHiddenContact(hContact))
		return 0;

	// check if that proto from which we received statuschange notification, isn't in autodisable list
	if (opt.AutoDisable) {
		char statusIDs[12], statusIDp[12];
		mir_snprintf(statusIDs, "s%d", myStatus);
		mir_snprintf(statusIDp, "p%d", myStatus);
		bEnableSound = db_get_b(0, MODULE, statusIDs, 1) ? FALSE : TRUE;
		bEnablePopup = db_get_b(0, MODULE, statusIDp, 1) ? FALSE : TRUE;
	}

	if (bEnablePopup && db_get_b(hContact, MODULE, "EnablePopups", 1) && !opt.TempDisabled) {
		int wStatus = Proto_GetStatus(szProto);
		wchar_t str[MAX_SECONDLINE] = { 0 };
		if (opt.ShowStatus)
			GetStatusText(hContact, newStatus, oldStatus, str);

		if (opt.ReadAwayMsg && wStatus != ID_STATUS_INVISIBLE && StatusHasAwayMessage(szProto, newStatus))
			db_set_ws(hContact, MODULE, "LastPopupText", str);

		PLUGINDATA *pdp = (PLUGINDATA *)mir_calloc(sizeof(PLUGINDATA));
		pdp->oldStatus = oldStatus;
		pdp->newStatus = newStatus;
		pdp->hAwayMsgHook = nullptr;
		pdp->hAwayMsgProcess = nullptr;
		ShowChangePopup(hContact, Skin_LoadProtoIcon(szProto, newStatus), newStatus, str, pdp);
	}

	if (opt.BlinkIcon && !opt.TempDisabled) {
		HICON hIcon = opt.BlinkIcon_Status ? Skin_LoadProtoIcon(szProto, newStatus) : Skin_LoadIcon(SKINICON_OTHER_USERONLINE);
		wchar_t str[256];
		mir_snwprintf(str, TranslateT("%s is now %s"), Clist_GetContactDisplayName(hContact), StatusList[Index(newStatus)].lpzStandardText);
		BlinkIcon(hContact, hIcon, str);
	}

	if (bEnableSound && db_get_b(0, "Skin", "UseSound", TRUE) && db_get_b(hContact, MODULE, "EnableSounds", 1) && !opt.TempDisabled) {
		if (oldStatus == ID_STATUS_OFFLINE)
			PlayChangeSound(hContact, StatusListEx[ID_STATUS_FROMOFFLINE].lpzSkinSoundName);
		else
			PlayChangeSound(hContact, StatusList[Index(newStatus)].lpzSkinSoundName);
	}

	if (opt.LogToFile) {
		wchar_t stzDate[MAX_STATUSTEXT], stzTime[MAX_STATUSTEXT], stzText[MAX_TEXT_LEN];

		GetTimeFormat(LOCALE_USER_DEFAULT, 0, nullptr, L"HH':'mm", stzTime, _countof(stzTime));
		GetDateFormat(LOCALE_USER_DEFAULT, 0, nullptr, L"dd/MM/yyyy", stzDate, _countof(stzDate));
		mir_snwprintf(stzText, TranslateT("%s, %s. %s changed status to %s (was %s)\r\n"),
			stzDate, stzTime, Clist_GetContactDisplayName(hContact), StatusList[Index(newStatus)].lpzStandardText,
			StatusList[Index(oldStatus)].lpzStandardText);
		LogToFile(stzText);
	}

	return 0;
}