PDA

Visualizza la versione completa : [c++ MFC]active x


giuseppe500
27-05-2008, 12:15
Ciao.
Ho un programma che deve accedere ad un com active x .
In c# e vb.net basta aggiungere il riferimento alla libreria per poi utilizzare l'iterfaccia esposta.
Come si fa in mfc a fare la stessa cosa?
grazie

giuseppe500
27-05-2008, 15:33
Ho trovato qualosa su google(poco)ma mi sembra che devo importare la dll o la lib con #import e il c++ genera il file con l'interfaccia.
Non so pero' che dll importare ,se è una dll o un tlb ecc....
Come fa il c++ a generare questo file co l'interfaccia ?

in particolare se aggiungo l'exe al file c++ cosi':
#include "c:\\Programmi\\Computers and Structures\\SAP2000 11\\sap2000.exe" mi da errori tipo questo:
c:\Programmi\Computers and Structures\SAP2000 11\Sap2000.exe(2): error C2018: unknown character '0x1'
grazie.

MItaly
27-05-2008, 17:30
Premesso che non so praticamente nulla a questo proposito, dovrebbe essere #import, non #include.

giuseppe500
27-05-2008, 17:57
si infatti avevo sbagliato.

adesso è ok , solo che mi da il seguente errore perchè esiste gia setProp , penso si possa risolvere con i namespace ,è possibile?

c:\c++\complus\complus\MainFrm.cpp(5) : warning C4278: 'SetProp': identifier in type library 'c:\\Programmi\\Computers and Structures\\SAP2000 11\\sap2000.exe' is already a macro; use the 'rename' qualifier

giuseppe500
27-05-2008, 18:07
inoltre mi compare un namespace SAP2000 e non so come accedere alle sue classi interne.
Perchè se utilizzo ::nomeclasse ho solo delle classi astratte che non possono essere instanziate.
NOn ho esperienza degli oggetti e delle librerie com ,dove si trovano secondo voi le classi non astratte?
grazie.

MItaly
27-05-2008, 18:14
Originariamente inviato da giuseppe500
c:\c++\complus\complus\MainFrm.cpp(5) : warning C4278: 'SetProp': identifier in type library 'c:\\Programmi\\Computers and Structures\\SAP2000 11\\sap2000.exe' is already a macro; use the 'rename' qualifier
... qualunque cosa esso sia. :) In alternativa prova a includere la direttiva #import in un blocco namespace.

inoltre mi compare un namespace SAP2000 e non so come accedere alle sue classi interne.
Non funziona come i normali namespace?

giuseppe500
27-05-2008, 18:25
si , Mytali , ma in questo namespace ho solo classi astratte , e non riesco a instanziare nulla.
Perchè secondo te?
mi ritrovo una classe astratta e un puntatore:

SAP2000::_SapObject
e
SAP2000::_SapObjectPtr
dove SAP2000::_SapObjectPtr ha tutte le funzioni di SAP2000::_SapObject che mi interessano , solo che non riesco ad instanziarlo perchè mi chiede il CLSID come parametro del costruttore e non so come ottenerlo.
Grazie.

giuseppe500
28-05-2008, 11:27
ho letto un po su com e sto cercando di utilizzare:

SAP2000::_SapObjectPtr pSap;
CLSID clsid;
hr = CLSIDFromProgID(OLESTR("SAP2000.SapObject"), &clsid);
IUnknown *pUnk = NULL;
hr = CoCreateInstance(clsid,NULL,CLSCTX_INPROC_SERVER,I ID_IUnknown,(void **)&pUnk);

il metodo cocreate instance non funziona correttamente e non so cosa mettere al posto di IID_IUnknown per avere un oggetto con l'interfaccia desiderata , penso.
In particolare ho provato a scorrere tutte le interfacce , per sap2000 ma non ho trovato niente e ho cercato di utilizzare il comviewer di ms con nessun risultato.

shodan
28-05-2008, 12:40
Ti riporto un pezzo di codice dell'SDK di msxml6. Spero ti chiarisca le idee.
Comunque dovresti avere la documentazione dell'ACTIVEX che intendi usare. Senza, mi sa che ci fai poco o nulla.



#include <stdio.h>
#include <msxml2.h>

// You might need to add the msxml5/sdk/(inc, lib) directories
// to the Tools->Options...->Directories in Visual Studio.
//
// You might also need to append "msxml2.lib" to the
// Project->Settings...->Link->Object/Libray Modules field.

int main(int argc, char* argv[])
{
HRESULT hr;
IXMLDOMDocument3 *pXMLDoc = NULL;
IXMLDOMParseError * pObjError = NULL;
BSTR bstr = NULL;
VARIANT_BOOL status;
VARIANT vSrc;

CoInitialize(NULL); // obbligatorio chiamarla, prima di ogni altra funzione COM

hr = CoCreateInstance(CLSID_DOMDocument30,
NULL,
CLSCTX_INPROC_SERVER,
IID_IXMLDOMDocument3,
(void**)&pXMLDoc);

if (FAILED(hr))
{
printf("Failed to CoCreate an instance of an XML DOM\n");
printf("Error code: %x\n", hr);
goto clean;
}

hr = pXMLDoc->put_async(VARIANT_FALSE);
if (FAILED(hr))
{
printf("Failed to set async property\n");
goto clean;
}

hr = pXMLDoc->put_validateOnParse(VARIANT_FALSE);
if (FAILED(hr))
{
printf("Failed to set validateOnParse\n");
goto clean;
}

hr = pXMLDoc->put_resolveExternals(VARIANT_FALSE);
if (FAILED(hr))
{
printf("Failed to disable resolving externals.\n");
goto clean;
}

VariantInit(&vSrc);
V_BSTR(&vSrc) = SysAllocString(L"stocks.xml");
V_VT(&vSrc) = VT_BSTR;

hr = pXMLDoc->load(vSrc, &status);

if(status!=VARIANT_TRUE)
{
hr = pXMLDoc->get_parseError(&pObjError);
hr = pObjError->get_reason(&bstr);
printf("Failed to load DOM from books.xml. %S\n",bstr);
goto clean;
}

hr = pXMLDoc->get_xml(&bstr);
printf("stocks.xml:\n%S\n", bstr);

clean:
if (bstr)
SysFreeString(bstr);
if (&vSrc)
VariantClear(&vSrc);
if (pObjError)
pObjError->Release();
if (pXMLDoc)
pXMLDoc->Release();
CoUninitialize();
return 0;

}

giuseppe500
28-05-2008, 14:16
grazie.
ma IID_IXMLDOMDocument3 come hai fatto a trovarla?si puo' trovare con il com viewer o qualche altra utility?
Ho la documentazione ma per c# e vb.net , io lo dovrei implementare in c++ .
Tutte le classi pero' ci sono .
Il problema è l'inizializzazione , non riesco a trovare l'interfaccia da passare alla cocrete instance(la tua IXMLDOMDocument3 per intenderci e la mia IID_IUnknown che vorrei sostituire con quella di sap)
SAP2000::_SapObjectPtr pSap;
CLSID clsid;
hr = CLSIDFromProgID(OLESTR("SAP2000.SapObject"), &clsid);
IUnknown *pUnk = NULL;
hr = CoCreateInstance(clsid,NULL,CLSCTX_LOCAL_SERVER,II D_IUnknown,(void **)&pUnk);
hr = pUnk->QueryInterface(clsid,(void **)&pSap);
pUnk->Release();


con l'interfaccia IID_IUnknown si crea effettivamente un instanza di sapobject,ma se chiamo i suoi metodi ottengo questo errore:
Unhandled exception at 0x46000000 in complus.exe: 0xC0000005: Access violation reading location 0x46000000.

Loading