#include "stdafx.h" static HANDLE hMirOTRMenuObject; static HGENMENU hStatusInfoItem, hHTMLConvMenuItem; HWND hDummyPaintWin; //contactmenu exec param(ownerdata) //also used in checkservice typedef struct { char *szServiceName; } MirOTRMenuExecParam,*lpMirOTRMenuExecParam; //////////////////////////////////////////// // MirOTR MENU /////////////////////////////////////////// static INT_PTR RemoveMirOTRMenuItem(WPARAM wParam, LPARAM) { CallService(MO_REMOVEMENUITEM,wParam,0); return 0; } static INT_PTR AddMirOTRMenuItem(WPARAM, LPARAM lParam) { MIROTRMENUITEM *mi=(MIROTRMENUITEM*)lParam; if ( mi->cbSize != sizeof( MIROTRMENUITEM )) return 0; TMO_MenuItem tmi = { 0 }; tmi.cbSize = sizeof(tmi); tmi.flags = mi->flags; tmi.hIcon = mi->hIcon; tmi.hIcolibItem = mi->icolibItem; tmi.hotKey = mi->hotKey; tmi.position = mi->position; tmi.ptszName = mi->ptszName; tmi.root = mi->root; //owner data lpMirOTRMenuExecParam cmep = ( lpMirOTRMenuExecParam )mir_calloc(sizeof(MirOTRMenuExecParam)); cmep->szServiceName = mir_strdup( mi->pszService ); tmi.ownerdata = cmep; INT_PTR menuHandle = CallService(MO_ADDNEWMENUITEM, (WPARAM) hMirOTRMenuObject, (LPARAM)&tmi ); return menuHandle; } static INT_PTR BuildMirOTRMenu(WPARAM hContact, LPARAM) { ListParam param = { 0 }; param.MenuObjectHandle = hMirOTRMenuObject; param.wParam = hContact; HMENU hMenu = CreatePopupMenu(); CallService(MO_BUILDMENU,(WPARAM)hMenu,(LPARAM)¶m); return (INT_PTR)hMenu; } //called with: //wparam - ownerdata //lparam - lparam from winproc INT_PTR MirOTRMenuExecService(WPARAM wParam,LPARAM lParam) { if (wParam!=0) { lpMirOTRMenuExecParam cmep=(lpMirOTRMenuExecParam)wParam; //call with wParam=(MCONTACT)hContact CallService(cmep->szServiceName,lParam,0); } return 0; } //true - ok,false ignore INT_PTR MirOTRMenuCheckService(WPARAM wParam,LPARAM) { PCheckProcParam pcpp = ( PCheckProcParam )wParam; TMO_MenuItem mi; if ( pcpp == NULL ) return FALSE; lpMirOTRMenuExecParam cmep = ( lpMirOTRMenuExecParam )pcpp->MenuItemOwnerData; if ( cmep == NULL ) //this is rootsection...build it return TRUE; MCONTACT hContact = (MCONTACT)pcpp->wParam, hSub; if((hSub = db_mc_getMostOnline(hContact)) != 0) hContact = hSub; ConnContext *context = otrl_context_find_miranda(otr_user_state, hContact); TrustLevel level = (TrustLevel)otr_context_get_trust(context); mi.cbSize = sizeof(mi); if ( CallService(MO_GETMENUITEM, (WPARAM)pcpp->MenuItemHandle, (LPARAM)&mi) == 0) { if ( mi.flags & CMIF_HIDDEN ) return FALSE; if ( mi.flags & CMIF_NOTPRIVATE && level==TRUST_PRIVATE ) return FALSE; if ( mi.flags & CMIF_NOTFINISHED && level==TRUST_FINISHED ) return FALSE; if ( mi.flags & CMIF_NOTUNVERIFIED && level==TRUST_UNVERIFIED ) return FALSE; if ( mi.flags & CMIF_NOTNOTPRIVATE && level==TRUST_NOT_PRIVATE ) return FALSE; if (pcpp->MenuItemHandle == hStatusInfoItem) { TCHAR text[128]; mi.ptszName = text; mi.flags = CMIM_NAME | CMIM_ICON | CMIF_TCHAR; switch (level) { case TRUST_PRIVATE:{ mi.hIcolibItem = GetIconHandle(ICON_PRIVATE); mir_tstrncpy(text,TranslateT(LANG_STATUS_PRIVATE),SIZEOF(text)); size_t len = mir_tstrlen(text); if(len < SIZEOF(text)) mir_sntprintf(text+len, SIZEOF(text)-len, _T(" [v%i]"), context->protocol_version); break;} case TRUST_UNVERIFIED:{ mi.hIcolibItem = GetIconHandle(ICON_UNVERIFIED); mir_tstrncpy(text,TranslateT(LANG_STATUS_UNVERIFIED),SIZEOF(text)); size_t len = mir_tstrlen(text); if(len < SIZEOF(text)) mir_sntprintf(text+len, SIZEOF(text)-len, _T(" [v%i]"), context->protocol_version); break;} case TRUST_FINISHED: mi.hIcolibItem = GetIconHandle(ICON_FINISHED); mi.ptszName = TranslateT(LANG_STATUS_FINISHED); break; default: mi.hIcolibItem = GetIconHandle(ICON_NOT_PRIVATE); mi.ptszName = TranslateT(LANG_STATUS_DISABLED); } CallService(MO_MODIFYMENUITEM, (WPARAM)hStatusInfoItem, (LPARAM)&mi); } else if (pcpp->MenuItemHandle == hHTMLConvMenuItem) { if (db_get_b(hContact, MODULENAME, "HTMLConv", 0) ) mi.flags |= CMIM_FLAGS|CMIF_CHECKED; else mi.flags = CMIM_FLAGS|(mi.flags &~CMIF_CHECKED); CallService(MO_MODIFYMENUITEM, (WPARAM)hHTMLConvMenuItem, (LPARAM)&mi); } } return TRUE; } INT_PTR FreeOwnerDataMirOTRMenu (WPARAM, LPARAM lParam) { lpMirOTRMenuExecParam cmep = ( lpMirOTRMenuExecParam )lParam; if ( cmep != NULL ) { if (cmep->szServiceName) mir_free(cmep->szServiceName); mir_free(cmep); } return 0; } INT_PTR OnAddMenuItemMirOTRMenu (WPARAM wParam, LPARAM lParam) { MENUITEMINFO *mii = (MENUITEMINFO*)wParam; if (!mii || mii->cbSize != sizeof(MENUITEMINFO)) return 0; TMO_MenuItem mi; mi.cbSize = sizeof(mi); if ( CallService(MO_GETMENUITEM, (WPARAM)lParam, (LPARAM)&mi) == 0) { if (mi.flags & CMIF_DISABLED) { mii->fMask |= MIIM_STATE; mii->fState |= MF_DISABLED; } } return 1; } LRESULT CALLBACK PopupMenuWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_MEASUREITEM: if (CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam)) return TRUE; break; case WM_DRAWITEM: if (CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam)) return TRUE; break; case WM_COMMAND: if (CallService(MO_PROCESSCOMMANDBYMENUIDENT, wParam, GetWindowLongPtr(hwnd, GWLP_USERDATA))) return TRUE; break; } return DefWindowProc(hwnd, message, wParam, lParam); } void ShowOTRMenu(MCONTACT hContact, POINT pt){ HMENU menu = (HMENU) CallService(MS_MIROTR_MENUBUILDMIROTR, hContact, 0); SetWindowLongPtr(hDummyPaintWin, GWLP_USERDATA, (LONG_PTR)hContact); TrackPopupMenu(menu, 0, pt.x, pt.y, 0, hDummyPaintWin, 0); DestroyMenu(menu); } void InitMirOTRMenu(void) { WNDCLASS wc = {0}; wc.hInstance = hInst; wc.lpfnWndProc = PopupMenuWndProc; wc.lpszClassName = _T("MirOTRPopupMenuProcessor"); RegisterClass(&wc); hDummyPaintWin = CreateWindowEx(0, _T("MirOTRPopupMenuProcessor"), NULL, 0, 0, 0, 1, 1, 0, 0, hInst, 0); CreateServiceFunction("MirOTRMenuExecService",MirOTRMenuExecService); CreateServiceFunction("MirOTRMenuCheckService",MirOTRMenuCheckService); // menu object CreateServiceFunction("MIROTRMENUS/FreeOwnerDataMirOTRMenu",FreeOwnerDataMirOTRMenu); CreateServiceFunction("MIROTRMENUS/OnAddMenuItemMirOTRMenu",OnAddMenuItemMirOTRMenu); CreateServiceFunction(MS_MIROTR_ADDMIROTRMENUITEM,AddMirOTRMenuItem); CreateServiceFunction(MS_MIROTR_MENUBUILDMIROTR,BuildMirOTRMenu); CreateServiceFunction(MS_MIROTR_REMOVEMIROTRMENUITEM,RemoveMirOTRMenuItem); hMirOTRMenuObject = MO_CreateMenuObject("MirOTRMenu", LPGEN("MirOTR menu"), "MirOTRMenuCheckService", "MirOTRMenuExecService"); MO_SetMenuObjectParam(hMirOTRMenuObject, OPT_USERDEFINEDITEMS, FALSE); MO_SetMenuObjectParam(hMirOTRMenuObject, OPT_MENUOBJECT_SET_FREE_SERVICE, "MIROTRMENUS/FreeOwnerDataMirOTRMenu"); MO_SetMenuObjectParam(hMirOTRMenuObject, OPT_MENUOBJECT_SET_ONADD_SERVICE, "MIROTRMENUS/OnAddMenuItemMirOTRMenu"); // menu items MIROTRMENUITEM mi = {0}; mi.cbSize = sizeof(mi); mi.flags = CMIF_DISABLED | CMIF_TCHAR; mi.ptszName = LPGENT("OTR Status"); mi.position = 0; hStatusInfoItem = (HGENMENU) AddMirOTRMenuItem(0, (LPARAM) &mi); mi.flags = CMIF_TCHAR | CMIF_NOTPRIVATE | CMIF_NOTUNVERIFIED; mi.ptszName = LANG_MENU_START; mi.position = 100001; mi.pszService = MS_OTR_MENUSTART; mi.icolibItem = GetIconHandle(ICON_UNVERIFIED); AddMirOTRMenuItem(0, (LPARAM) &mi); mi.flags = CMIF_TCHAR | CMIF_NOTNOTPRIVATE | CMIF_NOTFINISHED; mi.ptszName = LANG_MENU_REFRESH; mi.position = 100002; mi.pszService = MS_OTR_MENUREFRESH; mi.icolibItem = GetIconHandle(ICON_FINISHED); AddMirOTRMenuItem(0, (LPARAM) &mi); mi.flags = CMIF_TCHAR | CMIF_NOTNOTPRIVATE; mi.ptszName = LANG_MENU_STOP; mi.position = 100003; mi.pszService = MS_OTR_MENUSTOP; mi.icolibItem = GetIconHandle(ICON_NOT_PRIVATE); AddMirOTRMenuItem(0, (LPARAM) &mi); mi.flags = CMIF_TCHAR | CMIF_NOTNOTPRIVATE | CMIF_NOTFINISHED; mi.ptszName = LANG_MENU_VERIFY; mi.position = 200001; mi.pszService = MS_OTR_MENUVERIFY; mi.icolibItem = GetIconHandle(ICON_PRIVATE); AddMirOTRMenuItem(0, (LPARAM) &mi); mi.flags = CMIF_TCHAR|CMIF_CHECKED; mi.ptszName = LANG_MENU_TOGGLEHTML; mi.position = 300001; mi.pszService = MS_OTR_MENUTOGGLEHTML; hHTMLConvMenuItem = (HGENMENU) AddMirOTRMenuItem(0, (LPARAM) &mi); } void UninitMirOTRMenu(void) { DestroyWindow(hDummyPaintWin); hDummyPaintWin = 0; UnregisterClass(_T("MirOTRPopupMenuProcessor"), hInst); if ( hMirOTRMenuObject ) CallService(MO_REMOVEMENUOBJECT, (WPARAM)hMirOTRMenuObject, 0 ); hMirOTRMenuObject = 0; }