diff options
-rw-r--r-- | message_notify/MessageNotify.mdsp | 10 | ||||
-rw-r--r-- | message_notify/common.h | 2 | ||||
-rw-r--r-- | message_notify/m_speak.h | 278 | ||||
-rw-r--r-- | message_notify/messagenotify.cpp | 126 | ||||
-rw-r--r-- | message_notify/messagenotify.vcproj | 10 | ||||
-rw-r--r-- | message_notify/mywindowlist.cpp | 149 | ||||
-rw-r--r-- | message_notify/options.cpp | 37 | ||||
-rw-r--r-- | message_notify/options.h | 5 | ||||
-rw-r--r-- | message_notify/resource.h | 5 | ||||
-rw-r--r-- | message_notify/resource.rc | 19 |
10 files changed, 449 insertions, 192 deletions
diff --git a/message_notify/MessageNotify.mdsp b/message_notify/MessageNotify.mdsp index dc766df..c843cd4 100644 --- a/message_notify/MessageNotify.mdsp +++ b/message_notify/MessageNotify.mdsp @@ -96,9 +96,9 @@ extraResourceOptions= [Other]
1=..\..\include\m_database.h
[History]
-popups.cpp,6329
-mywindowlist.cpp,0
-options.cpp,5097
-common.h,643
..\..\include\m_database.h,16842
-messagenotify.cpp,627
+common.h,643
+options.cpp,5097
+mywindowlist.cpp,0
+popups.cpp,6329
+messagenotify.cpp,9468
diff --git a/message_notify/common.h b/message_notify/common.h index d21adf4..a446c6c 100644 --- a/message_notify/common.h +++ b/message_notify/common.h @@ -35,8 +35,6 @@ extern PLUGINLINK *pluginLink; extern HANDLE mainThread;
-extern HANDLE popupWindowList;
-
void StartFocusTimer();
void StopFocusTimer();
diff --git a/message_notify/m_speak.h b/message_notify/m_speak.h new file mode 100644 index 0000000..cd05737 --- /dev/null +++ b/message_notify/m_speak.h @@ -0,0 +1,278 @@ +/*
+Copyright (C) 2007 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef __M_SPEAK_H__
+# define __M_SPEAK_H__
+
+
+/*
+There is 2 ways of using the speak plugin:
+
+1. Older and simple way: just call
+ Speak_Say(hContact, _T("text to speak"))
+and the text will be spoken using contact settings. If hContact is NULL, it will use
+system settings.
+Previous versions only had an ascii version, so if you want to support then you need
+to call
+ Speak_SayA(hContact, "text to speak")
+
+
+2. Integrating with eSpeak GUI: for that you have first to register a speak type and
+then call the speak functions. In both case you have 2 options:
+
+2.1 Sending the full text: eSpeak GUI will only allow to enable/disable the type.
+To register call (in modules loaded):
+ Speak_Register("PluginName (DB key)", "name", "Prety name for GUI", "icon_xyz")
+And to speak call:
+ Speak_SayEx("name", hContact, _T("text to speak"))
+
+2.2 Using templates: you will not pass the text, but some variables. eSpeak handles
+the GUI to allow the user to create the text for those variables. These functions
+end with WT (with templates).
+To register call (in modules loaded):
+ char *templates[] = { "Name\nDefault\n%var1%\tDescription 1\n%var2%\tDescription2\n%var3%\tDescription 3" };
+ Speak_RegisterWT("PluginName (DB key)", "name", "Prety name for GUI", "icon_xyz",
+ templates, 1);
+And to speak call:
+ TCHAR *variables[] = { _T("var1"), _T("Value 1"), _T("var2"), _T("Value 2"), _T("var3"), _T("Value 3") };
+ Speak_SayExWT("name", hContact, 0, variables, 3);
+*/
+
+
+#define MIID_SPEAK { 0x1ef72725, 0x6a83, 0x483b, { 0xaa, 0x50, 0x89, 0x53, 0xe3, 0x59, 0xee, 0xad } }
+
+
+/*
+Speak a text
+
+wParam: (HANDLE) hContact
+lParam: (char *) text
+return: 0 on success
+*/
+#define MS_SPEAK_SAY_A "Speak/Say"
+
+
+/*
+Speak a unicode text
+
+wParam: (HANDLE) hContact
+lParam: (WCHAR *) text
+return: 0 on success
+*/
+#define MS_SPEAK_SAY_W "Speak/SayW"
+
+
+typedef struct {
+ int cbSize;
+
+ const char *module;
+ const char *name; // Internal type name
+ const char *description; // Will be translated
+ const char *icon; // Name off icolib icon
+
+ // Aditional data if wants to use add to history services
+ char **templates; // Each entry is: "Name\nDefault\n%var%\tDescription\n%var%\tDescription\n%var%\tDescription"
+ int numTemplates;
+
+} SPEAK_TYPE;
+
+
+/*
+Register and speak type
+
+wParam: (SPEAK_TYPE *) type
+lParam: 0
+return: 0 on success
+*/
+#define MS_SPEAK_REGISTER "Speak/Register"
+
+
+#define SPEAK_CHAR 1
+#define SPEAK_WCHAR 2
+
+typedef struct {
+ int cbSize;
+
+ const char *type; // Internal type name
+ HANDLE hContact;
+ int flags; // SPEAK_*
+
+ int templateNum; // -1 to use text
+ union
+ {
+ const void *text;
+
+ struct
+ {
+ void *variables;
+ int numVariables;
+ };
+ };
+
+} SPEAK_ITEM;
+
+
+/*
+Speak a text
+
+wParam: (SPEAK_ITEM *) Item
+lParam: 0
+return: 0 on success
+*/
+#define MS_SPEAK_SAYEX "Speak/SayEx"
+
+
+
+// Helper functions
+
+static int Speak_SayA(HANDLE hContact, const char *text)
+{
+ return CallService(MS_SPEAK_SAY_A, (WPARAM) hContact, (LPARAM) text);
+}
+
+static int Speak_SayW(HANDLE hContact, const WCHAR *text)
+{
+ return CallService(MS_SPEAK_SAY_W, (WPARAM) hContact, (LPARAM) text);
+}
+
+static int Speak_Register(char *module, char *name, char *description, char *icon)
+{
+ SPEAK_TYPE type;
+
+ if (!ServiceExists(MS_SPEAK_REGISTER))
+ return -1;
+
+ type.cbSize = sizeof(type);
+ type.module = module;
+ type.name = name;
+ type.description = description;
+ type.icon = icon;
+ type.templates = NULL;
+ type.numTemplates = 0;
+
+ return CallService(MS_SPEAK_REGISTER, (WPARAM) &type, 0);
+}
+
+static int Speak_RegisterWT(const char *module, const char *name, const char *description,
+ const char *icon, char **templates, int numTemplates)
+{
+ SPEAK_TYPE type;
+
+ if (!ServiceExists(MS_SPEAK_REGISTER))
+ return -1;
+
+ type.cbSize = sizeof(type);
+ type.module = module;
+ type.name = name;
+ type.description = description;
+ type.icon = icon;
+ type.templates = templates;
+ type.numTemplates = numTemplates;
+
+ return CallService(MS_SPEAK_REGISTER, (WPARAM) &type, 0);
+}
+
+static int Speak_SayExA(char *type, HANDLE hContact, const char *text)
+{
+ SPEAK_ITEM item;
+
+ if (!ServiceExists(MS_SPEAK_SAYEX))
+ // Try old service
+ return Speak_SayA(hContact, text);
+
+ item.cbSize = sizeof(item);
+ item.flags = SPEAK_CHAR;
+ item.type = type;
+ item.hContact = hContact;
+ item.templateNum = -1;
+ item.text = text;
+
+ return CallService(MS_SPEAK_SAYEX, (WPARAM) &item, 0);
+}
+
+static int Speak_SayExW(char *type, HANDLE hContact, const WCHAR *text)
+{
+ SPEAK_ITEM item;
+
+ if (!ServiceExists(MS_SPEAK_SAYEX))
+ // Try old service
+ return Speak_SayW(hContact, text);
+
+ item.cbSize = sizeof(item);
+ item.flags = SPEAK_WCHAR;
+ item.type = type;
+ item.hContact = hContact;
+ item.templateNum = -1;
+ item.text = text;
+
+ return CallService(MS_SPEAK_SAYEX, (WPARAM) &item, 0);
+}
+
+static int Speak_SayExWTA(char *type, HANDLE hContact, int templateNum, char **variables, int numVariables)
+{
+ SPEAK_ITEM item;
+
+ if (!ServiceExists(MS_SPEAK_SAYEX))
+ return -1;
+
+ item.cbSize = sizeof(item);
+ item.flags = SPEAK_CHAR;
+ item.type = type;
+ item.hContact = hContact;
+ item.templateNum = templateNum;
+ item.variables = variables;
+ item.numVariables = numVariables;
+
+ return CallService(MS_SPEAK_SAYEX, (WPARAM) &item, 0);
+}
+
+static int Speak_SayExWTW(char *type, HANDLE hContact, int templateNum, WCHAR **variables, int numVariables)
+{
+ SPEAK_ITEM item;
+
+ if (!ServiceExists(MS_SPEAK_SAYEX))
+ return -1;
+
+ item.cbSize = sizeof(item);
+ item.flags = SPEAK_WCHAR;
+ item.type = type;
+ item.hContact = hContact;
+ item.templateNum = templateNum;
+ item.variables = variables;
+ item.numVariables = numVariables;
+
+ return CallService(MS_SPEAK_SAYEX, (WPARAM) &item, 0);
+}
+
+
+#ifdef UNICODE
+# define MS_SPEAK_SAY MS_SPEAK_SAY_W
+# define Speak_Say Speak_SayW
+# define Speak_SayEx Speak_SayExW
+# define Speak_SayExWT Speak_SayExWTW
+#else
+# define MS_SPEAK_SAY MS_SPEAK_SAY_A
+# define Speak_Say Speak_SayA
+# define Speak_SayEx Speak_SayExA
+# define Speak_SayExWT Speak_SayExWTA
+#endif
+
+
+#endif // __M_SPEAK_H__
diff --git a/message_notify/messagenotify.cpp b/message_notify/messagenotify.cpp index 7cde52e..03d88a4 100644 --- a/message_notify/messagenotify.cpp +++ b/message_notify/messagenotify.cpp @@ -9,6 +9,11 @@ #include "popups.h"
#include <time.h>
+#include "collection.h"
+#include "m_speak.h"
+
+Map<HANDLE, HWND> open_msg_windows;
+
HINSTANCE hInst;
PLUGINLINK *pluginLink;
@@ -20,14 +25,12 @@ bool thread_api = false; int code_page = CP_ACP;
-HANDLE popupWindowList;
-
DWORD focusTimerId = 0;
PLUGININFOEX pluginInfo={
sizeof(PLUGININFOEX),
"Message Notify",
- PLUGIN_MAKE_VERSION(0,3,1,0),
+ PLUGIN_MAKE_VERSION(0, 4, 0, 0),
"Show a popup when a message is received",
"Scott Ellis",
"mail@scottellis.com.au",
@@ -89,9 +92,11 @@ bool window_focussed(HWND hwnd, HANDLE hContact) { mwd.cbSize = sizeof(mwd);
if(!CallService(MS_MSG_GETWINDOWDATA, (WPARAM)&mwid, (LPARAM)&mwd)) {
- if((mwd.uState & MSG_WINDOW_STATE_VISIBLE) != 0) {
+ //if((mwd.uState & MSG_WINDOW_STATE_VISIBLE) != 0) {
+ // return true;
+ //}
+ if(IsWindowVisible(mwd.hwndWindow))
return true;
- }
} else
return true;
@@ -105,6 +110,7 @@ bool window_focussed(HWND hwnd, HANDLE hContact) { void __stdcall FocusTimerProc(struct HWND__ *,unsigned int,unsigned int,unsigned long) {
if(options.notify_when != NOTIFY_NFORE) return;
+ /*
HANDLE hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
while (hContact) {
HWND hwnd;
@@ -116,6 +122,14 @@ void __stdcall FocusTimerProc(struct HWND__ *,unsigned int,unsigned int,unsigned }
hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0);
}
+ */
+ for(Map<HANDLE, HWND>::Iterator i = open_msg_windows.start(); i.has_val(); i.next()) {
+ if(!EmptyList(i.val().first)) {
+ if(window_focussed(i.val().second, i.val().first))
+ PostMessageWindowList(WMU_CLOSEPOPUP, (WPARAM)i.val().first, 0); // close popups
+ }
+ }
+
}
void StartFocusTimer() {
@@ -176,7 +190,7 @@ unsigned int __stdcall sttCheckWindowProc( VOID *dwParam ) { //if(debug) PUShowMessage("start of notify thread", SM_NOTIFY);
- HWND hwnd = (HWND)DBGetContactSettingDword(cd->hContact, MODULE, "WindowHandle", 0);
+ HWND hwnd = open_msg_windows[cd->hContact];//(HWND)DBGetContactSettingDword(cd->hContact, MODULE, "WindowHandle", 0);
bool window_open = (hwnd != 0);
bool window_has_focus = window_open && window_focussed(hwnd, cd->hContact);
@@ -184,6 +198,7 @@ unsigned int __stdcall sttCheckWindowProc( VOID *dwParam ) { || (options.notify_when == NOTIFY_NFORE && !window_has_focus)
|| (options.notify_when == NOTIFY_CLOSED && !window_open))
{
+ // show a popup
if(IsUnicodePopupsEnabled()) {
//if(debug) PUShowMessage("showing popup (unicode)", SM_NOTIFY);
// get contact display name from clist
@@ -200,12 +215,13 @@ unsigned int __stdcall sttCheckWindowProc( VOID *dwParam ) { }
}
- if(cd->blobsize) {
+ if(cd->blobsize && options.show_msg) {
// does blob contain unicode message?
int msglen = strlen((char *)cd->blob) + 1;
if(msglen != cd->blobsize && wcslen((wchar_t *)(&cd->blob[msglen]))) {
// yes
- ShowPopupW(cd->hContact, swzContactDisplayName, (wchar_t *)(&cd->blob[msglen]));
+ if(options.flags & MNNF_POPUP) ShowPopupW(cd->hContact, swzContactDisplayName, options.show_msg ? (wchar_t *)(&cd->blob[msglen]) : 0);
+ if(options.flags & MNNF_SPEAK) Speak_SayExW("messages", cd->hContact, (wchar_t *)(&cd->blob[msglen]));
} else {
// no, convert to unciode
wchar_t msg[MAX_SECONDLINE];
@@ -213,23 +229,30 @@ unsigned int __stdcall sttCheckWindowProc( VOID *dwParam ) { MultiByteToWideChar(CP_UTF8, 0, (char *) cd->blob, -1, msg, MAX_SECONDLINE);
else
MultiByteToWideChar(code_page, 0, (char *) cd->blob, -1, msg, MAX_SECONDLINE);
- ShowPopupW(cd->hContact, swzContactDisplayName, msg);
+ if(options.flags & MNNF_POPUP) {
+ if(options.show_msg) {
+ ShowPopupW(cd->hContact, swzContactDisplayName, msg);
+ } else
+ ShowPopupW(cd->hContact, swzContactDisplayName, 0);
+ }
+ if(options.flags & MNNF_SPEAK) Speak_SayExW("messages", cd->hContact, msg);
}
} else {
// no message
- ShowPopupW(cd->hContact, swzContactDisplayName, 0);
+ if(options.flags & MNNF_POPUP) ShowPopupW(cd->hContact, swzContactDisplayName, 0);
+ if(options.flags & MNNF_SPEAK) Speak_SayExW("messages", cd->hContact, L"empty message");
}
} else {
//if(debug) PUShowMessage("showing popup (ansi)", SM_NOTIFY);
char *szCDN = (char *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)cd->hContact, 0);
if(szCDN && szCDN[0]) {
if(cd->blobsize) {
- char msg[MAX_SECONDLINE];
- strncpy(msg, (char *)cd->blob, MAX_SECONDLINE - 1);
- msg[MAX_SECONDLINE - 1] = 0;
- ShowPopup(cd->hContact, szCDN, (char *)msg);
- } else
- ShowPopup(cd->hContact, szCDN, 0);
+ if((options.flags & MNNF_POPUP) && options.show_msg) ShowPopup(cd->hContact, szCDN, (char *)cd->blob);
+ if(options.flags & MNNF_SPEAK) Speak_SayExA("messages", cd->hContact, (char *)cd->blob);
+ } else {
+ if(options.flags & MNNF_POPUP) ShowPopup(cd->hContact, szCDN, 0);
+ if(options.flags & MNNF_SPEAK) Speak_SayExA("messages", cd->hContact, "empty message");
+ }
}
}
} else {
@@ -249,6 +272,12 @@ int OnDatabaseEventAdded(WPARAM wParam, LPARAM lParam) { //bool debug = (DBGetContactSettingByte(0, MODULE, "Debug", 0) != 0);
// safety checks
+ int status = CallService(MS_CLIST_GETSTATUSMODE, 0, 0);
+ if(status >= ID_STATUS_ONLINE && status <= ID_STATUS_OUTTOLUNCH && options.disable_status[status - ID_STATUS_ONLINE]) {
+ //if(debug) PUShowMessage("ignoring event (disabled for this status)", SM_NOTIFY);
+ return 0;
+ }
+
// messages from this contact ignored
if(CallService(MS_IGNORE_ISIGNORED, (WPARAM)hContact, (LPARAM)IGNOREEVENT_MESSAGE)) {
//if(debug) PUShowMessage("ignoring event (contact ignored)", SM_NOTIFY);
@@ -265,43 +294,32 @@ int OnDatabaseEventAdded(WPARAM wParam, LPARAM lParam) { DBEVENTINFO dbei = {0};
dbei.cbSize = sizeof(dbei);
- if((dbei.cbBlob = (DWORD)CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hDbEvent, 0)) == (DWORD)-1)
- //if(debug) PUShowMessage("invalid event", SM_NOTIFY);
- return 0;
+ if(options.show_msg || (options.flags & MNNF_SPEAK)) {
+ if((dbei.cbBlob = (DWORD)CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hDbEvent, 0)) == (DWORD)-1) {
+ //if(debug) PUShowMessage("invalid event", SM_NOTIFY);
+ return 0;
+ }
+ if(dbei.cbBlob > 0) dbei.pBlob = new BYTE[dbei.cbBlob];
+ } else
+ dbei.cbBlob = 0;
- if(dbei.cbBlob > 0) dbei.pBlob = new BYTE[dbei.cbBlob];
if(CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&dbei)) {
//if(debug) PUShowMessage("get event failed", SM_NOTIFY);
+ if(dbei.pBlob) delete[] dbei.pBlob;
return 0;
}
if ((dbei.flags & DBEF_SENT) || (dbei.eventType != EVENTTYPE_MESSAGE) || (dbei.flags & DBEF_READ)) {
//if(debug) PUShowMessage("ignoring event (read, sent, or type != message)", SM_NOTIFY);
+ if(dbei.pBlob) delete[] dbei.pBlob;
return 0;
}
- int status = CallService(MS_CLIST_GETSTATUSMODE, 0, 0);
- if(status >= ID_STATUS_ONLINE && status <= ID_STATUS_OUTTOLUNCH && options.disable_status[status - ID_STATUS_ONLINE]) {
- //if(debug) PUShowMessage("ignoring event (disabled for this status)", SM_NOTIFY);
- return 0;
- }
-
- if(dbei.cbBlob == 0 || dbei.pBlob == 0) {
- //if(debug) PUShowMessage("ignoring event (no text)", SM_NOTIFY);
- return 0; // just to be safe
- }
-
CheckWindowData *cd = new CheckWindowData;
cd->hContact = hContact;
- if(options.show_msg) {
- // send blob data
- cd->blobsize = dbei.cbBlob;
- cd->blob = dbei.pBlob;
- cd->flags = dbei.flags;
- } else {
- cd->blobsize = 0;
- delete dbei.pBlob;
- }
+ cd->blobsize = dbei.cbBlob;
+ cd->flags = dbei.flags;
+ cd->blob = dbei.pBlob;
// spawn a thread to deal with the data
if(thread_api) {
@@ -321,19 +339,33 @@ int OnDatabaseEventAdded(WPARAM wParam, LPARAM lParam) { return 0;
}
+/*
+void __cdecl windowData(void *param) {
+ Sleep(500);
+
+ HWND hWnd = (HWND)param;
+ char msg[512];
+ mir_snprintf(msg, 512, "window: %x, parent: %x, foreground: %x", hWnd, GetParent(hWnd), GetForegroundWindow());
+ PUShowMessage(msg, SM_NOTIFY);
+}
+*/
+
int OnWindowEvent(WPARAM wParam, LPARAM lParam) {
MessageWindowEventData *mwed = (MessageWindowEventData *)lParam;
switch(mwed->uType) {
- case MSG_WINDOW_EVT_OPENING:
+ //case MSG_WINDOW_EVT_OPENING:
case MSG_WINDOW_EVT_OPEN:
- DBWriteContactSettingDword(mwed->hContact, MODULE, "WindowHandle", (DWORD)mwed->hwndWindow);
+ //DBWriteContactSettingDword(mwed->hContact, MODULE, "WindowHandle", (DWORD)mwed->hwndWindow);
+ open_msg_windows[mwed->hContact] = mwed->hwndWindow;
if(options.notify_when == NOTIFY_CLOSED)
PostMessageWindowList(WMU_CLOSEPOPUP, (WPARAM)mwed->hContact, 0);
+ //mir_forkthread(windowData, (void *)mwed->hwndWindow);
break;
- case MSG_WINDOW_EVT_CLOSING:
+ //case MSG_WINDOW_EVT_CLOSING:
case MSG_WINDOW_EVT_CLOSE:
- DBWriteContactSettingDword(mwed->hContact, MODULE, "WindowHandle", 0);
+ //DBWriteContactSettingDword(mwed->hContact, MODULE, "WindowHandle", 0);
+ open_msg_windows.remove(mwed->hContact);
break;
default:
//ShowWarning("Window custom");
@@ -368,9 +400,11 @@ int OnModulesLoaded(WPARAM wParam, LPARAM lParam) { CallService(MS_UPDATE_REGISTER, 0, (WPARAM)&update);
}
+ // register with speak plugin (see m_speak.h)
+ Speak_Register(MODULE, "messages", "Messages", "core_main_1");
+
metacontacts_installed = (ServiceExists(MS_MC_GETMETACONTACT) != 0);
- hEventDbEventAdded = HookEvent(ME_DB_EVENT_ADDED, OnDatabaseEventAdded);
hIdle = HookEvent(ME_IDLE_CHANGED, OnIdleChanged);
hWindowEvent = HookEvent(ME_MSG_WINDOWEVENT, OnWindowEvent);
@@ -426,7 +460,7 @@ extern "C" int __declspec(dllexport) Load(PLUGINLINK *link) HookEvent(ME_SYSTEM_PRESHUTDOWN, OnPreShutdown);
HookEvent(ME_OPT_INITIALISE, OptInit);
- popupWindowList = (HANDLE)CallService(MS_UTILS_ALLOCWINDOWLIST, 0, 0);
+ hEventDbEventAdded = HookEvent(ME_DB_EVENT_ADDED, OnDatabaseEventAdded); // hooked early so SRMM can't mark it read too soon
return 0;
}
diff --git a/message_notify/messagenotify.vcproj b/message_notify/messagenotify.vcproj index dcd6151..f8b4855 100644 --- a/message_notify/messagenotify.vcproj +++ b/message_notify/messagenotify.vcproj @@ -78,7 +78,6 @@ <Tool
Name="VCLinkerTool"
AdditionalDependencies="unicows.lib user32.lib comctl32.lib"
- OutputFile="../../bin/debug/plugins/messagenotify.dll"
LinkIncremental="2"
SuppressStartupBanner="true"
IgnoreDefaultLibraryNames="Kernel32.lib Advapi32.lib User32.lib Gdi32.lib Shell32.lib Comdlg32.lib Version.lib Mpr.lib Rasapi32.lib Winmm.lib Winspool.lib Vfw32.lib Secur32.lib Oleacc.lib Oledlg.lib Sensapi.lib"
@@ -177,7 +176,6 @@ <Tool
Name="VCLinkerTool"
AdditionalDependencies="unicows.lib user32.lib comctl32.lib"
- OutputFile="../../bin/release/plugins/messagenotify.dll"
LinkIncremental="1"
SuppressStartupBanner="true"
IgnoreDefaultLibraryNames="Kernel32.lib Advapi32.lib User32.lib Gdi32.lib Shell32.lib Comdlg32.lib Version.lib Mpr.lib Rasapi32.lib Winmm.lib Winspool.lib Vfw32.lib Secur32.lib Oleacc.lib Oledlg.lib Sensapi.lib"
@@ -318,10 +316,18 @@ Filter="h;hpp;hxx;hm;inl"
>
<File
+ RelativePath=".\collection.h"
+ >
+ </File>
+ <File
RelativePath="common.h"
>
</File>
<File
+ RelativePath=".\m_speak.h"
+ >
+ </File>
+ <File
RelativePath="mywindowlist.h"
>
</File>
diff --git a/message_notify/mywindowlist.cpp b/message_notify/mywindowlist.cpp index 72a82e7..873d579 100644 --- a/message_notify/mywindowlist.cpp +++ b/message_notify/mywindowlist.cpp @@ -1,146 +1,43 @@ #include "common.h"
#include "mywindowlist.h"
+#include "collection.h"
-class WindowList {
+class WindowList: public LinkedList<HWND> {
public:
- struct ListNode {
- HWND hwnd;
- ListNode *next;
- };
-
- WindowList(): head(0), count(0) {}
- ~WindowList() {clear();}
-
- void clear() {
- ListNode *n;
- while(head) {
- n = head;
- head = head->next;
- delete n;
- }
- }
-
- void AddWindow(HWND hwnd) {
- if(HasWindow(hwnd)) return;
-
- ListNode *n = new ListNode;
- n->hwnd = hwnd;
- n->next = head;
- head = n;
- count++;
- }
-
- void RemoveWindow(HWND hwnd) {
- ListNode *n = head, *prev = 0;
- while(n) {
- if(n->hwnd == hwnd) {
- if(prev) prev->next = n->next;
- else head = n->next;
- delete n;
- count--;
- break;
- }
- prev = n;
- n = n->next;
- }
- }
+ WindowList(): LinkedList<HWND>() {}
+ virtual ~WindowList() {}
void PostListMessage(UINT msg, WPARAM wParam, LPARAM lParam) {
- ListNode *n = head;
- while(n) {
- PostMessage(n->hwnd, msg, wParam, lParam);
- n = n->next;
- }
- }
-
- bool HasWindow(HWND hwnd) {
- ListNode *n = head;
+ ListNode<HWND> *n = head;
while(n) {
- if(n->hwnd == hwnd)
- return true;
+ PostMessage(n->val, msg, wParam, lParam);
n = n->next;
}
- return false;
- }
-
- int GetCount() {
- return count;
}
-
-protected:
- ListNode *head;
- int count;
};
-class WindowMap {
+class WindowMap: public Map<HANDLE, WindowList> {
public:
- struct ListNode {
- HANDLE hContact;
- WindowList list;
- ListNode *next;
- };
-
- WindowMap(): head(0) {}
- ~WindowMap() {clear();}
-
- void clear() {
- ListNode *n = head;
- while(head) {
- n = head;
- head = head->next;
- delete n;
- }
- }
-
- WindowList *FindList(HANDLE hContact) {
- ListNode *n = head;
- while(n) {
- if(n->hContact == hContact)
- return &n->list;
- n = n->next;
- }
- return 0;
- }
+ WindowMap(): Map<HANDLE, WindowList>() {}
+ virtual ~WindowMap() {}
void Add(HANDLE hContact, HWND hWnd) {
- WindowList *l = FindList(hContact);
- if(l) l->AddWindow(hWnd);
- else {
- ListNode *n = new ListNode;
- n->hContact = hContact;
- n->list.AddWindow(hWnd);
- n->next = head;
- head = n;
- }
+ (*this)[hContact].add(hWnd);
}
void Remove(HANDLE hContact, HWND hWnd) {
- ListNode *n = head, *prev = 0;
- while(n) {
- if(n->hContact == hContact) {
- n->list.RemoveWindow(hWnd);
- if(n->list.GetCount() == 0) {
- if(prev) prev->next = n->next;
- else head = n->next;
- delete n;
- }
- break;
- }
- prev = n;
- n = n->next;
+ if(contains(hContact)) {
+ (*this)[hContact].remove(hWnd);
+ if((*this)[hContact].size() == 0)
+ remove(hContact);
}
}
void PostMapMessage(UINT msg, WPARAM wParam, LPARAM lParam) {
- ListNode *n = head;
- while(n) {
- n->list.PostListMessage(msg, wParam, lParam);
- n = n->next;
- }
+ for(Iterator i = start(); i.has_val();i.next())
+ i.val().second.PostListMessage(msg, wParam, lParam);
}
-protected:
- ListNode *head;
};
WindowMap window_map;
@@ -174,8 +71,8 @@ void PostMessageWindowList(UINT msg, WPARAM wParam, LPARAM lParam) { void PostMessageWindowListContact(HANDLE hContact, UINT msg, WPARAM wParam, LPARAM lParam) {
EnterCriticalSection(&list_cs);
- WindowList *l = window_map.FindList(hContact);
- if(l) l->PostListMessage(msg, wParam, lParam);
+ if(window_map.contains(hContact))
+ window_map[hContact].PostListMessage(msg, wParam, lParam);
LeaveCriticalSection(&list_cs);
}
@@ -184,8 +81,8 @@ bool InList(HANDLE hContact, HWND hWnd) { bool ret = false;
EnterCriticalSection(&list_cs);
- WindowList *l = window_map.FindList(hContact);
- if(l) ret = l->HasWindow(hWnd);
+ if(window_map.contains(hContact) && window_map[hContact].contains(hWnd))
+ ret = true;
LeaveCriticalSection(&list_cs);
return ret;
@@ -195,8 +92,8 @@ int CountList(HANDLE hContact) { int count = 0;
EnterCriticalSection(&list_cs);
- WindowList *l = window_map.FindList(hContact);
- if(l) count = l->GetCount();
+ if(window_map.contains(hContact))
+ count = window_map[hContact].size();
LeaveCriticalSection(&list_cs);
return count;
@@ -205,7 +102,7 @@ int CountList(HANDLE hContact) { bool EmptyList(HANDLE hContact) {
EnterCriticalSection(&list_cs);
- bool ret = (window_map.FindList(hContact) == 0);
+ bool ret = !window_map.contains(hContact);
LeaveCriticalSection(&list_cs);
return ret;
diff --git a/message_notify/options.cpp b/message_notify/options.cpp index c2f42b7..cb2058c 100644 --- a/message_notify/options.cpp +++ b/message_notify/options.cpp @@ -66,8 +66,23 @@ static BOOL CALLBACK DlgProcOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM l break;
};
}
- CheckDlgButton(hwndDlg, IDC_CHK_CLOSE, options.close_win ? TRUE : FALSE);
- CheckDlgButton(hwndDlg, IDC_CHK_MSG, options.show_msg ? TRUE : FALSE);
+
+ {
+ CheckDlgButton(hwndDlg, IDC_CHK_CLOSE, options.close_win ? TRUE : FALSE);
+ CheckDlgButton(hwndDlg, IDC_CHK_MSG, options.show_msg ? TRUE : FALSE);
+
+ CheckDlgButton(hwndDlg, IDC_CHK_SPEECH, (options.flags & MNNF_SPEAK));
+ if(options.flags & MNNF_POPUP) {
+ CheckDlgButton(hwndDlg, IDC_CHK_POPUPS, TRUE);
+ HWND hwnd = GetDlgItem(hwndDlg, IDC_CHK_CLOSE);
+ EnableWindow(hwndDlg, FALSE);
+ hwnd = GetDlgItem(hwndDlg, IDC_CHK_MSG);
+ EnableWindow(hwndDlg, FALSE);
+ } else {
+ CheckDlgButton(hwndDlg, IDC_CHK_POPUPS, FALSE);
+ }
+ }
+
return FALSE;
case WM_COMMAND:
@@ -93,6 +108,16 @@ static BOOL CALLBACK DlgProcOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM l case IDC_CHK_TABS:
SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 );
return TRUE;
+ case IDC_CHK_POPUPS:
+ {
+ bool checked = IsDlgButtonChecked(hwndDlg, IDC_CHK_POPUPS) ? true : false;
+ HWND hwnd = GetDlgItem(hwndDlg, IDC_CHK_CLOSE);
+ EnableWindow(hwndDlg, checked ? TRUE : FALSE);
+ hwnd = GetDlgItem(hwndDlg, IDC_CHK_MSG);
+ EnableWindow(hwndDlg, checked ? TRUE : FALSE);
+ }
+ SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 );
+ return TRUE;
}
}
break;
@@ -124,6 +149,11 @@ static BOOL CALLBACK DlgProcOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM l for(int i = 0; i < 9; i++)
options.disable_status[i] = (ListView_GetCheckState(GetDlgItem(hwndDlg, IDC_LST_STATUS), i) ? true : false);
+
+ options.flags = 0;
+ options.flags |= (IsDlgButtonChecked(hwndDlg, IDC_CHK_POPUPS) ? MNNF_POPUP : 0);
+ options.flags |= (IsDlgButtonChecked(hwndDlg, IDC_CHK_SPEECH) ? MNNF_SPEAK : 0);
+
SaveOptions();
if(options.notify_when == NOTIFY_NFORE)
@@ -172,6 +202,8 @@ void LoadOptions() { sprintf(buff, "DisableStatus%d", i);
options.disable_status[i] = (DBGetContactSettingByte(0, MODULE, buff, 0) == 1);
}
+
+ options.flags = (int)DBGetContactSettingDword(0, MODULE, "Flags", MNNF_POPUP);
}
void SaveOptions() {
@@ -184,6 +216,7 @@ void SaveOptions() { sprintf(buff, "DisableStatus%d", i);
DBWriteContactSettingByte(0, MODULE, buff, options.disable_status[i] ? 1 : 0);
}
+ DBWriteContactSettingDword(0, MODULE, "Flags", (DWORD)options.flags);
}
diff --git a/message_notify/options.h b/message_notify/options.h index 282f49f..a98e90d 100644 --- a/message_notify/options.h +++ b/message_notify/options.h @@ -16,12 +16,17 @@ #define ID_STATUS_ONTHEPHONE 40079
#define ID_STATUS_OUTTOLUNCH 40080
*/
+
+#define MNNF_POPUP 1
+#define MNNF_SPEAK 2
+
typedef struct Options_tag {
int notify_when;
bool consider_tabs;
bool close_win;
bool disable_status[9];
bool show_msg;
+ int flags;
} Options;
extern Options options;
diff --git a/message_notify/resource.h b/message_notify/resource.h index a20fa09..83486fc 100644 --- a/message_notify/resource.h +++ b/message_notify/resource.h @@ -18,6 +18,9 @@ #define IDC_CHK_MSG 1011
#define IDC_LIST1 1012
#define IDC_LST_STATUS 1012
+#define IDC_CHK_POPUPS 1013
+#define IDC_CHK_SPEACH 1014
+#define IDC_CHK_SPEECH 1014
// Next default values for new objects
//
@@ -25,7 +28,7 @@ #ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
-#define _APS_NEXT_CONTROL_VALUE 1013
+#define _APS_NEXT_CONTROL_VALUE 1014
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
diff --git a/message_notify/resource.rc b/message_notify/resource.rc index 89c59da..1bfc075 100644 --- a/message_notify/resource.rc +++ b/message_notify/resource.rc @@ -52,20 +52,23 @@ END // Dialog
//
-IDD_OPTIONS DIALOGEX 0, 0, 269, 110
+IDD_OPTIONS DIALOGEX 0, 0, 269, 181
STYLE DS_SETFONT | WS_CHILD
FONT 8, "MS Sans Serif", 0, 0, 0x0
BEGIN
GROUPBOX "Notification Options",IDC_STATIC,7,7,142,95
- CONTROL "Notify if window not open",IDC_RAD_CLOSED,"Button",BS_AUTORADIOBUTTON | WS_GROUP,13,20,132,10
+ CONTROL "Notify if window not open",IDC_RAD_CLOSED,"Button",BS_AUTORADIOBUTTON | WS_GROUP,13,21,132,10
CONTROL "Notify if window isn't 'foreground'",IDC_RAD_NFORE,
- "Button",BS_AUTORADIOBUTTON,13,34,132,10
- CONTROL "Notify always",IDC_RAD_ALWAYS,"Button",BS_AUTORADIOBUTTON,13,59,132,10
- CONTROL "Consider tabs",IDC_CHK_TABS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,29,46,112,10
- CONTROL "Close window on right click",IDC_CHK_CLOSE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,74,132,10
+ "Button",BS_AUTORADIOBUTTON,13,41,132,10
+ CONTROL "Notify always",IDC_RAD_ALWAYS,"Button",BS_AUTORADIOBUTTON,13,77,132,10
+ CONTROL "Consider tabs",IDC_CHK_TABS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,29,57,112,10
+ CONTROL "Close window on right click",IDC_CHK_CLOSE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,40,129,132,10
GROUPBOX "Disable when",IDC_STATIC,155,7,107,94
CONTROL "",IDC_LST_STATUS,"SysListView32",LVS_REPORT | LVS_NOLABELWRAP | LVS_ALIGNLEFT | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | WS_TABSTOP,159,17,99,80,WS_EX_CLIENTEDGE
- CONTROL "Include message text",IDC_CHK_MSG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,87,132,10
+ CONTROL "Include message text",IDC_CHK_MSG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,40,142,132,10
+ GROUPBOX "Notification Types",IDC_STATIC,7,103,255,71
+ CONTROL "Popups",IDC_CHK_POPUPS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,116,104,10
+ CONTROL "Speech",IDC_CHK_SPEECH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,154,104,10
END
@@ -82,7 +85,7 @@ BEGIN LEFTMARGIN, 7
RIGHTMARGIN, 262
TOPMARGIN, 7
- BOTTOMMARGIN, 103
+ BOTTOMMARGIN, 174
END
END
#endif // APSTUDIO_INVOKED
|