|
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
|
|
|
|
|
Put a break point directly after the CoCreateInstance call you're having problems with. When the break point is hit add the following to the watch window: "hrStatus, hr". If all goes well your debugger will tell you what the problem is.
Steve
|
|
|
|
|
Hi Shailesh,
What happens to your problem ?
Its always good practice to reply, whether you problem has been solved or not. It helps other to add this problem to their knowledege.
And reply further if not solved.
|
|
|
|
|
i want to launch an executeable thorugh shell.
can any one help me out ?
|
|
|
|
|
Doesn't this[^] section helps you?
|
|
|
|
|
Hi Andrew,
Thanks for this article, really it is very knowledgeble.
I have downloaded demo project for costum form "A VC++ Outlook COM Add-in that publicizes a custom form" , but when I am giving build in vc++(6.0) editor, it is giving following error :
/******************************/
Compiling...
Addin.cpp
D:\OutlookProject\demo\OutlookAddin_demo\Addin.cpp(59) : error C2665: 'AfxMessageBox' : none of the 2 overloads can convert parameter 1 from type 'const char *'
D:\OutlookProject\demo\OutlookAddin_demo\Addin.cpp(112) : error C2664: '__thiscall ATL::CComPtr<struct office::_commandbarbutton="">::ATL::CComPtr<struct office::_commandbarbutton="">(struct Office::_CommandBarButton *)' : cannot convert parameter 1 from
'long' to 'struct Office::_CommandBarButton *'
Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast
Error executing cl.exe.
/**************************************/
I am not able to solve this error, could you please help me to fix this error.
Note : In my system having outlook 2003
Many Thanks
Abhishek
Abhishek Tiwary
|
|
|
|
|
Hi
i have created a C# DLL in VS2003 and installed it in GAC with WISE installer which actually register the dll in gac and add registry key.
i am calling this dll from vbscript by using createobject method when
i first time installed the dll and access it from script it works fine
but when i change the version number after some updates in the code and install it again its not working
in event log its giving the error for Invalid class string when i call it from vbscript.
i even remove the previous version before new installation and restart my pc.
this happen for all the dlls i m working they all work first time same error after new version of dll
But if i change the ProgId its start working again.
the problem is i dont want to change Progid every time i create new version.
Any help
thanks...alot
Nav.
|
|
|
|
|
Hello,
I’ve developed ATL Control using VC++ 2003 to use it as GUI component for different programming environments. It works fine with .NET and Borland builder, but when I try to use it with VB6 or VC++6 I got ‘Permission denied’ error. It happened when I call ::GetClientRect(m_hWnd, &ClientRect) function, where m_hWnd is a private member of this control (handle of control’s window). What’s wrong? How to fix it?
Regards,
Leonid
|
|
|
|
|
i need to pass a path string to vc++ module in a com component, but i'm having difficulty in working betbeen string of C# and CHAR* of vc++. does anyone have any solution??
i have made an interface(COM) for a function sth like below.
test(CHAR* path)
{
}
|
|
|
|
|
Hello,
You need to use BSTR as argument’s type for COM server. Interop takes care about the rest.
Regards,
Leonid
|
|
|
|