|
Gupta Suraj wrote: "_variant_t vtSample(pICustom);"
Can you show code snippet, how you are using this interface? There is no way it should assign vt as VT_BOOL , unless pICustom is BOOL .
While debugging, you can step through the contructor of _variant_t , see which contructor is been called.
|
|
|
|
|
Thanks Prasad...
Actually,pICustom is a smart pointer. So when "vtSample(pICustom)" is executed, bool operator of _com_ptr template class is called. What I think is that the best matching constructor of _variant_t class is that which takes a bool as its paramter.So first bool operator of _com_ptr is called to convert the parameter to bool.
We don't have a overloaded constructor of _variant_t class which takes smart pointer as its parameter.
Please send your comment on this. Am i thinking in right direction?
Suraj.
Suraj Gupta
|
|
|
|
|
Try explicitly casting your object to an IDispatch pointer, for example (IDispatch *)pICustom. That should eliminate falling through to bool.
|
|
|
|
|
Thanks...It worked...
Suraj Gupta
|
|
|
|
|
Though, you had a solution to your problem;
Gupta Suraj wrote: bool operator of _com_ptr template class is called.
Which operator bool you are talking about ? In fact, it should return you custom interface type.
Its implementated like this,
operator T*() {
return p;
So I feel, it should return interface pointer.
Can you show how you have declared this interface ?
Gupta Suraj wrote: We don't have a overloaded constructor of _variant_t class which takes smart pointer as its parameter.
No, CComPtr , will be called for operator T* . Which returns appropriate interface pointer.
i.e. consider this declaration,
CComPtr<IMyInterface> pMy;
_variant_t f(pMy);
Here,in second statement pMy->Operator T* will be get called first. Which returns IMyInterface* .
So, it will set for VT_IDISPATCH automatically.
You dont even need to cast it.
|
|
|
|
|
Hi Prasad,
Here is code snippet of my application..
// Smart pointer(SampleObjects::ISampleSetDualPtr) typedef declarations
_COM_SMARTPTR_TYPEDEF(ISampleSetDual, __uuidof(ISampleSetDual));
// Smart pointer typedef declarations
SampleObjects::ISampleSetDualPtr pMutipleValues = SampleObjects::ISampleSetDualPtr )propertyPtr->Value;
_variant_t vtMultiValue(pMutipleValues);//This statement first causes bool operator of template class _com_ptr_t being called and then overloaded constructor of _variant_t class being called which takes bool as input parameter.
template<typename _iiid=""> class _com_ptr_t
{
......
......
......
operator bool() const throw()
{
return m_pInterface != NULL;
}
}
Please let me know your input on this.
Thanks,
Suraj
Suraj Gupta
|
|
|
|
|
Now I got your point.
I was in assumption, you are using CComPtr , where as you are using _com_ptr_t . Both are having different implementations.
Gupta Suraj wrote: _variant_t vtMultiValue(pMutipleValues);//This statement first causes bool operator of template class _com_ptr_t being called and then overloaded constructor of _variant_t class being called which takes bool as input parameter
Here, compiler looks for mathcing constructor of _variant_t . It doesn't find one with given smart pointer. _com_ptr_t is overloaded for operator bool() . Hence, there is match betn constructor with bool parameter of _variant_t and passed smart pointer variable.
Type casting as said in one of previous replies is one solution.
Or you can Use
_variant_t vtMultiValue(pMutipleValues.GetInterfacePtr()); to resolve ambiguity .
|
|
|
|
|
Thank you...
Solution you suggested works.
I thought another solution that works in this case is
_variant_t vtMultiValue(pMutipleValues, true);
You have being a great help.
Suraj
Suraj Gupta
|
|
|
|
|
Gupta Suraj wrote: _variant_t vtMultiValue(pMutipleValues, true);
Yes, that's becuase, as in previous case compiler was picking _variant_t( bool bSrc ) throw( ) version of constructor as match.
But, in this case that wont happen because of extra parameter provided(That resolved ambuguity in one way).
And compiler matches this construcor _variant_t( IDispatch* pDispSrc, bool fAddRef = true ) throw( ); To do that match, first parameter is typecasted with IDispatch* .
|
|
|
|
|
I’m automating MS Project and when I listen on an event from MS Project all works fine but when I’m trying to fill a TreeView I got the following exception:
Action being performed on this control is being called from the wrong thread. Marshal to the correct thread using Control.Invoke or Control.BeginInvoke to perform this action.
What have I missed?
_____________________________
...and justice for all
APe
|
|
|
|
|
I'm guessing you got the TreeView control from one thread and are filling from another.
« Superman »
|
|
|
|
|
Interfaces that cross apartment boundaries has to be marshaled.
No surprises here, it's according to the COM spec.
When you spawn a thread that should use COM stuff, you create another apartment and you have to initalize COM for that apartment with a call to ::CoInitalize() or ::CoInitializeEx(). If you want to use a COM interface that you got in another thread you have to marshal that interface to the new apartment.
There are several ways of doing this, but I think in your case the easiest way would be to use ::CoMarshalInterThreadInterfaceInStream() and ::CoGetInterfaceAndReleaseStream().
Have a look at MSDN here[^].
--
Roger
"It's supposed to be hard, otherwise anybody could do it!" - selfquote
"No one remembers a coward!" - Jan Elfström 1998 "...but everyone remembers an idiot!" - my lawyer 2005 when heard of Jan's saying above
|
|
|
|
|
Hello,
.NET interop service marshals all interfaces automatically for all new threads. Marshaling fails for incorrect data types in the interface. You can only use automation supported data types like BSTR, VARIANT_BOOL, SAFEARRAY etc. For complete list of data types see VS documentation on MSDN or ATL wizard in Visual Studio.
Regards
|
|
|
|
|
Ok, I've seen that function before.
I programming in .NET (C#). What type of method can I use in .NET.
I've run into the Control.Invoke method but I have about 30 calls to my TreeView and it is very time-consuming to rewrite all these calls...
_____________________________
...and justice for all
APe
|
|
|
|
|
d00_ape wrote: I programming in .NET (C#). What type of method can I use in .NET.
Sorry, I neither do .NET nor C#.
d00_ape wrote: I've run into the Control.Invoke method but I have about 30 calls to my TreeView and it is very time-consuming to rewrite all these calls...
Why would all those calls have to be rewritten?
This cannot have anything to do with eventual calls to the marshalling API.
--
Roger
"It's supposed to be hard, otherwise anybody could do it!" - selfquote
"No one remembers a coward!" - Jan Elfström 1998 "...but everyone remembers an idiot!" - my lawyer 2005 when heard of Jan's saying above
|
|
|
|
|
Roger Stoltz wrote: This cannot have anything to do with eventual calls to the marshalling API
Sorry I don't know what you mean with that...
I've posted this topic in the C# forum.
_____________________________
...and justice for all
APe
|
|
|
|
|
d00_ape wrote: Roger Stoltz wrote:
This cannot have anything to do with eventual calls to the marshalling API
Sorry I don't know what you mean with that...
I meant that it doesn't matter whether the code is implemented in C# or C++.
If adding marshalling of an interface would require "every call to be rewritten", then I suspect either a design flaw or the API to be used in a way it wasn't intended.
I hope you don't mean that "rewriting a call" means changing the name of your interface variable and you consider a "search'n'replace" for changing the name of a variable time consuming.
Why do you think that every call needs to be rewritten?
Why do you create a second thread and what does it do?
My questions are language independant.
--
Roger
"It's supposed to be hard, otherwise anybody could do it!" - selfquote
"No one remembers a coward!" - Jan Elfström 1998 "...but everyone remembers an idiot!" - my lawyer 2005 when heard of Jan's saying above
|
|
|
|
|
Hi,
Problem is that A call to CocreateInstance fails ....hence the requested interface pointer shown is NULL ...hrStatus = CoCreateInstance(
clsControl,
NULL,
CLSCTX_INPROC_SERVER,
IID_Control,
reinterpret_cast<lpvoid *="">(&m_pControl)
);
ABOVE the IID_Control is showing as NULL...
Any solutions , Kindly let me know
regards
Shailesh
|
|
|
|
|
Shailesh Halankar wrote: ABOVE the IID_Control is showing as NULL...
I think, you wants to say, m_pControl is NULL.
Can you show complete code ?
Have you used ::CoInitialize(NULL) before calling CoCreateInstance ?
|
|
|
|
|
Hello
ur right m_pControl is NULL ..hence error..
I can giv u some more of the code ...
HRESULT hrStatus = CLSIDFromProgID( TEXT("What ever prog ID"), &clsControl );
if( SUCCEEDED(hrStatus) )
{
//
// Create the object and initialize it.
//
hrStatus = CoCreateInstance(
clsControl,
NULL,
CLSCTX_INPROC_SERVER,
IID_IControl,
reinterpret_cast<lpvoid *="">(&m_pControl)
);
if( SUCCEEDED(hrStatus) )
{
// some code
}
}
|
|
|
|
|
Shailesh Halankar wrote: HRESULT hrStatus = CLSIDFromProgID( TEXT("What ever prog ID"), &clsControl );
if( SUCCEEDED(hrStatus) )
I think you are getting class id here.
Call, ::Coinitialize(NULL) before it.
Shailesh Halankar wrote: hrStatus = CoCreateInstance(
clsControl,
NULL,
CLSCTX_INPROC_SERVER,
IID_IControl,
reinterpret_cast(&m_pControl)
);
What is value of hrstatus here?
|
|
|
|
|
Hi Prasad
I cant use coinitialize function ..gives linker error..i think its coz its not a VC++ apllication that i m working on . Its a Embeded VC++ application that i m working on.
regards
Shailesh
|
|
|
|
|
Shailesh Halankar wrote: ..gives linker error
You need to link Ole232.lib .
Shailesh Halankar wrote: i think its coz its not a VC++ apllication that i m working on . Its a Embeded VC++ application that i m working on.
Doesn't matter.
BTW, you haven't answered my second question , about value of hresult.
|
|
|
|
|
Your code is hard to read. What is the HRESULT returned? Try entering "hr, hr" in your debugger watch window, assuming the variable containing the HRESULT returned from CoCreateInstance is named "hr ". If it was named "MyHr " you'd use the following string: "MyHr, hr".
Steve
|
|
|
|
|
my code ..is somewat like this
HRESULT hrStatus = CLSIDFromProgID( TEXT("some"), &clsControl );
if( SUCCEEDED(hrStatus) )
{
//
// Create the object and initialize it.
//
hrStatus = CoCreateInstance(
clsControl,
NULL,
CLSCTX_INPROC_SERVER,
IID_IControl,
reinterpret_cast<lpvoid *="">(&m_pControl)
);
if( SUCCEEDED(hrStatus) )
{
//some code
}
}
regards
Shailesh
|
|
|
|