diff options
author | George Hazan <ghazan@miranda.im> | 2018-04-10 16:28:29 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2018-04-10 16:28:29 +0300 |
commit | 95af2d0cfadb5707ac7fe941f1352b3c99eb2372 (patch) | |
tree | 6504436cbc0bfb1a4437d9c900dbefe60d20a51e | |
parent | a17e6fd208ed45a0422f4fe468bd75019be98cbc (diff) |
fix for one very rare crash due to unsynced array of status menus & accounts
-rw-r--r-- | include/m_protocols.h | 5 | ||||
-rw-r--r-- | src/mir_app/src/menu_clist.cpp | 89 | ||||
-rw-r--r-- | src/mir_app/src/miranda.h | 6 |
3 files changed, 36 insertions, 64 deletions
diff --git a/include/m_protocols.h b/include/m_protocols.h index ee81f41ef8..3c8a70a444 100644 --- a/include/m_protocols.h +++ b/include/m_protocols.h @@ -32,6 +32,7 @@ struct PROTO_INTERFACE; #include "statusmodes.h"
#include <m_core.h>
+#include <m_genmenu.h>
#include <m_system_cpp.h>
struct CCSDATA
@@ -281,6 +282,10 @@ struct MIR_APP_EXPORT PROTOACCOUNT int iIconBase; // index of the first icon in ClistImages
int iRealStatus; // last status reported by protocol
+ int protoindex;
+ int protostatus[MAX_STATUS_COUNT];
+ HGENMENU menuhandle[MAX_STATUS_COUNT];
+
bool IsEnabled(void) const;
bool IsLocked(void) const;
bool IsVisible(void) const;
diff --git a/src/mir_app/src/menu_clist.cpp b/src/mir_app/src/menu_clist.cpp index 649a60b727..1e4223ec5d 100644 --- a/src/mir_app/src/menu_clist.cpp +++ b/src/mir_app/src/menu_clist.cpp @@ -55,6 +55,7 @@ bool prochotkey; HANDLE hPreBuildMainMenuEvent, hStatusModeChangeEvent, hPreBuildContactMenuEvent, hPreBuildStatusMenuEvent;
HMENU hMainMenu, hStatusMenu;
+
const int statusModeList[MAX_STATUS_COUNT] =
{
ID_STATUS_OFFLINE, ID_STATUS_ONLINE, ID_STATUS_AWAY, ID_STATUS_NA, ID_STATUS_OCCUPIED,
@@ -75,31 +76,7 @@ static const int statusModePf2List[MAX_STATUS_COUNT] = static INT_PTR statusHotkeys[MAX_STATUS_COUNT];
-TMO_IntMenuItem **hStatusMainMenuHandles;
-int hStatusMainMenuHandlesCnt;
-
-struct tStatusMenuHandles
-{
- int protoindex;
- int protostatus[MAX_STATUS_COUNT];
- TMO_IntMenuItem *menuhandle[MAX_STATUS_COUNT];
-};
-
-tStatusMenuHandles *hStatusMenuHandles;
-int hStatusMenuHandlesCnt;
-
-struct BuildContactParam
-{
- char *szProto;
- int isOnList;
- int isOnline;
-};
-
-struct MenuItemData
-{
- HMENU OwnerMenu;
- int position;
-};
+static HGENMENU hStatusMainMenuHandles[MAX_STATUS_COUNT];
/////////////////////////////////////////////////////////////////////////////////////////
// service functions
@@ -239,6 +216,13 @@ MIR_APP_DLL(HGENMENU) Menu_AddContactMenuItem(TMO_MenuItem *pmi, const char *psz /////////////////////////////////////////////////////////////////////////////////////////
+struct BuildContactParam
+{
+ char *szProto;
+ int isOnList;
+ int isOnline;
+};
+
EXTERN_C MIR_APP_DLL(HMENU) Menu_BuildContactMenu(MCONTACT hContact)
{
NotifyEventHooks(hPreBuildContactMenuEvent, hContact, 0);
@@ -369,6 +353,12 @@ MIR_APP_DLL(HMENU) Menu_GetStatusMenu() /////////////////////////////////////////////////////////////////////////////////////////
+struct MenuItemData
+{
+ HMENU OwnerMenu;
+ int position;
+};
+
static BOOL FindMenuHandleByGlobalID(HMENU hMenu, TMO_IntMenuItem *id, MenuItemData* itdat)
{
if (!itdat)
@@ -714,21 +704,12 @@ void RebuildMenuOrder(void) RecursiveDeleteMenu(hStatusMenu);
// status menu
- if (hStatusMenuObject != 0) {
+ if (hStatusMenuObject != 0)
Menu_RemoveObject(hStatusMenuObject);
- mir_free(hStatusMainMenuHandles);
- mir_free(hStatusMenuHandles);
- }
hStatusMenuObject = Menu_AddObject("StatusMenu", LPGEN("Status menu"), "StatusMenuCheckService", "StatusMenuExecService");
Menu_ConfigureObject(hStatusMenuObject, MCO_OPT_FREE_SERVICE, (INT_PTR)"CLISTMENUS/FreeOwnerDataStatusMenu");
- hStatusMainMenuHandles = (TMO_IntMenuItem**)mir_calloc(_countof(statusModeList) * sizeof(TMO_IntMenuItem*));
- hStatusMainMenuHandlesCnt = _countof(statusModeList);
-
- hStatusMenuHandles = (tStatusMenuHandles*)mir_calloc(sizeof(tStatusMenuHandles)*accounts.getCount());
- hStatusMenuHandlesCnt = accounts.getCount();
-
g_menuProtos.destroy();
for (int s = 0; s < accounts.getCount(); s++) {
@@ -819,12 +800,12 @@ void RebuildMenuOrder(void) smep->pimi = (HGENMENU)i;
smep->szProto = mir_strdup(pa->szModuleName);
- hStatusMenuHandles[i].protoindex = i;
- hStatusMenuHandles[i].protostatus[j] = statusModeList[j];
- hStatusMenuHandles[i].menuhandle[j] = Menu_AddItem(hStatusMenuObject, &mi, smep);
+ pa->protoindex = i;
+ pa->protostatus[j] = statusModeList[j];
+ pa->menuhandle[j] = Menu_AddItem(hStatusMenuObject, &mi, smep);
mir_snprintf(buf, "ProtocolIcon_%s_%s", pa->szModuleName, mi.name.a);
- Menu_ConfigureItem(hStatusMenuHandles[i].menuhandle[j], MCI_OPT_UNIQUENAME, buf);
+ Menu_ConfigureItem(pa->menuhandle[j], MCI_OPT_UNIQUENAME, buf);
IcoLib_ReleaseIcon(mi.hIcon);
}
@@ -940,7 +921,6 @@ static int MenuProtoAck(WPARAM, LPARAM lParam) ACKDATA *ack = (ACKDATA*)lParam;
if (ack->type != ACKTYPE_STATUS) return 0;
if (ack->result != ACKRESULT_SUCCESS) return 0;
- if (hStatusMainMenuHandles == nullptr) return 0;
if (Clist_GetProtocolVisibility(ack->szModule) == 0) return 0;
int overallStatus = Proto_GetAverageStatus();
@@ -950,13 +930,12 @@ static int MenuProtoAck(WPARAM, LPARAM lParam) pos = 0;
// reset all current possible checked statuses
- for (int pos2 = 0; pos2 < hStatusMainMenuHandlesCnt; pos2++)
- if (pos2 >= 0 && pos2 < hStatusMainMenuHandlesCnt)
- Menu_ModifyItem(hStatusMainMenuHandles[pos2], nullptr, INVALID_HANDLE_VALUE, 0);
+ for (auto &it : hStatusMainMenuHandles)
+ Menu_ModifyItem(it, nullptr, INVALID_HANDLE_VALUE, 0);
currentStatusMenuItem = overallStatus;
pos = statustopos(currentStatusMenuItem);
- if (pos >= 0 && pos < hStatusMainMenuHandlesCnt)
+ if (pos >= 0 && pos < _countof(hStatusMainMenuHandles))
Menu_SetChecked(hStatusMainMenuHandles[pos], true);
}
else {
@@ -964,27 +943,27 @@ static int MenuProtoAck(WPARAM, LPARAM lParam) if (pos == -1)
pos = 0;
- if (pos >= 0 && pos < hStatusMainMenuHandlesCnt)
+ if (pos >= 0 && pos < _countof(hStatusMainMenuHandles))
Menu_ModifyItem(hStatusMainMenuHandles[pos], nullptr, INVALID_HANDLE_VALUE, 0);
currentStatusMenuItem = 0;
}
- for (int i = 0; i < accounts.getCount(); i++) {
- if (!mir_strcmp(accounts[i]->szModuleName, ack->szModule)) {
+ for (auto &pa : accounts) {
+ if (!mir_strcmp(pa->szModuleName, ack->szModule)) {
int iOldStatus = (INT_PTR)ack->hProcess;
if ((iOldStatus >= ID_STATUS_OFFLINE || iOldStatus == 0) && iOldStatus < ID_STATUS_OFFLINE + _countof(statusModeList)) {
int pos = statustopos(iOldStatus);
if (pos == -1)
pos = 0;
for (pos = 0; pos < _countof(statusModeList); pos++)
- Menu_ModifyItem(hStatusMenuHandles[i].menuhandle[pos], nullptr, INVALID_HANDLE_VALUE, 0);
+ Menu_ModifyItem(pa->menuhandle[pos], nullptr, INVALID_HANDLE_VALUE, 0);
}
if (ack->lParam >= ID_STATUS_OFFLINE && ack->lParam < ID_STATUS_OFFLINE + _countof(statusModeList)) {
int pos = statustopos((int)ack->lParam);
if (pos >= 0 && pos < _countof(statusModeList))
- Menu_SetChecked(hStatusMenuHandles[i].menuhandle[pos], true);
+ Menu_SetChecked(pa->menuhandle[pos], true);
}
break;
}
@@ -1075,12 +1054,6 @@ void InitCustomMenus(void) hMainMenu = CreatePopupMenu();
hStatusMenu = CreatePopupMenu();
- hStatusMainMenuHandles = nullptr;
- hStatusMainMenuHandlesCnt = 0;
-
- hStatusMenuHandles = nullptr;
- hStatusMenuHandlesCnt = 0;
-
// new menu sys
InitGenMenu();
@@ -1138,12 +1111,6 @@ void InitCustomMenus(void) void UninitCustomMenus(void)
{
- mir_free(hStatusMainMenuHandles);
- hStatusMainMenuHandles = nullptr;
-
- mir_free(hStatusMenuHandles);
- hStatusMenuHandles = nullptr;
-
Menu_RemoveObject(hMainMenuObject);
Menu_RemoveObject(hStatusMenuObject);
diff --git a/src/mir_app/src/miranda.h b/src/mir_app/src/miranda.h index 2cfd867299..442bf85e64 100644 --- a/src/mir_app/src/miranda.h +++ b/src/mir_app/src/miranda.h @@ -120,9 +120,9 @@ extern HANDLE hPreBuildMainMenuEvent, hPreBuildContactMenuEvent; extern HANDLE hShutdownEvent, hPreShutdownEvent;
extern HMENU hMainMenu, hStatusMenu;
-extern const int statusModeList[ MAX_STATUS_COUNT ];
-extern const int skinIconStatusList[ MAX_STATUS_COUNT ];
-extern const int skinIconStatusFlags[ MAX_STATUS_COUNT ];
+extern const int statusModeList[MAX_STATUS_COUNT];
+extern const int skinIconStatusList[MAX_STATUS_COUNT];
+extern const int skinIconStatusFlags[MAX_STATUS_COUNT];
extern OBJLIST<CListEvent> g_cliEvents;
|