INT_PTR MO_RemoveMenuItem(WPARAM wParam, LPARAM) { EnterCriticalSection( &csMenuHook ); PMO_IntMenuItem pimi = MO_GetIntMenuItem(( HGENMENU )wParam ); if ( !pimi ) { LeaveCriticalSection( &csMenuHook ); return -1; } if ( pimi->submenu.first ) { MO_RecursiveWalkMenu( pimi->submenu.first, FreeMenuItem, NULL ); pimi->submenu.first = NULL; } PMO_IntMenuItem prev = MO_RecursiveWalkMenu( pimi->owner->first, FindParent, pimi ); if ( prev ) prev->next = pimi->next; if ( pimi->owner->first == pimi ) pimi->owner->first = pimi->next; if ( pimi->owner->last == pimi ) pimi->owner->last = prev; pimi->signature = 0; // invalidate all future calls to that object pimi->parent->freeItem( pimi ); LeaveCriticalSection( &csMenuHook ); return 0; }
MIR_APP_DLL(HGENMENU) Menu_GetDefaultItem(HGENMENU hMenu) { if (!bIsGenMenuInited) return NULL; TMO_IntMenuItem *pimi = MO_GetIntMenuItem(hMenu); mir_cslock lck(csMenuHook); return (pimi) ? MO_RecursiveWalkMenu(pimi, FindDefaultItem, NULL) : NULL; }
PMO_IntMenuItem MO_AddOldNewMenuItem( HANDLE menuobjecthandle, PMO_MenuItem pmi ) { if ( !bIsGenMenuInited || pmi == NULL ) return NULL; int objidx = GetMenuObjbyId( (int)menuobjecthandle ); if ( objidx == -1 ) return NULL; if ( pmi->cbSize != sizeof( TMO_MenuItem )) return NULL; if ( pmi->flags & CMIF_ROOTHANDLE ) return NULL; //is item with popup or not if ( pmi->root == 0 ) { //yes,this without popup pmi->root = NULL; //first level } else { // no,search for needed root and create it if need TCHAR* tszRoot; #if defined( _UNICODE ) if ( pmi->flags & CMIF_UNICODE ) tszRoot = mir_tstrdup(TranslateTS(( TCHAR* )pmi->root )); else tszRoot = LangPackPcharToTchar(( char* )pmi->root ); #else tszRoot = mir_tstrdup(TranslateTS(( TCHAR* )pmi->root )); #endif PMO_IntMenuItem oldroot = MO_RecursiveWalkMenu( g_menus[objidx]->m_items.first, FindRoot, tszRoot ); mir_free( tszRoot ); if ( oldroot == NULL ) { //not found,creating root TMO_MenuItem tmi = { 0 }; tmi = *pmi; tmi.flags |= CMIF_ROOTHANDLE; tmi.ownerdata = 0; tmi.root = NULL; //copy pszPopupName tmi.ptszName = ( TCHAR* )pmi->root; if (( oldroot = MO_AddNewMenuItem( menuobjecthandle, &tmi )) != NULL ) MO_SetOptionsMenuItem( oldroot, OPT_MENUITEMSETUNIQNAME, (INT_PTR)pmi->root ); } pmi->root = oldroot; //popup will be created in next commands } pmi->flags |= CMIF_ROOTHANDLE; //add popup(root allready exists) return MO_AddNewMenuItem( menuobjecthandle, pmi ); }
static int GetNextObjectMenuItemId() { // if menu commands are exausted, pack the menu array if (NextObjectMenuItemId >= CLISTMENUIDMAX) { NextObjectMenuItemId = CLISTMENUIDMIN; for (int i = 0; i < g_menus.getCount(); i++) MO_RecursiveWalkMenu(g_menus[i]->m_items.first, PackMenuItems, NULL); } return NextObjectMenuItemId++; }
int RegisterAllIconsInIconLib() { // register all icons for (int mo = 0; mo < g_menus.getCount(); mo++) { if (hStatusMenuObject == g_menus[mo]->id) //skip status menu continue; MO_RecursiveWalkMenu(g_menus[mo]->m_items.first, MO_RegisterIcon, 0); } return 0; }
int OnIconLibChanges(WPARAM, LPARAM) { EnterCriticalSection( &csMenuHook ); for ( int mo=0; mo < g_menus.getCount(); mo++ ) if ( (int)hStatusMenuObject != g_menus[mo]->id ) //skip status menu MO_RecursiveWalkMenu( g_menus[mo]->m_items.first, MO_ReloadIcon, 0 ); LeaveCriticalSection( &csMenuHook ); cli.pfnReloadProtoMenus(); return 0; }
TIntMenuObject::~TIntMenuObject() { MO_RecursiveWalkMenu( m_items.first, FreeMenuItem, NULL ); FreeAndNil(( void** )&FreeService ); FreeAndNil(( void** )&onAddService ); FreeAndNil(( void** )&CheckService ); FreeAndNil(( void** )&ExecService ); FreeAndNil(( void** )&Name ); ImageList_Destroy(m_hMenuIcons); }
MIR_APP_DLL(BOOL) Menu_ProcessCommandById(int command, LPARAM lParam) { if (!bIsGenMenuInited) return -1; mir_cslock lck(csMenuHook); for (int i = 0; i < g_menus.getCount(); i++) if (TMO_IntMenuItem *pimi = MO_RecursiveWalkMenu(g_menus[i]->m_items.first, FindMenuByCommand, &command)) return Menu_ProcessCommand(pimi, lParam); return false; }
int OnIconLibChanges(WPARAM, LPARAM) { { mir_cslock lck(csMenuHook); for (int mo = 0; mo < g_menus.getCount(); mo++) if (hStatusMenuObject != g_menus[mo]->id) //skip status menu MO_RecursiveWalkMenu(g_menus[mo]->m_items.first, MO_ReloadIcon, 0); } cli.pfnReloadProtoMenus(); return 0; }
INT_PTR MO_GetDefaultMenuItem(WPARAM wParam, LPARAM) { if ( !bIsGenMenuInited ) return -1; PMO_IntMenuItem pimi = MO_GetIntMenuItem(( HGENMENU )wParam); EnterCriticalSection( &csMenuHook ); if ( pimi ) pimi = MO_RecursiveWalkMenu( pimi, FindDefaultItem, NULL ); LeaveCriticalSection( &csMenuHook ); return ( INT_PTR )pimi; }
MIR_APP_DLL(void) KillModuleMenus(int _hLang) { if (!bIsGenMenuInited) return; KillMenuItemsParam param(_hLang); mir_cslock lck(csMenuHook); for (int i = 0; i < g_menus.getCount(); i++) MO_RecursiveWalkMenu(g_menus[i]->m_items.first, (pfnWalkFunc)KillMenuItems, ¶m); for (int k = 0; k < param.arItems.getCount(); k++) Menu_RemoveItem(param.arItems[k]); }
MIR_APP_DLL(int) Menu_RemoveItem(HGENMENU hMenuItem) { mir_cslock lck(csMenuHook); TMO_IntMenuItem *pimi = MO_GetIntMenuItem(hMenuItem); if (pimi == NULL) return -1; if (pimi->submenu.first) { MO_RecursiveWalkMenu(pimi->submenu.first, FreeMenuItem, NULL); pimi->submenu.first = NULL; } TMO_IntMenuItem *prev = MO_RecursiveWalkMenu(pimi->owner->first, FindParent, pimi); if (prev) prev->next = pimi->next; if (pimi->owner->first == pimi) pimi->owner->first = pimi->next; if (pimi->owner->last == pimi) pimi->owner->last = prev; pimi->signature = 0; // invalidate all future calls to that object pimi->parent->freeItem(pimi); return 0; }
int MO_ProcessCommandBySubMenuIdent(int menuID, int command, LPARAM lParam) { if (!bIsGenMenuInited) return -1; TMO_IntMenuItem *pimi; { mir_cslock lck(csMenuHook); TIntMenuObject *pmo = GetMenuObjbyId(menuID); if (pmo == NULL) return -1; pimi = MO_RecursiveWalkMenu(pmo->m_items.first, FindMenuByCommand, &command); } return (pimi) ? Menu_ProcessCommand(pimi, lParam) : -1; }
INT_PTR MO_ProcessCommandByMenuIdent(WPARAM wParam,LPARAM lParam) { if ( !bIsGenMenuInited ) return -1; EnterCriticalSection( &csMenuHook ); for ( int i=0; i < g_menus.getCount(); i++ ) { PMO_IntMenuItem pimi = MO_RecursiveWalkMenu( g_menus[i]->m_items.first, FindMenuByCommand, ( void* )wParam ); if ( pimi ) { LeaveCriticalSection( &csMenuHook ); return MO_ProcessCommand( pimi, lParam ); } } LeaveCriticalSection( &csMenuHook ); return FALSE; }
MIR_APP_DLL(HGENMENU) Menu_CreateRoot(int hMenuObject, LPCTSTR ptszName, int position, HANDLE hIcoLib, int _hLang) { mir_cslock lck(csMenuHook); TIntMenuObject *pmo = GetMenuObjbyId(hMenuObject); if (pmo == NULL) return NULL; TMO_IntMenuItem *oldroot = MO_RecursiveWalkMenu(pmo->m_items.first, FindRoot, (void*)ptszName); if (oldroot != NULL) return oldroot; CMenuItem mi; mi.flags = CMIF_TCHAR; mi.hIcolibItem = hIcoLib; mi.hLangpack = _hLang; mi.name.t = (TCHAR*)ptszName; mi.position = position; return Menu_AddItem(hMenuObject, &mi, NULL); }
TMO_IntMenuItem* MO_RecursiveWalkMenu(TMO_IntMenuItem *parent, pfnWalkFunc func, void* param) { if (parent == NULL) return FALSE; TMO_IntMenuItem *pnext; for (TMO_IntMenuItem *pimi = parent; pimi != NULL; pimi = pnext) { TMO_IntMenuItem *submenu = pimi->submenu.first; pnext = pimi->next; if (func(pimi, param)) // it can destroy the menu item return pimi; if (submenu) { TMO_IntMenuItem *res = MO_RecursiveWalkMenu(submenu, func, param); if (res) return res; } } return FALSE; }
int MO_ProcessCommandBySubMenuIdent(int menuID, int command, LPARAM lParam) { if ( !bIsGenMenuInited ) return -1; EnterCriticalSection( &csMenuHook ); int objidx = GetMenuObjbyId( menuID ); if ( objidx == -1 ) { LeaveCriticalSection( &csMenuHook ); return -1; } PMO_IntMenuItem pimi = MO_RecursiveWalkMenu( g_menus[objidx]->m_items.first, FindMenuByCommand, ( void* )command ); if ( pimi ) { LeaveCriticalSection( &csMenuHook ); return MO_ProcessCommand( pimi, lParam ); } LeaveCriticalSection( &csMenuHook ); return -1; }
static INT_PTR AddStatusMenuItem(WPARAM wParam, LPARAM lParam) { CLISTMENUITEM *mi = (CLISTMENUITEM*)lParam; TMO_MenuItem tmi; if (!cli.pfnConvertMenu(mi, &tmi)) return 0; // for new style menus the pszPopupName contains the root menu handle PMO_IntMenuItem pRoot = NULL; if (mi->flags & CMIF_ROOTHANDLE) pRoot = MO_GetIntMenuItem(mi->hParentMenu); // for old style menus the pszPopupName really means the popup name else { MenuProto *mp = FindProtocolMenu(mi->pszContactOwner); if (mp && mi->pszPopupName) { if (mp->pMenu) { TCHAR *ptszName = (mi->flags & CMIF_UNICODE) ? mir_tstrdup(mi->ptszPopupName) : mir_a2t(mi->pszPopupName); pRoot = MO_RecursiveWalkMenu(mp->pMenu->submenu.first, FindRoot, ptszName); mir_free(ptszName); } if (pRoot == NULL) { TMO_MenuItem tmi = { 0 }; tmi.cbSize = sizeof(tmi); tmi.flags = (mi->flags & CMIF_UNICODE) | CMIF_ROOTHANDLE; tmi.position = 1001; tmi.root = mp->pMenu; tmi.hIcon = NULL; tmi.pszName = mi->pszPopupName; pRoot = MO_AddNewMenuItem(hStatusMenuObject, &tmi); } tmi.flags |= CMIF_ROOTHANDLE; tmi.root = pRoot; } } if (wParam) { int *res = (int*)wParam; *res = (int)pRoot; } // owner data StatusMenuExecParam *smep = NULL; if (mi->pszService) { smep = (StatusMenuExecParam*)mir_calloc(sizeof(StatusMenuExecParam)); smep->custom = TRUE; smep->svc = mir_strdup(mi->pszService); { char *buf = mir_strdup(mi->pszService); int i = 0; while (buf[i] != '\0' && buf[i] != '/') i++; buf[i] = '\0'; smep->proto = mir_strdup(buf); mir_free(buf); } tmi.ownerdata = smep; } PMO_IntMenuItem menuHandle = MO_AddNewMenuItem(hStatusMenuObject, &tmi); if (smep) smep->hMenuItem = menuHandle; char buf[MAX_PATH + 64]; char *p = (pRoot) ? mir_t2a(pRoot->mi.ptszName) : NULL; mir_snprintf(buf, SIZEOF(buf), "%s/%s", (p) ? p : "", mi->pszService ? mi->pszService : ""); mir_free(p); MO_SetOptionsMenuItem(menuHandle, OPT_MENUITEMSETUNIQNAME, (INT_PTR)buf); return (INT_PTR)menuHandle; }