COM & ATL - brauche Hilfe bitte

20/10/2008 - 17:22 von Sven | Report spam
Hi,

ich habe ein funktionierendes Projekt bekommen, in dem eine Browser
Komponente in Navision dargestellt wird (geht sonst nicht, da Navision keine
grafischen Komponenten anzeigt.). Ich versuche jetzt seit mehreren Tagen, das
ganze Werk so umzubauen, dass es eine RichTextBox anzeigt...
RICHTEXT.RichtextCtrl.1, richtx32.dll, 3B7C8863-D78F-101B-B9B5-04021C009402

Ich habe jetzt zwar einiges über C++, COM und Interfaces gelernt, aber
funktioniert hat es trotzdem nie. Das reine anzeigen hat mal funktioniert,
aber den Zugriff auf das Interface der Box hab ich nicht hin bekommen, also
konnte ich auch keinen Text laden etc.

Ich lasse meine klàglichen Versuche mal weg und poste den funktionierenden
Code mit dem IE Control. Vielleicht kann mir da jemand weiter helfen.

Spàtestens bei IWebBrowser2 * pWebBrowser; verlàsst es mich, ich weiß
nichtmal was das * da macht...

(Einige Funktionen habe ich raus geschnitten, um das Ganze wenigstens etwas
kürzer zu machen)

##################### compreg.h ########################

// compreg.h : Deklaration von CCompReg

#pragma once

#include "resource.h" // Hauptsymbole

// IComponentRegistrar
[
object,
uuid(a817e7a2-43fa-11d0-9e44-00aa00b6770a),
dual,
helpstring("IComponentRegistrar-Schnittstelle"),
pointer_default(unique)
]
__interface IComponentRegistrar : IDispatch
{
[id(1)] HRESULT Attach([in] BSTR bstrPath);
[id(2)] HRESULT RegisterAll();
[id(3)] HRESULT UnregisterAll();
[id(4)] HRESULT GetComponents([out, satype(BSTR)] SAFEARRAY** pbstrCLSIDs,
[out, satype(BSTR)] SAFEARRAY** pbstrDescriptions);
[id(5)] HRESULT RegisterComponent([in] BSTR bstrCLSID);
[id(6)] HRESULT UnregisterComponent([in] BSTR bstrCLSID);
[id(7), helpstring("method Navigate")] HRESULT Navigate([in] BSTR url);
[id(8), helpstring("method CleanIEControl")] HRESULT CleanIEControl(void);
[id(9), helpstring("method Stop")] HRESULT Stop(void);
[id(10), helpstring("method Back")] HRESULT Back(void);
[id(11), helpstring("method Forward")] HRESULT Forward(void);
[id(12), helpstring("method Refresh")] HRESULT Refresh(void);

};


// CCompReg
[
coclass,
threading("single"),
uuid(81D9BC17-65CA-4E5A-8726-04202DA8A55E),
helpstring("ComponentRegistrar-Klasse")
]
class ATL_NO_VTABLE CCompReg :
public IComponentRegistrar
{
public:
CCompReg();

// IComponentRegistrar
public:
STDMETHOD(Attach)(BSTR bstrPath)
{
return S_OK;
}
STDMETHOD(RegisterAll)()
{
return _AtlComModule.RegisterServer(TRUE);
}
STDMETHOD(UnregisterAll)()
{
_AtlComModule.UnregisterServer(TRUE);
return S_OK;
}
STDMETHOD(GetComponents)(SAFEARRAY **ppCLSIDs, SAFEARRAY **ppDescriptions)
{
if( ppCLSIDs == NULL || ppDescriptions == NULL )
return E_POINTER;
int nComponents = 0;
for (_ATL_OBJMAP_ENTRY** ppEntry = _AtlComModule.m_ppAutoObjMapFirst;
ppEntry < _AtlComModule.m_ppAutoObjMapLast; ppEntry++)
{
if (*ppEntry != NULL)
{
_ATL_OBJMAP_ENTRY* pEntry = *ppEntry;
if (pEntry->pclsid != NULL)
{
LPCTSTR pszDescription = pEntry->pfnGetObjectDescription();
if (pszDescription)
nComponents++;
}
}
}
SAFEARRAYBOUND rgBound[1];
rgBound[0].lLbound = 0;
rgBound[0].cElements = nComponents;
*ppCLSIDs = SafeArrayCreate(VT_BSTR, 1, rgBound);
if( *ppCLSIDs == NULL )
return AtlHresultFromLastError();
*ppDescriptions = SafeArrayCreate(VT_BSTR, 1, rgBound);
if( *ppDescriptions == NULL )
return AtlHresultFromLastError();
LONG i = 0;
for (_ATL_OBJMAP_ENTRY** ppEntry = _AtlComModule.m_ppAutoObjMapFirst;
ppEntry < _AtlComModule.m_ppAutoObjMapLast; ppEntry++)
{
if (*ppEntry != NULL)
{
_ATL_OBJMAP_ENTRY* pEntry = *ppEntry;
if (pEntry->pclsid != NULL)
{
LPCTSTR pszDescription = pEntry->pfnGetObjectDescription();
if (pszDescription)
{
LPOLESTR pszCLSID;
StringFromCLSID(*pEntry->pclsid, &pszCLSID);
BSTR pBSTR = OLE2BSTR(pszCLSID);
if( pBSTR == NULL )
{
CoTaskMemFree(pszCLSID);
return E_OUTOFMEMORY;
}
HRESULT hResult = SafeArrayPutElement(*ppCLSIDs, &i, pBSTR);
CoTaskMemFree(pszCLSID);
if( FAILED(hResult) )
return hResult;
pBSTR = T2BSTR_EX(pszDescription);
if( pBSTR == NULL )
{
return E_OUTOFMEMORY;
}
hResult = SafeArrayPutElement(*ppDescriptions, &i, pBSTR);
if( FAILED(hResult) )
return hResult;
i++;
}
}
}
}

return S_OK;
}
STDMETHOD(RegisterComponent)(BSTR bstrCLSID)
{
CLSID clsid;
CLSIDFromString(bstrCLSID, &clsid);
_AtlComModule.RegisterServer(TRUE, &clsid);
return S_OK;
}
STDMETHOD(UnregisterComponent)(BSTR bstrCLSID)
{
CLSID clsid;
CLSIDFromString(bstrCLSID, &clsid);
_AtlComModule.UnregisterServer(FALSE, &clsid);
return S_OK;
}

STDMETHOD(Navigate)(BSTR url);
STDMETHOD(CleanIEControl)(void);
STDMETHOD(Stop)(void);
STDMETHOD(Refresh)(void);
STDMETHOD(Back)(void);
STDMETHOD(Forward)(void);
private:
CComPtr<IUnknown> spUnk;
HWND m_hWnd;
CAxWindow wnd;
//CWindow wnd;
IWebBrowser2 * pWebBrowser;
};




####################### compreg.cpp ####################

// compreg.cpp : Implementierung von CCompReg
#include "stdafx.h"
#include "compreg.h"

CCompReg::CCompReg()
{
//Merge ActiveX Window in Navision Frame
::AtlAxWinInit();
m_hWnd = ::GetFocus();

if(m_hWnd)
{
//ataching m_hWnd in wnd, for a nice interface
wnd.Attach(m_hWnd);

//Now we have full control over navision :-)
// snow would be a nice christmas add on

//adding scrollbars here
wnd.ModifyStyle(0, WS_HSCROLL | WS_VSCROLL);


HRESULT hr = wnd.CreateControl(OLESTR("about:blank"));


if(SUCCEEDED(hr))
{
//Get the IUnknown Interface for the freshly initialized ActiveX-Control
HRESULT hr = wnd.QueryControl(&spUnk);
if(SUCCEEDED(hr))
{
#ifdef _DEBUG
if(S_OK == spUnk->QueryInterface(IID_IWebBrowser2,(void**)&pWebBrowser))
{
::MessageBox(0, "Init succeeded", 0, 0);
}
else
{
::MessageBox(0, "Init failed", 0, 0);
}
#endif _DEBUG

//In god we trust, pray that this implements IID_IWebBrowser2 Interface
#ifdef NDEBUG
HRESULT hr = spUnk->QueryInterface(IID_IWebBrowser2,(void**)&pWebBrowser);

if(SUCCEEDED(hr))
{
//Init success
}
else
{
//Do sth. ;-)
}
#endif NDEBUG
}
else
{
//Do sth. ;-)
}
}
else
{
//Do sth. ;-)
}
}
else
{
//Do sth. ;-)
}
}


STDMETHODIMP CCompReg::CleanIEControl()
{
//IUnknown schliessen!
if(pWebBrowser)
pWebBrowser->Release();
return S_OK;
}



STDMETHODIMP CCompReg::Refresh()
{
if(pWebBrowser)
{
pWebBrowser->Refresh();
}
return S_OK;
}

STDMETHODIMP CCompReg::Navigate(BSTR url)
{
try{
if(!url)
{
url = SysAllocString(L"about:blank");
}
if(url == L"")
{
url = SysAllocString(L"about:blank");
}

if(S_OK == pWebBrowser->Stop())
{
if(S_OK == pWebBrowser->Navigate(url,NULL,NULL,NULL,NULL))
{

return S_OK;
}
else
{
return S_FALSE;
}
}
return S_OK;
}
catch(char * str)
{
//::MessageBox(0, str, 0, 0);
return S_FALSE;
}
}
 

Lesen sie die antworten

#1 Martin Richter [MVP]
21/10/2008 - 08:53 | Warnen spam
Hallo Sven!

ich habe ein funktionierendes Projekt bekommen, in dem eine Browser
Komponente in Navision dargestellt wird (geht sonst nicht, da Navision keine
grafischen Komponenten anzeigt.). Ich versuche jetzt seit mehreren Tagen, das
ganze Werk so umzubauen, dass es eine RichTextBox anzeigt...
RICHTEXT.RichtextCtrl.1, richtx32.dll, 3B7C8863-D78F-101B-B9B5-04021C009402



Und warum machst Du das als COM Element und nicht einfach als normales
Control?

Ich habe jetzt zwar einiges über C++, COM und Interfaces gelernt, aber
funktioniert hat es trotzdem nie. Das reine anzeigen hat mal funktioniert,
aber den Zugriff auf das Interface der Box hab ich nicht hin bekommen, also
konnte ich auch keinen Text laden etc.



Warum COM, wenn das auch mit der WinAPI geht?


Ich lasse meine klàglichen Versuche mal weg und poste den funktionierenden
Code mit dem IE Control. Vielleicht kann mir da jemand weiter helfen.

Spàtestens bei IWebBrowser2 * pWebBrowser; verlàsst es mich, ich weiß
nichtmal was das * da macht...



Wenn Du nicht weißt was ein Zeiger ist, solltest Du erst einmal
Grundlagen büffeln.

Was ist nun eigentlich Dein Problem?
Wenn es sich um natives C++ handelt empfehle ich Dir die Gruppe
microsoft.public.de.vc


Martin Richter [MVP] WWJD http://blog.m-ri.de
"A well-written program is its own heaven; a poorly written
program is its own hell!" The Tao of Programming
FAQ: http://www.mpdvc.de Samples: http://www.codeproject.com

Ähnliche fragen