BHO yöntemimi javascript'ten aramaya çalışıyorum. şu yayınlarda belirtildiği gibi sorun aynıdır:Javascript'ten BHO yöntemini mi arıyorsunuz?
- 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
Üçüncü bağlantı başka SO bu konuda konuşmak sonrası ama anlamadı ihtiyaç ve kod. Ayrıca, paylaşılan çalışma örneği, Windows 7'de 8 ve Windows 7'de Windows 7'de kilitlenme yapmaya devam eder. Örneğin,
Eğer BHO'um AT + kullanarak C++ dilinde yazılırsa. Ben denedim ne
: Ben çok temel bir BHO'yu yazılı ve İgor Tandetnik tarafından bahsedilen here olarak yaklaşımını denedi
. Hiçbir özel durum oluşturulur, ancak IE'de aşağıdaki html dosyasını açtığımda nesnesi tanımlanmamış diyor.
<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>
Soru:
- teşhir ve javascript dan BHO yöntemini çağırın veya [2] yılında jeffdav tarafından yanıtlandı olarak ben bir activex (kullanarak maruz zorunda yapmak mümkün olup olmadığını açıklığa kavuşturmak Lütfen)? Eğer evetse o zaman nasıl yapılır.
- Temel olarak
window.external
'u genişletmek istiyorum ancak yukarıdaki bağlantıda gösterilen yol [2]var x = new ActiveXObject("MySampleATL.MyClass");
; Hem çağrı kuralları hem de aynı mıdır?
Not:
- o BHO IDL dosyasında bu
[id(1), helpstring("method DoSomething")] HRESULT DoSomething();
ekleme yoluyla mümkün olduğunu ima verir SO üzerinde ilgili yayın yoktur. Google’dan nasıl yapıldığını ve destekleyici bir kaynak bulamadığından emin değilim. - Bu iletinin farkındayım calling-into-your-bho-from-a-client-script, ancak ActiveX kullanarak sorunu çözdüğü için denemedim.
- ActiveX'ten sakınma nedenim temel olarak güvenlik kısıtlamalarından kaynaklanmaktadır.
düzenleme 1
O
window.external
uzatmak için bir yol var gibi görünüyor.
this’u kontrol edin. Özel olarak
IDocHostUIHandler::GetExternal: Extending the DOM.
başlıklı bölüm Artık IDispatch arayüzümüzü kabul etmek IDocHostUIHandler'ı uygulayan aynı nesnede.Sonra böyle bir şey yapabilirsiniz: Bu yaklaşım ile mevcut pencereleri yöntemlere eklenecek alışkanlık olduğunu
HRESULT CBrowserHost::GetExternal(IDispatch **ppDispatch)
{
*ppDispatch = this;
return S_OK;
}
sorunu değil, bunların yerine. Lütfen yanlış olup olmadığımı söyle.
Düzenleme 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>
bu üç gün geçirdikten sonra Düzen 3
, ben ActiveX yolu almak gerektiğini düşünüyorum. Temel bir activex yazmanın yolu, basit, yazılı bir yoldur ve tüm önemli IE sürümlerinde test edilir. Bu soruyu açık olarak bırakıyorum, lütfen Uri'nin cevabındaki yorumları görün (ona çok teşekkürler). Onun önerilerinin çoğunu denedim (4 ve 5 hariç).
I will also suggest you to see the MSDN IDispatcEx sample
. Eğer bir çözüm bulursanız lütfen gönderin, eğer bir çözüm bulursam kesinlikle buradan güncelleme yapacağım. Düzenleme 4
See my last comment in URI's post. Issue Resolved.
Cevabınız için teşekkür ederiz. Önerinizi denedim ama javascriptimde bho nesnesine eriştiğimde bana 'object undefined' veriyor. Lütfen güncellenmiş cevabımı görün, BHO kodunu ve ilgili javascript'i ekledim. – Favonius
Bu iki ifadeyi değiştirdim params.rgvarg = & varTanduBar; params.rgdispidNamedArgs = null; 'buna' params.rgvarg = & varMyBho; params.rgdispidNamedArgs = NULL; '. Aksi takdirde aynı kodu kullandım. – Favonius
Ayrıca, DISPATCH_PROPERTYPUTREF ve DISPATCH_PROPERTYPUT işlevlerini denedim. Ama bu durumda her ikisi de çalışmıyor. – Favonius