मैं जावास्क्रिप्ट से अपनी बीएचओ विधि को कॉल करने की कोशिश कर रहा हूं। समस्या एक ही रूप में निम्न पदों में कहा गया है:जावास्क्रिप्ट से बीएचओ विधि को कॉल करना?
- Call BHO from Javascript function
- http://social.msdn.microsoft.com/Forums/en-US/ieextensiondevelopment/thread/91d4076e-4795-4d9e-9b07-5b9c9eca62fb/
- Calling C++ function from JavaScript script running in a web browser control
तीसरा लिंक है एक और अतः इसके बारे में बात पोस्ट, लेकिन मैं समझ में नहीं आया आवश्यकता और कोड। इसके अलावा साझा कामकाजी नमूना विंडोज 7 पर यानी 8 और विंडोज विस्टा के साथ 7 या तो विंडोज विस्टा के साथ दुर्घटनाग्रस्त रहता है।
यदि यह मेरे बीएचओ को एटीएल का उपयोग कर सी ++ में लिखा जाता है।
मैं क्या कोशिश की है:
मैं एक बहुत ही बुनियादी BHO लिखा और इगोर Tandetnik ने उल्लेख किया here के रूप में दृष्टिकोण की कोशिश की है। कोई अपवाद उत्पन्न नहीं हुआ है, लेकिन जब मैं IE में निम्न HTML फ़ाइल खोलता हूं तो यह कहता है कि ऑब्जेक्ट अपरिभाषित।
<html>
<head>
<script language='javascript'>
function call_external(){
try{
alert(window.external.TestScript);
//JQueryTest.HelloJquery('a');
}catch(err){
alert(err.description);
}
}
</script>
</head>
<body id='bodyid' onload="call_external();">
<center><div><span>Hello jQuery!!</span></div></center>
</boay>
</html>
प्रश्न:
- कृपया स्पष्ट करें कि बेनकाब और जावास्क्रिप्ट से BHO विधि कॉल या के रूप में [2] में jeffdav द्वारा उत्तर दिया मैं एक ActiveX (का उपयोग कर इसे बेनकाब करने के लिए है करने के लिए यह संभव है)? यदि हां तो यह कैसे करें।
- असल में मैं
window.external
का विस्तार करना चाहता हूं लेकिन उपर्युक्त लिंक [2] में दिखाया गया तरीकाvar x = new ActiveXObject("MySampleATL.MyClass");
का उपयोग करता है; क्या दोनों कॉलिंग सम्मेलन समान या अलग हैं?
नोट:
- वहाँ इतने पर एक संबंधित पोस्ट जो संकेत है कि यह BHO आईडीएल फ़ाइल में इस
[id(1), helpstring("method DoSomething")] HRESULT DoSomething();
डालने के माध्यम से संभव है देता है। मुझे यकीन नहीं है कि यह कैसे किया गया था और Google के माध्यम से कोई सहायक संसाधन नहीं मिला। - मुझे इस पोस्ट calling-into-your-bho-from-a-client-script के बारे में पता है, लेकिन मैंने कोशिश नहीं की है क्योंकि यह ActiveX का उपयोग कर समस्या को हल कर रहा है।
- एक्टिवएक्स से बचने का मेरा कारण मुख्य रूप से सुरक्षा प्रतिबंधों के कारण है।
संपादित करें 1
ऐसा लगता है वहाँ
window.external
विस्तार करने के लिए एक तरीका है।
this देखें। विशेष रूप से
IDocHostUIHandler::GetExternal: Extending the DOM.
शीर्षक वाला अनुभाग मानते हुए कि हमारा आईडीस्पैच इंटरफ़ेस उसी ऑब्जेक्ट पर है जो IDocHostUIHandler लागू करता है।फिर हम कुछ इस तरह कर सकते हैं:
HRESULT CBrowserHost::GetExternal(IDispatch **ppDispatch)
{
*ppDispatch = this;
return S_OK;
}
समस्या इस दृष्टिकोण के साथ है कि यह मौजूदा खिड़कियों तरीकों को संलग्न नहीं होगा, बल्कि उन्हें बदलना। कृपया बताएं कि मैं गलत हूं या नहीं।
संपादित 2
The BHO Class:
class ATL_NO_VTABLE CTestScript :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CTestScript, &CLSID_TestScript>,
public IObjectWithSiteImpl<CTestScript>,
public IDispatchImpl<ITestScript, &IID_ITestScript, &LIBID_TestBHOLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
public IDispEventImpl<1, CTestScript, &DIID_DWebBrowserEvents2, &LIBID_SHDocVw, 1, 1>
{
public:
CTestScript()
{
}
DECLARE_REGISTRY_RESOURCEID(IDR_TESTSCRIPT)
DECLARE_NOT_AGGREGATABLE(CTestScript)
BEGIN_COM_MAP(CTestScript)
COM_INTERFACE_ENTRY(ITestScript)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IObjectWithSite)
END_COM_MAP()
DECLARE_PROTECT_FINAL_CONSTRUCT()
HRESULT FinalConstruct()
{
return S_OK;
}
void FinalRelease()
{
}
public:
BEGIN_SINK_MAP(CTestScript)
SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_DOCUMENTCOMPLETE, OnDocumentComplete)
//SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_NAVIGATECOMPLETE2, OnNavigationComplete)
END_SINK_MAP()
void STDMETHODCALLTYPE OnDocumentComplete(IDispatch *pDisp, VARIANT *pvarURL);
//void STDMETHODCALLTYPE OnNavigationComplete(IDispatch *pDisp, VARIANT *pvarURL);
STDMETHOD(SetSite)(IUnknown *pUnkSite);
HRESULT STDMETHODCALLTYPE DoSomething(){
::MessageBox(NULL, L"Hello", L"World", MB_OK);
return S_OK;
}
public:
//private:
// InstallBHOMethod();
private:
CComPtr<IWebBrowser2> m_spWebBrowser;
BOOL m_fAdvised;
};
// TestScript.cpp : Implementation of CTestScript
#include "stdafx.h"
#include "TestScript.h"
// CTestScript
STDMETHODIMP CTestScript::SetSite(IUnknown* pUnkSite)
{
if (pUnkSite != NULL)
{
HRESULT hr = pUnkSite->QueryInterface(IID_IWebBrowser2, (void **)&m_spWebBrowser);
if (SUCCEEDED(hr))
{
hr = DispEventAdvise(m_spWebBrowser);
if (SUCCEEDED(hr))
{
m_fAdvised = TRUE;
}
}
}else
{
if (m_fAdvised)
{
DispEventUnadvise(m_spWebBrowser);
m_fAdvised = FALSE;
}
m_spWebBrowser.Release();
}
return IObjectWithSiteImpl<CTestScript>::SetSite(pUnkSite);
}
void STDMETHODCALLTYPE CTestScript::OnDocumentComplete(IDispatch *pDisp, VARIANT *pvarURL)
{
CComPtr<IDispatch> dispDoc;
CComPtr<IHTMLDocument2> ifDoc;
CComPtr<IHTMLWindow2> ifWnd;
CComPtr<IDispatchEx> dispxWnd;
HRESULT hr = m_spWebBrowser->get_Document(&dispDoc);
hr = dispDoc.QueryInterface(&ifDoc);
hr = ifDoc->get_parentWindow(&ifWnd);
hr = ifWnd.QueryInterface(&dispxWnd);
// now ... be careful. Do exactly as described here. Very easy to make mistakes
CComBSTR propName(L"myBho");
DISPID dispid;
hr = dispxWnd->GetDispID(propName, fdexNameEnsure, &dispid);
CComVariant varMyBho((IDispatch*)this);
DISPPARAMS params;
params.cArgs = 1;
params.cNamedArgs = 0;
params.rgvarg = &varMyBho;
params.rgdispidNamedArgs = NULL;
hr = dispxWnd->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT,
¶ms, NULL, NULL, NULL);
}
The Javascript:
<script language='javascript'>
function call_external(){
try{
alert(window.ITestScript);
}catch(err){
alert(err.description);
}
}
</script>
संपादित 3
इस पर तीन दिन बिताने के बाद, मुझे लगता है कि मैं ActiveX पथ लेना चाहिए। एक बुनियादी सक्रियण लिखना आसान, लिखित एक तरीका है और सभी प्रमुख आईई रिलीज पर परीक्षण किया जाता है। मैं इस सवाल को खुले के रूप में छोड़ रहा हूं, कृपया उरी के जवाब में टिप्पणियां देखें (उनके लिए बहुत धन्यवाद)। मैंने अपने अधिकांश सुझावों की कोशिश की है (4 और 5 को छोड़कर)।
I will also suggest you to see the MSDN IDispatcEx sample
। यदि आपको कोई समाधान मिलता है तो कृपया मुझे पोस्ट करें, अगर मुझे कोई समाधान मिल जाए तो मैं निश्चित रूप से यहां अपडेट करूँगा।
संपादित 4
See my last comment in URI's post. Issue Resolved.
आपके उत्तर के लिए धन्यवाद। मैंने आपके सुझाव की कोशिश की लेकिन जब मैं अपने जावास्क्रिप्ट में bho ऑब्जेक्ट तक पहुंच रहा हूं तो यह मुझे 'ऑब्जेक्ट अपरिभाषित' दे रहा है। कृपया मेरा अद्यतन उत्तर देखें, मैंने बीएचओ कोड और संबंधित जावास्क्रिप्ट शामिल किया है। – Favonius
मैंने इन दो कथनों को बदल दिया है 'params.rgvarg = और varTanduBar; params.rgdispidNamedArgs = null; 'इस' params.rgvarg = और varMyBho; params.rgdispidNamedArgs = NULL; '। अन्यथा मैंने एक ही कोड का उपयोग किया है। – Favonius
इसके अलावा, मैंने 'DISPATCH_PROPERTYPUTREF' और' DISPATCH_PROPERTYPUT' को आजमाया है। लेकिन इस मामले में दोनों काम नहीं कर रहे हैं। – Favonius