/* Name: NewEventNotify - Plugin for Miranda IM File: main.c - Main DLL procedures Version: 0.2.2.2 Description: Notifies you about some events Author: jokusoftware, Date: 18.07.02 13:59 / Update: 22.10.07 19:56 Copyright: (C) 2002 Starzinger Michael This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "neweventnotify.h" #include #include #include #include //needed for ICQEVENTTYPE_* (Webpager & Emailexpress) #include //needed for reply instead of read #include #include #include #include #include #include int g_IsSrmmServiceAvail = 0; int g_IsSrmmWindowAPI = 0; int g_UnicodeCore = 0; extern PLUGIN_DATA* PopUpList[20]; //--------------------------- //---Some global variables for the plugin struct MM_INTERFACE mmi; HINSTANCE hInst; PLUGIN_OPTIONS pluginOptions; PLUGINLINK *pluginLink; int hLangpack; PLUGININFOEX pluginInfo = { sizeof(PLUGININFOEX), "NewEventNotify", PLUGIN_MAKE_VERSION(0, VER_MAJOR, VER_MINOR, VER_BUILD), "Notifies you when you receive a message, url, file or any other event by displaying a popup. Uses the PopUp-Plugin by hrk. " "Original plugin was written by icebreaker, modified by Prezes and some " "bugfixes were made by vj, vlko, Nightwish, TheLeech and others. More fixes & updates by Joe @ Whale", "icebreaker, Prezes, vj, vlko, Joe @ Whale", "jokusoftware@miranda-im.org", "GNU GPL", "http://addons.miranda-im.org/details.php?action=viewfile&id=3637", 0, 0, {0x3503D584, 0x6234, 0x4BEF, {0xA5, 0x53, 0x6C, 0x1B, 0x9C, 0xD4, 0x71, 0xF2 } } // {3503D584-6234-4BEF-A553-6C1B9CD471F2} }; //--------------------------- //---Hooks //---Handles to my hooks, needed to unhook them again HANDLE hHookedInit; HANDLE hHookedOpt; HANDLE hHookedNewEvent; HANDLE hHookedDeletedEvent; //---Called when a new event is added to the database int HookedNewEvent(WPARAM wParam, LPARAM lParam) //wParam: contact-handle //lParam: dbevent-handle { HANDLE hContact = (HANDLE)wParam; DBEVENTINFO dbe = {0}; PLUGIN_DATA* pdata; DBEVENTTYPEDESCR* pei; //are popups currently enabled? if (pluginOptions.bDisable) return 0; //get DBEVENTINFO without pBlob dbe.cbSize = sizeof(dbe); CallService(MS_DB_EVENT_GET, (WPARAM)lParam, (LPARAM)&dbe); // Nightwish (no popups for RSS contacts at all...) if (pluginOptions.bNoRSS) { if (dbe.szModule != NULL) { if (!strncmp(dbe.szModule, "RSS", 3)) return 0; } } //do not show popups for sub-contacts if (hContact && ServiceExists(MS_MC_GETMETACONTACT) && CallService(MS_MC_GETMETACONTACT, (WPARAM)hContact, 0)) return 0; //is it an event info about online/offline status user if (dbe.eventType == 25368) return 0; //custom database event types if (ServiceExists(MS_DB_EVENT_GETTYPE)) { pei = (DBEVENTTYPEDESCR*)CallService(MS_DB_EVENT_GETTYPE, (WPARAM)dbe.szModule, (LPARAM)dbe.eventType); if (pei && pei->cbSize >= DBEVENTTYPEDESCR_SIZE) { // ignore events according to flags if (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) { if (pluginOptions.bHideSend && NumberPopupData(hContact, EVENTTYPE_MESSAGE) != -1) { // JK, only message event, do not influence others 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)) { // JK, only merge with message events, do not mess with others PopupUpdate(hContact, (HANDLE)lParam); } else { //now finally show a popup PopupShow(&pluginOptions, hContact, (HANDLE)lParam, (UINT)dbe.eventType); } return 0; } //---Called when all the modules are loaded int HookedInit(WPARAM wParam, LPARAM lParam) { hHookedNewEvent = HookEvent(ME_DB_EVENT_ADDED, HookedNewEvent); // Plugin sweeper support if (ServiceExists("PluginSweeper/Add")) CallService("PluginSweeper/Add", (WPARAM)MODULE, (LPARAM)MODULE); if (ServiceExists(MS_MSG_GETWINDOWDATA)) g_IsSrmmWindowAPI = 1; else g_IsSrmmWindowAPI = 0; if (ServiceExists(MS_MSG_MOD_MESSAGEDIALOGOPENED)) g_IsSrmmServiceAvail = 1; else g_IsSrmmServiceAvail = 0; return 0; } //---Called when an options dialog has to be created int HookedOptions(WPARAM wParam, LPARAM lParam) { OptionsAdd(hInst, wParam); return 0; } //--------------------------- //---Exported Functions PLUGININFOEX* handleMirandaPluginInfo(DWORD mirandaVersion) { if (mirandaVersion >= PLUGIN_MAKE_VERSION(0, 3, 3, 0)) { // Are we running under Unicode Windows version ? if ((GetVersion() & 0x80000000) == 0) { pluginInfo.flags = 1; // UNICODE_AWARE } return &pluginInfo; } else return NULL; } __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) { pluginInfo.cbSize = sizeof(PLUGININFOEX); return handleMirandaPluginInfo(mirandaVersion); } static const MUUID interfaces[] = {MIID_EVENTNOTIFY, MIID_LAST}; __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) { return interfaces; } int __declspec(dllexport) Load(PLUGINLINK *link) { pluginLink = link; hHookedInit = HookEvent(ME_SYSTEM_MODULESLOADED, HookedInit); hHookedOpt = HookEvent(ME_OPT_INITIALISE, HookedOptions); mir_getMMI(&mmi); mir_getLP(&pluginInfo); InitI18N(); { // Are we running under unicode Miranda core ? char szVer[MAX_PATH]; CallService(MS_SYSTEM_GETVERSIONTEXT, MAX_PATH, (LPARAM)szVer); _strlwr(szVer); // make sure it is lowercase g_UnicodeCore = (strstr(szVer, "unicode") != NULL); } OptionsInit(&pluginOptions); pluginOptions.hInst = hInst; if (pluginOptions.bMenuitem) MenuitemInit(!pluginOptions.bDisable); return 0; } int __declspec(dllexport) Unload(void) { UnhookEvent(hHookedNewEvent); UnhookEvent(hHookedOpt); UnhookEvent(hHookedInit); return 0; } BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { hInst=hinstDLL; return TRUE; } //------------------------------------- //---Check Window Message function // Took this snippet of code from "EventNotify" by micron-x, thx *g* // checks if the message-dialog window is already opened // return values: // 0 - No window found // 1 - Split-mode window found // 2 - Single-mode window found int CheckMsgWnd(HANDLE hContact) { if (g_IsSrmmWindowAPI) { MessageWindowData mwd; MessageWindowInputData mwid; mwid.cbSize = sizeof(MessageWindowInputData); mwid.hContact = hContact; mwid.uFlags = MSG_WINDOW_UFLAG_MSG_BOTH; mwd.cbSize = sizeof(MessageWindowData); mwd.hContact = hContact; if (!CallService(MS_MSG_GETWINDOWDATA, (WPARAM) &mwid, (LPARAM) &mwd)) { if (mwd.hwndWindow != NULL && (mwd.uState & MSG_WINDOW_STATE_EXISTS)) return 1; } } if (g_IsSrmmServiceAvail) { // use the service provided by tabSRMM if (CallService(MS_MSG_MOD_MESSAGEDIALOGOPENED, (WPARAM)hContact, 0)) return 1; else return 0; } else { // old way: find it by using the window class & title char newtitle[256]; char *szProto,*szStatus,*contactName; szProto= (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact,0); contactName= (char*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact,0); szStatus= (char*)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, szProto?DBGetContactSettingWord(hContact,szProto,"Status",ID_STATUS_OFFLINE):ID_STATUS_OFFLINE,0); // vj: This code was added by preeze and it does not work: // vlko: it maybe work with other plugins _snprintf(newtitle,sizeof(newtitle),"%s (%s)",contactName,szStatus); if(FindWindow("TMsgWindow",newtitle)) return 2; _snprintf(newtitle,sizeof(newtitle),"[%s (%s)]",contactName,szStatus); if(FindWindow("TfrmContainer",newtitle)) return 1; // vj: I have restored this code from original plugin's source: (NewEventNotify 0.0.4) _snprintf(newtitle,sizeof(newtitle),"%s (%s): %s",contactName,szStatus,Translate("Message Session")); if(FindWindow("#32770",newtitle)) // JK, this works for old SRMMs (1.0.4.x) and for mine SRMMJ return 1; _snprintf(newtitle,sizeof(newtitle),"%s (%s): %s",contactName,szStatus,Translate("Message Received")); if(FindWindow("#32770",newtitle)) return 2; return 0; } }