|
Hi, thanks a lot.
Should the class factory and CMyComObject point to a global pool object manager, for the factory will pop out an object from there and CMyComObject will return it back?
|
|
|
|
|
Well, if I understood correctly, you would like to change your CMyComObject Release method to add the object to some manager instead of deletion and the factory will first ask this manager for an existing instance before creating new one.
This can be correct I would probably use the same way.
|
|
|
|
|
Yes, this is exactly what i wanted to do.
Thanks a lot,
Dudi
|
|
|
|
|
hi,
I need a help !! Please someone help me !
I am developing ATL COM which contains property of type COM object (ATL coclass): CComObject<dombookingareaholder> *m_AreaHolder.
Just for info: domBookingAreaHolder is a ATL co class.
I want to allow all clients (C++, VB, VBSCript) to be able to get and put the property.
Below is the code for ATL COM:
1) domBooking.CPP
<br />
<br />
class ATL_NO_VTABLE domBooking : <br />
public CComObjectRootEx<CComSingleThreadModel>,<br />
public CComCoClass<domBooking, &CLSID_domBooking>,<br />
public ISupportErrorInfo,<br />
public IDispatchImpl<IdomBooking, &IID_IdomBooking, &LIBID_DOMIBMSLib><br />
{<br />
public:<br />
domBooking()<br />
{<br />
}<br />
<br />
HRESULT FinalConstruct()<br />
{<br />
CComObject<domBookingAreaHolder>::CreateInstance(&m_AreaHolder);<br />
return S_OK;<br />
}<br />
<br />
void FinalRelease()<br />
{ <br />
m_AreaHolder = NULL;<br />
}<br />
<br />
DECLARE_REGISTRY_RESOURCEID(IDR_DOMBOOKING)<br />
<br />
DECLARE_PROTECT_FINAL_CONSTRUCT()<br />
<br />
BEGIN_COM_MAP(domBooking)<br />
COM_INTERFACE_ENTRY(IdomBooking)<br />
COM_INTERFACE_ENTRY(IDispatch) <br />
END_COM_MAP()<br />
<br />
public:<br />
<br />
STDMETHOD(get_AreaHolder)(IDispatch*** pVal);<br />
STDMETHOD(put_AreaHolder)(IDispatch** newVal);<br />
<br />
<big>CComObject<domBookingAreaHolder> *m_AreaHolder;</big><br />
<br />
};<br />
<br />
1) How I can accomplish this ?
2) how the propety for get and set being implemeted ?
3) and lastly how client can call to object property using set and put in VC++ ?
Thank u very very much in advance . Any advice and suggestions strongly aprreciated.
Regards,
Newbie
|
|
|
|
|
Use VARIANT instead of IDispatch
STDMETHOD(get_AreaHolder)(VARIANT** pVal);
STDMETHOD(put_AreaHolder)(VARIANT* newVal);
Example of use:
VARIANT v;
v.vt=VT_DISPATCH;
v.pdispVal=pInterfaceAreaHolder;
obDomBooking->put_AreaHolder(&v); Once the interface pointer arrives in the put_AreaHolder method, you should query it for the AreaHolder interface and store the result in m_AreaHolder; when destroying, call Release on the same m_AreaHolder. Of course, don't forget the usual checkings.
rechi
|
|
|
|
|
How do I pass an array from C# to a COM object.
What is the method parameter syntax for the COM object and how
does C# use the COM object
|
|
|
|
|
To pass an array into a COM object you need to use a VARIANT_ARRAY. How you build it in C#, I dunno.
Christian
No offense, but I don't really want to encourage the creation of another VB developer. - Larry Antram 22 Oct 2002
Hey, at least Logo had, at it's inception, a mechanical turtle. VB has always lacked even that... - Shog9 04-09-2002
Again, you can screw up a C/C++ program just as easily as a VB program. OK, maybe not as easily, but it's certainly doable. - Jamie Nordmeyer - 15-Nov-2002
|
|
|
|
|
Seems that in some cases one is more effective than the other. How to choose?
Thanks!
---------------
Concentrating on Ideas
http://www.edovia.com
|
|
|
|
|
CComQIPtr supports automatic querying of COM interfaces through QueryInterface. Both do automatic AddRefs and Releases. You should use CComPtr for IUnknowns. CComQIPtr is good for getting a particular interface:
CComQIPtr<IConnectionPointContainer, &IID_IConnectionPointContainer> pCPC(pUnk);
CComPtr is good for being passed into other COM calls where you're receiving an interface pointer back:
CComPtr<IConnectionPoint> pCP;
pCPC->FindConnectionPoint(IID_IPropertyNotifySink, &pCP);
|
|
|
|
|
Hey all,
I'm working on a component that returns a SAFEARRAY. Here's the IDL for the method as well as the C++ declaration:
[id(2), helpstring("List of Report Type (Names) available to a user on a specific date")] HRESULT GetReportTypes([in] BSTR UserID, [in] INT CloseDate, [out, retval] VARIANT* pReportTypes);
STDMETHODIMP CReports::GetReportTypes(BSTR UserID, INT CloseDate, VARIANT *pReportTypes)
Now without loading this up with a ton of code I'll explain what I am doing and then show the important parts of the code.
Basically, I want to return a SAFEARRAY that is mulitdimensionl, in this case the array is [x][1] in size and x is determined by the number of records retrieved. So here's how I'm creating the SAFEARRAY:
<br />
SAFEARRAYBOUND SABounds[2];<br />
SABounds[0].cElements = (DWORD)pRsHPASReports->RecordCount + 1;
SABounds[1].cElements = SABounds[0].cElements;<br />
SABounds[0].lLbound = 0;<br />
SABounds[1].lLbound = 0; <br />
<br />
VariantInit(pReportTypes);<br />
pReportTypes->vt = VT_VARIANT | VT_ARRAY;<br />
pReportTypes->parray = SafeArrayCreate(VT_VARIANT, 2, SABounds);<br />
and then after opening the recordset I loop through the records filling in the SAFEARRAY with my data, like so:
<br />
while(! pRsHPASReports->IsEOF)<br />
{<br />
ldimension[0] = lLoop++;<br />
ldimension[1] = 0;<br />
<br />
CComVariant bstrTmp( pRsHPASReports->Fields->Item["RptType"]->Value );<br />
TESTHR(SafeArrayPutElement( pReportTypes->parray, ldimension, &bstrTmp ));<br />
<br />
ldimension[1] = 1;<br />
CComVariant bstrTmp2( pRsHPASReports->Fields->Item["Title"]->Value );<br />
TESTHR(SafeArrayPutElement( pReportTypes->parray, ldimension, &bstrTmp2 ));<br />
<br />
pRsHPASReports->MoveNext();<br />
}<br />
pretty standard stuff, right? Well, as you can see from the comment above, If I have a record count of 1 then the SAFEARRAY does not appear to be initialized properly... I'm forced to add 1 to the count so that I can build the array. My question is why can't I create a SAFEARRAY with a size [1][1]?
On the client side, when checking the bounds on the SAFEARRAY I see 0 to 1 ... yet the element at postion 1 is empty. I've looked high and low on the web for a soloution and have not been successful...
So, anyone know how I can create a SAFEARRAY with just one element?
Thanks,
Dave "Dak Lozar" Loeser
When access is allowed to a member, it said to be accessible. Otherwise, it is inaccessible.
|
|
|
|
|
If you want to have the VB array (a to b) in i-th dimension bounds, you should initialize the SABounds[i].lLbound = a; and SABounds[i].cElements = b-a+1; As a rule, a is equal 0, so cElements = b-0+1 and = b+1.
But RecordCount is equal to size of array (cElements), therefore, you haven't to add extra "1". Your array in VB will have (0 to x-1) bounds.
SAFEARRAYBOUND SABounds[2];
SABounds[0].cElements = (DWORD)pRsHPASReports->RecordCount;
SABounds[0].lLbound = 0;
SABounds[1].cElements = 2;
SABounds[1].lLbound = 0;
VariantInit(pReportTypes);
pReportTypes->vt = VT_VARIANT | VT_ARRAY;
pReportTypes->parray = SafeArrayCreate(VT_VARIANT, 2, SABounds);
lLoop = 0;
while(! pRsHPASReports->IsEOF)
{
ldimension[0] = lLoop++;
ldimension[1] = 0;
CComVariant bstrTmp( pRsHPASReports->Fields->Item["RptType"]->Value );
TESTHR(SafeArrayPutElement( pReportTypes->parray, ldimension, &bstrTmp ));
ldimension[1]++;
CComVariant bstrTmp2( pRsHPASReports->Fields->Item["Title"]->Value );
TESTHR(SafeArrayPutElement( pReportTypes->parray, ldimension, &bstrTmp2 ));
pRsHPASReports->MoveNext();
}
With best wishes,
Vita
|
|
|
|
|
I have a simple COM server dll that creates dialogs through calls to interface methods. When creating the dialogs, the CWnd* is creating some difficulty for me (I think). The problem is that the main .exe (CFrameWnd) will dissapear (moves behind other windows) while the dialog is shown . I think the parent window is defaulting to NULL or some other window.
I pass in the HWND from the .exe main frame window to the interface method. I call CWnd::FromHandle(), and get a temporary window pointer. This pointer's m_hWnd doesn't match up with Spy++, but I'm not sure why this is?
I'm hoping that this is a simple problem, and that I'm doing something ridiculous.
Thanks for any help you can give.
Dave
|
|
|
|
|
What is the best way to register an ActiveX control created with MFC to the current user registry part to avoid administrator's right?
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
I THINK NO WAY AT ALL..!!!
Code the Dreams.
|
|
|
|
|
What's the best way of passing a binary file through COM. For example, if I had a GIF file on my COM server and wanted to send it to a client then how would I go about it? I'm new to using COM and have only passed types like BSTR, etc.
Thanks
|
|
|
|
|
You can use an IStream (or ISequentialStream), or a SAFEARRAY of VT_UI1 (bytes), or even a BSTR if you wanted to. The first will result in more roundtrips, since you'd then call IStream methods to get the data, while the second (and the third is really a hack of the second) might mean that you need a lot of memory available if it was a big file (so not a GIF, then...)
Steve S
[This signature space available for rent]
|
|
|
|
|
Thanks loads Steve. Got it working using an IStream with the client grabbing 4K chunks. Is there an optimum erm.."chunk" size?
|
|
|
|
|
hi
I have embedded an excel spreadsheet in an ASP webpage. The problem occurs when the spreadsheet was repeatedly opened to populate data. The application becomes slow and eventually dies, with memory handles over 70 000!
I have used <object> to call the excel spreadsheet.
Could this be the reason? Can some one please help me with this?
Regards
|
|
|
|
|
Hello, I'm learning about COM and COM+ and will eventually (when I understand it properly) port a legacy MFC business application I'm responsible for into separate COM components created using ATL.
I'm starting to get an early grasp on things and have done a lot of reading and experimentation, but I have a practical question that doesn't seem to be answered in any of my COM books or anywhere in MSDN:
How much of a large application with many different components should a single .dll server ATL project contain?
Specifically: lets say I have a largish application that will consist of 3 tiers (not counting the presentation layer which is a separate application consuming the COM objects):
Collection and business objects layer
Transaction objects layer (for persistence to database and retrieval)
Data layer (OLEDB - SQL server)
Each business object (and their collection objects) will each have a mirrored transaction (persistence) object "below" them just "above" the data layer to allow for database indpendance among other things.
Most components will use other components (for example a Customer component will use an Address book component etc).
Should I build my .dll files to incorporate all related objects from all tiers into each .dll (for example a Suppliers collection, supplier object and their associated Supplier transaction objects in one ATL project (.dll file))?
Or should I build components of a similar tier into a single ATL project (.dll) file?
My guess is that they should be split tier by tier and then within each tier split again by business object to support re-use later depending upon how re-useable (and independant of other components) they will be.
The end result though could be dozens to hundreds of separate .dll files for my potential application.
If this is the case, is there a penalty for too much granularity this way?
What would be a practical "rule" for this? (I know, the answer probably is it depends
|
|
|
|
|
First, if the clients are ever going to execute remotely, I would suggest 'exe' and not 'dll'.
Second, I have migrated a previous COM solution involving a bunch of dll's into a single exe with dozens of pieces to it. One huge benefit is that you don't have to worry about different versions getting mixed together. When you have to make an inevitable change, instead of adding a bunch of version cross-checking in your dll's, you just update the single exe and not worry about it.
You may even find that some of your data layer is no longer needed. Some information is more easily and more efficiently maintained as global variables within this single process.
|
|
|
|
|
I was hoping someone could explain an easy way to serialize a COM or ActiveX object in VB.NET or C#. What I am trying to do is save the state of the Office XP Web Components (a spreadsheet to be specific) which are COM based and no matter what I have tried it has failed.
Do I HAVE to write a wrapper class that implements the Serializable attribute? Or is there a simpler way I just can’t find. I have even tried storing OcxState but can’t seem to figure out how to get it onto disk.
Aaron Luke Richey
|
|
|
|
|
If you know how to do this using raw C/C++ code (IPropertyBag interface), I believe you'll soon get it done with other languages.
In addition to posting in the right forum (isn't your question about .NET after all ? ), have you tried to cast one of the AxHost member (such as OcxState) to IPropertyBag ?
A good way to try this is to derive a class from AxHost so you access protected members. Also, use Anakrino[^] to disassemble the AxHost internals.
Back to real work : D-21.
|
|
|
|
|
I have situations where I want to provide access to a DCOM server over a large network, or perhaps even the Internet. I find that if I enable the guest account, this will work for many users. But, if the remote user has logged in to their computer or domain as, for example, user 'jsmith', and if the
DCOM server computer or domain happens to also have an account for user jsmith, then their passwords must match. This seems to be true whether the guest account is enabled or not. Indeed, if I create these duplicate accounts, then I don't need the guest account. This is just as well, since many clients balk at enabling the guest account, and it is particularly scary to do so on the Internet. But how can I handle a situation where there are two jsmith's out there (obviously on two different computers/domains) each with a different password?
|
|
|
|
|
Anyone who knows how to give a ActiveX control full permission to files on the client's computer??
Can I do this by signing the cab-file?? How do I do that??
|
|
|
|
|
If you look up in MFC's documentation on various OLE classes, e.g. COleVariant you are asked to look up in Win32 SDK OLE Programmer's Reference for more information. Where can I find this? Is it anything i can download?
One other thing, I am totally new to COM. Will it help me to have this reference, or is useless without a learner's book. It seems to be a very complex subject .
Regards, Haakon S.
|
|
|
|
|