|
Hi,
I am using COM to access Excel and read from an existing Excel file.
I tried to use a smart pointer but had a problem with that so I am using GetIdsOfNames for calling the function. However, I don't seem to be able to correctly call the function Open (of WorkBooks).
In VB it is possible to send only the file name, but from what I have seen in C++ I have to give 12 parameters (!). It seems that I don't know what they should be...
Can someone please send me a code snippet of a successfull call to this open function?
thanks!
|
|
|
|
|
If you don't know what they are, then chances are they are optional parameters.
You can handle this by passing a variant that has a particular makeup,
namely
v.vt = VT_ERROR;
v.scode = DISP_E_PARAMNOTFOUND;
and using the variant for any 'optional' arguments.
Steve S
|
|
|
|
|
This is exatly what I was looking for!
problem is solved.
thanks.
|
|
|
|
|
Currently I am developing an application, which uses SafeArray to pass UDT. When I create SafeArray at server side and destoy it at client side, there is no issue. But when I create SafeArray at client side, and tries to destoy it at server side, the method returns with HRESULT values (error 0x800703E6)-"Invalid access to memory location" .
The procedure at both ends as below -
SafeArray consists of array of SafeArrays. So first create & access root SafeArray, fill it. Then access SafeArray at level 2, fill it, unaccess it , unaccess root level SafeArray, destroy root level SafeArray.
It works in client side, ut fails at server side.
|
|
|
|
|
What arguments are you passing to the SafeArrayCreate function to create the outer and inner ones
Steve S
|
|
|
|
|
1. The client code for creation is - SafeArrayCreate( VT_VARIANT, 1, &saBounds) where saBounds[] = (0, 20}, It consists of other SafeArrays and normal data types like INT, BSTR.
2. Passed to server as - SetData(SAFEARRAY **psaData)
3. At server side - hr = SafeArrayDestroy( *psaProjConfig )
4. The hr is S_OK at step 3.
5. But when method returns, client throws error as "Invalid access to memory location"
Thanks for the interest shown.
Regards,
Mandar
|
|
|
|
|
1-4 No problem, that's exactly right.
5. Is the parameter [in,out] by any chance?
If so, that's your problem. You need to do
4. hr = SafeArrayDestroy(*psaProjConfig);
*psaProjConfig = NULL;
That tells OLEAUT32 (which contains the automation marshalling code) that there is nothing to marshall back. Without that step, the marshaller at the client end will be trying to marshall freed memory.
Hope that helps
Steve S
|
|
|
|
|
Thanks Steve. Prevoiusly SafeArray was [in] parameter. As pointed out by you, I make it [in,out] parameter as we are changing its value. But till I am getting error after returning the method.
|
|
|
|
|
But are you really changing the value?
In my example, after destroying the SafeArray on the server side, I set the value to be NULL. Since it's an in/out, you pass not 'SAFEARRAY*' but 'SAFEARRAY**', of course.
I know 'Mr.Prakash' says it's not safe to destroy the array on the server side, but that isn't true.
I think it's still failing because the automation marshaller is trying to send back the deleted safearray.
Steve S
|
|
|
|
|
Hi,
I solved the problem. I write the code to destoying the SafeArray at Client side only, after returnung method from Server. My method has SafeArray as a [in] parameter. Now it is working properly.
Thank for the help.
|
|
|
|
|
mandarpb wrote:
But when I create SafeArray at client side, and tries to destoy it at server side
I guess it should not be done, pointers should be destroyed by the owner of the pointer i.e client in this case.
This space is empty.
|
|
|
|
|
Hi,
Yes, your solution is right.
Thank for the help.
Regards,
Mandar
|
|
|
|
|
any place to get detailed info on variant arrays..and how to use them??
|
|
|
|
|
MSDN.
A variant array is just that, an array of VARIANT types, use just like any other kind of SAFEARRAY, except of course, that your basic array type is VARIANT rather than BSTR or whatever.
It's worth remembering that SafeArrayGetElement and SafeArrayPutElement deal with COPYING the data they work with, so Get gives you a new, second, copy and Put will not care what you do with the original you pass it. This is true for other "managed" types (IUnknown, BSTR etc) not just VARIANTs.
Of course, your element type is determined by the .vt member of each element, not by the type of the array, but each element is the same size
Steve S
|
|
|
|
|
guys i have a variant..being returned by a method..how do i get its vt..and also how do i then extract the value from this variant..
thanks
-anand
|
|
|
|
|
|
hey thanks ian..
one more thing plz..how do i then get the value from this variant?
thanks
|
|
|
|
|
Depends what it is. There are various macros beginning V_ that you might find useful.
Say you have
VARIANT v;
HRESULT x = myobj.mycall(...,...,..., &v);
You can have code like this:
switch(V_VT(&v))
{
case VT_BSTR: // Returned a string
// V_BSTR(&v) is the BSTR being passed back...
break;
case VT_I4: // Returned a 'long'
// V_I4(&v) is the number
and so on.
Does that help?
Steve S
|
|
|
|
|
Dang! You beat me to it
|
|
|
|
|
Thanks a lot people...
|
|
|
|
|
Hi,
I've created a control with rounded corners by calling SetWindowRgn. If you place this control on a VB-form and keep on loading/unloading the form, a memory leak appears. If you remove the call to SetWindowRgn, there's no memory leak. MSDN says that you should delete a region after a call to SetWindowRgn because Windows will delete it when it is finished with it, but it seems to me this moment is not until the program exits.
Has anyone any noticed also noticed this ?
|
|
|
|
|
But did you delete the region that you had created?
P.R.A.K.A.S.H
|
|
|
|
|
No I didn't because that is what MSDN is saying in the Remarks section of SetWindowRgn :
After a successful call to SetWindowRgn, the system owns the region specified by the region handle hRgn. The system does not make a copy of the region. Thus, you should not make any further function calls with this region handle. In particular, do not delete this region handle. The system deletes the region handle when it no longer needed.
|
|
|
|
|
yeah u are rite, it should not be deleted that means then its not a porblem, windows may be removing it form the memory when it feels ok to remove it,
may be internal Garbage collector
One more thing, how many times the setwindowrgn is called???
If you call it twice, then its going to leak the memory.
P.R.A.K.A.S.H
|
|
|
|
|
What you say illustrates the problem, Windows will delete the memory when it thinks it is done with the region, but it seems to me that is not until termination of the application. My control calls SetWindowRgn each time the dimensions of the control or some visual property like the backcolor change, so yes, that is considerabye more then twice.
This is a problem because now, applications which use my control are forced not use Load/Unload constructs for forms with my control on it.
|
|
|
|