From a5d58f74315af7451155d7976311ecd30627445f Mon Sep 17 00:00:00 2001 From: George Hazan Date: Mon, 24 Jun 2013 22:52:54 +0000 Subject: fix for hanging in NewXstatusNotify's popups git-svn-id: http://svn.miranda-ng.org/main/trunk@5129 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/NewXstatusNotify/src/common.h | 3 +- plugins/NewXstatusNotify/src/main.cpp | 2 +- plugins/NewXstatusNotify/src/popup.cpp | 147 ++++++++++++++++----------------- 3 files changed, 73 insertions(+), 79 deletions(-) (limited to 'plugins') diff --git a/plugins/NewXstatusNotify/src/common.h b/plugins/NewXstatusNotify/src/common.h index 78cdc6b807..a80d4ddab8 100644 --- a/plugins/NewXstatusNotify/src/common.h +++ b/plugins/NewXstatusNotify/src/common.h @@ -71,8 +71,6 @@ #define MODULE "NewStatusNotify" -#define WM_AWAYMSG WM_USER + 0x0192 - #define MAX_STATUSTEXT 36 #define MAX_STANDARDTEXT 36 #define MAX_SKINSOUNDNAME 36 @@ -118,6 +116,7 @@ typedef struct tagPLUGINDATA { WORD newStatus; WORD oldStatus; + HWND hWnd; HANDLE hAwayMsgProcess; HANDLE hAwayMsgHook; } PLUGINDATA; diff --git a/plugins/NewXstatusNotify/src/main.cpp b/plugins/NewXstatusNotify/src/main.cpp index 2c59b6c9c2..6e0057b537 100644 --- a/plugins/NewXstatusNotify/src/main.cpp +++ b/plugins/NewXstatusNotify/src/main.cpp @@ -680,7 +680,7 @@ void ShowStatusChangePopup(HANDLE hContact, char *szProto, WORD oldStatus, WORD ppd.PluginWindowProc = PopupDlgProc; - PLUGINDATA *pdp = (PLUGINDATA *)mir_alloc(sizeof(PLUGINDATA)); + PLUGINDATA *pdp = (PLUGINDATA *)mir_calloc(sizeof(PLUGINDATA)); pdp->oldStatus = oldStatus; pdp->newStatus = newStatus; pdp->hAwayMsgHook = NULL; diff --git a/plugins/NewXstatusNotify/src/popup.cpp b/plugins/NewXstatusNotify/src/popup.cpp index 8a0e5b19f2..211b4f6956 100644 --- a/plugins/NewXstatusNotify/src/popup.cpp +++ b/plugins/NewXstatusNotify/src/popup.cpp @@ -21,6 +21,41 @@ #include "common.h" +static int AwayMsgHook(WPARAM wParam, LPARAM lParam, LPARAM pObj) +{ + PLUGINDATA *pdp = (PLUGINDATA*)pObj; + if (pdp == NULL) + return 0; + + ACKDATA *ack = (ACKDATA *)lParam; + if (ack->type != ACKTYPE_AWAYMSG || ack->hProcess != pdp->hAwayMsgProcess) + return 0; + + //The first thing we go is removing the hook from the chain to avoid useless calls. + UnhookEvent(pdp->hAwayMsgHook); + pdp->hAwayMsgHook = NULL; + + if (ack->result != ACKRESULT_SUCCESS) + return 0; + + HANDLE hContact = PUGetContact(pdp->hWnd); + ptrT pstzLast( db_get_tsa(hContact, MODULE, "LastPopupText")); + + TCHAR *tszStatus = (TCHAR*)ack->lParam; + if (tszStatus == NULL || *tszStatus == 0) + return 0; + + TCHAR stzText[1024]; + if (pstzLast) + mir_sntprintf(stzText, SIZEOF(stzText), _T("%s\n%s"), pstzLast, tszStatus); + else + _tcsncpy(stzText, tszStatus, SIZEOF(stzText)); + SendMessage(pdp->hWnd, WM_SETREDRAW, FALSE, 0); + PUChangeTextT(pdp->hWnd, stzText); + SendMessage(pdp->hWnd, WM_SETREDRAW, TRUE, 0); + return 0; +} + void QueryAwayMessage(HWND hWnd, PLUGINDATA *pdp) { HANDLE hContact = PUGetContact(hWnd); @@ -30,48 +65,15 @@ void QueryAwayMessage(HWND hWnd, PLUGINDATA *pdp) if ((CallProtoService(szProto, PS_GETCAPS,PFLAGNUM_1, 0) & PF1_MODEMSGRECV) && (CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_3, 0) & Proto_Status2Flag(pdp->newStatus))) { + pdp->hWnd = hWnd; //The following HookEventMessage will hook the ME_PROTO_ACK event and send a WM_AWAYMSG to hWnd when the hooks get notified. - pdp->hAwayMsgHook = HookEventMessage(ME_PROTO_ACK, hWnd, WM_AWAYMSG); + pdp->hAwayMsgHook = HookEventParam(ME_PROTO_ACK, AwayMsgHook, (LPARAM)pdp); //The following instruction asks Miranda to retrieve the away message and associates a hProcess (handle) to this request. This handle will appear in the ME_PROTO_ACK event. pdp->hAwayMsgProcess = (HANDLE)CallContactService(hContact, PSS_GETAWAYMSG, 0, 0); } } } -void ReceivedAwayMessage(HWND hWnd, LPARAM lParam, PLUGINDATA * pdp) -{ - ACKDATA *ack = (ACKDATA *)lParam; - if (ack->type != ACKTYPE_AWAYMSG || ack->hProcess != pdp->hAwayMsgProcess) - return; - - //The first thing we go is removing the hook from the chain to avoid useless calls. - UnhookEvent(pdp->hAwayMsgHook); - pdp->hAwayMsgHook = NULL; - - if (ack->result != ACKRESULT_SUCCESS) - return; - - DBVARIANT dbv; - HANDLE hContact = PUGetContact(hWnd); - - if ( db_get_ts(hContact, MODULE, "LastPopupText", &dbv)) - return; - - TCHAR stzText[MAX_SECONDLINE], *tszStatus = (TCHAR*)ack->lParam; - _tcscpy(stzText, dbv.ptszVal); - db_free(&dbv); - - if (tszStatus == NULL || *tszStatus == 0) - return; - - if (stzText[0]) - _tcscat(stzText, _T("\n")); - _tcscat(stzText, tszStatus); - SendMessage(hWnd, WM_SETREDRAW, FALSE, 0); - PUChangeTextT(hWnd, stzText); - SendMessage(hWnd, WM_SETREDRAW, TRUE, 0); -} - void PopupAction(HWND hWnd, BYTE action) { HANDLE hContact = PUGetContact(hWnd); @@ -114,56 +116,49 @@ LRESULT CALLBACK PopupDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa { PLUGINDATA *pdp = NULL; - switch(message) - { - case WM_MEASUREITEM: //Needed by the contact's context menu - return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam); + switch(message) { + case WM_MEASUREITEM: //Needed by the contact's context menu + return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam); - case WM_DRAWITEM: //Needed by the contact's context menu - return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam); + case WM_DRAWITEM: //Needed by the contact's context menu + return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam); - case WM_COMMAND: - //This one returns TRUE if it processed the menu command, and FALSE if it did not process it. - if (CallServiceSync(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM)PUGetContact(hwnd))) - break; - - PopupAction(hwnd, opt.LeftClickAction); + case WM_COMMAND: + //This one returns TRUE if it processed the menu command, and FALSE if it did not process it. + if (CallServiceSync(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM)PUGetContact(hwnd))) break; - case WM_CONTEXTMENU: - PopupAction(hwnd, opt.RightClickAction); - break; + PopupAction(hwnd, opt.LeftClickAction); + break; - case UM_FREEPLUGINDATA: - pdp = (PLUGINDATA *)PUGetPluginData(hwnd); - if (pdp != NULL) { - if (pdp->hAwayMsgHook != NULL) { - UnhookEvent(pdp->hAwayMsgHook); - pdp->hAwayMsgHook = NULL; - } + case WM_CONTEXTMENU: + PopupAction(hwnd, opt.RightClickAction); + break; - mir_free(pdp); - } - return FALSE; - - case UM_INITPOPUP: - pdp = (PLUGINDATA *)PUGetPluginData(hwnd); - if (pdp != NULL) { - char *szProto = GetContactProto( PUGetContact(hwnd)); - if (szProto && opt.ReadAwayMsg && StatusHasAwayMessage(szProto, pdp->newStatus)) { - WORD myStatus = (WORD)CallProtoService(szProto, PS_GETSTATUS, 0, 0); - if (myStatus != ID_STATUS_INVISIBLE) - QueryAwayMessage(hwnd, pdp); - } + case UM_FREEPLUGINDATA: + pdp = (PLUGINDATA *)PUGetPluginData(hwnd); + if (pdp != NULL) { + if (pdp->hAwayMsgHook != NULL) { + UnhookEvent(pdp->hAwayMsgHook); + pdp->hAwayMsgHook = NULL; } - return FALSE; + mir_free(pdp); + } + return FALSE; + + case UM_INITPOPUP: + pdp = (PLUGINDATA *)PUGetPluginData(hwnd); + if (pdp != NULL) { + char *szProto = GetContactProto( PUGetContact(hwnd)); + if (szProto && opt.ReadAwayMsg && StatusHasAwayMessage(szProto, pdp->newStatus)) { + WORD myStatus = (WORD)CallProtoService(szProto, PS_GETSTATUS, 0, 0); + if (myStatus != ID_STATUS_INVISIBLE) + QueryAwayMessage(hwnd, pdp); + } + } - case WM_AWAYMSG: //We're here because ME_PROTO_ACK has been hooked to this window (too!). - pdp = (PLUGINDATA *)PUGetPluginData(hwnd); - if (pdp != NULL) - ReceivedAwayMessage(hwnd, lParam, pdp); - return FALSE; + return FALSE; } return DefWindowProc(hwnd, message, wParam, lParam); -- cgit v1.2.3