From 2c5081fe7d0e6b155847c5ead1b32b4b42bfe4ae Mon Sep 17 00:00:00 2001 From: George Hazan Date: Wed, 2 Nov 2016 18:30:41 +0300 Subject: - common mouse hovering processing code moved to MIR_APP_DLL - now all chats support mToolTip --- bin10/lib/mir_app.lib | Bin 86632 -> 85644 bytes bin10/lib/mir_app64.lib | Bin 82930 -> 81868 bytes bin12/lib/mir_app.lib | Bin 86632 -> 85644 bytes bin12/lib/mir_app64.lib | Bin 82930 -> 81868 bytes bin14/lib/mir_app.lib | Bin 86632 -> 85644 bytes bin14/lib/mir_app64.lib | Bin 82930 -> 81868 bytes include/m_chat.h | 2 + include/m_chat_int.h | 155 ++++++++++++++++---------------- plugins/Scriver/src/chat/window.cpp | 88 +----------------- plugins/TabSRMM/src/chat/chat.h | 2 +- plugins/TabSRMM/src/chat/window.cpp | 174 +++--------------------------------- src/core/stdmsg/src/chat_window.cpp | 86 +----------------- src/mir_app/src/chat_svc.cpp | 1 + src/mir_app/src/chat_tools.cpp | 155 ++++++++++++++++++++++++++++++++ src/mir_app/src/mir_app.def | 1 + src/mir_app/src/mir_app64.def | 1 + 16 files changed, 254 insertions(+), 411 deletions(-) diff --git a/bin10/lib/mir_app.lib b/bin10/lib/mir_app.lib index 22f52dee1a..52d915d2f5 100644 Binary files a/bin10/lib/mir_app.lib and b/bin10/lib/mir_app.lib differ diff --git a/bin10/lib/mir_app64.lib b/bin10/lib/mir_app64.lib index 34660e461e..029f559c9a 100644 Binary files a/bin10/lib/mir_app64.lib and b/bin10/lib/mir_app64.lib differ diff --git a/bin12/lib/mir_app.lib b/bin12/lib/mir_app.lib index 22f52dee1a..52d915d2f5 100644 Binary files a/bin12/lib/mir_app.lib and b/bin12/lib/mir_app.lib differ diff --git a/bin12/lib/mir_app64.lib b/bin12/lib/mir_app64.lib index 34660e461e..029f559c9a 100644 Binary files a/bin12/lib/mir_app64.lib and b/bin12/lib/mir_app64.lib differ diff --git a/bin14/lib/mir_app.lib b/bin14/lib/mir_app.lib index 22f52dee1a..52d915d2f5 100644 Binary files a/bin14/lib/mir_app.lib and b/bin14/lib/mir_app.lib differ diff --git a/bin14/lib/mir_app64.lib b/bin14/lib/mir_app64.lib index 34660e461e..029f559c9a 100644 Binary files a/bin14/lib/mir_app64.lib and b/bin14/lib/mir_app64.lib differ diff --git a/include/m_chat.h b/include/m_chat.h index 479b44ceee..12917f70ac 100644 --- a/include/m_chat.h +++ b/include/m_chat.h @@ -387,6 +387,8 @@ EXTERN_C MIR_APP_DLL(int) Chat_ChangeUserId(const char *szModule, const wchar_t EXTERN_C MIR_APP_DLL(int) Chat_SendUserMessage(const char *szModule, const wchar_t *wszId, const wchar_t *wszText); EXTERN_C MIR_APP_DLL(int) Chat_SetStatusbarText(const char *szModule, const wchar_t *wszId, const wchar_t *wszText); +EXTERN_C MIR_APP_DLL(void) Chat_HoverMouse(struct SESSION_INFO *si, HWND hwnd, LPARAM lParam, bool bUseToolTip); + ///////////////////////////////////////////////////////////////////////////////////////// #define GC_SSE_ONLYLISTED 0x0001 // processes only listed contacts, resets all contacts otherwise diff --git a/include/m_chat_int.h b/include/m_chat_int.h index eccd2318b8..9bc689994d 100644 --- a/include/m_chat_int.h +++ b/include/m_chat_int.h @@ -133,106 +133,109 @@ struct GCModuleInfoBase struct COMMANDINFO { - char *lpCommand; - COMMANDINFO *last, *next; + char *lpCommand; + COMMANDINFO *last, *next; }; struct FONTINFO { - LOGFONT lf; - COLORREF color; + LOGFONT lf; + COLORREF color; }; struct LOGINFO { - wchar_t *ptszText; - wchar_t *ptszNick; - wchar_t *ptszUID; - wchar_t *ptszStatus; - wchar_t *ptszUserInfo; - BOOL bIsMe; - BOOL bIsHighlighted; - time_t time; - int iType; + wchar_t *ptszText; + wchar_t *ptszNick; + wchar_t *ptszUID; + wchar_t *ptszStatus; + wchar_t *ptszUserInfo; + BOOL bIsMe; + BOOL bIsHighlighted; + time_t time; + int iType; DWORD dwFlags; - LOGINFO *next, *prev; + LOGINFO *next, *prev; }; struct STATUSINFO { - wchar_t* pszGroup; - HICON hIcon; - WORD Status; - STATUSINFO *next; + wchar_t *pszGroup; + HICON hIcon; + WORD Status; + STATUSINFO *next; }; struct USERINFO { - wchar_t* pszNick; - wchar_t* pszUID; - WORD Status; - int iStatusEx; - WORD ContactStatus; - USERINFO *next; + wchar_t* pszNick; + wchar_t* pszUID; + WORD Status; + int iStatusEx; + WORD ContactStatus; + USERINFO *next; }; struct GCSessionInfoBase { - HWND hWnd; + HWND hWnd; - BOOL bFGSet; - BOOL bBGSet; - BOOL bFilterEnabled; - BOOL bNicklistEnabled; - BOOL bInitDone; + BOOL bFGSet; + BOOL bBGSet; + BOOL bFilterEnabled; + BOOL bNicklistEnabled; + BOOL bInitDone; BOOL bTrimmed; - char* pszModule; - wchar_t* ptszID; - wchar_t* ptszName; - wchar_t* ptszStatusbarText; - wchar_t* ptszTopic; - - int iType; - int iFG; - int iBG; - int iSplitterY; - int iSplitterX; - int iLogFilterFlags; - int nUsersInNicklist; - int iEventCount; - int iWidth; - int iHeight; - int iStatusCount; - - WORD wStatus; - WORD wState; - WORD wCommandsNum; - void *pItemData; + char* pszModule; + wchar_t* ptszID; + wchar_t* ptszName; + wchar_t* ptszStatusbarText; + wchar_t* ptszTopic; + + int iType; + int iFG; + int iBG; + int iSplitterY; + int iSplitterX; + int iLogFilterFlags; + int nUsersInNicklist; + int iEventCount; + int iWidth; + int iHeight; + int iStatusCount; + + WORD wStatus; + WORD wState; + WORD wCommandsNum; + void *pItemData; MCONTACT hContact; - HWND hwndStatus; - time_t LastTime; - - COMMANDINFO* lpCommands; - COMMANDINFO* lpCurrentCommand; - LOGINFO* pLog; - LOGINFO* pLogEnd; - USERINFO* pUsers; - USERINFO* pMe; - STATUSINFO* pStatuses; - - wchar_t pszLogFileName[MAX_PATH]; + HWND hwndStatus; + time_t LastTime; + + BOOL isToolTip; + int currentHovered; + + COMMANDINFO* lpCommands; + COMMANDINFO* lpCurrentCommand; + LOGINFO* pLog; + LOGINFO* pLogEnd; + USERINFO* pUsers; + USERINFO* pMe; + STATUSINFO* pStatuses; + + wchar_t pszLogFileName[MAX_PATH]; SESSION_INFO *next; }; struct GCLogStreamDataBase { - char* buffer; - int bufferOffset, bufferLen; - HWND hwnd; - LOGINFO* lin; - BOOL bStripFormat; - BOOL bRedraw; + char* buffer; + int bufferOffset, bufferLen; + HWND hwnd; + LOGINFO* lin; + BOOL bStripFormat; + BOOL bRedraw; SESSION_INFO *si; }; @@ -266,12 +269,12 @@ struct GlobalLogSettingsBase int iSplitterY; int iWidth; int iHeight; - wchar_t* pszTimeStamp; - wchar_t* pszTimeStampLog; - wchar_t* pszIncomingNick; - wchar_t* pszOutgoingNick; - wchar_t* pszHighlightWords; - wchar_t* pszLogDir; + wchar_t *pszTimeStamp; + wchar_t *pszTimeStampLog; + wchar_t *pszIncomingNick; + wchar_t *pszOutgoingNick; + wchar_t *pszHighlightWords; + wchar_t *pszLogDir; HFONT UserListFont; HFONT UserListHeadingsFont; HFONT NameFont; diff --git a/plugins/Scriver/src/chat/window.cpp b/plugins/Scriver/src/chat/window.cpp index 461cb94a2c..c895b9e179 100644 --- a/plugins/Scriver/src/chat/window.cpp +++ b/plugins/Scriver/src/chat/window.cpp @@ -744,70 +744,6 @@ static LRESULT CALLBACK LogSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPAR return mir_callNextSubclass(hwnd, LogSubclassProc, msg, wParam, lParam); } -static void ProcessNickListHovering(HWND hwnd, int hoveredItem, SESSION_INFO * parentdat) -{ - static int currentHovered = -1; - static HWND hwndToolTip = NULL; - static HWND oldParent = NULL; - - if (hoveredItem == currentHovered) - return; - - currentHovered = hoveredItem; - - if (oldParent != hwnd && hwndToolTip) { - SendMessage(hwndToolTip, TTM_DELTOOL, 0, 0); - DestroyWindow(hwndToolTip); - hwndToolTip = NULL; - } - if (hoveredItem == -1) { - SendMessage(hwndToolTip, TTM_ACTIVATE, 0, 0); - return; - } - - BOOL bNewTip = FALSE; - if (!hwndToolTip) { - hwndToolTip = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL, - WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP, - CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, - hwnd, NULL, g_hInst, NULL); - bNewTip = TRUE; - } - - RECT clientRect; - GetClientRect(hwnd, &clientRect); - TOOLINFO ti = { sizeof(TOOLINFO) }; - ti.uFlags = TTF_SUBCLASS; - ti.hinst = g_hInst; - ti.hwnd = hwnd; - ti.uId = 1; - ti.rect = clientRect; - - wchar_t tszBuf[1024]; tszBuf[0] = 0; - USERINFO *ui = pci->SM_GetUserFromIndex(parentdat->ptszID, parentdat->pszModule, currentHovered); - if (ui) { - if (ProtoServiceExists(parentdat->pszModule, MS_GC_PROTO_GETTOOLTIPTEXT)) { - wchar_t *p = (wchar_t*)CallProtoService(parentdat->pszModule, MS_GC_PROTO_GETTOOLTIPTEXT, (WPARAM)parentdat->ptszID, (LPARAM)ui->pszUID); - if (p != NULL) { - wcsncpy_s(tszBuf, p, _TRUNCATE); - mir_free(p); - } - } - - if (tszBuf[0] == 0) - mir_snwprintf(tszBuf, L"%s: %s\r\n%s: %s\r\n%s: %s", - TranslateT("Nickname"), ui->pszNick, - TranslateT("Unique ID"), ui->pszUID, - TranslateT("Status"), pci->TM_WordToString(parentdat->pStatuses, ui->Status)); - - ti.lpszText = tszBuf; - } - - SendMessage(hwndToolTip, bNewTip ? TTM_ADDTOOL : TTM_UPDATETIPTEXT, 0, (LPARAM)&ti); - SendMessage(hwndToolTip, TTM_ACTIVATE, ti.lpszText != NULL, 0); - SendMessage(hwndToolTip, TTM_SETMAXTIPWIDTH, 0, 400); -} - static LRESULT CALLBACK NicklistSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { SESSION_INFO *si = (SESSION_INFO*)GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA); @@ -991,28 +927,8 @@ static LRESULT CALLBACK NicklistSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, break; case WM_MOUSEMOVE: - POINT pt = { LOWORD(lParam), HIWORD(lParam) }; - RECT clientRect; - GetClientRect(hwnd, &clientRect); - - // Mouse capturing/releasing - BOOL bInClient = PtInRect(&clientRect, pt); - if (bInClient && GetCapture() != hwnd) - SetCapture(hwnd); - else if (!bInClient) - ReleaseCapture(); - - if (bInClient) { - // hit test item under mouse - DWORD nItemUnderMouse = (DWORD)SendMessage(hwnd, LB_ITEMFROMPOINT, 0, lParam); - if (HIWORD(nItemUnderMouse) == 1) - nItemUnderMouse = (DWORD)(-1); - else - nItemUnderMouse &= 0xFFFF; - - ProcessNickListHovering(hwnd, (int)nItemUnderMouse, si); - } - else ProcessNickListHovering(hwnd, -1, NULL); + Chat_HoverMouse(si, hwnd, lParam, ServiceExists("mToolTip/HideTip")); + break; } return mir_callNextSubclass(hwnd, NicklistSubclassProc, msg, wParam, lParam); diff --git a/plugins/TabSRMM/src/chat/chat.h b/plugins/TabSRMM/src/chat/chat.h index 59f4078655..d85b8986a6 100644 --- a/plugins/TabSRMM/src/chat/chat.h +++ b/plugins/TabSRMM/src/chat/chat.h @@ -62,7 +62,7 @@ struct SESSION_INFO : public GCSessionInfoBase int iLogTrayFlags, iLogPopupFlags, iDiskLogFlags; int iSearchItem; - wchar_t szSearch[255]; + wchar_t szSearch[255]; }; struct LOGSTREAMDATA : public GCLogStreamDataBase diff --git a/plugins/TabSRMM/src/chat/window.cpp b/plugins/TabSRMM/src/chat/window.cpp index d44c0bb5b6..679b64152a 100644 --- a/plugins/TabSRMM/src/chat/window.cpp +++ b/plugins/TabSRMM/src/chat/window.cpp @@ -1263,76 +1263,6 @@ static LRESULT CALLBACK LogSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPAR return mir_callNextSubclass(hwnd, LogSubclassProc, msg, wParam, lParam); } -///////////////////////////////////////////////////////////////////////////////////////// -// process mouse - hovering for the nickname list.fires events so the protocol can -// show the userinfo - tooltip. - -static void ProcessNickListHovering(HWND hwnd, int hoveredItem, SESSION_INFO *parentdat) -{ - static int currentHovered = -1; - static HWND hwndToolTip = NULL; - static HWND oldParent = NULL; - - if (hoveredItem == currentHovered) - return; - - currentHovered = hoveredItem; - - if (oldParent != hwnd && hwndToolTip) { - SendMessage(hwndToolTip, TTM_DELTOOL, 0, 0); - DestroyWindow(hwndToolTip); - hwndToolTip = NULL; - } - - if (hoveredItem == -1) { - SendMessage(hwndToolTip, TTM_ACTIVATE, 0, 0); - return; - } - - bool bNewTip = false; - if (!hwndToolTip) { - bNewTip = true; - hwndToolTip = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL, - WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP, - CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, - hwnd, NULL, g_hInst, NULL); - } - - RECT clientRect; - GetClientRect(hwnd, &clientRect); - - TOOLINFO ti = { sizeof(ti) }; - ti.uFlags = TTF_SUBCLASS; - ti.hinst = g_hInst; - ti.hwnd = hwnd; - ti.uId = 1; - ti.rect = clientRect; - - wchar_t tszBuf[1024]; tszBuf[0] = 0; - - USERINFO *ui1 = pci->SM_GetUserFromIndex(parentdat->ptszID, parentdat->pszModule, currentHovered); - if (ui1) { - if (ProtoServiceExists(parentdat->pszModule, MS_GC_PROTO_GETTOOLTIPTEXT)) { - wchar_t *p = (wchar_t*)CallProtoService(parentdat->pszModule, MS_GC_PROTO_GETTOOLTIPTEXT, (WPARAM)parentdat->ptszID, (LPARAM)ui1->pszUID); - if (p != NULL) { - wcsncpy_s(tszBuf, p, _TRUNCATE); - mir_free(p); - } - } - - if (tszBuf[0] == 0) - mir_snwprintf(tszBuf, L"%s: %s\r\n%s: %s\r\n%s: %s", - TranslateT("Nickname"), ui1->pszNick, - TranslateT("Unique ID"), ui1->pszUID, - TranslateT("Status"), pci->TM_WordToString(parentdat->pStatuses, ui1->Status)); - ti.lpszText = tszBuf; - } - - SendMessage(hwndToolTip, bNewTip ? TTM_ADDTOOL : TTM_UPDATETIPTEXT, 0, (LPARAM)&ti); - SendMessage(hwndToolTip, TTM_ACTIVATE, (ti.lpszText != NULL), 0); - SendMessage(hwndToolTip, TTM_SETMAXTIPWIDTH, 0, 400); -} - ///////////////////////////////////////////////////////////////////////////////////////// // subclassing for the nickname list control.It is an ownerdrawn listbox @@ -1341,9 +1271,6 @@ static LRESULT CALLBACK NicklistSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, HWND hwndParent = GetParent(hwnd); TWindowData *dat = (TWindowData*)GetWindowLongPtr(hwndParent, GWLP_USERDATA); - static BOOL isToolTip = NULL; - static int currentHovered = -1; - switch (msg) { case WM_NCCALCSIZE: if (CSkin::m_DisableScrollbars) { @@ -1521,8 +1448,8 @@ static LRESULT CALLBACK NicklistSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, case WM_CONTEXTMENU: { - SESSION_INFO *parentdat = dat->si; - if (parentdat == NULL) + SESSION_INFO *si = dat->si; + if (si == NULL) break; int height = 0; @@ -1544,7 +1471,7 @@ static LRESULT CALLBACK NicklistSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, else item &= 0xFFFF; - USERINFO *ui = pci->SM_GetUserFromIndex(parentdat->ptszID, parentdat->pszModule, item); + USERINFO *ui = pci->SM_GetUserFromIndex(si->ptszID, si->pszModule, item); if (ui) { HMENU hMenu = 0; USERINFO uinew; @@ -1553,26 +1480,26 @@ static LRESULT CALLBACK NicklistSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, hti.pt.y += height - 4; ClientToScreen(hwnd, &hti.pt); - UINT uID = CreateGCMenu(hwnd, &hMenu, 0, hti.pt, parentdat, uinew.pszUID, uinew.pszNick); + UINT uID = CreateGCMenu(hwnd, &hMenu, 0, hti.pt, si, uinew.pszUID, uinew.pszNick); switch (uID) { case 0: break; case 20020: // add to highlight... { - THighLightEdit the = { THighLightEdit::CMD_ADD, parentdat, ui }; - HWND hwndDlg = CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_ADDHIGHLIGHT), parentdat->dat->pContainer->hwnd, CMUCHighlight::dlgProcAdd, (LPARAM)&the); + THighLightEdit the = { THighLightEdit::CMD_ADD, si, ui }; + HWND hwndDlg = CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_ADDHIGHLIGHT), si->dat->pContainer->hwnd, CMUCHighlight::dlgProcAdd, (LPARAM)&the); TranslateDialogDefault(hwndDlg); RECT rc, rcWnd; - GetClientRect(parentdat->pContainer->hwnd, &rcWnd); + GetClientRect(si->pContainer->hwnd, &rcWnd); GetWindowRect(hwndDlg, &rc); SetWindowPos(hwndDlg, HWND_TOP, (rcWnd.right - (rc.right - rc.left)) / 2, (rcWnd.bottom - (rc.bottom - rc.top)) / 2, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW); } break; case ID_MESS: - pci->DoEventHookAsync(GetParent(hwnd), parentdat->ptszID, parentdat->pszModule, GC_USER_PRIVMESS, ui->pszUID, NULL, 0); + pci->DoEventHookAsync(GetParent(hwnd), si->ptszID, si->pszModule, GC_USER_PRIVMESS, ui->pszUID, NULL, 0); break; default: @@ -1584,9 +1511,9 @@ static LRESULT CALLBACK NicklistSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, if (pItems) { if (SendMessage(hwnd, LB_GETSELITEMS, iSelectedItems, (LPARAM)pItems) != LB_ERR) { for (int i = 0; i < iSelectedItems; i++) { - USERINFO *ui1 = pci->SM_GetUserFromIndex(parentdat->ptszID, parentdat->pszModule, pItems[i]); + USERINFO *ui1 = pci->SM_GetUserFromIndex(si->ptszID, si->pszModule, pItems[i]); if (ui1) - pci->DoEventHookAsync(hwndParent, parentdat->ptszID, parentdat->pszModule, GC_USER_NICKLISTMENU, ui1->pszUID, NULL, (LPARAM)uID); + pci->DoEventHookAsync(hwndParent, si->ptszID, si->pszModule, GC_USER_NICKLISTMENU, ui1->pszUID, NULL, (LPARAM)uID); } } mir_free(pItems); @@ -1602,86 +1529,7 @@ static LRESULT CALLBACK NicklistSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, break; case WM_MOUSEMOVE: - RECT clientRect; - { - POINT pt = { LOWORD(lParam), HIWORD(lParam) }; - GetClientRect(hwnd, &clientRect); - if (PtInRect(&clientRect, pt)) { - // hit test item under mouse - DWORD nItemUnderMouse = (DWORD)SendMessage(hwnd, LB_ITEMFROMPOINT, 0, lParam); - if (HIWORD(nItemUnderMouse) == 1) - nItemUnderMouse = (DWORD)(-1); - else - nItemUnderMouse &= 0xFFFF; - - if (M.GetByte("adv_TipperTooltip", 1) && ServiceExists("mToolTip/HideTip")) { - if ((int)nItemUnderMouse == currentHovered) break; - currentHovered = (int)nItemUnderMouse; - - KillTimer(hwnd, 1); - - if (isToolTip) { - CallService("mToolTip/HideTip", 0, 0); - isToolTip = FALSE; - } - - if (nItemUnderMouse != -1) - SetTimer(hwnd, 1, 450, 0); - } - else ProcessNickListHovering(hwnd, (int)nItemUnderMouse, dat->si); - } - else { - if (M.GetByte("adv_TipperTooltip", 1) && ServiceExists("mToolTip/HideTip")) { - KillTimer(hwnd, 1); - if (isToolTip) { - CallService("mToolTip/HideTip", 0, 0); - isToolTip = FALSE; - } - } - else ProcessNickListHovering(hwnd, -1, NULL); - } - } - break; - - case WM_TIMER: - POINT pt; - GetCursorPos(&pt); - ScreenToClient(hwnd, &pt); - { - SESSION_INFO *parentdat = dat->si; - - DWORD nItemUnderMouse = (DWORD)SendDlgItemMessage(dat->hwnd, IDC_LIST, LB_ITEMFROMPOINT, 0, MAKELPARAM(pt.x, pt.y)); - if (HIWORD(nItemUnderMouse) == 1) - nItemUnderMouse = (DWORD)(-1); - else - nItemUnderMouse &= 0xFFFF; - if (((int)nItemUnderMouse != currentHovered) || (nItemUnderMouse == -1)) { - KillTimer(hwnd, 1); - break; - } - - USERINFO *ui1 = pci->SM_GetUserFromIndex(parentdat->ptszID, parentdat->pszModule, currentHovered); - if (ui1) { - wchar_t tszBuf[1024]; tszBuf[0] = 0; - if (ProtoServiceExists(parentdat->pszModule, MS_GC_PROTO_GETTOOLTIPTEXT)) { - wchar_t *p = (wchar_t*)CallProtoService(parentdat->pszModule, MS_GC_PROTO_GETTOOLTIPTEXT, (WPARAM)parentdat->ptszID, (LPARAM)ui1->pszUID); - if (p) { - wcsncpy_s(tszBuf, p, _TRUNCATE); - mir_free(p); - } - } - if (tszBuf[0] == 0) - mir_snwprintf(tszBuf, L"%s:\t%s\n%s:\t%s\n%s:\t%s", - TranslateT("Nick"), ui1->pszNick, - TranslateT("Unique ID"), ui1->pszUID, - TranslateT("Status"), pci->TM_WordToString(parentdat->pStatuses, ui1->Status)); - - CLCINFOTIP ti = { sizeof(ti) }; - if (CallService("mToolTip/ShowTipW", (WPARAM)tszBuf, (LPARAM)&ti)) - isToolTip = TRUE; - } - KillTimer(hwnd, 1); - } + Chat_HoverMouse(dat->si, hwnd, lParam, M.GetByte("adv_TipperTooltip", 1) && ServiceExists("mToolTip/HideTip")); break; } return mir_callNextSubclass(hwnd, NicklistSubclassProc, msg, wParam, lParam); diff --git a/src/core/stdmsg/src/chat_window.cpp b/src/core/stdmsg/src/chat_window.cpp index e0bdf171c2..6dac99e58e 100644 --- a/src/core/stdmsg/src/chat_window.cpp +++ b/src/core/stdmsg/src/chat_window.cpp @@ -945,70 +945,6 @@ static LRESULT CALLBACK TabSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPAR return mir_callNextSubclass(hwnd, TabSubclassProc, msg, wParam, lParam); } -static void ProcessNickListHovering(HWND hwnd, int hoveredItem, SESSION_INFO *si) -{ - static int currentHovered = -1; - static HWND hwndToolTip = NULL; - static HWND oldParent = NULL; - - if (hoveredItem == currentHovered) - return; - - currentHovered = hoveredItem; - - if (oldParent != hwnd && hwndToolTip) { - SendMessage(hwndToolTip, TTM_DELTOOL, 0, 0); - DestroyWindow(hwndToolTip); - hwndToolTip = NULL; - } - if (hoveredItem == -1) { - SendMessage(hwndToolTip, TTM_ACTIVATE, 0, 0); - return; - } - - BOOL bNewTip = FALSE; - if (!hwndToolTip) { - hwndToolTip = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL, - WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP, - CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, - hwnd, NULL, g_hInst, NULL); - bNewTip = TRUE; - } - - RECT clientRect; - GetClientRect(hwnd, &clientRect); - TOOLINFO ti = { sizeof(TOOLINFO) }; - ti.uFlags = TTF_SUBCLASS; - ti.hinst = g_hInst; - ti.hwnd = hwnd; - ti.uId = 1; - ti.rect = clientRect; - - wchar_t tszBuf[1024]; tszBuf[0] = 0; - USERINFO *ui = pci->SM_GetUserFromIndex(si->ptszID, si->pszModule, currentHovered); - if (ui) { - if (ProtoServiceExists(si->pszModule, MS_GC_PROTO_GETTOOLTIPTEXT)) { - wchar_t *p = (wchar_t*)CallProtoService(si->pszModule, MS_GC_PROTO_GETTOOLTIPTEXT, (WPARAM)si->ptszID, (LPARAM)ui->pszUID); - if (p != NULL) { - wcsncpy_s(tszBuf, p, _TRUNCATE); - mir_free(p); - } - } - - if (tszBuf[0] == 0) - mir_snwprintf(tszBuf, L"%s: %s\r\n%s: %s\r\n%s: %s", - TranslateT("Nickname"), ui->pszNick, - TranslateT("Unique ID"), ui->pszUID, - TranslateT("Status"), pci->TM_WordToString(si->pStatuses, ui->Status)); - - ti.lpszText = tszBuf; - } - - SendMessage(hwndToolTip, bNewTip ? TTM_ADDTOOL : TTM_UPDATETIPTEXT, 0, (LPARAM)&ti); - SendMessage(hwndToolTip, TTM_ACTIVATE, ti.lpszText != NULL, 0); - SendMessage(hwndToolTip, TTM_SETMAXTIPWIDTH, 0, 400); -} - static LRESULT CALLBACK NicklistSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { SESSION_INFO *si = (SESSION_INFO*)GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA); @@ -1115,27 +1051,7 @@ static LRESULT CALLBACK NicklistSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, break; case WM_MOUSEMOVE: - POINT pt = { LOWORD(lParam), HIWORD(lParam) }; - RECT clientRect; - GetClientRect(hwnd, &clientRect); - BOOL bInClient = PtInRect(&clientRect, pt); - // Mouse capturing/releasing - if (bInClient && GetCapture() != hwnd) - SetCapture(hwnd); - else if (!bInClient) - ReleaseCapture(); - - if (bInClient) { - // hit test item under mouse - DWORD nItemUnderMouse = (DWORD)SendMessage(hwnd, LB_ITEMFROMPOINT, 0, lParam); - if (HIWORD(nItemUnderMouse) == 1) - nItemUnderMouse = (DWORD)(-1); - else - nItemUnderMouse &= 0xFFFF; - - ProcessNickListHovering(hwnd, (int)nItemUnderMouse, si); - } - else ProcessNickListHovering(hwnd, -1, NULL); + Chat_HoverMouse(si, hwnd, lParam, ServiceExists("mToolTip/HideTip")); break; } diff --git a/src/mir_app/src/chat_svc.cpp b/src/mir_app/src/chat_svc.cpp index cd6ca15c45..3ce6a8417d 100644 --- a/src/mir_app/src/chat_svc.cpp +++ b/src/mir_app/src/chat_svc.cpp @@ -239,6 +239,7 @@ EXTERN_C MIR_APP_DLL(int) Chat_NewSession( si->iLogFilterFlags = db_get_dw(NULL, CHAT_MODULE, "FilterFlags", 0x03E0); si->bFilterEnabled = db_get_b(NULL, CHAT_MODULE, "FilterEnabled", 0); si->bNicklistEnabled = db_get_b(NULL, CHAT_MODULE, "ShowNicklist", 1); + si->currentHovered = -1; if (mi->bColor) { si->iFG = 4; diff --git a/src/mir_app/src/chat_tools.cpp b/src/mir_app/src/chat_tools.cpp index ec3ab03934..b50f2ba7ce 100644 --- a/src/mir_app/src/chat_tools.cpp +++ b/src/mir_app/src/chat_tools.cpp @@ -751,3 +751,158 @@ wchar_t* GetChatLogsFilename(SESSION_INFO *si, time_t tTime) return si->pszLogFileName; } + +///////////////////////////////////////////////////////////////////////////////////////// +// process mouse - hovering for the nickname list.fires events so the protocol can +// show the userinfo - tooltip. + +static void ProcessNickListHovering(HWND hwnd, int hoveredItem, SESSION_INFO *parentdat) +{ + static int currentHovered = -1; + static HWND hwndToolTip = NULL; + static HWND oldParent = NULL; + + if (hoveredItem == currentHovered) + return; + + currentHovered = hoveredItem; + + if (oldParent != hwnd && hwndToolTip) { + SendMessage(hwndToolTip, TTM_DELTOOL, 0, 0); + DestroyWindow(hwndToolTip); + hwndToolTip = NULL; + } + + if (hoveredItem == -1) { + SendMessage(hwndToolTip, TTM_ACTIVATE, 0, 0); + return; + } + + bool bNewTip = false; + if (!hwndToolTip) { + bNewTip = true; + hwndToolTip = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL, + WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + hwnd, NULL, g_hInst, NULL); + } + + RECT clientRect; + GetClientRect(hwnd, &clientRect); + + TOOLINFO ti = { sizeof(ti) }; + ti.uFlags = TTF_SUBCLASS; + ti.hinst = g_hInst; + ti.hwnd = hwnd; + ti.uId = 1; + ti.rect = clientRect; + + wchar_t tszBuf[1024]; tszBuf[0] = 0; + + USERINFO *ui1 = chatApi.SM_GetUserFromIndex(parentdat->ptszID, parentdat->pszModule, currentHovered); + if (ui1) { + if (ProtoServiceExists(parentdat->pszModule, MS_GC_PROTO_GETTOOLTIPTEXT)) { + wchar_t *p = (wchar_t*)CallProtoService(parentdat->pszModule, MS_GC_PROTO_GETTOOLTIPTEXT, (WPARAM)parentdat->ptszID, (LPARAM)ui1->pszUID); + if (p != NULL) { + wcsncpy_s(tszBuf, p, _TRUNCATE); + mir_free(p); + } + } + + if (tszBuf[0] == 0) + mir_snwprintf(tszBuf, L"%s: %s\r\n%s: %s\r\n%s: %s", + TranslateT("Nickname"), ui1->pszNick, + TranslateT("Unique ID"), ui1->pszUID, + TranslateT("Status"), chatApi.TM_WordToString(parentdat->pStatuses, ui1->Status)); + ti.lpszText = tszBuf; + } + + SendMessage(hwndToolTip, bNewTip ? TTM_ADDTOOL : TTM_UPDATETIPTEXT, 0, (LPARAM)&ti); + SendMessage(hwndToolTip, TTM_ACTIVATE, (ti.lpszText != NULL), 0); + SendMessage(hwndToolTip, TTM_SETMAXTIPWIDTH, 0, 400); +} + +static void CALLBACK ChatTimerProc(HWND hwnd, UINT, UINT_PTR idEvent, DWORD) +{ + SESSION_INFO *si = (SESSION_INFO*)idEvent; + + POINT pt; + GetCursorPos(&pt); + ScreenToClient(hwnd, &pt); + + DWORD nItemUnderMouse = (DWORD)SendMessage(hwnd, LB_ITEMFROMPOINT, 0, MAKELPARAM(pt.x, pt.y)); + if (HIWORD(nItemUnderMouse) == 1) + nItemUnderMouse = (DWORD)(-1); + else + nItemUnderMouse &= 0xFFFF; + if (((int)nItemUnderMouse != si->currentHovered) || (nItemUnderMouse == -1)) { + KillTimer(hwnd, idEvent); + return; + } + + USERINFO *ui1 = chatApi.SM_GetUserFromIndex(si->ptszID, si->pszModule, si->currentHovered); + if (ui1) { + wchar_t tszBuf[1024]; tszBuf[0] = 0; + if (ProtoServiceExists(si->pszModule, MS_GC_PROTO_GETTOOLTIPTEXT)) { + wchar_t *p = (wchar_t*)CallProtoService(si->pszModule, MS_GC_PROTO_GETTOOLTIPTEXT, (WPARAM)si->ptszID, (LPARAM)ui1->pszUID); + if (p) { + wcsncpy_s(tszBuf, p, _TRUNCATE); + mir_free(p); + } + } + if (tszBuf[0] == 0) + mir_snwprintf(tszBuf, L"%s:\t%s\n%s:\t%s\n%s:\t%s", + TranslateT("Nick"), ui1->pszNick, + TranslateT("Unique ID"), ui1->pszUID, + TranslateT("Status"), chatApi.TM_WordToString(si->pStatuses, ui1->Status)); + + CLCINFOTIP ti = { sizeof(ti) }; + if (CallService("mToolTip/ShowTipW", (WPARAM)tszBuf, (LPARAM)&ti)) + si->isToolTip = TRUE; + } + KillTimer(hwnd, idEvent); +} + +MIR_APP_DLL(void) Chat_HoverMouse(SESSION_INFO *si, HWND hwnd, LPARAM lParam, bool bUseToolTip) +{ + RECT clientRect; + { + POINT pt = { LOWORD(lParam), HIWORD(lParam) }; + GetClientRect(hwnd, &clientRect); + if (PtInRect(&clientRect, pt)) { + // hit test item under mouse + DWORD nItemUnderMouse = (DWORD)SendMessage(hwnd, LB_ITEMFROMPOINT, 0, lParam); + if (HIWORD(nItemUnderMouse) == 1) + nItemUnderMouse = (DWORD)(-1); + else + nItemUnderMouse &= 0xFFFF; + + if (bUseToolTip) { + if ((int)nItemUnderMouse == si->currentHovered) + return; + si->currentHovered = (int)nItemUnderMouse; + + KillTimer(hwnd, 1); + + if (si->isToolTip) { + CallService("mToolTip/HideTip", 0, 0); + si->isToolTip = FALSE; + } + + if (nItemUnderMouse != -1) + SetTimer(hwnd, (UINT_PTR)si, 450, ChatTimerProc); + } + else ProcessNickListHovering(hwnd, (int)nItemUnderMouse, si); + } + else { + if (bUseToolTip) { + KillTimer(hwnd, 1); + if (si->isToolTip) { + CallService("mToolTip/HideTip", 0, 0); + si->isToolTip = FALSE; + } + } + else ProcessNickListHovering(hwnd, -1, NULL); + } + } +} diff --git a/src/mir_app/src/mir_app.def b/src/mir_app/src/mir_app.def index ba2397c37b..cb33d7d808 100644 --- a/src/mir_app/src/mir_app.def +++ b/src/mir_app/src/mir_app.def @@ -326,3 +326,4 @@ Font_RegisterW @326 Options_AddPage @327 Options_Open @328 Options_OpenPage @329 +Chat_HoverMouse @330 diff --git a/src/mir_app/src/mir_app64.def b/src/mir_app/src/mir_app64.def index a1084ad408..6bf981dead 100644 --- a/src/mir_app/src/mir_app64.def +++ b/src/mir_app/src/mir_app64.def @@ -326,3 +326,4 @@ Font_RegisterW @326 Options_AddPage @327 Options_Open @328 Options_OpenPage @329 +Chat_HoverMouse @330 -- cgit v1.2.3