15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


OLE method with a class/ptr as param-how?

Lior Messinger -- 100274.2607@compuserve.com
Monday, February 24, 1997

Environment: NT 4.0, VC 4.2b

Hi,

I hope this question fall sinot the appt. categories - it is on classes (ActiveX
Template Library, COleVariant etc.) but also about OLE in general. I hope you
could put it on the list - here it goes:

Hi,

I need to create a COMponent that creates and returns a complex data structure
and fields. Does anyone know how do I implement a method that receive and
returns a class, a structure in memory, or just a simple pointer to memory? 
It seems it can's be done with IDispatch or only with a vtable interface
(true?)... - but I need an in-process component, to be access from C++, so I
need only the vtable interface. I have ATL2.0, and I couldn't see nothing there,
neither on the COle* classes.


Thanks for any lead or a sample,
Lior Messinger,
Fundtech





Bing Hou -- hou@tfn.com
Tuesday, February 25, 1997

[Mini-digest: 4 responses]


Well, much for my COM/OLE enforced education, you are not supposed to 
receive and return a class from a COMponent(I like it). Step one step back, 
think what you need a pointer to a class that is returned by a 
COMponent(still like it) for? You probably want to make some function calls 
through that pointer. Hmm, a pointer to a bunch of functions pointers. 

In other words, you would implement the class you want to be returned a COM 
class, or be contained by a COM object. thereafter, you could invoke/create 
it through OLE. Then you could manipulate it through interfaces.


Bing Hou
hou@tfn.com
------------------------------------------------------------------------
  "The saints are the sinners who keep on trying."





______________________________ Reply Separator _________________________________
Subject: OLE method with a class/ptr as param-how?
Author:  Lior Messinger <100274.2607@compuserve.com> at Internet
Date:    2/24/97 10:39 AM


Environment: NT 4.0, VC 4.2b
     
Hi,
     
I hope this question fall sinot the appt. categories - it is on classes (ActiveX
Template Library, COleVariant etc.) but also about OLE in general. I hope you 
could put it on the list - here it goes:
     
Hi,
     
I need to create a COMponent that creates and returns a complex data structure 
and fields. Does anyone know how do I implement a method that receive and 
returns a class, a structure in memory, or just a simple pointer to memory? 
It seems it can's be done with IDispatch or only with a vtable interface 
(true?)... - but I need an in-process component, to be access from C++, so I 
need only the vtable interface. I have ATL2.0, and I couldn't see nothing there,
neither on the COle* classes.
     
     
Thanks for any lead or a sample,
Lior Messinger,
Fundtech
     
     
-----From: Regis NICOLAS 

At 10:39 AM 2/24/97 EST, you wrote:
>Environment: NT 4.0, VC 4.2b
>
>Hi,
>
>I hope this question fall sinot the appt. categories - it is on classes
(ActiveX
>Template Library, COleVariant etc.) but also about OLE in general. I hope you
>could put it on the list - here it goes:
>
>Hi,
>
>I need to create a COMponent that creates and returns a complex data structure
>and fields. Does anyone know how do I implement a method that receive and
>returns a class, a structure in memory, or just a simple pointer to memory? 
>It seems it can's be done with IDispatch or only with a vtable interface
>(true?)... - but I need an in-process component, to be access from C++, so I
>need only the vtable interface. I have ATL2.0, and I couldn't see nothing
there,
>neither on the COle* classes.
>
>
>Thanks for any lead or a sample,
>Lior Messinger,
>Fundtech
>
>
>
Have a look to CoGetMalloc. It returns a IMalloc interface you can use to
allocate and free memory.
But in your case I think this is not the good solution. You should write
your own COM interface for managing your structure with accessors to get and
set values in and out.

Hope this helps,
Regis

------------------------------
Regis NICOLAS -    R&D Windows
Smartcode Technologie

mailto:nicolas@smartcode.fr
http://www.smartcode.fr/
http://www.smartcodesoft.com/
Tel.: (33) (0)4 67 59 30 16

-----From: Nathan Cornillon 


	If you use the LPDISPATCH as the return type, you could basically =
return another OLE object.  The returned object would then be accessable =
from VC, VB and all the other languages with OLE support.  I'd take a =
look at CCmdTarget.  Hope that helps.

	Nathan

-----Original Message-----
From:	Lior Messinger [SMTP:100274.2607@compuserve.com]
Sent:	Monday, February 24, 1997 9:39 AM
To:	MFC Mailing List
Subject:	OLE method with a class/ptr as param-how?

Environment: NT 4.0, VC 4.2b

Hi,

I hope this question fall sinot the appt. categories - it is on classes =
(ActiveX
Template Library, COleVariant etc.) but also about OLE in general. I =
hope you
could put it on the list - here it goes:

Hi,

I need to create a COMponent that creates and returns a complex data =
structure
and fields. Does anyone know how do I implement a method that receive =
and
returns a class, a structure in memory, or just a simple pointer to =
memory?=20
It seems it can's be done with IDispatch or only with a vtable interface
(true?)... - but I need an in-process component, to be access from C++, =
so I
need only the vtable interface. I have ATL2.0, and I couldn't see =
nothing there,
neither on the COle* classes.


Thanks for any lead or a sample,
Lior Messinger,
Fundtech


-----From: "Doug Brubacher" 

     I have responded to several questions of this nature previously on the 
     list:
     
     The way I have passed structures in the past is through a Variant 
     which was defined as a safearrays of Variants as in this example:
     
     VARIANT CVariable::GetInfo() const
     {
        SAFEARRAY       *psaInfoArray;
        SAFEARRAYBOUND  rgsabound[1];
         VARIANT         vInfoArray;
     
        rgsabound[0].lLbound = 0;
        rgsabound[0].cElements = 9;
        psaInfoArray = SafeArrayCreate(VT_VARIANT, 1, rgsabound);
     
        if ( NULL == psaInfoArray )
         {
             ASSERT( FALSE );
                AfxThrowMemoryException();
         }
         GetInfoArrayEx( psaInfoArray );
         VariantInit( &vInfoArray );
         V_VT( &vInfoArray) = VT_ARRAY | VT_VARIANT;
         V_ARRAY( &vInfoArray) = psaInfoArray;
     
         return vInfoArray;
     }
     
     int CVariable::GetInfoArrayEx( SAFEARRAY* psaInfoArray ) const
     {
         COleVariant ovElement;
         long    lValue;
         BSTR    bstrValue;
         double  dflValue;
         long    lElement;
         VARIANT HUGEP* pvElement;
     
         if ( FAILED( SafeArrayAccessData(psaInfoArray, (void HUGEP* FAR*) 
     &pvElement) ))
         {
             ASSERT( FALSE );
                throw new CSizingEngineException( ERROR_UNEXPECTED );
         }
     
     //  Element  o,VT_R8    Minimum value
         lElement++;
         ovElement.ChangeType( VT_R8 );
        dflValue = m_rvMin;
         ovElement = dflValue;
         pvElement[lElement] = ovElement.Detach();
     .
     
     .
     //  Element  8,VT_R8    Maximum value
         lElement++;
         ovElement.ChangeType( VT_R8 );
        dflValue = m_rvMax;
         ovElement = dflValue;
         pvElement[lElement] = ovElement.Detach();
     
         if ( FAILED( SafeArrayUnaccessData( psaInfoArray )))
         {
             ASSERT( FALSE );
                throw new CSizingEngineException( ERROR_UNEXPECTED );
         }
     
         return lElement;
     }
     
     Of course the client must understand what information is available in 
     each element of the array.
     I have also had need to pass a pointer to a COM object as in the 
     following:
     
     STDMETHODIMP CSizingEngine::CopyColumn( COND_ID target, COND_ID 
     source, VARGROUP varGroup, ERRORIDPTR pErrorID )
     {
         if ( source == target )
         {
             *pErrorID = ERROR_CONDITIONINVALID;
             return S_OK;
         }
     
        CComObject* pConditionTarget;
        CComObject* pConditionSource;
     
         pConditionTarget = GetCondition( target, pErrorID );
         if ( NULL != pConditionTarget )
             pConditionSource = GetCondition( source, pErrorID );
         if ( NULL == pConditionTarget || NULL == pConditionSource )
             return S_OK;
     
        LPDISPATCH lpDisp = NULL;
     
        HRESULT hres = pConditionSource->QueryInterface(IID_IDispatch, 
     (void**)&lpDisp); // Note this increments the Reference Count
     
         if ( FAILED(hres) )
         {
             *pErrorID = ERROR_UNEXPECTED;
             return S_OK;
         }
     
         VARIANT vSource;
     
         VariantInit( &vSource );
         V_VT( &vSource ) = VT_DISPATCH;
         V_DISPATCH( &vSource ) = lpDisp;
     
         pConditionSource->Release();    // Reduce the reference count
         return pConditionTarget->CopyColumn( varGroup, vSource, pErrorID 
     );
     }
     
     Hope this helps,
     
     Regards
     
     Doug Brubacher
     Work: Doug_Brubacher@compuware.com
     Home: DouglasB@msn.com





Become an MFC-L member | Вернуться в корень Архива |