From 3a09ce8ad3e0aa8bb97266def2f38e1295392d2d Mon Sep 17 00:00:00 2001 From: MikalaiR Date: Fri, 22 Jan 2016 13:03:56 +0000 Subject: IEView: set custom context menu handler from javascript git-svn-id: http://svn.miranda-ng.org/main/trunk@16142 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/IEView/src/IEView.cpp | 107 +++++++++++++++++++++++++--------- plugins/IEView/src/IEView.h | 8 +++ plugins/IEView/src/external_funcs.cpp | 9 +++ plugins/IEView/src/external_funcs.h | 2 + 4 files changed, 97 insertions(+), 29 deletions(-) (limited to 'plugins/IEView') diff --git a/plugins/IEView/src/IEView.cpp b/plugins/IEView/src/IEView.cpp index 63276c293a..1ae29850a9 100644 --- a/plugins/IEView/src/IEView.cpp +++ b/plugins/IEView/src/IEView.cpp @@ -414,7 +414,7 @@ STDMETHODIMP_(ULONG) IEView::Release(void) STDMETHODIMP IEView::GetTypeInfoCount(UINT *pctinfo) { if (pctinfo == NULL) return E_INVALIDARG; - *pctinfo = 3; + *pctinfo = 4; return S_OK; } STDMETHODIMP IEView::GetTypeInfo(UINT, LCID, LPTYPEINFO*) @@ -432,7 +432,8 @@ STDMETHODIMP IEView::GetIDsOfNames(REFIID /*riid*/, LPOLESTR *rgszNames, UINT cN rgDispId[i] = DISPID_EXTERNAL_DB_SET; else if (!wcscmp(L"win32_ShellExecute", rgszNames[i])) rgDispId[i] = DISPID_EXTERNAL_WIN32_SHELL_EXECUTE; - + else if (!wcscmp(L"IEView_SetContextMenuHandler", rgszNames[i])) + rgDispId[i] = DISPID_EXTERNAL_SET_CONTEXTMENUHANDLER; else { rgDispId[i] = NULL; @@ -460,6 +461,8 @@ STDMETHODIMP IEView::Invoke(DISPID dispIdMember, return External::db_set(pDispParams, pVarResult); case DISPID_EXTERNAL_WIN32_SHELL_EXECUTE: return External::win32_ShellExecute(pDispParams, pVarResult); + case DISPID_EXTERNAL_SET_CONTEXTMENUHANDLER: + return External::IEView_SetContextMenuHandler(this, pDispParams, pVarResult); } return DISP_E_MEMBERNOTFOUND; @@ -598,34 +601,41 @@ STDMETHODIMP IEView::ShowContextMenu(DWORD dwID, POINT *ppt, IUnknown *pcmdTarge */ } #else - CComPtr pOleCommandTarget; - if (SUCCEEDED(pcmdTarget->QueryInterface(IID_IOleCommandTarget, (void**)&pOleCommandTarget))) { - CComPtr pOleWindow; - if (SUCCEEDED(pOleCommandTarget.QueryInterface(&pOleWindow))) { - HWND hSPWnd; - pOleWindow->GetWindow(&hSPWnd); - - HMENU hMenu = GetSubMenu(LoadMenu(hInstance, MAKEINTRESOURCE(IDR_CONTEXTMENU)), 0); - TranslateMenu(hMenu); - if (dwID == 5) // anchor - EnableMenuItem(hMenu, ID_MENU_COPYLINK, MF_BYCOMMAND | MF_ENABLED); - else if (dwID == 4) // text select - EnableMenuItem(hMenu, ID_MENU_COPY, MF_BYCOMMAND | MF_ENABLED); - else if (dwID == 1) // control (image) - EnableMenuItem(hMenu, ID_MENU_SAVEIMAGE, MF_BYCOMMAND | MF_ENABLED); + if (wszContextMenuHandler != nullptr) + { + CallJScript(wszContextMenuHandler, 1, CMStringW(FORMAT, L"%d", dwID)); + } + else + { + CComPtr pOleCommandTarget; + if (SUCCEEDED(pcmdTarget->QueryInterface(IID_IOleCommandTarget, (void**)&pOleCommandTarget))) { + CComPtr pOleWindow; + if (SUCCEEDED(pOleCommandTarget.QueryInterface(&pOleWindow))) { + HWND hSPWnd; + pOleWindow->GetWindow(&hSPWnd); + + HMENU hMenu = GetSubMenu(LoadMenu(hInstance, MAKEINTRESOURCE(IDR_CONTEXTMENU)), 0); + TranslateMenu(hMenu); + if (dwID == 5) // anchor + EnableMenuItem(hMenu, ID_MENU_COPYLINK, MF_BYCOMMAND | MF_ENABLED); + else if (dwID == 4) // text select + EnableMenuItem(hMenu, ID_MENU_COPY, MF_BYCOMMAND | MF_ENABLED); + else if (dwID == 1) // control (image) + EnableMenuItem(hMenu, ID_MENU_SAVEIMAGE, MF_BYCOMMAND | MF_ENABLED); - int iSelection = TrackPopupMenu(hMenu, - TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, - ppt->x, - ppt->y, - 0, - hwnd, - (RECT*)NULL); - DestroyMenu(hMenu); - if (iSelection == ID_MENU_CLEARLOG) - clear(NULL); - else - SendMessage(hSPWnd, WM_COMMAND, iSelection, (LPARAM)NULL); + int iSelection = TrackPopupMenu(hMenu, + TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, + ppt->x, + ppt->y, + 0, + hwnd, + (RECT*)NULL); + DestroyMenu(hMenu); + if (iSelection == ID_MENU_CLEARLOG) + clear(NULL); + else + SendMessage(hSPWnd, WM_COMMAND, iSelection, (LPARAM)NULL); + } } } #endif @@ -1120,3 +1130,42 @@ void IEView::navigate(IEVIEWNAVIGATE *nav) else navigate(nav->url); } + +VARIANT IEView::CallJScript(const CMString strFunc, size_t nPCount, const CMString strArgs, ...) +{ + VARIANT vaResult = { 0 }; + CComPtr spScript; + if (FAILED(getDocument()->get_Script(&spScript))) return vaResult; + + BSTR bstrMember(SysAllocString(strFunc)); + DISPID dispid = NULL; + + HRESULT hr = spScript->GetIDsOfNames(IID_NULL, &bstrMember, 1, LOCALE_SYSTEM_DEFAULT, &dispid); + if (FAILED(hr)) return vaResult; + + va_list(args); + va_start(args, strArgs); + + DISPPARAMS dispparams; + memset(&dispparams, 0, sizeof dispparams); + dispparams.cArgs = nPCount; + dispparams.rgvarg = new VARIANT[dispparams.cArgs]; + dispparams.cNamedArgs = 0; + + for (size_t i = 0; i < nPCount; i++) + { + dispparams.rgvarg[i].bstrVal = SysAllocString(va_arg(args, CMString)); + dispparams.rgvarg[i].vt = VT_BSTR; + } + + EXCEPINFO excepInfo = { 0 }; + + UINT nArgErr = (UINT)-1; + + hr = spScript->Invoke(dispid, IID_NULL, 0, DISPATCH_METHOD, &dispparams, &vaResult, &excepInfo, &nArgErr); + + for (size_t i = 0; i < nPCount; i++) SysFreeString(dispparams.rgvarg[i].bstrVal); + + delete[] dispparams.rgvarg; + return vaResult; +} \ No newline at end of file diff --git a/plugins/IEView/src/IEView.h b/plugins/IEView/src/IEView.h index bb464d45e0..0f6e32c71c 100644 --- a/plugins/IEView/src/IEView.h +++ b/plugins/IEView/src/IEView.h @@ -443,6 +443,7 @@ private: WCHAR* selectedText; bool isContactSet; MCONTACT hContact; + wchar_t *wszContextMenuHandler; // IUnknown STDMETHODIMP QueryInterface(REFIID riid, PVOID *ppv); @@ -508,6 +509,8 @@ private: STDMETHOD(SetZoneMapping)(DWORD dwZone, LPCWSTR lpszPattern, DWORD dwFlags); STDMETHOD(GetZoneMappings)(DWORD dwZone, IEnumString **ppenumString, DWORD dwFlags); + VARIANT IEView::CallJScript(const CMString strFunc, size_t nPCount, const CMString strArgs, ...); + IHTMLDocument2 *getDocument(); WCHAR* getHrefFromAnchor(CComPtr element); WCHAR* getSelection(); @@ -558,5 +561,10 @@ public: static void release(); static void setOptions(); + inline void Set_ContextMenuHandler(const wchar_t* handler) + { + replaceStrW(wszContextMenuHandler, handler); + } + }; #endif diff --git a/plugins/IEView/src/external_funcs.cpp b/plugins/IEView/src/external_funcs.cpp index 6550b928fd..9eb72c5db0 100644 --- a/plugins/IEView/src/external_funcs.cpp +++ b/plugins/IEView/src/external_funcs.cpp @@ -2,6 +2,15 @@ namespace External { + + HRESULT IEView_SetContextMenuHandler(IEView *self, DISPPARAMS *pDispParams, VARIANT *pVarResult) + { + if (pDispParams->cArgs < 1 || pDispParams == nullptr) + return E_INVALIDARG; + self->Set_ContextMenuHandler(mir_wstrdup(pDispParams->rgvarg[0].bstrVal)); + return S_OK; + } + HRESULT db_get(DISPPARAMS *pDispParams, VARIANT *pVarResult) { if (pDispParams->cArgs < 3) diff --git a/plugins/IEView/src/external_funcs.h b/plugins/IEView/src/external_funcs.h index a9526cb831..c107f49b21 100644 --- a/plugins/IEView/src/external_funcs.h +++ b/plugins/IEView/src/external_funcs.h @@ -1,5 +1,6 @@ enum EXTERNAL_FUNCTIONS { + DISPID_EXTERNAL_SET_CONTEXTMENUHANDLER = 630, DISPID_EXTERNAL_DB_GET = 652, DISPID_EXTERNAL_DB_SET, DISPID_EXTERNAL_WIN32_SHELL_EXECUTE @@ -7,6 +8,7 @@ enum EXTERNAL_FUNCTIONS namespace External { + HRESULT IEView_SetContextMenuHandler(IEView *self, DISPPARAMS *pDispParams, VARIANT *pVarResult); HRESULT db_get(DISPPARAMS *pDispParams, VARIANT *pVarResult); HRESULT db_set(DISPPARAMS *pDispParams, VARIANT *pVarResult); HRESULT win32_ShellExecute(DISPPARAMS *pDispParams, VARIANT *pVarResult); -- cgit v1.2.3