|
|
Why are you crossposting ancient stuff?
--
Booohoo!
|
|
|
|
|
Hi,
I am trying to return an object from a COM interface method. The method returns a _variant_t. I know how to retrieve int, short, dispatch, etc etc, but how do I simply retrieve an object from the _variant_t?
Thanks,
Ben
|
|
|
|
|
Hi Ben,
Sorry I didn't get your problem, do you want to return an object on a method through a variant or you want to retrieve the object fron the variant?
Can you refrase your question?
Fabian
|
|
|
|
|
Hi Fabian,
The method I am calling returns an object (a NOTESDOCUMENT to be specific). But it is returned as a _variant_t. I need to get it back to a NOTESDOCUMENT before I can perform any operations on it.
Thanks, Ben
|
|
|
|
|
You need to know how the object is encoded into the variant. Usually, a safearray of bytes can be used to encode an object (VT_ARRAY|VT_UI1) - in this case, you could simply extract the bytes and cast it to the relevant object structure.
|
|
|
|
|
Hi Ben,
Ok then, what you have to do to get the object is first to check the vt member of the _variant_t variable and see if it is an VT_UNKNOWN or VT_DISPATCH, according to that you will use the appropriated member to QI and get your object back.
Something like this
<br />
INotesDocument *pNtsDoc; <br />
HRESULT hr;<br />
if(vtReturned.vt & VT_UNKNOWN)<br />
hr = vtReturned.punkVal->QueryInterface(&pNtsDoc);<br />
else (vtReturned.vt & VT_DISPATCH)<br />
hr = vtReturned.pdispVal->QueryInterface(&pNtsDoc);<br />
else<br />
hr = E_INVALIDARG;
Don't forget to release the object once you finished using it.
Regards,
Fabian
|
|
|
|
|
Hey, thanks heaps. That worked. It was a VT_UNKNOWN.
Thanks again, Ben
|
|
|
|
|
hi
Try the following pseudo like code
In the interface method (called function) put:
pvarRtn->vt = LPDISPATCH<br />
pYourInterface->QueryInterface(IID_IDispatch, (void **) varID->ppdispVal);
In the client code (calling function) put:
CComQIPtr<IYourInterface> pYourInterface = varID.ppdispVal;
rgds...mil10
|
|
|
|
|
I'm getting an error that I'm trying to track down, but haven't been able to find any documentation on. I've successfully called CoCreateInstance on an object and am trying to call one of its member functions. When I do, a _com_error exception is thrown. ErrorMessage gives me the following:
IDispatch error #2494
I couldn't find anything in the MSDN nor online about IDispatch and this error number. As I'm a COM newbie, I presume I've messed things up
Let me know if you would like to see some code.
Thanks.
|
|
|
|
|
"Returns the string message for the HRESULT recorded within the _com_error object. If the HRESULT is a mapped 16-bit wCode, then a generic message “IDispatch error #<wcode>” is returned." -- documentation on _com_error::ErrorMessage .
"If the HRESULT is within the range 0x80040200 to 0x8004FFFF, the WCode method returns the HRESULT minus 0x80040200, else it returns zero." -- documentation on wCode .
I suspect this is an object-defined error - the Visual Basic documentation suggests adding a constant to the constant vbObjectError , which is 0x80040000 , to get an error code - the meaning of which will obviously depend on the object itself.
You could try using the Description , Source and HelpFile functions on the _com_error object to see if the object has supplied more error information.
Stability. What an interesting concept. -- Chris Maunder
|
|
|
|
|
I guess I read too much documentation yesterday, because I should have found most of the things you just mentioned. I had tried HelpFile but it didn't have a value. The other two I hadn't tried.
It was an object-defined error code. I had misread the API documentation and was passing in a filename instead of a directory name. The Description field ended up really useful. As soon as I saw what it was, I knew what I had done wrong.
It works now! Thanks.
--Kaleb
|
|
|
|
|
I'm just starting to learn COM and have found quite a few decent tutorials. However, none of them explain the easiest way to get the IID, CLISID, and ProgID. In fact, they all generally assume that it is known.
I have a 3rd party DLL that I'm working with. I have done a #import "dllname.dll" and have the generated C++ wrapper to look at.
In order to find the ProgID, I opened up the OLE/COM Object viewer, and navigated to the library in question. Then I found the class names that I was interested in. After having the class names, I went to regedit and pulled up HKLM\Software\Classes\CLSID\<id> by doing a find on the class name, then looked at the ProgID entry.
At this point, I can call CLSIDFromProgID and then CoCreateInstance successfully using a CComPtr<IClassType>. But, if I still don't know how to get at the IID that I would need should I call CoCreateInstance directly without a CComPtr.
What's the best way to get at the IID? I also presume that there's a better way to get at the CLSID and ProgID?
|
|
|
|
|
IID generally follows this rule,
interface name IMyInterface so iid is IID_IMyInterface
CLSID_IMyInterface.
God is Real, unless declared Integer.
|
|
|
|
|
I had tried that as a that's the convention that many of the examples that I had found used, but when I looked through the .tlh and .tli files that were generated from the #import, there is no reference to either CLSID or IID anywhere in those two files, thus the compiler complains about an undeclared identifier. Is that something that would typically be defined in the dll so that a #import would pull it in?
Thanks again.
|
|
|
|
|
did you put named_guids in the #import statement ?
God is Real, unless declared Integer.
|
|
|
|
|
Thanks! I had missed that attribute. I noticed the namespace ones and some others, but didn't even see that one. That will make things much easier.
Thanks again.
--Kaleb
|
|
|
|
|
Hi all,
I am working on this from last few days, but no success yet .
I am creating two activeX control in SetClientsite of another activeX control. using AtlAxCreateControl() function.
The two inner controls are clearly visible me in IE( container for the outer activeX control).
My question is even if i am able to create these control. how can I control
these child ActiveX from Parent ActiveX. because the AtlAxCreateControl() does not return anything about the control which I can be keep as a refernce in the outer activeX. or in Simple term how the other component knows about the inner component.
2. How to resize the two child controls?
Can someone help me?
Thanks in advance,
Abhishake
|
|
|
|
|
MSDN -----> Article 'Write ActiveX Controls Using Custom Interfaces Provided by ATL 3.0, Part III'.
The above articale would expain you what is happening behind the scene or more simply you would use connection points for interaction between the control and container.
Jitendra
|
|
|
|
|
hi,
i m trying to make my COM server to handle asynchronous calls. But for i have an error while trying to update the idl file for this purpose.
While adding these lines
coclass FullServ
{
[default] interface IFullServ;
interface ICallFactory;
}
it throughs the following error
error MIDL2337 : unsatisfied forward declaration : ICallFactory [ Coclass 'FullServ' ]
It will be so kind of u if u can help me out.
Shahzad Ahmad
|
|
|
|
|
It's telling you that it couldn't find a full declaration of ICallFactory .
Make sure you've imported ObjIdl.idl , where this interface is defined. This interface wasn't defined in the headers which shipped with Visual Studio 6; you'll need a newer version of the Platform SDK, which you can obtain from http://www.microsoft.com/msdownload/platformsdk/sdkupdate/[^].
Stability. What an interesting concept. -- Chris Maunder
|
|
|
|
|
Thanks Mike.I have done this. But when i include the Plateform 2000 SDK files in Visul C++ setting i have other error of in
BEGIN_OBJECT_MAP(ObjectMap)
OBJECT_ENTRY(CLSID_TryAsync, CTryAsync)
END_OBJECT_MAP()
Error: Can not access private member
Now i tried to simply replace the objidl.idl file of Visual studio with that of SDK. After This i havenot get any error in IDL File But it gives the following error if i try to make my object class inherit from IClassFactory.
error C2504: 'ICallFactory' : base class undefined
Thirdly when i include
async_uuid(06896d00-fb66-4222-8991-eb85c11720f9),
in IDL and my declaration of Interface is this
interface ITryAsync : IUnknown
{
[id(1), helpstring("method Add")] HRESULT Add [in] int a, [out, retval] int* b);
};
It gives Followin error
error MIDL2021 : duplicate id : [ Procedure 'Finish_Add' ( Interface 'AsyncITryAsync' ) ]
It will be so kind of you if you can help me in this regard.
If u have some useful sample then Please send me or give me its link.
|
|
|
|
|
hi,
i want to develop an application in which com client can call methds of COM Server asynchronously. For this i have gone through non-blocking method calls" article from microsoft. But there are some problems. i m getting error on adding this line to IDL file.
[
object,
uuid(637D4FFD-3DBB-4783-B2A3-196AC10FF804),
// async_uuid(6847c7fb-15fc-4638-b403-779d654d90e2),
dual,
helpstring("IAsync Interface"),
pointer_default(unique)
]
interface IAsync : IUnknown
{
[id(1), helpstring("method add")] HRESULT add([in] int a, [ out ] int * b);
It gives the following error
error MIDL2021 : duplicate id : [ Procedure 'Finish_add' ( Interface 'AsyncIAsync' ) ]
Secondly if i wnt to make it server for VB Client i made the following change to the code
coclass Async
{
[default] interface IAsync;
interface ICallFactory;
};
and it return following error
error MIDL2337 : unsatisfied forward declaration : ICallFactory [ Coclass 'Async' ]
it will be so kind of u if u can help me in this regard. By giving any link or help
|
|
|
|
|
Using P/Invoke how would i know that i should be passing "by value" or "by reference" to the arguments of a method or function of the DLL?
2. Equivalent type in .Net of the used data type for each variable (e.g what's the equivalent type of BSTR in VB.Net/C#?
3. In the type library it says:
VARIANT_BOOL _stdcall NE_QueryElementByID(
[in] long net,
[in] ElementTypeEnum eltype,
[in, out] IDAttRec* id,
[in, out] HandleAttRec* h);
This is the way i called it in VB.Net...is this correct?
...
<dllimport("neteng.dll")> _
Public Shared Function NE_QueryElementByID(ByRef net As Long, ByRef eltype As ElementTypeEnum, ByRef id As IDAttRec, ByRef h As HandleAttRec) As Boolean
End Function
...
Dim h1 As HandleAttRec
hi.Handle = 0
Dim id1 As IDAttRec
Dim m_startid As Int32 = 4424
id1.UserID = 99
id1.LayerKey = 1
dim bol as Boolean = NE_QueryElementByID(net, ElementTypeEnum.NE_EDGE, id1, h1)
Tnx a lot!
|
|
|
|
|
COM's IDL follows C's convention: arguments are always copied (pass-by-value). Where it gets tricky is that the value copied might be a pointer, simulating pass-by-reference.
In this case, you'll want to pass net and eltype ByVal , while id and h should be passed ByRef .
However, if you have a type library, why aren't you using tlbimp ?
Stability. What an interesting concept. -- Chris Maunder
|
|
|
|