int HookedNewEvent(WPARAM wParam, LPARAM lParam) { HANDLE hContact = (HANDLE)wParam; PLUGIN_DATA* pdata; //are popups currently enabled? if (pluginOptions.bDisable) return 0; //get DBEVENTINFO without pBlob DBEVENTINFO dbe = { sizeof(dbe) }; db_event_get((HANDLE)lParam, &dbe); //do not show popups for sub-contacts if (hContact && ServiceExists(MS_MC_GETMETACONTACT) && CallService(MS_MC_GETMETACONTACT, (WPARAM)hContact, 0)) return 0; //custom database event types if (ServiceExists(MS_DB_EVENT_GETTYPE)) { DBEVENTTYPEDESCR *pei = (DBEVENTTYPEDESCR*)CallService(MS_DB_EVENT_GETTYPE, (WPARAM)dbe.szModule, (LPARAM)dbe.eventType); // ignore events according to flags if (pei && pei->cbSize >= DBEVENTTYPEDESCR_SIZE && pei->flags & DETF_NONOTIFY) return 0; } //if event was allready read don't show it if (pluginOptions.bReadCheck && (dbe.flags & DBEF_READ)) return 0; //is it an event sent by the user? -> don't show if (dbe.flags & DBEF_SENT) { // JK, only message event, do not influence others if (pluginOptions.bHideSend && NumberPopupData(hContact, EVENTTYPE_MESSAGE) != -1) { pdata = PopupList[NumberPopupData(hContact, EVENTTYPE_MESSAGE)]; PopupAct(pdata->hWnd, MASK_DISMISS, pdata); // JK, only dismiss, i.e. do not kill event (e.g. file transfer) } return 0; } //which status do we have, are we allowed to post popups? //UNDER CONSTRUCTION!!! CallService(MS_CLIST_GETSTATUSMODE, 0, 0); /// TODO: JK: ???? if (dbe.eventType == EVENTTYPE_MESSAGE && (pluginOptions.bMsgWindowCheck && hContact && CheckMsgWnd(hContact))) return 0; //is another popup for this contact already present? -> merge message popups if enabled if (dbe.eventType == EVENTTYPE_MESSAGE && (pluginOptions.bMergePopup && NumberPopupData(hContact, EVENTTYPE_MESSAGE) != -1)) PopupUpdate(hContact, (HANDLE)lParam); else PopupShow(&pluginOptions, hContact, (HANDLE)lParam, (UINT)dbe.eventType); return 0; }
int PopupUpdate(MCONTACT hContact, MEVENT hEvent) { // merge only message popups PLUGIN_DATA *pdata = (PLUGIN_DATA*)PopupList[NumberPopupData(hContact, EVENTTYPE_MESSAGE)]; if (hEvent) { pdata->countEvent++; pdata->lastEventData->next = (EVENT_DATA_EX *)mir_alloc(sizeof(EVENT_DATA_EX)); pdata->lastEventData->next->prev = pdata->lastEventData; pdata->lastEventData = pdata->lastEventData->next; pdata->lastEventData->hEvent = hEvent; pdata->lastEventData->number = pdata->lastEventData->prev->number + 1; pdata->lastEventData->next = NULL; if (!pdata->pluginOptions->bShowON && pdata->countEvent > pdata->pluginOptions->iNumberMsg && pdata->pluginOptions->iNumberMsg) pdata->firstShowEventData = pdata->firstShowEventData->next; //re-init timer delay KillTimer(pdata->hWnd, TIMER_TO_ACTION); SetTimer(pdata->hWnd, TIMER_TO_ACTION, pdata->iSeconds * 1000, NULL); } TCHAR lpzText[MAX_SECONDLINE*2] = _T("\0\0"); if (pdata->pluginOptions->bShowHeaders) mir_sntprintf(lpzText, TranslateT("[b]Number of new message(s): %d[/b]\n"), pdata->countEvent); int doReverse = pdata->pluginOptions->bShowON; if ((pdata->firstShowEventData != pdata->firstEventData && doReverse) || (pdata->firstShowEventData != pdata->lastEventData && !doReverse)) mir_sntprintf(lpzText, _T("%s...\n"), lpzText); //take the active event as starting one EVENT_DATA_EX *eventData = pdata->firstShowEventData; int iEvent = 0; while (true) { if (iEvent) eventData = (doReverse) ? eventData->next : eventData->prev; iEvent++; //get DBEVENTINFO with pBlob if preview is needed (when is test then is off) DBEVENTINFO dbe = {0}; dbe.cbSize = sizeof(dbe); dbe.pBlob = NULL; dbe.cbBlob = 0; if (pdata->pluginOptions->bPreview && eventData->hEvent) { dbe.cbBlob = db_event_getBlobSize(eventData->hEvent); dbe.pBlob = (PBYTE)mir_alloc(dbe.cbBlob); } if (eventData->hEvent) db_event_get(eventData->hEvent, &dbe); if (pdata->pluginOptions->bShowDate || pdata->pluginOptions->bShowTime) { TCHAR timestamp[MAX_DATASIZE]; TCHAR formatTime[MAX_DATASIZE]; if (pdata->pluginOptions->bShowDate) _tcsncpy(formatTime, _T("%Y.%m.%d"), _countof(formatTime)); else if (pdata->pluginOptions->bShowTime) mir_tstrncat(formatTime, _T(" %H:%M"), _countof(formatTime) - mir_tstrlen(formatTime)); time_t localTime = dbe.timestamp; _tcsftime(timestamp, _countof(timestamp), formatTime, localtime(&localTime)); mir_sntprintf(lpzText, _T("%s[b][i]%s[/i][/b]\n"), lpzText, timestamp); } // prepare event preview TCHAR* szEventPreview = GetEventPreview(&dbe); mir_sntprintf(lpzText, _T("%s%s"), lpzText, szEventPreview); mir_free(szEventPreview); if (dbe.pBlob) mir_free(dbe.pBlob); if (doReverse) { if ((iEvent >= pdata->pluginOptions->iNumberMsg && pdata->pluginOptions->iNumberMsg) || !eventData->next) break; } else if ((iEvent >= pdata->pluginOptions->iNumberMsg && pdata->pluginOptions->iNumberMsg) || !eventData->prev) break; mir_sntprintf(lpzText, _T("%s\n"), lpzText); } if ((doReverse && eventData->next) || (!doReverse && eventData->prev)) mir_sntprintf(lpzText, _T("%s\n..."), lpzText); PUChangeTextT(pdata->hWnd, lpzText); return 0; }
int PopupShow(PLUGIN_OPTIONS* pluginOptions, MCONTACT hContact, MEVENT hEvent, UINT eventType) { TCHAR* sampleEvent; long iSeconds; //there has to be a maximum number of popups shown at the same time if (PopupCount >= MAX_POPUPS) return 2; //check if we should report this kind of event //get the prefered icon as well //CHANGE: iSeconds is -1 because I use my timer to hide popup POPUPDATAW pudw; pudw.iSeconds = -1; switch (eventType) { case EVENTTYPE_MESSAGE: if (!(pluginOptions->maskNotify & MASK_MESSAGE)) return 1; pudw.lchIcon = Skin_LoadIcon(SKINICON_EVENT_MESSAGE); pudw.colorBack = pluginOptions->bDefaultColorMsg ? 0 : pluginOptions->colBackMsg; pudw.colorText = pluginOptions->bDefaultColorMsg ? 0 : pluginOptions->colTextMsg; iSeconds = pluginOptions->iDelayMsg; sampleEvent = TranslateT("This is a sample message event :-)"); break; case EVENTTYPE_URL: if (!(pluginOptions->maskNotify & MASK_URL)) return 1; pudw.lchIcon = Skin_LoadIcon(SKINICON_EVENT_URL); pudw.colorBack = pluginOptions->bDefaultColorUrl ? 0 : pluginOptions->colBackUrl; pudw.colorText = pluginOptions->bDefaultColorUrl ? 0 : pluginOptions->colTextUrl; iSeconds = pluginOptions->iDelayUrl; sampleEvent = TranslateT("This is a sample URL event ;-)"); break; case EVENTTYPE_FILE: if (!(pluginOptions->maskNotify & MASK_FILE)) return 1; pudw.lchIcon = Skin_LoadIcon(SKINICON_EVENT_FILE); pudw.colorBack = pluginOptions->bDefaultColorFile ? 0 : pluginOptions->colBackFile; pudw.colorText = pluginOptions->bDefaultColorFile ? 0 : pluginOptions->colTextFile; iSeconds = pluginOptions->iDelayFile; sampleEvent = TranslateT("This is a sample file event :-D"); break; default: if (!(pluginOptions->maskNotify & MASK_OTHER)) return 1; pudw.lchIcon = Skin_LoadIcon(SKINICON_OTHER_MIRANDA); pudw.colorBack = pluginOptions->bDefaultColorOthers ? 0 : pluginOptions->colBackOthers; pudw.colorText = pluginOptions->bDefaultColorOthers ? 0 : pluginOptions->colTextOthers; iSeconds = pluginOptions->iDelayOthers; sampleEvent = TranslateT("This is a sample other event ;-D"); break; } //get DBEVENTINFO with pBlob if preview is needed (when is test then is off) DBEVENTINFO dbe = { sizeof(dbe) }; if (hEvent) { if ((pluginOptions->bPreview || eventType == EVENTTYPE_ADDED || eventType == EVENTTYPE_AUTHREQUEST)) { dbe.cbBlob = db_event_getBlobSize(hEvent); dbe.pBlob = (PBYTE)mir_alloc(dbe.cbBlob); } db_event_get(hEvent, &dbe); } EVENT_DATA_EX *eventData = (EVENT_DATA_EX*)mir_alloc(sizeof(EVENT_DATA_EX)); eventData->hEvent = hEvent; eventData->number = 1; eventData->next = NULL; eventData->prev = NULL; // retrieve correct hContact for AUTH events if (dbe.pBlob && (eventType == EVENTTYPE_ADDED || eventType == EVENTTYPE_AUTHREQUEST)) hContact = DbGetAuthEventContact(&dbe); // set plugin_data ... will be usable within PopupDlgProc PLUGIN_DATA *pdata = (PLUGIN_DATA*)mir_alloc(sizeof(PLUGIN_DATA)); pdata->eventType = eventType; pdata->hContact = hContact; pdata->pluginOptions = pluginOptions; pdata->countEvent = 1; pdata->iLock = 0; pdata->iSeconds = (iSeconds > 0) ? iSeconds : pluginOptions->iDelayDefault; pdata->firstEventData = pdata->firstShowEventData = pdata->lastEventData = eventData; // finally create the popup pudw.lchContact = hContact; pudw.PluginWindowProc = PopupDlgProc; pudw.PluginData = pdata; // if hContact is NULL, && hEvent is NULL then popup is only Test if ((hContact == NULL) && (hEvent == NULL)) { _tcsncpy(pudw.lptzContactName, TranslateT("Plugin Test"), MAX_CONTACTNAME); _tcsncpy(pudw.lptzText, TranslateTS(sampleEvent), MAX_SECONDLINE); } else { // get the needed event data _tcsncpy(pudw.lptzContactName, (TCHAR*)pcli->pfnGetContactDisplayName(hContact, 0), MAX_CONTACTNAME); _tcsncpy(pudw.lptzText, ptrT(GetEventPreview(&dbe)), MAX_SECONDLINE); } PopupCount++; PopupList[NumberPopupData(NULL, -1)] = pdata; // send data to popup plugin if (ServiceExists(MS_POPUP_ADDPOPUPT)) { // popup creation failed, release popupdata if (PUAddPopupW(&pudw) < 0) { FreePopupEventData(pdata); mir_free(pdata); } } if (dbe.pBlob) mir_free(dbe.pBlob); return 0; }