summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/m_message.h23
-rw-r--r--plugins/Scriver/src/chat/window.cpp18
-rw-r--r--plugins/Scriver/src/msgdialog.cpp6
-rw-r--r--plugins/Scriver/src/msgs.cpp6
-rw-r--r--plugins/Scriver/src/statusicon.cpp259
-rw-r--r--plugins/Scriver/src/statusicon.h4
-rw-r--r--plugins/TabSRMM/src/commonheaders.h2
-rw-r--r--plugins/TabSRMM/src/controls.cpp79
-rw-r--r--plugins/TabSRMM/src/generic_msghandlers.cpp251
-rw-r--r--src/core/modules.cpp4
-rw-r--r--src/miranda32_10.vcxproj3
-rw-r--r--src/miranda32_10.vcxproj.filters6
-rw-r--r--src/miranda32_11.vcxproj3
-rw-r--r--src/miranda32_11.vcxproj.filters6
-rw-r--r--src/modules/srmm/statusicon.cpp206
15 files changed, 357 insertions, 519 deletions
diff --git a/include/m_message.h b/include/m_message.h
index 8dbb18d79e..c12b0150f4 100644
--- a/include/m_message.h
+++ b/include/m_message.h
@@ -131,8 +131,6 @@ typedef struct {
#define MBF_DISABLED 0x01
#define MBF_HIDDEN 0x02
-/* State of icon with such flag will not be saved, and you must set it manually */
-#define MBF_OWNERSTATE 0x04
typedef struct {
int cbSize;
@@ -153,23 +151,36 @@ typedef struct {
int flags; // bitwize OR of MBCF_* flags above
} StatusIconClickData;
-#define MS_MSG_ADDICON "MessageAPI/AddIcon"
+// wParam = 0 (unused)
// lParam = (StatusIconData *)&StatusIconData
+#define MS_MSG_ADDICON "MessageAPI/AddIcon"
-#define MS_MSG_REMOVEICON "MessageAPI/RemoveIcon"
+// wParam = 0 (unused)
// lParam = (StatusIconData *)&StatusIconData
// only szModule and szId are used
+#define MS_MSG_REMOVEICON "MessageAPI/RemoveIcon"
-#define MS_MSG_MODIFYICON "MessageAPI/ModifyIcon"
// wParam = (HANDLE)hContact
// lParam = (StatusIconData *)&StatusIconData
// if hContact is null, icon is modified for all contacts
// otherwise, only the flags field is valid
// if either hIcon, hIconDisabled or szTooltip is null, they will not be modified
+#define MS_MSG_MODIFYICON "MessageAPI/ModifyIcon"
+
+// wParam = (HANDLE)hContact
+// lParam = (int)zero-based index of a visible icon
+// returns (StatusIconData*)icon description filled for the required contact
+// don't free this memory.
+#define MS_MSG_GETNTHICON "MessageAPI/GetNthIcon"
-#define ME_MSG_ICONPRESSED "MessageAPI/IconPressed"
// wParam = (HANDLE)hContact;
// lParam = (StatusIconClickData *)&StatusIconClickData;
// catch to show a popup menu, etc.
+#define ME_MSG_ICONPRESSED "MessageAPI/IconPressed"
+
+// wParam = (HANDLE)hContact;
+// lParam = (StatusIconkData*)pIcon
+// catch to be notified about the icon list's change.
+#define ME_MSG_ICONSCHANGED "MessageAPI/IconsChanged"
#endif // M_MESSAGE_H__
diff --git a/plugins/Scriver/src/chat/window.cpp b/plugins/Scriver/src/chat/window.cpp
index a384eeb7e4..8802af4fc6 100644
--- a/plugins/Scriver/src/chat/window.cpp
+++ b/plugins/Scriver/src/chat/window.cpp
@@ -1245,28 +1245,26 @@ INT_PTR CALLBACK RoomWndProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
case DM_UPDATESTATUSBAR:
{
- StatusIconData sid;
- StatusBarData sbd;
- HICON hIcon;
MODULEINFO* mi = MM_FindModule(si->pszModule);
TCHAR szTemp[512];
- hIcon = si->wStatus==ID_STATUS_ONLINE ? mi->hOnlineIcon : mi->hOfflineIcon;
+ HICON hIcon = si->wStatus==ID_STATUS_ONLINE ? mi->hOnlineIcon : mi->hOfflineIcon;
mir_sntprintf(szTemp, SIZEOF(szTemp), _T("%s : %s"), mi->ptszModDispName, si->ptszStatusbarText ? si->ptszStatusbarText : _T(""));
+
+ StatusBarData sbd;
sbd.iItem = 0;
sbd.iFlags = SBDF_TEXT | SBDF_ICON;
sbd.hIcon = hIcon;
sbd.pszText = szTemp;
SendMessage(GetParent(hwndDlg), CM_UPDATESTATUSBAR, (WPARAM) &sbd, (LPARAM)hwndDlg);
+
sbd.iItem = 1;
sbd.hIcon = NULL;
- sbd.pszText = _T("");
+ sbd.pszText = _T("");
SendMessage(GetParent(hwndDlg), CM_UPDATESTATUSBAR, (WPARAM) &sbd, (LPARAM)hwndDlg);
- sid.cbSize = sizeof(sid);
- sid.szModule = SRMMMOD;
- sid.dwId = 0;
- sid.flags = 0;
- ModifyStatusIcon((WPARAM)si->windowData.hContact, (LPARAM)&sid);
+ StatusIconData sid = { sizeof(sid) };
+ sid.szModule = SRMMMOD;
+ CallService(MS_MSG_MODIFYICON, (WPARAM)si->windowData.hContact, (LPARAM)&sid);
}
break;
diff --git a/plugins/Scriver/src/msgdialog.cpp b/plugins/Scriver/src/msgdialog.cpp
index 75d5fb77f2..25652a8c7e 100644
--- a/plugins/Scriver/src/msgdialog.cpp
+++ b/plugins/Scriver/src/msgdialog.cpp
@@ -1266,7 +1266,7 @@ INT_PTR CALLBACK DlgProcMessage(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lP
db_get_b(NULL, SRMMMOD, SRMSGSET_TYPINGNEW, SRMSGDEFSET_TYPINGNEW)));
db_set_b(dat->windowData.hContact, SRMMMOD, SRMSGSET_TYPING, (BYTE)!typingNotify);
sid.flags = typingNotify ? MBF_DISABLED : 0;
- ModifyStatusIcon((WPARAM)dat->windowData.hContact, (LPARAM)&sid);
+ CallService(MS_MSG_MODIFYICON, (WPARAM)dat->windowData.hContact, (LPARAM)&sid);
}
break;
@@ -1503,7 +1503,7 @@ INT_PTR CALLBACK DlgProcMessage(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lP
sid.cbSize = sizeof(sid);
sid.szModule = SRMMMOD;
sid.flags = MBF_DISABLED;
- ModifyStatusIcon((WPARAM)dat->windowData.hContact, (LPARAM)&sid);
+ CallService(MS_MSG_MODIFYICON, (WPARAM)dat->windowData.hContact, (LPARAM)&sid);
sid.dwId = 1;
if (IsTypingNotificationSupported(dat) && g_dat.flags2 & SMF2_SHOWTYPINGSWITCH)
sid.flags = (db_get_b(dat->windowData.hContact, SRMMMOD, SRMSGSET_TYPING,
@@ -1511,7 +1511,7 @@ INT_PTR CALLBACK DlgProcMessage(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lP
else
sid.flags = MBF_HIDDEN;
- ModifyStatusIcon((WPARAM)dat->windowData.hContact, (LPARAM)&sid);
+ CallService(MS_MSG_MODIFYICON, (WPARAM)dat->windowData.hContact, (LPARAM)&sid);
}
break;
diff --git a/plugins/Scriver/src/msgs.cpp b/plugins/Scriver/src/msgs.cpp
index 0eaf5158c8..26600238b0 100644
--- a/plugins/Scriver/src/msgs.cpp
+++ b/plugins/Scriver/src/msgs.cpp
@@ -377,7 +377,7 @@ static void RegisterStatusIcons()
sid.hIconDisabled = CopyIcon(GetCachedIcon("scriver_TYPINGOFF"));
sid.flags = MBF_HIDDEN;
sid.szTooltip = NULL;
- AddStickyStatusIcon((WPARAM) 0, (LPARAM)&sid);
+ CallService(MS_MSG_ADDICON, 0, (LPARAM)&sid);
}
void ChangeStatusIcons()
@@ -386,13 +386,13 @@ void ChangeStatusIcons()
sid.szModule = SRMMMOD;
sid.hIcon = CopyIcon(GetCachedIcon("scriver_UNICODEON"));
sid.hIconDisabled = CopyIcon(GetCachedIcon("scriver_UNICODEOFF"));
- ModifyStatusIcon(0, (LPARAM)&sid);
+ CallService(MS_MSG_MODIFYICON, 0, (LPARAM)&sid);
sid.dwId = 1;
sid.hIcon = CopyIcon(GetCachedIcon("scriver_TYPING"));
sid.hIconDisabled = CopyIcon(GetCachedIcon("scriver_TYPINGOFF"));
sid.flags = MBF_HIDDEN;
- ModifyStatusIcon(0, (LPARAM)&sid);
+ CallService(MS_MSG_MODIFYICON, 0, (LPARAM)&sid);
}
int StatusIconPressed(WPARAM wParam, LPARAM lParam)
diff --git a/plugins/Scriver/src/statusicon.cpp b/plugins/Scriver/src/statusicon.cpp
index b283bb22f8..b530c3ebe3 100644
--- a/plugins/Scriver/src/statusicon.cpp
+++ b/plugins/Scriver/src/statusicon.cpp
@@ -23,236 +23,77 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "commonheaders.h"
-struct StatusIconListNode {
- StatusIconData sid;
- struct StatusIconListNode *next;
-};
-
HANDLE hHookIconPressedEvt;
-static struct StatusIconListNode *status_icon_list = 0;
-static int status_icon_list_size = 0;
-
-static INT_PTR AddStatusIcon(WPARAM wParam, LPARAM lParam) {
- StatusIconData *sid = (StatusIconData *)lParam;
- struct StatusIconListNode *siln = (struct StatusIconListNode *)mir_alloc(sizeof(struct StatusIconListNode));
-
- siln->sid.cbSize = sid->cbSize;
- siln->sid.szModule = mir_strdup(sid->szModule);
- siln->sid.dwId = sid->dwId;
- siln->sid.hIcon = sid->hIcon;
- siln->sid.hIconDisabled = sid->hIconDisabled;
- siln->sid.flags = sid->flags;
- if (sid->szTooltip) siln->sid.szTooltip = mir_strdup(sid->szTooltip);
- else siln->sid.szTooltip = 0;
-
- siln->next = status_icon_list;
- status_icon_list = siln;
- status_icon_list_size++;
-
- WindowList_Broadcast(g_dat.hParentWindowList, DM_STATUSICONCHANGE, 0, 0);
- return 0;
-}
-
-INT_PTR AddStickyStatusIcon(WPARAM wParam, LPARAM lParam) {
- StatusIconData *sid = (StatusIconData *)lParam;
- struct StatusIconListNode *siln = (struct StatusIconListNode *)mir_alloc(sizeof(struct StatusIconListNode));
- struct StatusIconListNode *siln2 = status_icon_list;
-
- siln->sid.cbSize = sid->cbSize;
- siln->sid.szModule = mir_strdup(sid->szModule);
- siln->sid.dwId = sid->dwId;
- siln->sid.hIcon = sid->hIcon;
- siln->sid.hIconDisabled = sid->hIconDisabled;
- siln->sid.flags = sid->flags;
- if (sid->szTooltip) siln->sid.szTooltip = mir_strdup(sid->szTooltip);
- else siln->sid.szTooltip = 0;
- siln->next = NULL;
-
- while(siln2 && siln2->next) {
- siln2 = siln2->next;
- }
- if (siln2) {
- siln2->next = siln;
- } else {
- status_icon_list = siln;
- }
-
- status_icon_list_size++;
-
- WindowList_Broadcast(g_dat.hParentWindowList, DM_STATUSICONCHANGE, 0, 0);
- return 0;
-}
-
-static INT_PTR RemoveStatusIcon(WPARAM wParam, LPARAM lParam) {
- StatusIconData *sid = (StatusIconData *)lParam;
- struct StatusIconListNode *current = status_icon_list, *prev = 0;
-
- while(current) {
- if (strcmp(current->sid.szModule, sid->szModule) == 0 && current->sid.dwId == sid->dwId) {
- if (prev) prev->next = current->next;
- else status_icon_list = current->next;
-
- status_icon_list_size--;
-
- mir_free(current->sid.szModule);
- ReleaseIconSmart(current->sid.hIcon);
- ReleaseIconSmart(current->sid.hIconDisabled);
- mir_free(current->sid.szTooltip);
- mir_free(current);
- WindowList_Broadcast(g_dat.hParentWindowList, DM_STATUSICONCHANGE, 0, 0);
- return 0;
- }
-
- prev = current;
- current = current->next;
- }
-
- return 1;
-}
-
-static void RemoveAllStatusIcons(void) {
- struct StatusIconListNode *current;
-
- while(status_icon_list) {
- current = status_icon_list;
- status_icon_list = status_icon_list->next;
- status_icon_list_size--;
-
- mir_free(current->sid.szModule);
- DestroyIcon(current->sid.hIcon);
- if (current->sid.hIconDisabled) DestroyIcon(current->sid.hIconDisabled);
- if (current->sid.szTooltip) mir_free(current->sid.szTooltip);
- mir_free(current);
- }
-
- WindowList_Broadcast(g_dat.hParentWindowList, DM_STATUSICONCHANGE, 0, 0);
-}
-
-INT_PTR ModifyStatusIcon(WPARAM wParam, LPARAM lParam) {
- HANDLE hContact = (HANDLE)wParam;
-
- StatusIconData *sid = (StatusIconData *)lParam;
- struct StatusIconListNode *current = status_icon_list;
-
- while(current) {
- if (strcmp(current->sid.szModule, sid->szModule) == 0 && current->sid.dwId == sid->dwId) {
- if (!hContact) {
- current->sid.flags = sid->flags;
- if (sid->hIcon) {
- ReleaseIconSmart(current->sid.hIcon);
- current->sid.hIcon = sid->hIcon;
- }
- if (sid->hIconDisabled) {
- ReleaseIconSmart(current->sid.hIconDisabled);
- current->sid.hIconDisabled = sid->hIconDisabled;
- }
- if (sid->szTooltip) {
- if (current->sid.szTooltip) mir_free(current->sid.szTooltip);
- current->sid.szTooltip = mir_strdup(sid->szTooltip);
- }
-
- WindowList_Broadcast(g_dat.hParentWindowList, DM_STATUSICONCHANGE, 0, 0);
- } else {
- char buff[256];
- HWND hwnd;
- sprintf(buff, "SRMMStatusIconFlags%d", (int)sid->dwId);
- db_set_b(hContact, sid->szModule, buff, (BYTE)sid->flags);
- hwnd = WindowList_Find(g_dat.hMessageWindowList, hContact);
- if (hwnd == NULL) {
- hwnd = SM_FindWindowByContact(hContact);
- }
- if (hwnd != NULL) {
- PostMessage(GetParent(hwnd), DM_STATUSICONCHANGE, 0, 0);
- }
- }
- return 0;
- }
- current = current->next;
- }
-
- return 1;
-}
-
-void DrawStatusIcons(HANDLE hContact, HDC hDC, RECT r, int gap) {
- struct StatusIconListNode *current = status_icon_list;
+void DrawStatusIcons(HANDLE hContact, HDC hDC, RECT r, int gap)
+{
HICON hIcon;
- char buff[256];
- int flags;
int x = r.left;
- while(current) {
- sprintf(buff, "SRMMStatusIconFlags%d", (int)current->sid.dwId);
- flags = db_get_b(hContact, current->sid.szModule, buff, current->sid.flags);
- if (!(flags & MBF_HIDDEN)) {
- if ((flags & MBF_DISABLED) && current->sid.hIconDisabled) hIcon = current->sid.hIconDisabled;
- else hIcon = current->sid.hIcon;
- SetBkMode(hDC, TRANSPARENT);
- DrawIconEx(hDC, x, (r.top + r.bottom - GetSystemMetrics(SM_CYSMICON)) >> 1, hIcon, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0, NULL, DI_NORMAL);
+ StatusIconData *si;
+ int nIcon = 0;
+ while ((si = (StatusIconData*)CallService(MS_MSG_GETNTHICON, (WPARAM)hContact, nIcon++)) != NULL) {
+ if ((si->flags & MBF_DISABLED) && si->hIconDisabled) hIcon = si->hIconDisabled;
+ else hIcon = si->hIcon;
+
+ SetBkMode(hDC, TRANSPARENT);
+ DrawIconEx(hDC, x, (r.top + r.bottom - GetSystemMetrics(SM_CYSMICON)) >> 1, hIcon, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0, NULL, DI_NORMAL);
- x += GetSystemMetrics(SM_CYSMICON) + gap;
- }
- current = current->next;
+ x += GetSystemMetrics(SM_CYSMICON) + gap;
}
}
-void CheckStatusIconClick(HANDLE hContact, HWND hwndFrom, POINT pt, RECT r, int gap, int click_flags) {
- StatusIconClickData sicd;
- struct StatusIconListNode *current = status_icon_list;
+void CheckStatusIconClick(HANDLE hContact, HWND hwndFrom, POINT pt, RECT r, int gap, int click_flags)
+{
unsigned int iconNum = (pt.x - r.left) / (GetSystemMetrics(SM_CXSMICON) + gap) + 1;
- int flags;
- char buff[256];
-
- while(current) {
- sprintf(buff, "SRMMStatusIconFlags%d", (int)current->sid.dwId);
- flags = db_get_b(hContact, current->sid.szModule, buff, current->sid.flags);
- if (!(flags & MBF_HIDDEN)) iconNum--;
- if (iconNum == 0) break;
- current = current->next;
- }
+ StatusIconData *si = (StatusIconData*)CallService(MS_MSG_GETNTHICON, (WPARAM)hContact, iconNum);
+ if (si == NULL)
+ return;
+
+ ClientToScreen(hwndFrom, &pt);
+
+ StatusIconClickData sicd = { sizeof(sicd) };
+ sicd.clickLocation = pt;
+ sicd.dwId = si->dwId;
+ sicd.szModule = si->szModule;
+ sicd.flags = click_flags;
+ NotifyEventHooks(hHookIconPressedEvt, (WPARAM)hContact, (LPARAM)&sicd);
+}
- if (current) {
- ClientToScreen(hwndFrom, &pt);
- sicd.cbSize = sizeof(StatusIconClickData);
- sicd.clickLocation = pt;
- sicd.dwId = current->sid.dwId;
- sicd.szModule = current->sid.szModule;
- sicd.flags = click_flags;
- NotifyEventHooks(hHookIconPressedEvt, (WPARAM)hContact, (LPARAM)&sicd);
+static int OnSrmmIconChanged(WPARAM wParam, LPARAM)
+{
+ HANDLE hContact = (HANDLE)wParam;
+ if (hContact == NULL)
+ WindowList_Broadcast(g_dat.hParentWindowList, DM_STATUSICONCHANGE, 0, 0);
+ else {
+ HWND hwnd = WindowList_Find(g_dat.hMessageWindowList, hContact);
+ if (hwnd == NULL)
+ hwnd = SM_FindWindowByContact(hContact);
+ if (hwnd != NULL)
+ PostMessage(GetParent(hwnd), DM_STATUSICONCHANGE, 0, 0);
}
+ return 0;
}
+int InitStatusIcons()
+{
+ HookEvent(ME_MSG_ICONSCHANGED, OnSrmmIconChanged);
-HANDLE hServiceIcon[3];
-int InitStatusIcons() {
- hServiceIcon[0] = CreateServiceFunction(MS_MSG_ADDICON, AddStatusIcon);
- hServiceIcon[1] = CreateServiceFunction(MS_MSG_REMOVEICON, RemoveStatusIcon);
- hServiceIcon[2] = CreateServiceFunction(MS_MSG_MODIFYICON, ModifyStatusIcon);
hHookIconPressedEvt = CreateHookableEvent(ME_MSG_ICONPRESSED);
return 0;
}
-int DeinitStatusIcons() {
- int i;
+int DeinitStatusIcons()
+{
DestroyHookableEvent(hHookIconPressedEvt);
- for(i = 0; i < 3; i++) DestroyServiceFunction(hServiceIcon[i]);
- RemoveAllStatusIcons();
return 0;
}
-INT_PTR GetStatusIconsCount(HANDLE hContact) {
- char buff[256];
- int count = 0;
- int flags;
- struct StatusIconListNode *current = status_icon_list;
- while(current) {
- sprintf(buff, "SRMMStatusIconFlags%d", (int)current->sid.dwId);
- flags = db_get_b(hContact, current->sid.szModule, buff, current->sid.flags);
- if (!(flags & MBF_HIDDEN)) {
- count ++;
- }
- current = current->next;
- }
- return count;
-// return status_icon_list_size;
+int GetStatusIconsCount(HANDLE hContact)
+{
+ StatusIconData *si;
+ int nIcon = 0;
+ while ((si = (StatusIconData*)CallService(MS_MSG_GETNTHICON, (WPARAM)hContact, nIcon)) != NULL)
+ nIcon++;
+ return nIcon;
}
diff --git a/plugins/Scriver/src/statusicon.h b/plugins/Scriver/src/statusicon.h
index c606cf6291..c05cbd7ab8 100644
--- a/plugins/Scriver/src/statusicon.h
+++ b/plugins/Scriver/src/statusicon.h
@@ -26,9 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
int InitStatusIcons();
int DeinitStatusIcons();
-INT_PTR GetStatusIconsCount(HANDLE hContact);
+int GetStatusIconsCount(HANDLE hContact);
void DrawStatusIcons(HANDLE hContact, HDC hdc, RECT r, int gap);
void CheckStatusIconClick(HANDLE hContact, HWND hwndFrom, POINT pt, RECT rc, int gap, int flags);
-INT_PTR AddStickyStatusIcon(WPARAM wParam, LPARAM lParam);
-INT_PTR ModifyStatusIcon(WPARAM wParam, LPARAM lParam);
#endif
diff --git a/plugins/TabSRMM/src/commonheaders.h b/plugins/TabSRMM/src/commonheaders.h
index e1cf7c3a55..36ba7e241e 100644
--- a/plugins/TabSRMM/src/commonheaders.h
+++ b/plugins/TabSRMM/src/commonheaders.h
@@ -242,8 +242,6 @@ extern TContainerData *pFirstContainer, *pLastActiveContainer;
extern HANDLE hTypingNotify;
extern SESSION_INFO *m_WndList;
extern ButtonSet g_ButtonSet;
-extern int status_icon_list_size;
-extern TStatusBarIconNode *status_icon_list;
extern HANDLE g_hEvent;
extern RECT rcLastStatusBarClick;
extern PLUGININFOEX pluginInfo;
diff --git a/plugins/TabSRMM/src/controls.cpp b/plugins/TabSRMM/src/controls.cpp
index eff180cab9..5477979d29 100644
--- a/plugins/TabSRMM/src/controls.cpp
+++ b/plugins/TabSRMM/src/controls.cpp
@@ -923,39 +923,19 @@ LONG_PTR CALLBACK StatusBarSubclassProc(HWND hWnd, UINT msg, WPARAM wParam, LPAR
*/
case WM_USER + 101:
{
+ int list_icons = 0;
struct TWindowData *dat = (struct TWindowData *)lParam;
- RECT rcs;
- int statwidths[5];
- TStatusBarIconNode *current = status_icon_list;
- int list_icons = 0;
- char buff[100];
- DWORD flags;
-
- while (current && dat) {
- flags=current->sid.flags;
- if (current->sid.flags&MBF_OWNERSTATE){
- TStatusBarIconNode *currentSIN = dat->pSINod;
-
- while (currentSIN) {
- if (strcmp(currentSIN->sid.szModule, current->sid.szModule) == 0 && currentSIN->sid.dwId == current->sid.dwId) {
- flags=currentSIN->sid.flags;
- break;
- }
- currentSIN = currentSIN->next;
- }
- }
- else {
- sprintf(buff, "SRMMStatusIconFlags%d", (int)current->sid.dwId);
- flags = M->GetByte(dat->hContact, current->sid.szModule, buff, current->sid.flags);
- }
- if (!(flags & MBF_HIDDEN))
+ if (dat) {
+ while ( CallService(MS_MSG_GETNTHICON, (WPARAM)dat->hContact, list_icons))
list_icons++;
- current = current->next;
}
SendMessage(hWnd, WM_SIZE, 0, 0);
+
+ RECT rcs;
GetWindowRect(hWnd, &rcs);
+ int statwidths[5];
statwidths[0] = (rcs.right - rcs.left) - (2 * SB_CHAR_WIDTH + 20) - (52 + ((list_icons) * (PluginConfig.m_smcxicon + 2)));
statwidths[1] = (rcs.right - rcs.left) - (62 + ((list_icons) * (PluginConfig.m_smcxicon + 2)));
statwidths[2] = -1;
@@ -1030,48 +1010,13 @@ LONG_PTR CALLBACK StatusBarSubclassProc(HWND hWnd, UINT msg, WPARAM wParam, LPAR
SendMessage(hWnd, SB_GETRECT, 2, (LPARAM)&rc);
if (dat && PtInRect(&rc, pt)) {
int gap = 2;
- TStatusBarIconNode *current = status_icon_list;
- TStatusBarIconNode *clicked = NULL;
- TStatusBarIconNode *currentSIN = NULL;
-
unsigned int iconNum = (pt.x - rc.left) / (PluginConfig.m_smcxicon + gap);
- unsigned int list_icons = 0;
- char buff[100];
- DWORD flags;
-
- while (current) {
- if (current->sid.flags&MBF_OWNERSTATE&&dat->pSINod){
- TStatusBarIconNode *currentSIN = dat->pSINod;
- flags=current->sid.flags;
- while (currentSIN) {
- if (strcmp(currentSIN->sid.szModule, current->sid.szModule) == 0 && currentSIN->sid.dwId == current->sid.dwId) {
- flags=currentSIN->sid.flags;
- break;
- }
- currentSIN = currentSIN->next;
- }
- }
- else {
- sprintf(buff, "SRMMStatusIconFlags%d", (int)current->sid.dwId);
- flags = M->GetByte(dat->hContact, current->sid.szModule, buff, current->sid.flags);
- }
- if (!(flags & MBF_HIDDEN)) {
- if (list_icons++ == iconNum)
- clicked = current;
- }
- current = current->next;
- }
- if (clicked&&clicked->sid.flags&MBF_OWNERSTATE) {
- currentSIN=dat->pSINod;
- while (currentSIN) {
- if (strcmp(currentSIN->sid.szModule, clicked->sid.szModule) == 0 && currentSIN->sid.dwId == clicked->sid.dwId) {
- clicked=currentSIN;
- break;
- }
- currentSIN = currentSIN->next;
- }
- }
+ int list_icons = 0;
+ StatusIconData *si, *clicked = NULL;
+ while ((si = (StatusIconData*)CallService(MS_MSG_GETNTHICON, (WPARAM)dat->hContact, list_icons)) != NULL)
+ if (list_icons++ == iconNum)
+ clicked = si;
if ((int)iconNum == list_icons && pContainer) {
TCHAR wBuf[512];
@@ -1100,7 +1045,7 @@ LONG_PTR CALLBACK StatusBarSubclassProc(HWND hWnd, UINT msg, WPARAM wParam, LPAR
}
else {
if (clicked) {
- CallService("mToolTip/ShowTip", (WPARAM)clicked->sid.szTooltip, (LPARAM)&ti);
+ CallService("mToolTip/ShowTip", (WPARAM)clicked->szTooltip, (LPARAM)&ti);
tooltip_active = TRUE;
}
}
diff --git a/plugins/TabSRMM/src/generic_msghandlers.cpp b/plugins/TabSRMM/src/generic_msghandlers.cpp
index 402301a9ff..ad5ae42a4b 100644
--- a/plugins/TabSRMM/src/generic_msghandlers.cpp
+++ b/plugins/TabSRMM/src/generic_msghandlers.cpp
@@ -2015,199 +2015,44 @@ void TSAPI DM_UpdateTitle(TWindowData *dat, WPARAM wParam, LPARAM lParam)
*/
static HANDLE hHookIconPressedEvt;
-TStatusBarIconNode *status_icon_list = 0;
-int status_icon_list_size = 0;
-static INT_PTR SI_AddStatusIcon(WPARAM wParam, LPARAM lParam)
+static int OnSrmmIconChanged(WPARAM wParam, LPARAM)
{
- StatusIconData *sid = (StatusIconData *)lParam;
- TStatusBarIconNode *siln = (TStatusBarIconNode *)mir_alloc(sizeof(TStatusBarIconNode));
-
- siln->sid.cbSize = sid->cbSize;
- siln->sid.szModule = mir_strdup(sid->szModule);
- siln->sid.dwId = sid->dwId;
- siln->sid.hIcon = sid->hIcon;
- siln->sid.hIconDisabled = sid->hIconDisabled;
- siln->sid.flags = sid->flags;
- siln->sid.szTooltip = mir_strdup(sid->szTooltip);
- siln->next = status_icon_list;
- status_icon_list = siln;
- status_icon_list_size++;
-
- M->BroadcastMessage(DM_STATUSICONCHANGE, 0, 0);
- return 0;
-}
-
-static INT_PTR SI_RemoveStatusIcon(WPARAM wParam, LPARAM lParam)
-{
- StatusIconData *sid = (StatusIconData *)lParam;
- TStatusBarIconNode *current = status_icon_list, *prev = 0;
-
- while (current) {
- if (strcmp(current->sid.szModule, sid->szModule) == 0 && current->sid.dwId == sid->dwId) {
- if (prev) prev->next = current->next;
- else status_icon_list = current->next;
-
- status_icon_list_size--;
-
- mir_free(current->sid.szModule);
- DestroyIcon(current->sid.hIcon);
- if (current->sid.hIconDisabled)
- DestroyIcon(current->sid.hIconDisabled);
- mir_free(current->sid.szTooltip);
- mir_free(current);
- M->BroadcastMessage(DM_STATUSICONCHANGE, 0, 0);
- return 0;
- }
-
- prev = current;
- current = current->next;
- }
- return 1;
-}
-
-static void SI_RemoveAllStatusIcons(void)
-{
- TStatusBarIconNode *current;
-
- while (status_icon_list) {
- current = status_icon_list;
- status_icon_list = status_icon_list->next;
- status_icon_list_size--;
-
- mir_free(current->sid.szModule);
- DestroyIcon(current->sid.hIcon);
- if (current->sid.hIconDisabled) DestroyIcon(current->sid.hIconDisabled);
- if (current->sid.szTooltip) mir_free(current->sid.szTooltip);
- mir_free(current);
- }
- M->BroadcastMessage(DM_STATUSICONCHANGE, 0, 0);
-}
-
-static INT_PTR SI_ModifyStatusIcon(WPARAM wParam, LPARAM lParam)
-{
- StatusIconData *sid = (StatusIconData *)lParam;
- if ( !sid || !sid->szModule)
- return 1;
-
- TStatusBarIconNode *current = status_icon_list;
HANDLE hContact = (HANDLE)wParam;
-
- while (current) {
- if ( strcmp(current->sid.szModule, sid->szModule) == 0 && current->sid.dwId == sid->dwId) {
- if (!hContact) {
- current->sid.flags = sid->flags;
- if (sid->hIcon) {
- DestroyIcon(current->sid.hIcon);
- current->sid.hIcon = sid->hIcon;
- }
- if (sid->hIconDisabled) {
- DestroyIcon(current->sid.hIconDisabled);
- current->sid.hIconDisabled = sid->hIconDisabled;
- }
- if (sid->szTooltip)
- replaceStr(current->sid.szTooltip, sid->szTooltip);
-
- M->BroadcastMessage(DM_STATUSICONCHANGE, 0, 0);
- }
- else {
- char buff[256];
- HWND hwnd;
- if ( !(sid->flags & MBF_OWNERSTATE)) {
- sprintf(buff, "SRMMStatusIconFlags%d", (int)sid->dwId);
- M->WriteByte(hContact, sid->szModule, buff, (BYTE)sid->flags);
- }
- if ((hwnd = M->FindWindow(hContact))) {
- if (sid->flags & MBF_OWNERSTATE) {
- TStatusBarIconNode *siln = NULL;
- TWindowData *dat = (TWindowData*) GetWindowLongPtr(hwnd, GWLP_USERDATA);
- TStatusBarIconNode *psi = dat->pSINod;
- while (psi) {
- if (strcmp(psi->sid.szModule, sid->szModule) == 0 && psi->sid.dwId == sid->dwId) {
- siln = psi;
- break;
- }
- psi = psi->next;
- }
- if (!siln) {
- siln = (TStatusBarIconNode *)mir_alloc(sizeof(TStatusBarIconNode));
- siln->sid.szModule = mir_strdup(sid->szModule);
- siln->sid.dwId = sid->dwId;
- siln->sid.hIcon = sid->hIcon;
- siln->sid.hIconDisabled = sid->hIconDisabled;
- siln->sid.flags = sid->flags;
-
- if (sid->szTooltip) siln->sid.szTooltip = mir_strdup(sid->szTooltip);
- else siln->sid.szTooltip = 0;
-
- siln->next = dat->pSINod;
- dat->pSINod = siln;
- }
- else {
- siln->sid.hIcon = sid->hIcon;
- siln->sid.hIconDisabled = sid->hIconDisabled;
- siln->sid.flags = sid->flags;
- if (siln->sid.szTooltip) mir_free(siln->sid.szTooltip);
-
- if (sid->szTooltip) siln->sid.szTooltip = mir_strdup(sid->szTooltip);
- else siln->sid.szTooltip = 0;
-
- }
- }
- PostMessage(hwnd, DM_STATUSICONCHANGE, 0, 0);
- }
- }
- return 0;
- }
- current = current->next;
+ if (hContact == NULL)
+ M->BroadcastMessage(DM_STATUSICONCHANGE, 0, 0);
+ else {
+ HWND hwnd = M->FindWindow(hContact);
+ if (hwnd)
+ PostMessage(hwnd, DM_STATUSICONCHANGE, 0, 0);
}
- return 1;
+ return 0;
}
void DrawStatusIcons(struct TWindowData *dat, HDC hDC, RECT r, int gap)
{
- TStatusBarIconNode* current = status_icon_list;
- HICON hIcon = NULL;
- char buff[256];
- int flags;
- int x = r.left;
- LONG cx_icon = PluginConfig.m_smcxicon;
- LONG cy_icon = PluginConfig.m_smcyicon;
- LONG y = (r.top + r.bottom - cx_icon) >> 1;
+ HICON hIcon = NULL;
+ int x = r.left;
+ LONG cx_icon = PluginConfig.m_smcxicon;
+ LONG cy_icon = PluginConfig.m_smcyicon;
+ LONG y = (r.top + r.bottom - cx_icon) >> 1;
SetBkMode(hDC, TRANSPARENT);
- while (current) {
- if (current->sid.flags&MBF_OWNERSTATE) {
- TStatusBarIconNode *currentSIN = dat->pSINod;
- flags = current->sid.flags;
- hIcon = current->sid.hIcon;
- while (currentSIN) {
- if (strcmp(currentSIN->sid.szModule, current->sid.szModule) == 0 && currentSIN->sid.dwId == current->sid.dwId) {
- flags = currentSIN->sid.flags;
- hIcon = currentSIN->sid.hIcon;
- break;
- }
- currentSIN = currentSIN->next;
- }
- } else {
- sprintf(buff, "SRMMStatusIconFlags%d", (int)current->sid.dwId);
- flags = M->GetByte(dat->hContact, current->sid.szModule, buff, current->sid.flags);
- }
- if (!(flags & MBF_HIDDEN)) {
- if (!(flags&MBF_OWNERSTATE) && (flags & MBF_DISABLED) && current->sid.hIconDisabled)
- hIcon = current->sid.hIconDisabled;
- else if (!(flags&MBF_OWNERSTATE))
- hIcon = current->sid.hIcon;
+ StatusIconData *si;
+ int nIcon = 0;
+ while ((si = (StatusIconData*)CallService(MS_MSG_GETNTHICON, (WPARAM)dat->hContact, nIcon++)) != NULL) {
+ if ((si->flags & MBF_DISABLED) && si->hIconDisabled)
+ hIcon = si->hIconDisabled;
+ else
+ hIcon = si->hIcon;
- if (flags & MBF_DISABLED && current->sid.hIconDisabled == (HICON)0)
- CSkin::DrawDimmedIcon(hDC, x, y, cx_icon, cy_icon, hIcon, 50);
- else
- DrawIconEx(hDC, x, y, hIcon, 16, 16, 0, NULL, DI_NORMAL);
+ if (si->flags & MBF_DISABLED && si->hIconDisabled == (HICON)0)
+ CSkin::DrawDimmedIcon(hDC, x, y, cx_icon, cy_icon, hIcon, 50);
+ else
+ DrawIconEx(hDC, x, y, hIcon, 16, 16, 0, NULL, DI_NORMAL);
- x += 16 + gap;
- }
- current = current->next;
+ x += 16 + gap;
}
DrawIconEx(hDC, x, y, PluginConfig.g_buttonBarIcons[ICON_DEFAULT_SOUNDS],
cx_icon, cy_icon, 0, NULL, DI_NORMAL);
@@ -2235,13 +2080,9 @@ void DrawStatusIcons(struct TWindowData *dat, HDC hDC, RECT r, int gap)
void SI_CheckStatusIconClick(struct TWindowData *dat, HWND hwndFrom, POINT pt, RECT r, int gap, int code)
{
StatusIconClickData sicd;
- TStatusBarIconNode *current = status_icon_list;
- TStatusBarIconNode *clicked = NULL;
UINT iconNum = (pt.x - (r.left + 0)) / (PluginConfig.m_smcxicon + gap);
UINT list_icons = 0;
- char buff[100];
- DWORD flags;
if (dat && (code == NM_CLICK || code == NM_RCLICK)) {
POINT ptScreen;
@@ -2251,27 +2092,13 @@ void SI_CheckStatusIconClick(struct TWindowData *dat, HWND hwndFrom, POINT pt, R
return;
}
- while (current && dat) {
- if (current->sid.flags & MBF_OWNERSTATE) {
- TStatusBarIconNode *currentSIN = dat->pSINod;
- flags = current->sid.flags;
- while (currentSIN) {
- if (strcmp(currentSIN->sid.szModule, current->sid.szModule) == 0 && currentSIN->sid.dwId == current->sid.dwId) {
- flags = currentSIN->sid.flags;
- break;
- }
- currentSIN = currentSIN->next;
- }
- } else {
- sprintf(buff, "SRMMStatusIconFlags%d", (int)current->sid.dwId);
- flags = M->GetByte(dat->hContact, current->sid.szModule, buff, current->sid.flags);
- }
- if ( !(flags & MBF_HIDDEN)) {
- if (list_icons++ == iconNum)
- clicked = current;
+ StatusIconData *si, *clicked = NULL;
+ if (dat)
+ while ((si = (StatusIconData*)CallService(MS_MSG_GETNTHICON, (WPARAM)dat->hContact, list_icons)) != NULL) {
+ if (list_icons == iconNum)
+ clicked = si;
+ list_icons++;
}
- current = current->next;
- }
if ((int)iconNum == list_icons && code != NM_RCLICK) {
if (GetKeyState(VK_SHIFT) & 0x8000) {
@@ -2297,8 +2124,8 @@ void SI_CheckStatusIconClick(struct TWindowData *dat, HWND hwndFrom, POINT pt, R
} else if (clicked) {
sicd.cbSize = sizeof(StatusIconClickData);
GetCursorPos(&sicd.clickLocation);
- sicd.dwId = clicked->sid.dwId;
- sicd.szModule = clicked->sid.szModule;
+ sicd.dwId = clicked->dwId;
+ sicd.szModule = clicked->szModule;
sicd.flags = (code == NM_RCLICK ? MBCF_RIGHTBUTTON : 0);
NotifyEventHooks(hHookIconPressedEvt, (WPARAM)dat->hContact, (LPARAM)&sicd);
InvalidateRect(dat->pContainer->hwndStatus, NULL, TRUE);
@@ -2307,22 +2134,14 @@ void SI_CheckStatusIconClick(struct TWindowData *dat, HWND hwndFrom, POINT pt, R
int SI_InitStatusIcons()
{
- CreateServiceFunction(MS_MSG_ADDICON, SI_AddStatusIcon);
- CreateServiceFunction(MS_MSG_REMOVEICON, SI_RemoveStatusIcon);
- CreateServiceFunction(MS_MSG_MODIFYICON, SI_ModifyStatusIcon);
+ HookEvent(ME_MSG_ICONSCHANGED, OnSrmmIconChanged);
+
hHookIconPressedEvt = CreateHookableEvent(ME_MSG_ICONPRESSED);
return 0;
}
-
int SI_DeinitStatusIcons()
{
DestroyHookableEvent(hHookIconPressedEvt);
- SI_RemoveAllStatusIcons();
return 0;
}
-
-int SI_GetStatusIconsCount()
-{
- return status_icon_list_size;
-}
diff --git a/src/core/modules.cpp b/src/core/modules.cpp
index 1eb92eab3c..b36a6812cc 100644
--- a/src/core/modules.cpp
+++ b/src/core/modules.cpp
@@ -43,6 +43,7 @@ int LoadAccountsModule(void); // core: account manager
int LoadIgnoreModule(void); // protocol filter: ignore
int LoadDbintfModule(void);
int LoadEventsModule(void);
+int LoadSrmmModule(void);
int LoadContactsModule(void);
int LoadContactListModule(void);// ui: clist
@@ -81,6 +82,7 @@ void UnloadNewPlugins(void);
void UnloadProtocolsModule(void);
void UnloadSkinSounds(void);
void UnloadSkinHotkeys(void);
+void UnloadSrmmModule(void);
void UnloadSslModule(void);
void UnloadUtilsModule(void);
@@ -138,6 +140,7 @@ int LoadDefaultModules(void)
if ( LoadSkinSounds()) return 1;
if ( LoadSkinHotkeys()) return 1;
if ( LoadFontserviceModule()) return 1;
+ if ( LoadSrmmModule()) return 1;
if ( LoadDescButtonModule()) return 1;
if ( LoadOptionsModule()) return 1;
@@ -170,6 +173,7 @@ void UnloadDefaultModules(void)
UnloadProtocolsModule();
UnloadSkinSounds();
UnloadSkinHotkeys();
+ UnloadSrmmModule();
// UnloadErrorsModule();
UnloadIcoLibModule();
UnloadUtilsModule();
diff --git a/src/miranda32_10.vcxproj b/src/miranda32_10.vcxproj
index 973bd08757..3fbd6ce645 100644
--- a/src/miranda32_10.vcxproj
+++ b/src/miranda32_10.vcxproj
@@ -478,6 +478,9 @@
<ClCompile Include="modules\skin\sounds.cpp">
<PrecompiledHeaderFile>..\..\core\commonheaders.h</PrecompiledHeaderFile>
</ClCompile>
+ <ClCompile Include="modules\srmm\statusicon.cpp">
+ <PrecompiledHeaderFile>..\..\core\commonheaders.h</PrecompiledHeaderFile>
+ </ClCompile>
<ClCompile Include="modules\utils\bmpfilter.cpp">
<PrecompiledHeaderFile>..\..\core\commonheaders.h</PrecompiledHeaderFile>
</ClCompile>
diff --git a/src/miranda32_10.vcxproj.filters b/src/miranda32_10.vcxproj.filters
index ad46aa0a85..fc15b485fc 100644
--- a/src/miranda32_10.vcxproj.filters
+++ b/src/miranda32_10.vcxproj.filters
@@ -73,6 +73,9 @@
<Filter Include="Modules\extraicons">
<UniqueIdentifier>{e125e36b-fc7d-4a78-8f13-67d3c9333621}</UniqueIdentifier>
</Filter>
+ <Filter Include="Modules\srmm">
+ <UniqueIdentifier>{3da88f1b-9c87-43dc-a7a1-140d8dc6eefc}</UniqueIdentifier>
+ </Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\include\m_addcontact.h">
@@ -620,6 +623,9 @@
<ClCompile Include="core\stdafx.cpp">
<Filter>Core</Filter>
</ClCompile>
+ <ClCompile Include="modules\srmm\statusicon.cpp">
+ <Filter>Modules\srmm</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="resource.rc">
diff --git a/src/miranda32_11.vcxproj b/src/miranda32_11.vcxproj
index 553711141d..762b9e1626 100644
--- a/src/miranda32_11.vcxproj
+++ b/src/miranda32_11.vcxproj
@@ -483,6 +483,9 @@
<ClCompile Include="modules\skin\sounds.cpp">
<PrecompiledHeaderFile>..\..\core\commonheaders.h</PrecompiledHeaderFile>
</ClCompile>
+ <ClCompile Include="modules\srmm\statusicon.cpp">
+ <PrecompiledHeaderFile>..\..\core\commonheaders.h</PrecompiledHeaderFile>
+ </ClCompile>
<ClCompile Include="modules\utils\bmpfilter.cpp">
<PrecompiledHeaderFile>..\..\core\commonheaders.h</PrecompiledHeaderFile>
</ClCompile>
diff --git a/src/miranda32_11.vcxproj.filters b/src/miranda32_11.vcxproj.filters
index ad46aa0a85..4ec98818a1 100644
--- a/src/miranda32_11.vcxproj.filters
+++ b/src/miranda32_11.vcxproj.filters
@@ -73,6 +73,9 @@
<Filter Include="Modules\extraicons">
<UniqueIdentifier>{e125e36b-fc7d-4a78-8f13-67d3c9333621}</UniqueIdentifier>
</Filter>
+ <Filter Include="Modules\srmm">
+ <UniqueIdentifier>{b3f78380-76da-4a82-a0e2-1a14b173dac1}</UniqueIdentifier>
+ </Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\include\m_addcontact.h">
@@ -620,6 +623,9 @@
<ClCompile Include="core\stdafx.cpp">
<Filter>Core</Filter>
</ClCompile>
+ <ClCompile Include="modules\srmm\statusicon.cpp">
+ <Filter>Modules\srmm</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="resource.rc">
diff --git a/src/modules/srmm/statusicon.cpp b/src/modules/srmm/statusicon.cpp
new file mode 100644
index 0000000000..dcf055a88f
--- /dev/null
+++ b/src/modules/srmm/statusicon.cpp
@@ -0,0 +1,206 @@
+/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-13 Miranda NG project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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 "..\..\core\commonheaders.h"
+
+struct StatusIconChild : public MZeroedObject
+{
+ ~StatusIconChild()
+ {
+ mir_free(szTooltip);
+ }
+
+ HANDLE hContact;
+ HICON hIcon, hIconDisabled;
+ int flags;
+ char *szTooltip;
+};
+
+struct StatusIconMain : public MZeroedObject
+{
+ StatusIconMain() :
+ arChildren(3, HandleKeySortT)
+ {}
+
+ ~StatusIconMain()
+ {
+ mir_free(sid.szModule);
+ mir_free(sid.szTooltip);
+ }
+
+ StatusIconData sid;
+ OBJLIST<StatusIconChild> arChildren;
+};
+
+static int CompareIcons(const StatusIconMain *p1, const StatusIconMain *p2)
+{
+ int res = strcmp(p1->sid.szModule, p2->sid.szModule);
+ if (res)
+ return res;
+
+ return p1->sid.dwId - p2->sid.dwId;
+}
+
+static OBJLIST<StatusIconMain> arIcons(3, CompareIcons);
+
+static HANDLE hHookIconsChanged;
+
+INT_PTR ModifyStatusIcon(WPARAM wParam, LPARAM lParam)
+{
+ StatusIconData *sid = (StatusIconData *)lParam;
+ if (sid == NULL || sid->cbSize != sizeof(StatusIconData))
+ return 1;
+
+ StatusIconMain *p = arIcons.find((StatusIconMain*)sid);
+ if (p == NULL)
+ return 1;
+
+ HANDLE hContact = (HANDLE)wParam;
+ if (hContact == NULL) {
+ memcpy(&p->sid, sid, sizeof(p->sid));
+ replaceStr(p->sid.szModule, sid->szModule);
+ replaceStr(p->sid.szTooltip, sid->szTooltip);
+ NotifyEventHooks(hHookIconsChanged, NULL, (LPARAM)p);
+ return 0;
+ }
+
+ StatusIconChild *pc = p->arChildren.find((StatusIconChild*)&hContact);
+ if (pc == NULL) {
+ pc = new StatusIconChild();
+ pc->hContact = hContact;
+ p->arChildren.insert(pc);
+ }
+
+ pc->flags = sid->flags;
+ pc->hIcon = sid->hIcon;
+ pc->hIconDisabled = sid->hIconDisabled;
+ replaceStr(pc->szTooltip, sid->szTooltip);
+ NotifyEventHooks(hHookIconsChanged, wParam, (LPARAM)p);
+ return 0;
+}
+
+static INT_PTR AddStatusIcon(WPARAM wParam, LPARAM lParam)
+{
+ StatusIconData *sid = (StatusIconData *)lParam;
+ if (sid == NULL || sid->cbSize != sizeof(StatusIconData))
+ return 1;
+
+ StatusIconMain *p = arIcons.find((StatusIconMain*)sid);
+ if (p != NULL)
+ return ModifyStatusIcon(0, lParam);
+
+ p = new StatusIconMain;
+ memcpy(&p->sid, sid, sizeof(p->sid));
+ p->sid.szModule = mir_strdup(sid->szModule);
+ p->sid.szTooltip = mir_strdup(sid->szTooltip);
+ arIcons.insert(p);
+
+ NotifyEventHooks(hHookIconsChanged, NULL, (LPARAM)p);
+ return 0;
+}
+
+static INT_PTR RemoveStatusIcon(WPARAM wParam, LPARAM lParam)
+{
+ StatusIconData *sid = (StatusIconData *)lParam;
+ if (sid == NULL || sid->cbSize != sizeof(StatusIconData))
+ return 1;
+
+ StatusIconMain *p = arIcons.find((StatusIconMain*)sid);
+ if (p == NULL)
+ return 1;
+
+ arIcons.remove(p);
+ return 0;
+}
+
+static INT_PTR GetNthIcon(WPARAM wParam, LPARAM lParam)
+{
+ static StatusIconData res;
+
+ for (int i=arIcons.getCount()-1, nVis = 0; i >= 0; i--) {
+ StatusIconMain &p = arIcons[i];
+
+ StatusIconChild *pc = p.arChildren.find((StatusIconChild*)&wParam);
+ if (pc) {
+ if (pc->flags & MBF_HIDDEN)
+ continue;
+ }
+ else if (p.sid.flags & MBF_HIDDEN)
+ continue;
+
+ if (nVis == (int)lParam) {
+ memcpy(&res, &p, sizeof(res));
+ if (pc) {
+ res.hIcon = pc->hIcon;
+ res.hIconDisabled = pc->hIconDisabled;
+ res.flags = pc->flags;
+ res.szTooltip = pc->szTooltip;
+ }
+ return (INT_PTR)&res;
+ }
+ nVis++;
+ }
+
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+static int OnWindowEvent(WPARAM, LPARAM lParam)
+{
+ MessageWindowEventData *evt = (MessageWindowEventData*)lParam;
+ if (evt->uType == MSG_WINDOW_EVT_CLOSE) {
+ for (int i=0; i < arIcons.getCount(); i++) {
+ StatusIconMain &p = arIcons[i];
+ p.arChildren.remove((StatusIconChild*)&evt->hContact);
+ }
+ }
+
+ return 0;
+}
+
+static int OnModulesLoaded(WPARAM, LPARAM)
+{
+ HookEvent(ME_MSG_WINDOWEVENT, OnWindowEvent);
+ return 0;
+}
+
+int LoadSrmmModule()
+{
+ CreateServiceFunction(MS_MSG_ADDICON, AddStatusIcon);
+ CreateServiceFunction(MS_MSG_REMOVEICON, RemoveStatusIcon);
+ CreateServiceFunction(MS_MSG_MODIFYICON, ModifyStatusIcon);
+ CreateServiceFunction(MS_MSG_GETNTHICON, GetNthIcon);
+
+ HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded);
+
+ hHookIconsChanged = CreateHookableEvent(ME_MSG_ICONSCHANGED);
+ return 0;
+}
+
+void UnloadSrmmModule()
+{
+ arIcons.destroy();
+ NotifyEventHooks(hHookIconsChanged, NULL, NULL);
+ DestroyHookableEvent(hHookIconsChanged);
+}