From e84bafdd3f3d2eb67e10a9bd3fbe600748962b6f Mon Sep 17 00:00:00 2001 From: George Hazan Date: Fri, 24 Mar 2017 15:38:17 +0300 Subject: revolution in chat menus - common code moved to the core (Chat_CreateGCMenu, Chat_DestroyGCMenu); - ability added to any plugin to add its own items into any GC menu, not only to the protocol plugins to do that a plugin calls Chat_AddMenuItems and returns 0 to allow any other plugin to process menu hook --- include/m_chat.h | 5 +- include/m_chat_int.h | 4 ++ libs/win32/mir_app.lib | Bin 115652 -> 116354 bytes libs/win64/mir_app.lib | Bin 111296 -> 111932 bytes plugins/Scriver/src/chat.h | 2 - plugins/Scriver/src/chat_tools.cpp | 88 -------------------------- plugins/Scriver/src/chat_window.cpp | 13 ++-- plugins/TabSRMM/src/chat.h | 2 - plugins/TabSRMM/src/chat_main.cpp | 17 +++++ plugins/TabSRMM/src/chat_tools.cpp | 98 ----------------------------- plugins/TabSRMM/src/chat_window.cpp | 21 ++++--- protocols/AimOscar/src/chat.cpp | 13 ++-- protocols/Discord/src/groupchat.cpp | 6 +- protocols/FacebookRM/src/chat.cpp | 8 +-- protocols/IRCG/src/resource.h | 1 - protocols/IRCG/src/services.cpp | 27 ++++---- protocols/JabberG/src/jabber_chat.cpp | 95 ++++++++++++++-------------- protocols/MSN/src/msn_chat.cpp | 9 +-- protocols/SkypeWeb/src/skype_chatrooms.cpp | 31 +++------ protocols/VKontakte/src/vk_chats.cpp | 13 ++-- protocols/WhatsApp/src/chat.cpp | 12 ++-- src/core/stdmsg/src/chat_util.cpp | 90 -------------------------- src/core/stdmsg/src/chat_window.cpp | 12 ++-- src/core/stdmsg/src/stdafx.h | 2 - src/mir_app/res/resource.rc | 2 +- src/mir_app/src/chat.h | 6 +- src/mir_app/src/chat_tools.cpp | 93 +++++++++++++++++++++++++++ src/mir_app/src/mir_app.def | 3 + src/mir_app/src/mir_app64.def | 3 + src/mir_app/src/resource.h | 2 +- src/mir_app/src/searchresults.cpp | 2 +- src/mir_app/src/srmm_base.cpp | 4 -- 32 files changed, 238 insertions(+), 446 deletions(-) diff --git a/include/m_chat.h b/include/m_chat.h index 6188353d45..c241b7675c 100644 --- a/include/m_chat.h +++ b/include/m_chat.h @@ -538,13 +538,14 @@ typedef struct { LPWSTR pszID; // The unique identifier of the session that triggered the hook, do NOT change. LPWSTR pszUID; // Contains the unique identifier if Type = MENU_ON_NICKLIST. do NOT change. int Type; // Type of menu. MENU_ON_* flags used. do NOT change. - int nItems; // Set this to the number of menu items you want to add - gc_item *Item; // pointer to the first in the array of gc_item's + HMENU hMenu; // pass this handle to a call of Srmm_AddMenuItems } GCMENUITEMS; #define ME_GC_BUILDMENU "GChat/BuildMenu" +EXTERN_C MIR_APP_DLL(void) Chat_AddMenuItems(HMENU hMenu, int nItems, const gc_item *Item); + ////////////////////////////////////////////////////////////////////////// // Get Chat ToolTip Text for buddy // wParam = (WPARAM)(wchar_t*) roomID parentdat->ptszID diff --git a/include/m_chat_int.h b/include/m_chat_int.h index 0538621c60..0d61454f5e 100644 --- a/include/m_chat_int.h +++ b/include/m_chat_int.h @@ -387,6 +387,10 @@ EXTERN_C MIR_APP_DLL(DWORD) CALLBACK Srmm_MessageStreamCallback(DWORD_PTR dwCook // updates options for all windows EXTERN_C MIR_APP_DLL(void) Chat_UpdateOptions(); +// chat menu creation / destruction +EXTERN_C MIR_APP_DLL(UINT) Chat_CreateGCMenu(HWND hwnd, HMENU hMenu, POINT pt, SESSION_INFO *si, const wchar_t *pszUID, const wchar_t *pszWordText); +EXTERN_C MIR_APP_DLL(void) Chat_DestroyGCMenu(HMENU hMenu, int iIndex); + ///////////////////////////////////////////////////////////////////////////////////////// #include diff --git a/libs/win32/mir_app.lib b/libs/win32/mir_app.lib index 31252ff008..440bc9179c 100644 Binary files a/libs/win32/mir_app.lib and b/libs/win32/mir_app.lib differ diff --git a/libs/win64/mir_app.lib b/libs/win64/mir_app.lib index 894f9a1be4..ce654a1a3a 100644 Binary files a/libs/win64/mir_app.lib and b/libs/win64/mir_app.lib differ diff --git a/plugins/Scriver/src/chat.h b/plugins/Scriver/src/chat.h index fb21c082b8..54de98256a 100644 --- a/plugins/Scriver/src/chat.h +++ b/plugins/Scriver/src/chat.h @@ -84,8 +84,6 @@ char SM_GetStatusIndicator(SESSION_INFO *si, USERINFO *ui); // tools.c BOOL DoSoundsFlashPopupTrayStuff(SESSION_INFO *si, GCEVENT *gce, BOOL bHighlight, int bManyFix); wchar_t* my_strstri(const wchar_t* s1, const wchar_t* s2) ; -UINT CreateGCMenu(HWND hwndDlg, HMENU *hMenu, int iIndex, POINT pt, SESSION_INFO *si, wchar_t* pszUID, wchar_t* pszWordText); -void DestroyGCMenu(HMENU *hMenu, int iIndex); ///////////////////////////////////////////////////////////////////////////////////////// diff --git a/plugins/Scriver/src/chat_tools.cpp b/plugins/Scriver/src/chat_tools.cpp index 050d4656c5..18511598f0 100644 --- a/plugins/Scriver/src/chat_tools.cpp +++ b/plugins/Scriver/src/chat_tools.cpp @@ -30,91 +30,3 @@ wchar_t* my_strstri(const wchar_t* s1, const wchar_t* s2) return nullptr; } - -UINT CreateGCMenu(HWND hwnd, HMENU *hMenu, int iIndex, POINT pt, SESSION_INFO *si, wchar_t* pszUID, wchar_t* pszWordText) -{ - GCMENUITEMS gcmi = { 0 }; - HMENU hSubMenu = 0; - - *hMenu = GetSubMenu(g_hMenu, iIndex); - gcmi.pszID = si->ptszID; - gcmi.pszModule = si->pszModule; - gcmi.pszUID = pszUID; - - if (iIndex == 1) { - int iLen = GetRichTextLength(hwnd, CP_ACP, FALSE); - - EnableMenuItem(*hMenu, IDM_CLEAR, MF_ENABLED); - EnableMenuItem(*hMenu, ID_COPYALL, MF_ENABLED); - if (!iLen) { - EnableMenuItem(*hMenu, ID_COPYALL, MF_BYCOMMAND | MF_GRAYED); - EnableMenuItem(*hMenu, IDM_CLEAR, MF_BYCOMMAND | MF_GRAYED); - } - - if (pszWordText && pszWordText[0]) { - wchar_t szMenuText[4096]; - mir_snwprintf(szMenuText, TranslateT("Look up '%s':"), pszWordText); - ModifyMenu(*hMenu, 4, MF_STRING | MF_BYPOSITION, 4, szMenuText); - SetSearchEngineIcons(*hMenu, g_dat.hSearchEngineIconList); - } - else ModifyMenu(*hMenu, 4, MF_STRING | MF_GRAYED | MF_BYPOSITION, 4, TranslateT("No word to look up")); - gcmi.Type = MENU_ON_LOG; - } - else if (iIndex == 0) { - wchar_t szTemp[50]; - if (pszWordText) - mir_snwprintf(szTemp, TranslateT("&Message %s"), pszWordText); - else - mir_wstrncpy(szTemp, TranslateT("&Message"), _countof(szTemp) - 1); - - if (mir_wstrlen(szTemp) > 40) - mir_wstrncpy(szTemp + 40, L"...", 4); - ModifyMenu(*hMenu, ID_MESS, MF_STRING | MF_BYCOMMAND, ID_MESS, szTemp); - gcmi.Type = MENU_ON_NICKLIST; - } - - NotifyEventHooks(pci->hBuildMenuEvent, 0, (WPARAM)&gcmi); - - if (gcmi.nItems > 0) - AppendMenu(*hMenu, MF_SEPARATOR, 0, 0); - - for (int i = 0; i < gcmi.nItems; i++) { - wchar_t *ptszText = TranslateW(gcmi.Item[i].pszDesc); - DWORD dwState = gcmi.Item[i].bDisabled ? MF_GRAYED : 0; - - if (gcmi.Item[i].uType == MENU_NEWPOPUP) { - hSubMenu = CreateMenu(); - AppendMenu(*hMenu, dwState | MF_POPUP, (UINT_PTR)hSubMenu, ptszText); - } - else if (gcmi.Item[i].uType == MENU_POPUPHMENU) - AppendMenu(hSubMenu == 0 ? *hMenu : hSubMenu, dwState | MF_POPUP, gcmi.Item[i].dwID, ptszText); - else if (gcmi.Item[i].uType == MENU_POPUPITEM) - AppendMenu(hSubMenu == 0 ? *hMenu : hSubMenu, dwState | MF_STRING, gcmi.Item[i].dwID, ptszText); - else if (gcmi.Item[i].uType == MENU_POPUPCHECK) - AppendMenu(hSubMenu == 0 ? *hMenu : hSubMenu, dwState | MF_CHECKED | MF_STRING, gcmi.Item[i].dwID, ptszText); - else if (gcmi.Item[i].uType == MENU_POPUPSEPARATOR) - AppendMenu(hSubMenu == 0 ? *hMenu : hSubMenu, MF_SEPARATOR, 0, ptszText); - else if (gcmi.Item[i].uType == MENU_SEPARATOR) - AppendMenu(*hMenu, MF_SEPARATOR, 0, ptszText); - else if (gcmi.Item[i].uType == MENU_HMENU) - AppendMenu(*hMenu, dwState | MF_POPUP, gcmi.Item[i].dwID, ptszText); - else if (gcmi.Item[i].uType == MENU_ITEM) - AppendMenu(*hMenu, dwState | MF_STRING, gcmi.Item[i].dwID, ptszText); - else if (gcmi.Item[i].uType == MENU_CHECK) - AppendMenu(*hMenu, dwState | MF_CHECKED | MF_STRING, gcmi.Item[i].dwID, ptszText); - } - return TrackPopupMenu(*hMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwnd, nullptr); -} - -void DestroyGCMenu(HMENU *hMenu, int iIndex) -{ - MENUITEMINFO mii = { 0 }; - mii.cbSize = sizeof(mii); - mii.fMask = MIIM_SUBMENU; - while(GetMenuItemInfo(*hMenu, iIndex, TRUE, &mii)) - { - if (mii.hSubMenu != nullptr) - DestroyMenu(mii.hSubMenu); - RemoveMenu(*hMenu, iIndex, MF_BYPOSITION); - } -} diff --git a/plugins/Scriver/src/chat_window.cpp b/plugins/Scriver/src/chat_window.cpp index 699ff3518f..13a273c3ca 100644 --- a/plugins/Scriver/src/chat_window.cpp +++ b/plugins/Scriver/src/chat_window.cpp @@ -861,8 +861,8 @@ LRESULT CChatRoomDlg::WndProc_Log(UINT msg, WPARAM wParam, LPARAM lParam) SESSION_INFO *si = m_si; CHARRANGE all = { 0, -1 }; - HMENU hMenu = nullptr; - UINT uID = CreateGCMenu(m_log.GetHwnd(), &hMenu, 1, pt, si, nullptr, pszWord); + HMENU hMenu = GetSubMenu(g_hMenu, 1); + UINT uID = Chat_CreateGCMenu(m_log.GetHwnd(), hMenu, pt, si, nullptr, pszWord); inMenu = FALSE; switch (uID) { case 0: @@ -904,7 +904,7 @@ LRESULT CChatRoomDlg::WndProc_Log(UINT msg, WPARAM wParam, LPARAM lParam) DoEventHook(GC_USER_LOGMENU, nullptr, nullptr, uID); break; } - DestroyGCMenu(&hMenu, 5); + Chat_DestroyGCMenu(hMenu, 5); } break; @@ -950,14 +950,13 @@ LRESULT CChatRoomDlg::WndProc_Nicklist(UINT msg, WPARAM wParam, LPARAM lParam) USERINFO *ui = pci->SM_GetUserFromIndex(m_si->ptszID, m_si->pszModule, (int)item); if (ui) { - HMENU hMenu = 0; + HMENU hMenu = GetSubMenu(g_hMenu, 0); USERINFO uinew; - memcpy(&uinew, ui, sizeof(USERINFO)); if (hti.pt.x == -1 && hti.pt.y == -1) hti.pt.y += height - 4; ClientToScreen(m_nickList.GetHwnd(), &hti.pt); - UINT uID = CreateGCMenu(m_nickList.GetHwnd(), &hMenu, 0, hti.pt, m_si, uinew.pszUID, uinew.pszNick); + UINT uID = Chat_CreateGCMenu(m_nickList.GetHwnd(), hMenu, hti.pt, m_si, uinew.pszUID, uinew.pszNick); switch (uID) { case 0: @@ -971,7 +970,7 @@ LRESULT CChatRoomDlg::WndProc_Nicklist(UINT msg, WPARAM wParam, LPARAM lParam) DoEventHook(GC_USER_NICKLISTMENU, ui, nullptr, uID); break; } - DestroyGCMenu(&hMenu, 1); + Chat_DestroyGCMenu(hMenu, 1); return TRUE; } } diff --git a/plugins/TabSRMM/src/chat.h b/plugins/TabSRMM/src/chat.h index e9947ed8b3..e9f7b1ce0c 100644 --- a/plugins/TabSRMM/src/chat.h +++ b/plugins/TabSRMM/src/chat.h @@ -131,8 +131,6 @@ wchar_t* my_strstri(const wchar_t* s1, const wchar_t* s2); int GetRichTextLength(HWND hwnd); bool IsHighlighted(SESSION_INFO *si, GCEVENT *pszText); char GetIndicator(SESSION_INFO *si, LPCTSTR ptszNick, int *iNickIndex); -UINT CreateGCMenu(HWND hwndDlg, HMENU *hMenu, int iIndex, POINT pt, SESSION_INFO *si, wchar_t* pszUID, wchar_t* pszWordText); -void DestroyGCMenu(HMENU *hMenu, int iIndex); void Chat_SetFilters(SESSION_INFO *si); void DoFlashAndSoundWorker(FLASH_PARAMS* p); BOOL DoPopup(SESSION_INFO *si, GCEVENT* gce); diff --git a/plugins/TabSRMM/src/chat_main.cpp b/plugins/TabSRMM/src/chat_main.cpp index 626c5aea5c..bbc0162b93 100644 --- a/plugins/TabSRMM/src/chat_main.cpp +++ b/plugins/TabSRMM/src/chat_main.cpp @@ -206,6 +206,22 @@ static void CheckUpdate() db_set_b(0, "Compatibility", "TabChatFonts", 3); } +///////////////////////////////////////////////////////////////////////////////////////// + +static gc_item tabItems[] = +{ + { TranslateT("Highlight user..."), 20020, MENU_ITEM } +}; + +static int OnCreateGCMenu(WPARAM, LPARAM lParam) +{ + GCMENUITEMS *gcitems = (GCMENUITEMS*)lParam; + if (gcitems->Type == MENU_ON_NICKLIST) + Chat_AddMenuItems(gcitems->hMenu, _countof(tabItems), tabItems); + + return 0; +} + // load the module int Chat_Load() { @@ -239,6 +255,7 @@ int Chat_Load() g_hMenu = LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_MENU)); + HookEvent(ME_GC_BUILDMENU, OnCreateGCMenu); g_Settings.Highlight = new CMUCHighlight(); return 0; } diff --git a/plugins/TabSRMM/src/chat_tools.cpp b/plugins/TabSRMM/src/chat_tools.cpp index 99f121c538..a3fe2d7e42 100644 --- a/plugins/TabSRMM/src/chat_tools.cpp +++ b/plugins/TabSRMM/src/chat_tools.cpp @@ -503,104 +503,6 @@ BOOL LogToFile(SESSION_INFO *si, GCEVENT *gce) return oldLogToFile(si, gce); // call kernel method } -UINT CreateGCMenu(HWND hwndDlg, HMENU *hMenu, int iIndex, POINT pt, SESSION_INFO *si, wchar_t* pszUID, wchar_t* pszWordText) -{ - HMENU hSubMenu = 0; - - *hMenu = GetSubMenu(g_hMenu, iIndex); - TranslateMenu(*hMenu); - - GCMENUITEMS gcmi = { 0 }; - gcmi.pszID = si->ptszID; - gcmi.pszModule = si->pszModule; - gcmi.pszUID = pszUID; - - if (iIndex == 1) { - int i = GetRichTextLength(GetDlgItem(hwndDlg, IDC_SRMM_LOG)); - - EnableMenuItem(*hMenu, ID_CLEARLOG, MF_ENABLED); - EnableMenuItem(*hMenu, ID_COPYALL, MF_ENABLED); - ModifyMenu(*hMenu, 4, MF_GRAYED | MF_BYPOSITION, 4, nullptr); - if (!i) { - EnableMenuItem(*hMenu, ID_COPYALL, MF_BYCOMMAND | MF_GRAYED); - EnableMenuItem(*hMenu, ID_CLEARLOG, MF_BYCOMMAND | MF_GRAYED); - if (pszWordText && pszWordText[0]) - ModifyMenu(*hMenu, 4, MF_ENABLED | MF_BYPOSITION, 4, nullptr); - } - - if (pszWordText && pszWordText[0]) { - wchar_t szMenuText[4096]; - mir_snwprintf(szMenuText, TranslateT("Look up '%s':"), pszWordText); - ModifyMenu(*hMenu, 4, MF_STRING | MF_BYPOSITION, 4, szMenuText); - } - else ModifyMenu(*hMenu, 4, MF_STRING | MF_GRAYED | MF_BYPOSITION, 4, TranslateT("No word to look up")); - gcmi.Type = MENU_ON_LOG; - } - else if (iIndex == 0) { - wchar_t szTemp[50]; - if (pszWordText) - mir_snwprintf(szTemp, TranslateT("&Message %s"), pszWordText); - else - wcsncpy_s(szTemp, TranslateT("&Message"), _TRUNCATE); - - if (mir_wstrlen(szTemp) > 40) - wcsncpy_s(szTemp + 40, 4, L"...", _TRUNCATE); - ModifyMenu(*hMenu, ID_MESS, MF_STRING | MF_BYCOMMAND, ID_MESS, szTemp); - gcmi.Type = MENU_ON_NICKLIST; - } - - NotifyEventHooks(pci->hBuildMenuEvent, 0, (WPARAM)&gcmi); - - if (gcmi.nItems > 0) - AppendMenu(*hMenu, MF_SEPARATOR, 0, 0); - - for (int i = 0; i < gcmi.nItems; i++) { - wchar_t *ptszText = TranslateW(gcmi.Item[i].pszDesc); - DWORD dwState = gcmi.Item[i].bDisabled ? MF_GRAYED : 0; - - if (gcmi.Item[i].uType == MENU_NEWPOPUP) { - hSubMenu = CreateMenu(); - AppendMenu(*hMenu, dwState | MF_POPUP, (UINT_PTR)hSubMenu, ptszText); - } - else if (gcmi.Item[i].uType == MENU_POPUPHMENU) - AppendMenu(hSubMenu == 0 ? *hMenu : hSubMenu, dwState | MF_POPUP, gcmi.Item[i].dwID, ptszText); - else if (gcmi.Item[i].uType == MENU_POPUPITEM) - AppendMenu(hSubMenu == 0 ? *hMenu : hSubMenu, dwState | MF_STRING, gcmi.Item[i].dwID, ptszText); - else if (gcmi.Item[i].uType == MENU_POPUPCHECK) - AppendMenu(hSubMenu == 0 ? *hMenu : hSubMenu, dwState | MF_CHECKED | MF_STRING, gcmi.Item[i].dwID, ptszText); - else if (gcmi.Item[i].uType == MENU_POPUPSEPARATOR) - AppendMenu(hSubMenu == 0 ? *hMenu : hSubMenu, MF_SEPARATOR, 0, ptszText); - else if (gcmi.Item[i].uType == MENU_SEPARATOR) - AppendMenu(*hMenu, MF_SEPARATOR, 0, ptszText); - else if (gcmi.Item[i].uType == MENU_HMENU) - AppendMenu(*hMenu, dwState | MF_POPUP, gcmi.Item[i].dwID, ptszText); - else if (gcmi.Item[i].uType == MENU_ITEM) - AppendMenu(*hMenu, dwState | MF_STRING, gcmi.Item[i].dwID, ptszText); - else if (gcmi.Item[i].uType == MENU_CHECK) - AppendMenu(*hMenu, dwState | MF_CHECKED | MF_STRING, gcmi.Item[i].dwID, ptszText); - } - - if (iIndex == 0) { - AppendMenu(*hMenu, MF_SEPARATOR, 0, 0); - int pos = GetMenuItemCount(*hMenu); - InsertMenu(*hMenu, pos, MF_BYPOSITION, (UINT_PTR)20020, TranslateT("Highlight user...")); - } - - return TrackPopupMenu(*hMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwndDlg, nullptr); -} - -void DestroyGCMenu(HMENU *hMenu, int iIndex) -{ - MENUITEMINFO mii = { 0 }; - mii.cbSize = sizeof(mii); - mii.fMask = MIIM_SUBMENU; - while (GetMenuItemInfo(*hMenu, iIndex, TRUE, &mii)) { - if (mii.hSubMenu != nullptr) - DestroyMenu(mii.hSubMenu); - RemoveMenu(*hMenu, iIndex, MF_BYPOSITION); - } -} - /* * set all filters and notification config for a session * uses per channel mask + filterbits, default config as backup diff --git a/plugins/TabSRMM/src/chat_window.cpp b/plugins/TabSRMM/src/chat_window.cpp index e147e83d2f..d5aa212c48 100644 --- a/plugins/TabSRMM/src/chat_window.cpp +++ b/plugins/TabSRMM/src/chat_window.cpp @@ -1606,14 +1606,14 @@ LRESULT CChatRoomDlg::WndProc_Nicklist(UINT msg, WPARAM wParam, LPARAM lParam) USERINFO *ui = pci->SM_GetUserFromIndex(si->ptszID, si->pszModule, item); if (ui) { - HMENU hMenu = 0; + HMENU hMenu = GetSubMenu(g_hMenu, 0); USERINFO uinew; memcpy(&uinew, ui, sizeof(USERINFO)); if (hti.pt.x == -1 && hti.pt.y == -1) hti.pt.y += height - 4; ClientToScreen(m_nickList.GetHwnd(), &hti.pt); - UINT uID = CreateGCMenu(m_nickList.GetHwnd(), &hMenu, 0, hti.pt, si, uinew.pszUID, uinew.pszNick); + UINT uID = Chat_CreateGCMenu(m_nickList.GetHwnd(), hMenu, hti.pt, si, uinew.pszUID, uinew.pszNick); switch (uID) { case 0: break; @@ -1639,7 +1639,7 @@ LRESULT CChatRoomDlg::WndProc_Nicklist(UINT msg, WPARAM wParam, LPARAM lParam) DoEventHook(GC_USER_NICKLISTMENU, ui, nullptr, uID); break; } - DestroyGCMenu(&hMenu, 1); + Chat_DestroyGCMenu(hMenu, 1); return TRUE; } } @@ -2174,8 +2174,8 @@ INT_PTR CChatRoomDlg::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) } } - HMENU hMenu = 0; - UINT uID = CreateGCMenu(m_hwnd, &hMenu, 1, pt, m_si, nullptr, pszWord); + HMENU hMenu = GetSubMenu(g_hMenu, 1); + UINT uID = Chat_CreateGCMenu(m_hwnd, hMenu, pt, m_si, nullptr, pszWord); switch (uID) { case 0: PostMessage(m_hwnd, WM_MOUSEACTIVATE, 0, 0); @@ -2213,7 +2213,7 @@ INT_PTR CChatRoomDlg::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) break; } - DestroyGCMenu(&hMenu, 5); + Chat_DestroyGCMenu(hMenu, 5); } } break; @@ -2248,8 +2248,8 @@ INT_PTR CChatRoomDlg::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) // clicked a nick name if (g_Settings.bClickableNicks) { if (msg == WM_RBUTTONDOWN) { - HMENU hMenu = 0; - USERINFO uiNew; + HMENU hMenu = GetSubMenu(g_hMenu, 0); + for (USERINFO *ui = m_si->pUsers; ui; ui = ui->next) { if (mir_wstrcmp(ui->pszNick, tr.lpstrText)) continue; @@ -2257,8 +2257,9 @@ INT_PTR CChatRoomDlg::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) pt.x = (short)LOWORD(((ENLINK*)lParam)->lParam); pt.y = (short)HIWORD(((ENLINK*)lParam)->lParam); ClientToScreen(((NMHDR*)lParam)->hwndFrom, &pt); + USERINFO uiNew; memcpy(&uiNew, ui, sizeof(USERINFO)); - UINT uID = CreateGCMenu(m_hwnd, &hMenu, 0, pt, m_si, uiNew.pszUID, uiNew.pszNick); + UINT uID = Chat_CreateGCMenu(m_hwnd, hMenu, pt, m_si, uiNew.pszUID, uiNew.pszNick); switch (uID) { case 0: break; @@ -2271,7 +2272,7 @@ INT_PTR CChatRoomDlg::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) DoEventHook(GC_USER_NICKLISTMENU, ui, nullptr, (LPARAM)uID); break; } - DestroyGCMenu(&hMenu, 1); + Chat_DestroyGCMenu(hMenu, 1); return TRUE; } return TRUE; diff --git a/protocols/AimOscar/src/chat.cpp b/protocols/AimOscar/src/chat.cpp index bd7a371619..24df22d77b 100644 --- a/protocols/AimOscar/src/chat.cpp +++ b/protocols/AimOscar/src/chat.cpp @@ -162,16 +162,15 @@ int CAimProto::OnGCEvent(WPARAM, LPARAM lParam) int CAimProto::OnGCMenuHook(WPARAM, LPARAM lParam) { GCMENUITEMS *gcmi = (GCMENUITEMS*)lParam; - - if (gcmi == NULL || _stricmp(gcmi->pszModule, m_szModuleName)) return 0; + if (mir_strcmp(gcmi->pszModule, m_szModuleName)) + return 0; if (gcmi->Type == MENU_ON_LOG) { static const struct gc_item Items[] = { { TranslateT("&Invite user..."), 10, MENU_ITEM, FALSE }, { TranslateT("&Leave chat session"), 20, MENU_ITEM, FALSE } }; - gcmi->nItems = _countof(Items); - gcmi->Item = (gc_item*)Items; + Chat_AddMenuItems(gcmi->hMenu, _countof(Items), Items); } else if (gcmi->Type == MENU_ON_NICKLIST) { char* sn = mir_u2a(gcmi->pszUID); @@ -182,16 +181,14 @@ int CAimProto::OnGCMenuHook(WPARAM, LPARAM lParam) { L"", 100, MENU_SEPARATOR, FALSE }, { TranslateT("&Leave chat session"), 110, MENU_ITEM, FALSE } }; - gcmi->nItems = _countof(Items); - gcmi->Item = (gc_item*)Items; + Chat_AddMenuItems(gcmi->hMenu, _countof(Items), Items); } else { static const struct gc_item Items[] = { { TranslateT("User &details"), 10, MENU_ITEM, FALSE }, { TranslateT("User &history"), 20, MENU_ITEM, FALSE } }; - gcmi->nItems = _countof(Items); - gcmi->Item = (gc_item*)Items; + Chat_AddMenuItems(gcmi->hMenu, _countof(Items), Items); } mir_free(sn); } diff --git a/protocols/Discord/src/groupchat.cpp b/protocols/Discord/src/groupchat.cpp index e0f1603ac8..729afc84f0 100644 --- a/protocols/Discord/src/groupchat.cpp +++ b/protocols/Discord/src/groupchat.cpp @@ -60,10 +60,8 @@ int CDiscordProto::GroupchatMenuHook(WPARAM, LPARAM lParam) if (pChat == nullptr) return 0; - if (gcmi->Type == MENU_ON_LOG) { - gcmi->nItems = _countof(sttLogListItems); - gcmi->Item = sttLogListItems; - } + if (gcmi->Type == MENU_ON_LOG) + Chat_AddMenuItems(gcmi->hMenu, _countof(sttLogListItems), sttLogListItems); return 0; } diff --git a/protocols/FacebookRM/src/chat.cpp b/protocols/FacebookRM/src/chat.cpp index 126976137f..880077eb7d 100644 --- a/protocols/FacebookRM/src/chat.cpp +++ b/protocols/FacebookRM/src/chat.cpp @@ -348,8 +348,7 @@ int FacebookProto::OnGCMenuHook(WPARAM, LPARAM lParam) { LPGENW("&Invite user..."), 10, MENU_ITEM, FALSE }, { LPGENW("&Leave chat session"), 20, MENU_ITEM, FALSE } }; - gcmi->nItems = _countof(Items); - gcmi->Item = (gc_item*)Items; + Chat_AddMenuItems(gcmi->hMenu, _countof(Items), Items); } else if (gcmi->Type == MENU_ON_NICKLIST) { @@ -364,8 +363,6 @@ int FacebookProto::OnGCMenuHook(WPARAM, LPARAM lParam) }; gcmi->nItems = _countof(Items); gcmi->Item = (gc_item*)Items;*/ - gcmi->nItems = 0; - gcmi->Item = NULL; } else { @@ -374,8 +371,7 @@ int FacebookProto::OnGCMenuHook(WPARAM, LPARAM lParam) { LPGENW("User &details"), 10, MENU_ITEM, FALSE }, { LPGENW("User &history"), 20, MENU_ITEM, FALSE } }; - gcmi->nItems = _countof(Items); - gcmi->Item = (gc_item*)Items; + Chat_AddMenuItems(gcmi->hMenu, _countof(Items), Items); } } diff --git a/protocols/IRCG/src/resource.h b/protocols/IRCG/src/resource.h index 8727232122..b2462f00ca 100644 --- a/protocols/IRCG/src/resource.h +++ b/protocols/IRCG/src/resource.h @@ -11,7 +11,6 @@ #define IDD_PREFS_OTHER 113 #define IDD_ADDSERVER 120 #define IDD_LIST 123 -#define IDR_MENU 129 #define IDD_QUICKCONN 133 #define IDI_MAIN 136 #define IDD_USERINFO 154 diff --git a/protocols/IRCG/src/services.cpp b/protocols/IRCG/src/services.cpp index 6dae62da22..8e56330c58 100644 --- a/protocols/IRCG/src/services.cpp +++ b/protocols/IRCG/src/services.cpp @@ -819,28 +819,23 @@ int __cdecl CIrcProto::GCMenuHook(WPARAM, LPARAM lParam) if (gcmi) { if (!mir_strcmpi(gcmi->pszModule, m_szModuleName)) { if (gcmi->Type == MENU_ON_LOG) { - if (mir_wstrcmpi(gcmi->pszID, SERVERWINDOW)) { - gcmi->nItems = _countof(logItems); - gcmi->Item = logItems; - } - else gcmi->nItems = 0; + if (mir_wstrcmpi(gcmi->pszID, SERVERWINDOW)) + Chat_AddMenuItems(gcmi->hMenu, _countof(logItems), logItems); } if (gcmi->Type == MENU_ON_NICKLIST) { CONTACT user = { (wchar_t*)gcmi->pszUID, NULL, NULL, false, false, false }; MCONTACT hContact = CList_FindContact(&user); - gcmi->nItems = _countof(nickItems); - gcmi->Item = nickItems; BOOL bIsInList = (hContact && db_get_b(hContact, "CList", "NotOnList", 0) == 0); - gcmi->Item[gcmi->nItems - 1].bDisabled = bIsInList; + nickItems[_countof(nickItems)-1].bDisabled = bIsInList; unsigned long ulAdr = 0; if (m_manualHost) ulAdr = ConvertIPToInteger(m_mySpecifiedHostIP); else ulAdr = ConvertIPToInteger(m_IPFromServer ? m_myHost : m_myLocalHost); - gcmi->Item[23].bDisabled = ulAdr == 0 ? TRUE : FALSE; // DCC submenu + nickItems[23].bDisabled = ulAdr == 0 ? TRUE : FALSE; // DCC submenu CHANNELINFO *wi = (CHANNELINFO *)Chat_GetUserInfo(m_szModuleName, gcmi->pszID); BOOL bServOwner = strchr(sUserModes.c_str(), 'q') == NULL ? FALSE : TRUE; @@ -852,13 +847,13 @@ int __cdecl CIrcProto::GCMenuHook(WPARAM, LPARAM lParam) BOOL bForceEnable = GetAsyncKeyState(VK_CONTROL); - gcmi->Item[6].bDisabled /* "Control" submenu */ = !(bForceEnable || bHalfop || bOp || bAdmin || bOwner); - gcmi->Item[7].uType = gcmi->Item[8].uType = /* +/- Owner */ bServOwner ? MENU_POPUPITEM : 0; - gcmi->Item[9].uType = gcmi->Item[10].uType = /* +/- Admin */ bServAdmin ? MENU_POPUPITEM : 0; - gcmi->Item[7].bDisabled = gcmi->Item[8].bDisabled = gcmi->Item[9].bDisabled = gcmi->Item[10].bDisabled = /* +/- Owner/Admin */ - !(bForceEnable || bOwner); - gcmi->Item[11].bDisabled = gcmi->Item[12].bDisabled = gcmi->Item[13].bDisabled = gcmi->Item[14].bDisabled = /* +/- Op/hop */ - !(bForceEnable || bOp || bAdmin || bOwner); + nickItems[6].bDisabled = !(bForceEnable || bHalfop || bOp || bAdmin || bOwner); + nickItems[7].uType = nickItems[8].uType = bServOwner ? MENU_POPUPITEM : 0; + nickItems[9].uType = nickItems[10].uType = bServAdmin ? MENU_POPUPITEM : 0; + nickItems[7].bDisabled = nickItems[8].bDisabled = nickItems[9].bDisabled = nickItems[10].bDisabled = !(bForceEnable || bOwner); + nickItems[11].bDisabled = nickItems[12].bDisabled = nickItems[13].bDisabled = nickItems[14].bDisabled = !(bForceEnable || bOp || bAdmin || bOwner); + + Chat_AddMenuItems(gcmi->hMenu, _countof(nickItems), nickItems); } } } diff --git a/protocols/JabberG/src/jabber_chat.cpp b/protocols/JabberG/src/jabber_chat.cpp index e5b5a5c0b2..7223db5d5f 100644 --- a/protocols/JabberG/src/jabber_chat.cpp +++ b/protocols/JabberG/src/jabber_chat.cpp @@ -350,38 +350,39 @@ void CJabberProto::GcQuit(JABBER_LIST_ITEM *item, int code, HXML reason) ///////////////////////////////////////////////////////////////////////////////////////// // Context menu hooks -static gc_item *sttFindGcMenuItem(GCMENUITEMS *items, DWORD id) +static gc_item *sttFindGcMenuItem(int nItems, gc_item *items, DWORD id) { - for (int i = 0; i < items->nItems; i++) - if (items->Item[i].dwID == id) - return items->Item + i; - return NULL; + for (int i = 0; i < nItems; i++) + if (items[i].dwID == id) + return items + i; + + return nullptr; } -static void sttSetupGcMenuItem(GCMENUITEMS *items, DWORD id, bool disabled) +static void sttSetupGcMenuItem(int nItems, gc_item *items, DWORD id, bool disabled) { - for (int i = 0; i < items->nItems; i++) - if (!id || (items->Item[i].dwID == id)) - items->Item[i].bDisabled = disabled; + for (int i = 0; i < nItems; i++) + if (!id || (items[i].dwID == id)) + items[i].bDisabled = disabled; } -static void sttShowGcMenuItem(GCMENUITEMS *items, DWORD id, int type) +static void sttShowGcMenuItem(int nItems, gc_item *items, DWORD id, int type) { - for (int i = 0; i < items->nItems; i++) - if (!id || (items->Item[i].dwID == id)) - items->Item[i].uType = type; + for (int i = 0; i < nItems; i++) + if (!id || (items[i].dwID == id)) + items[i].uType = type; } -static void sttSetupGcMenuItems(GCMENUITEMS *items, DWORD *ids, bool disabled) +static void sttSetupGcMenuItems(int nItems, gc_item *items, DWORD *ids, bool disabled) { for (; *ids; ++ids) - sttSetupGcMenuItem(items, *ids, disabled); + sttSetupGcMenuItem(nItems, items, *ids, disabled); } -static void sttShowGcMenuItems(GCMENUITEMS *items, DWORD *ids, int type) +static void sttShowGcMenuItems(int nItems, gc_item *items, DWORD *ids, int type) { for (; *ids; ++ids) - sttShowGcMenuItem(items, *ids, type); + sttShowGcMenuItem(nItems, items, *ids, type); } static gc_item sttLogListItems[] = @@ -506,14 +507,11 @@ int CJabberProto::JabberGcMenuHook(WPARAM, LPARAM lParam) if (gcmi->Type == MENU_ON_LOG) { static wchar_t url_buf[1024] = { 0 }; - gcmi->nItems = _countof(sttLogListItems); - gcmi->Item = sttLogListItems; - static DWORD sttModeratorItems[] = { IDM_LST_PARTICIPANT, 0 }; static DWORD sttAdminItems[] = { IDM_LST_MODERATOR, IDM_LST_MEMBER, IDM_LST_ADMIN, IDM_LST_OWNER, IDM_LST_BAN, 0 }; static DWORD sttOwnerItems[] = { IDM_CONFIG, IDM_DESTROY, 0 }; - sttSetupGcMenuItem(gcmi, 0, FALSE); + sttSetupGcMenuItem(_countof(sttLogListItems), sttLogListItems, 0, FALSE); int idx = IDM_LINK0; wchar_t *ptszStatusMsg = item->getTemp()->m_tszStatusMessage; @@ -522,7 +520,7 @@ int CJabberProto::JabberGcMenuHook(WPARAM, LPARAM lParam) for (wchar_t *p = wcsstr(ptszStatusMsg, L"http"); p && *p; p = wcsstr(p + 1, L"http")) { if (!wcsncmp(p, L"http://", 7) || !wcsncmp(p, L"https://", 8)) { mir_wstrncpy(bufPtr, p, _countof(url_buf) - (bufPtr - url_buf)); - gc_item *pItem = sttFindGcMenuItem(gcmi, idx); + gc_item *pItem = sttFindGcMenuItem(_countof(sttLogListItems), sttLogListItems, idx); pItem->pszDesc = bufPtr; pItem->uType = MENU_POPUPITEM; for (; *bufPtr && !iswspace(*bufPtr); ++bufPtr); @@ -534,28 +532,26 @@ int CJabberProto::JabberGcMenuHook(WPARAM, LPARAM lParam) } } for (; idx <= IDM_LINK9; ++idx) - sttFindGcMenuItem(gcmi, idx)->uType = 0; + sttFindGcMenuItem(_countof(sttLogListItems), sttLogListItems, idx)->uType = 0; if (!GetAsyncKeyState(VK_CONTROL)) { if (me) { - sttSetupGcMenuItems(gcmi, sttModeratorItems, (me->m_role < ROLE_MODERATOR)); - sttSetupGcMenuItems(gcmi, sttAdminItems, (me->m_affiliation < AFFILIATION_ADMIN)); - sttSetupGcMenuItems(gcmi, sttOwnerItems, (me->m_affiliation < AFFILIATION_OWNER)); + sttSetupGcMenuItems(_countof(sttLogListItems), sttLogListItems, sttModeratorItems, (me->m_role < ROLE_MODERATOR)); + sttSetupGcMenuItems(_countof(sttLogListItems), sttLogListItems, sttAdminItems, (me->m_affiliation < AFFILIATION_ADMIN)); + sttSetupGcMenuItems(_countof(sttLogListItems), sttLogListItems, sttOwnerItems, (me->m_affiliation < AFFILIATION_OWNER)); } if (m_ThreadInfo->jabberServerCaps & JABBER_CAPS_PRIVATE_STORAGE) - sttSetupGcMenuItem(gcmi, IDM_BOOKMARKS, FALSE); + sttSetupGcMenuItem(_countof(sttLogListItems), sttLogListItems, IDM_BOOKMARKS, FALSE); } + Chat_AddMenuItems(gcmi->hMenu, _countof(sttLogListItems), sttLogListItems); } else if (gcmi->Type == MENU_ON_NICKLIST) { - gcmi->nItems = _countof(sttListItems); - gcmi->Item = sttListItems; - static DWORD sttRJidItems[] = { IDM_RJID_VCARD, IDM_RJID_ADD, IDM_RJID_COPY, 0 }; if (me && him) { int i, idx; BOOL force = GetAsyncKeyState(VK_CONTROL); - sttSetupGcMenuItem(gcmi, 0, FALSE); + sttSetupGcMenuItem(_countof(sttListItems), sttListItems, 0, FALSE); idx = IDM_LINK0; LISTFOREACH_NODEF(i, this, LIST_CHATROOM) @@ -563,7 +559,7 @@ int CJabberProto::JabberGcMenuHook(WPARAM, LPARAM lParam) if (!item->bChatActive) continue; - gc_item *pItem = sttFindGcMenuItem(gcmi, idx); + gc_item *pItem = sttFindGcMenuItem(_countof(sttListItems), sttListItems, idx); pItem->pszDesc = item->jid; pItem->uType = MENU_POPUPITEM; if (++idx > IDM_LINK9) @@ -571,16 +567,16 @@ int CJabberProto::JabberGcMenuHook(WPARAM, LPARAM lParam) } for (; idx <= IDM_LINK9; ++idx) - sttFindGcMenuItem(gcmi, idx)->uType = 0; + sttFindGcMenuItem(_countof(sttListItems), sttListItems, idx)->uType = 0; for (i = 0; i < _countof(sttAffiliationItems); i++) { - gc_item *pItem = sttFindGcMenuItem(gcmi, sttAffiliationItems[i].id); + gc_item *pItem = sttFindGcMenuItem(_countof(sttListItems), sttListItems, sttAffiliationItems[i].id); pItem->uType = (him->m_affiliation == sttAffiliationItems[i].value) ? MENU_POPUPCHECK : MENU_POPUPITEM; pItem->bDisabled = !(force || sttAffiliationItems[i].check(me, him)); } for (i = 0; i < _countof(sttRoleItems); i++) { - gc_item *pItem = sttFindGcMenuItem(gcmi, sttRoleItems[i].id); + gc_item *pItem = sttFindGcMenuItem(_countof(sttListItems), sttListItems, sttRoleItems[i].id); pItem->uType = (him->m_role == sttRoleItems[i].value) ? MENU_POPUPCHECK : MENU_POPUPITEM; pItem->bDisabled = !(force || sttRoleItems[i].check(me, him)); } @@ -590,38 +586,39 @@ int CJabberProto::JabberGcMenuHook(WPARAM, LPARAM lParam) if (wchar_t *tmp = wcschr(sttRJidBuf, '/')) *tmp = 0; if (MCONTACT hContact = HContactFromJID(him->m_tszRealJid)) { - gcmi->Item[3].uType = MENU_HMENU; - gcmi->Item[3].dwID = (INT_PTR)Menu_BuildContactMenu(hContact); - sttShowGcMenuItems(gcmi, sttRJidItems, 0); + sttListItems[3].uType = MENU_HMENU; + sttListItems[3].dwID = (INT_PTR)Menu_BuildContactMenu(hContact); + sttShowGcMenuItems(_countof(sttListItems), sttListItems, sttRJidItems, 0); } else { - gcmi->Item[3].uType = MENU_NEWPOPUP; - sttShowGcMenuItems(gcmi, sttRJidItems, MENU_POPUPITEM); + sttListItems[3].uType = MENU_NEWPOPUP; + sttShowGcMenuItems(_countof(sttListItems), sttListItems, sttRJidItems, MENU_POPUPITEM); } - sttSetupGcMenuItem(gcmi, IDM_CPY_RJID, FALSE); + sttSetupGcMenuItem(_countof(sttListItems), sttListItems, IDM_CPY_RJID, FALSE); } else { - gcmi->Item[3].uType = 0; - sttShowGcMenuItems(gcmi, sttRJidItems, 0); + sttListItems[3].uType = 0; + sttShowGcMenuItems(_countof(sttListItems), sttListItems, sttRJidItems, 0); - sttSetupGcMenuItem(gcmi, IDM_CPY_RJID, TRUE); + sttSetupGcMenuItem(_countof(sttListItems), sttListItems, IDM_CPY_RJID, TRUE); } if (!force) { if (me->m_role < ROLE_MODERATOR || (me->m_affiliation <= him->m_affiliation)) - sttSetupGcMenuItem(gcmi, IDM_KICK, TRUE); + sttSetupGcMenuItem(_countof(sttListItems), sttListItems, IDM_KICK, TRUE); if ((me->m_affiliation < AFFILIATION_ADMIN) || (me->m_affiliation == AFFILIATION_ADMIN) && (me->m_affiliation <= him->m_affiliation)) - sttSetupGcMenuItem(gcmi, IDM_SET_BAN, TRUE); + sttSetupGcMenuItem(_countof(sttListItems), sttListItems, IDM_SET_BAN, TRUE); } } else { - sttSetupGcMenuItem(gcmi, 0, TRUE); - gcmi->Item[2].uType = 0; - sttShowGcMenuItems(gcmi, sttRJidItems, 0); + sttSetupGcMenuItem(_countof(sttListItems), sttListItems, 0, TRUE); + sttListItems[2].uType = 0; + sttShowGcMenuItems(_countof(sttListItems), sttListItems, sttRJidItems, 0); } + Chat_AddMenuItems(gcmi->hMenu, _countof(sttListItems), sttListItems); } return 0; diff --git a/protocols/MSN/src/msn_chat.cpp b/protocols/MSN/src/msn_chat.cpp index f46ca005ca..e276f165a5 100644 --- a/protocols/MSN/src/msn_chat.cpp +++ b/protocols/MSN/src/msn_chat.cpp @@ -574,8 +574,7 @@ int CMsnProto::MSN_GCMenuHook(WPARAM, LPARAM lParam) { LPGENW("&Invite user..."), 10, MENU_ITEM, FALSE }, { LPGENW("&Leave chat session"), 20, MENU_ITEM, FALSE } }; - gcmi->nItems = _countof(Items); - gcmi->Item = (gc_item*)Items; + Chat_AddMenuItems(gcmi->hMenu, _countof(Items), Items); } else if (gcmi->Type == MENU_ON_NICKLIST) { char *email = mir_u2a(gcmi->pszUID); @@ -587,8 +586,7 @@ int CMsnProto::MSN_GCMenuHook(WPARAM, LPARAM lParam) { L"", 100, MENU_SEPARATOR, FALSE }, { LPGENW("&Leave chat session"), 110, MENU_ITEM, FALSE } }; - gcmi->nItems = _countof(Items); - gcmi->Item = (gc_item*)Items; + Chat_AddMenuItems(gcmi->hMenu, _countof(Items), Items); } else { static struct gc_item Items[] = @@ -608,8 +606,7 @@ int CMsnProto::MSN_GCMenuHook(WPARAM, LPARAM lParam) if (pszRole && !mir_wstrcmpi(pszRole, L"admin")) Items[3].pszDesc = LPGENW("&Deop user"); } - gcmi->nItems = _countof(Items); - gcmi->Item = (gc_item*)Items; + Chat_AddMenuItems(gcmi->hMenu, _countof(Items), Items); } mir_free(email); } diff --git a/protocols/SkypeWeb/src/skype_chatrooms.cpp b/protocols/SkypeWeb/src/skype_chatrooms.cpp index 30f566e0fc..0d0f304798 100644 --- a/protocols/SkypeWeb/src/skype_chatrooms.cpp +++ b/protocols/SkypeWeb/src/skype_chatrooms.cpp @@ -635,33 +635,22 @@ int CSkypeProto::OnGroupChatMenuHook(WPARAM, LPARAM lParam) { LPGENW("&Leave chat session"), 20, MENU_ITEM, FALSE }, { LPGENW("&Change topic..."), 30, MENU_ITEM, FALSE } }; - gcmi->nItems = _countof(Items); - gcmi->Item = (gc_item*)Items; + Chat_AddMenuItems(gcmi->hMenu, _countof(Items), Items); } else if (gcmi->Type == MENU_ON_NICKLIST) { -/* if (IsMe(_T2A(gcmi->pszUID))) + static const struct gc_item Items[] = { - gcmi->nItems = 0; - gcmi->Item = NULL; - } - else - {*/ - static const struct gc_item Items[] = - { - { LPGENW("Kick &user"), 10, MENU_ITEM }, - { NULL, 0, MENU_SEPARATOR }, - { LPGENW("Set &role"), 20, MENU_NEWPOPUP }, - { LPGENW("&Admin"), 30, MENU_POPUPITEM }, - { LPGENW("&User"), 40, MENU_POPUPITEM }, - { LPGENW("Change nick..."), 50, MENU_ITEM }, - }; - gcmi->nItems = _countof(Items); - gcmi->Item = (gc_item*)Items; -// } + { LPGENW("Kick &user"), 10, MENU_ITEM }, + { NULL, 0, MENU_SEPARATOR }, + { LPGENW("Set &role"), 20, MENU_NEWPOPUP }, + { LPGENW("&Admin"), 30, MENU_POPUPITEM }, + { LPGENW("&User"), 40, MENU_POPUPITEM }, + { LPGENW("Change nick..."), 50, MENU_ITEM }, + }; + Chat_AddMenuItems(gcmi->hMenu, _countof(Items), Items); } - return 0; } diff --git a/protocols/VKontakte/src/vk_chats.cpp b/protocols/VKontakte/src/vk_chats.cpp index 5806f618ce..484602e265 100644 --- a/protocols/VKontakte/src/vk_chats.cpp +++ b/protocols/VKontakte/src/vk_chats.cpp @@ -797,14 +797,11 @@ int CVkProto::OnGcMenuHook(WPARAM, LPARAM lParam) if (mir_strcmpi(gcmi->pszModule, m_szModuleName)) return 0; - if (gcmi->Type == MENU_ON_LOG) { - gcmi->nItems = _countof(sttLogListItems); - gcmi->Item = sttLogListItems; - } - else if (gcmi->Type == MENU_ON_NICKLIST) { - gcmi->nItems = _countof(sttListItems); - gcmi->Item = sttListItems; - } + if (gcmi->Type == MENU_ON_LOG) + Chat_AddMenuItems(gcmi->hMenu, _countof(sttLogListItems), sttLogListItems); + else if (gcmi->Type == MENU_ON_NICKLIST) + Chat_AddMenuItems(gcmi->hMenu, _countof(sttListItems), sttListItems); + return 0; } diff --git a/protocols/WhatsApp/src/chat.cpp b/protocols/WhatsApp/src/chat.cpp index a87be6a24f..38f4878f7d 100644 --- a/protocols/WhatsApp/src/chat.cpp +++ b/protocols/WhatsApp/src/chat.cpp @@ -273,14 +273,10 @@ int WhatsAppProto::OnChatMenu(WPARAM, LPARAM lParam) if (mir_strcmpi(gcmi->pszModule, m_szModuleName)) return 0; - if (gcmi->Type == MENU_ON_LOG) { - gcmi->nItems = _countof(sttLogListItems); - gcmi->Item = sttLogListItems; - } - else if (gcmi->Type == MENU_ON_NICKLIST) { - gcmi->nItems = _countof(sttNickListItems); - gcmi->Item = sttNickListItems; - } + if (gcmi->Type == MENU_ON_LOG) + Chat_AddMenuItems(gcmi->hMenu, _countof(sttLogListItems), sttLogListItems); + else if (gcmi->Type == MENU_ON_NICKLIST) + Chat_AddMenuItems(gcmi->hMenu, _countof(sttNickListItems), sttNickListItems); return 0; } diff --git a/src/core/stdmsg/src/chat_util.cpp b/src/core/stdmsg/src/chat_util.cpp index 602c2c14c5..5dff47b878 100644 --- a/src/core/stdmsg/src/chat_util.cpp +++ b/src/core/stdmsg/src/chat_util.cpp @@ -187,96 +187,6 @@ void CheckColorsInModule(const char* pszModule) } } -UINT CreateGCMenu(HWND hwndDlg, HMENU *hMenu, int iIndex, POINT pt, SESSION_INFO *si, wchar_t* pszUID, wchar_t* pszWordText) -{ - HMENU hSubMenu = 0; - *hMenu = GetSubMenu(g_hMenu, iIndex); - TranslateMenu(*hMenu); - - GCMENUITEMS gcmi = {}; - gcmi.pszID = si->ptszID; - gcmi.pszModule = si->pszModule; - gcmi.pszUID = pszUID; - - if (iIndex == 1) { - int i = GetRichTextLength(GetDlgItem(hwndDlg, IDC_SRMM_LOG)); - - EnableMenuItem(*hMenu, ID_CLEARLOG, MF_ENABLED); - EnableMenuItem(*hMenu, ID_COPYALL, MF_ENABLED); - ModifyMenu(*hMenu, 4, MF_GRAYED | MF_BYPOSITION, 4, NULL); - if (!i) { - EnableMenuItem(*hMenu, ID_COPYALL, MF_BYCOMMAND | MF_GRAYED); - EnableMenuItem(*hMenu, ID_CLEARLOG, MF_BYCOMMAND | MF_GRAYED); - if (pszWordText && pszWordText[0]) - ModifyMenu(*hMenu, 4, MF_ENABLED | MF_BYPOSITION, 4, NULL); - } - - if (pszWordText && pszWordText[0]) { - wchar_t szMenuText[4096]; - mir_snwprintf(szMenuText, TranslateT("Look up '%s':"), pszWordText); - ModifyMenu(*hMenu, 4, MF_STRING | MF_BYPOSITION, 4, szMenuText); - } - else ModifyMenu(*hMenu, 4, MF_STRING | MF_GRAYED | MF_BYPOSITION, 4, TranslateT("No word to look up")); - gcmi.Type = MENU_ON_LOG; - } - else if (iIndex == 0) { - wchar_t szTemp[50]; - if (pszWordText) - mir_snwprintf(szTemp, TranslateT("&Message %s"), pszWordText); - else - mir_wstrncpy(szTemp, TranslateT("&Message"), _countof(szTemp) - 1); - - if (mir_wstrlen(szTemp) > 40) - mir_wstrcpy(szTemp + 40, L"..."); - ModifyMenu(*hMenu, ID_MESS, MF_STRING | MF_BYCOMMAND, ID_MESS, szTemp); - gcmi.Type = MENU_ON_NICKLIST; - } - - NotifyEventHooks(pci->hBuildMenuEvent, 0, (WPARAM)&gcmi); - - if (gcmi.nItems > 0) - AppendMenu(*hMenu, MF_SEPARATOR, 0, 0); - - for (int i = 0; i < gcmi.nItems; i++) { - wchar_t* ptszText = TranslateW(gcmi.Item[i].pszDesc); - DWORD dwState = gcmi.Item[i].bDisabled ? MF_GRAYED : 0; - - if (gcmi.Item[i].uType == MENU_NEWPOPUP) { - hSubMenu = CreateMenu(); - AppendMenu(*hMenu, dwState | MF_POPUP, (UINT_PTR)hSubMenu, ptszText); - } - else if (gcmi.Item[i].uType == MENU_POPUPHMENU) - AppendMenu(hSubMenu == 0 ? *hMenu : hSubMenu, dwState | MF_POPUP, gcmi.Item[i].dwID, ptszText); - else if (gcmi.Item[i].uType == MENU_POPUPITEM) - AppendMenu(hSubMenu == 0 ? *hMenu : hSubMenu, dwState | MF_STRING, gcmi.Item[i].dwID, ptszText); - else if (gcmi.Item[i].uType == MENU_POPUPCHECK) - AppendMenu(hSubMenu == 0 ? *hMenu : hSubMenu, dwState | MF_CHECKED | MF_STRING, gcmi.Item[i].dwID, ptszText); - else if (gcmi.Item[i].uType == MENU_POPUPSEPARATOR) - AppendMenu(hSubMenu == 0 ? *hMenu : hSubMenu, MF_SEPARATOR, 0, ptszText); - else if (gcmi.Item[i].uType == MENU_SEPARATOR) - AppendMenu(*hMenu, MF_SEPARATOR, 0, ptszText); - else if (gcmi.Item[i].uType == MENU_HMENU) - AppendMenu(*hMenu, dwState | MF_POPUP, gcmi.Item[i].dwID, ptszText); - else if (gcmi.Item[i].uType == MENU_ITEM) - AppendMenu(*hMenu, dwState | MF_STRING, gcmi.Item[i].dwID, ptszText); - else if (gcmi.Item[i].uType == MENU_CHECK) - AppendMenu(*hMenu, dwState | MF_CHECKED | MF_STRING, gcmi.Item[i].dwID, ptszText); - } - return TrackPopupMenu(*hMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwndDlg, NULL); -} - -void DestroyGCMenu(HMENU *hMenu, int iIndex) -{ - MENUITEMINFO mii = {}; - mii.cbSize = sizeof(mii); - mii.fMask = MIIM_SUBMENU; - while (GetMenuItemInfo(*hMenu, iIndex, TRUE, &mii)) { - if (mii.hSubMenu != NULL) - DestroyMenu(mii.hSubMenu); - RemoveMenu(*hMenu, iIndex, MF_BYPOSITION); - } -} - void ValidateFilename(wchar_t *filename) { wchar_t *p1 = filename; diff --git a/src/core/stdmsg/src/chat_window.cpp b/src/core/stdmsg/src/chat_window.cpp index 96bef14272..bac422eb9a 100644 --- a/src/core/stdmsg/src/chat_window.cpp +++ b/src/core/stdmsg/src/chat_window.cpp @@ -1017,8 +1017,8 @@ LRESULT CChatRoomDlg::WndProc_Nicklist(UINT msg, WPARAM wParam, LPARAM lParam) hti.pt.y += height - 4; ClientToScreen(m_nickList.GetHwnd(), &hti.pt); - HMENU hMenu = 0; - UINT uID = CreateGCMenu(m_nickList.GetHwnd(), &hMenu, 0, hti.pt, m_si, uinew.pszUID, uinew.pszNick); + HMENU hMenu = GetSubMenu(g_hMenu, 0); + UINT uID = Chat_CreateGCMenu(m_nickList.GetHwnd(), hMenu, hti.pt, m_si, uinew.pszUID, uinew.pszNick); switch (uID) { case 0: break; @@ -1031,7 +1031,7 @@ LRESULT CChatRoomDlg::WndProc_Nicklist(UINT msg, WPARAM wParam, LPARAM lParam) DoEventHook(GC_USER_NICKLISTMENU, ui, nullptr, uID); break; } - DestroyGCMenu(&hMenu, 1); + Chat_DestroyGCMenu(hMenu, 1); return TRUE; } } @@ -1254,8 +1254,8 @@ INT_PTR CChatRoomDlg::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) } CHARRANGE all = { 0, -1 }; - HMENU hMenu = 0; - UINT uID = CreateGCMenu(m_hwnd, &hMenu, 1, pt, m_si, nullptr, pszWord); + HMENU hMenu = GetSubMenu(g_hMenu, 1); + UINT uID = Chat_CreateGCMenu(m_hwnd, hMenu, pt, m_si, nullptr, pszWord); switch (uID) { case 0: PostMessage(m_hwnd, WM_MOUSEACTIVATE, 0, 0); @@ -1303,7 +1303,7 @@ INT_PTR CChatRoomDlg::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) DoEventHook(GC_USER_LOGMENU, nullptr, nullptr, uID); break; } - DestroyGCMenu(&hMenu, 5); + Chat_DestroyGCMenu(hMenu, 5); } break; diff --git a/src/core/stdmsg/src/stdafx.h b/src/core/stdmsg/src/stdafx.h index 08f35ac924..6ea8005aa1 100644 --- a/src/core/stdmsg/src/stdafx.h +++ b/src/core/stdmsg/src/stdafx.h @@ -147,8 +147,6 @@ void ShowRoom(SESSION_INFO *si); int GetColorIndex(const char* pszModule, COLORREF cr); void CheckColorsInModule(const char* pszModule); int GetRichTextLength(HWND hwnd); -UINT CreateGCMenu(HWND hwndDlg, HMENU *hMenu, int iIndex, POINT pt, SESSION_INFO *si, wchar_t* pszUID, wchar_t* pszWordText); -void DestroyGCMenu(HMENU *hMenu, int iIndex); void SetButtonsPos(HWND hwndDlg, bool bIsChat); int RestoreWindowPosition(HWND hwnd, MCONTACT hContact, bool bHide); diff --git a/src/mir_app/res/resource.rc b/src/mir_app/res/resource.rc index 28b3100092..113bde9218 100644 --- a/src/mir_app/res/resource.rc +++ b/src/mir_app/res/resource.rc @@ -1266,7 +1266,7 @@ BEGIN MENUITEM "&Add to list", IDC_ADD MENUITEM SEPARATOR MENUITEM "User &details", IDC_DETAILS - MENUITEM "Send &message", IDC_SENDMESSAGE + MENUITEM "Send &message", IDM_SENDMESSAGE END POPUP "Log" BEGIN diff --git a/src/mir_app/src/chat.h b/src/mir_app/src/chat.h index dee0182b12..cb7e26f97c 100644 --- a/src/mir_app/src/chat.h +++ b/src/mir_app/src/chat.h @@ -38,6 +38,7 @@ extern int g_cbSession, g_cbModuleInfo, g_iFontMode, g_iChatLang; extern wchar_t *g_szFontGroup; extern mir_cs csChat; +extern HCURSOR g_hCurHyperlinkHand; extern char* pLogIconBmpBits[14]; extern LIST g_arSessions; @@ -79,9 +80,6 @@ INT_PTR JoinChat(WPARAM wParam, LPARAM lParam); INT_PTR LeaveChat(WPARAM wParam, LPARAM lParam); int PrebuildContactMenu(WPARAM wParam, LPARAM lParam); -// colorchooser.c -void ColorChooser(SESSION_INFO *si, BOOL bFG, HWND hwndDlg, HWND hwndTarget, HWND hwndChooser); - // options.c int OptionsInit(void); int OptionsUnInit(void); @@ -106,8 +104,6 @@ int GetColorIndex(const char *pszModule, COLORREF cr); void CheckColorsInModule(const char *pszModule); int GetRichTextLength(HWND hwnd); bool IsHighlighted(SESSION_INFO *si, GCEVENT *pszText); -UINT CreateGCMenu(HWND hwndDlg, HMENU *hMenu, int iIndex, POINT pt, SESSION_INFO *si, wchar_t* pszUID, wchar_t* pszWordText); -void DestroyGCMenu(HMENU *hMenu, int iIndex); BOOL DoEventHook(SESSION_INFO *si, int iType, const USERINFO *pUser, const wchar_t* pszText, INT_PTR dwItem); BOOL IsEventSupported(int eventType); BOOL LogToFile(SESSION_INFO *si, GCEVENT *gce); diff --git a/src/mir_app/src/chat_tools.cpp b/src/mir_app/src/chat_tools.cpp index 3c861cd593..df67d45517 100644 --- a/src/mir_app/src/chat_tools.cpp +++ b/src/mir_app/src/chat_tools.cpp @@ -749,3 +749,96 @@ MIR_APP_DLL(wchar_t*) Chat_UnescapeTags(wchar_t *str_in) *d = 0; return str_in; } + +///////////////////////////////////////////////////////////////////////////////////////// + +MIR_APP_DLL(void) Chat_AddMenuItems(HMENU hMenu, int nItems, const gc_item *Item) +{ + if (nItems > 0) + AppendMenu(hMenu, MF_SEPARATOR, 0, 0); + + HMENU hSubMenu = nullptr; + for (int i = 0; i < nItems; i++) { + wchar_t *ptszText = TranslateW(Item[i].pszDesc); + DWORD dwState = Item[i].bDisabled ? MF_GRAYED : 0; + + if (Item[i].uType == MENU_NEWPOPUP) { + hSubMenu = CreateMenu(); + AppendMenu(hMenu, dwState | MF_POPUP, (UINT_PTR)hSubMenu, ptszText); + } + else if (Item[i].uType == MENU_POPUPHMENU) + AppendMenu(hSubMenu == 0 ? hMenu : hSubMenu, dwState | MF_POPUP, Item[i].dwID, ptszText); + else if (Item[i].uType == MENU_POPUPITEM) + AppendMenu(hSubMenu == 0 ? hMenu : hSubMenu, dwState | MF_STRING, Item[i].dwID, ptszText); + else if (Item[i].uType == MENU_POPUPCHECK) + AppendMenu(hSubMenu == 0 ? hMenu : hSubMenu, dwState | MF_CHECKED | MF_STRING, Item[i].dwID, ptszText); + else if (Item[i].uType == MENU_POPUPSEPARATOR) + AppendMenu(hSubMenu == 0 ? hMenu : hSubMenu, MF_SEPARATOR, 0, ptszText); + else if (Item[i].uType == MENU_SEPARATOR) + AppendMenu(hMenu, MF_SEPARATOR, 0, ptszText); + else if (Item[i].uType == MENU_HMENU) + AppendMenu(hMenu, dwState | MF_POPUP, Item[i].dwID, ptszText); + else if (Item[i].uType == MENU_ITEM) + AppendMenu(hMenu, dwState | MF_STRING, Item[i].dwID, ptszText); + else if (Item[i].uType == MENU_CHECK) + AppendMenu(hMenu, dwState | MF_CHECKED | MF_STRING, Item[i].dwID, ptszText); + } +} + +///////////////////////////////////////////////////////////////////////////////////////// + +MIR_APP_DLL(UINT) Chat_CreateGCMenu(HWND hwnd, HMENU hMenu, POINT pt, SESSION_INFO *si, const wchar_t *pszUID, const wchar_t *pszWordText) +{ + GCMENUITEMS gcmi = {}; + gcmi.pszID = si->ptszID; + gcmi.pszModule = si->pszModule; + gcmi.pszUID = (wchar_t*)pszUID; + gcmi.hMenu = hMenu; + + if (pszUID == nullptr) { + int iLen = GetRichTextLength(hwnd); + + EnableMenuItem(hMenu, IDM_CLEAR, MF_ENABLED); + EnableMenuItem(hMenu, IDM_COPYALL, MF_ENABLED); + if (!iLen) { + EnableMenuItem(hMenu, IDM_COPYALL, MF_BYCOMMAND | MF_GRAYED); + EnableMenuItem(hMenu, IDM_CLEAR, MF_BYCOMMAND | MF_GRAYED); + } + + if (pszWordText && pszWordText[0]) { + wchar_t szMenuText[4096]; + mir_snwprintf(szMenuText, TranslateT("Look up '%s':"), pszWordText); + ModifyMenu(hMenu, 4, MF_STRING | MF_BYPOSITION, 4, szMenuText); + } + else ModifyMenu(hMenu, 4, MF_STRING | MF_GRAYED | MF_BYPOSITION, 4, TranslateT("No word to look up")); + gcmi.Type = MENU_ON_LOG; + } + else { + wchar_t szTemp[50]; + if (pszWordText) + mir_snwprintf(szTemp, TranslateT("&Message %s"), pszWordText); + else + mir_wstrncpy(szTemp, TranslateT("&Message"), _countof(szTemp) - 1); + + if (mir_wstrlen(szTemp) > 40) + mir_wstrncpy(szTemp + 40, L"...", 4); + ModifyMenu(hMenu, IDM_SENDMESSAGE, MF_STRING | MF_BYCOMMAND, IDM_SENDMESSAGE, szTemp); + gcmi.Type = MENU_ON_NICKLIST; + } + + NotifyEventHooks(chatApi.hBuildMenuEvent, 0, (WPARAM)&gcmi); + + return TrackPopupMenu(hMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwnd, nullptr); +} + +MIR_APP_DLL(void) Chat_DestroyGCMenu(HMENU hMenu, int iIndex) +{ + MENUITEMINFO mii = { 0 }; + mii.cbSize = sizeof(mii); + mii.fMask = MIIM_SUBMENU; + while (GetMenuItemInfo(hMenu, iIndex, TRUE, &mii)) { + if (mii.hSubMenu != nullptr) + DestroyMenu(mii.hSubMenu); + RemoveMenu(hMenu, iIndex, MF_BYPOSITION); + } +} diff --git a/src/mir_app/src/mir_app.def b/src/mir_app/src/mir_app.def index 1cca4f34e8..7af41520aa 100644 --- a/src/mir_app/src/mir_app.def +++ b/src/mir_app/src/mir_app.def @@ -436,3 +436,6 @@ Chat_UpdateOptions @418 NONAME ?WndProc_Nicklist@CSrmmBaseDialog@@UAEJIIJ@Z @439 NONAME ?onDblClick_List@CSrmmBaseDialog@@IAEXPAVCCtrlListBox@@@Z @440 NONAME ?OnDestroy@CSrmmBaseDialog@@MAEXXZ @441 NONAME +Chat_AddMenuItems @442 NONAME +Chat_DestroyGCMenu @443 NONAME +Chat_CreateGCMenu @444 NONAME diff --git a/src/mir_app/src/mir_app64.def b/src/mir_app/src/mir_app64.def index 79a966ee14..01e2359241 100644 --- a/src/mir_app/src/mir_app64.def +++ b/src/mir_app/src/mir_app64.def @@ -436,3 +436,6 @@ Chat_UpdateOptions @418 NONAME ?WndProc_Nicklist@CSrmmBaseDialog@@UEAA_JI_K_J@Z @439 NONAME ?onDblClick_List@CSrmmBaseDialog@@IEAAXPEAVCCtrlListBox@@@Z @440 NONAME ?OnDestroy@CSrmmBaseDialog@@MEAAXXZ @441 NONAME +Chat_AddMenuItems @442 NONAME +Chat_DestroyGCMenu @443 NONAME +Chat_CreateGCMenu @444 NONAME diff --git a/src/mir_app/src/resource.h b/src/mir_app/src/resource.h index 30d9aed425..a224363be6 100644 --- a/src/mir_app/src/resource.h +++ b/src/mir_app/src/resource.h @@ -585,7 +585,7 @@ #define POPUP_GROUPHIDEOFFLINE 40006 #define POPUP_HIDEOFFLINEROOT 40007 #define POPUP_DISABLEGROUPS 40008 -#define IDC_SENDMESSAGE 40009 +#define IDM_SENDMESSAGE 40009 #define IDM_COPYALL 40011 #define IDM_SELECTALL 40012 #define IDM_CLEAR 40013 diff --git a/src/mir_app/src/searchresults.cpp b/src/mir_app/src/searchresults.cpp index 98ab3d797c..d5760e2121 100644 --- a/src/mir_app/src/searchresults.cpp +++ b/src/mir_app/src/searchresults.cpp @@ -367,7 +367,7 @@ void ShowMoreOptionsMenu(HWND hwndDlg, int x, int y) CallService(MS_USERINFO_SHOWDIALOG, hContact, 0); } break; - case IDC_SENDMESSAGE: + case IDM_SENDMESSAGE: { MCONTACT hContact = (MCONTACT)CallProtoServiceInt(0, lsr->szProto, PS_ADDTOLIST, PALF_TEMPORARY, (LPARAM)&lsr->psr); CallService(MS_MSG_SENDMESSAGE, hContact, 0); diff --git a/src/mir_app/src/srmm_base.cpp b/src/mir_app/src/srmm_base.cpp index 41ff060148..f5dd07a69e 100644 --- a/src/mir_app/src/srmm_base.cpp +++ b/src/mir_app/src/srmm_base.cpp @@ -26,8 +26,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "chat.h" #include -extern HCURSOR g_hCurHyperlinkHand; - CSrmmBaseDialog::CSrmmBaseDialog(HINSTANCE hInst, int idDialog, SESSION_INFO *si) : CDlgBase(hInst, idDialog), m_log(this, IDC_SRMM_LOG), @@ -157,8 +155,6 @@ static LRESULT CALLBACK stubMessageProc(HWND hwnd, UINT msg, WPARAM wParam, LPAR return mir_callNextSubclass(hwnd, stubMessageProc, msg, wParam, lParam); } -///////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////// // process mouse - hovering for the nickname list.fires events so the protocol can // show the userinfo - tooltip. -- cgit v1.2.3