|
For me it is crashing when I am changing BSTR to VT_I4 with change type , can you please give me the solution if you found?
My code looks like:
varValue.ChangeType(VT_I4); //_variant_t varValue is BSTR
where varValue is BSTR type and it is null, how can we change in this situation?
modified 17-Jun-19 8:59am.
|
|
|
|
|
Hi,
I need to use the System.Printing.Activation dll bu I'm unabled to find it in the .NET Framework 3.5
I was searching on the net but I can't find it and I saw no other case like mine. Did somebody have tehe same problem I have.
Please help me.
Regards.
|
|
|
|
|
I Just found an answer to my question. The reference i was searching is include into the ReachFramework.dll
apologies
|
|
|
|
|
Hi,
I have a VB code (ActiveX ExE) which has a VB form called DocX.
This form has a GET property (name it retProp) which returns an object.
I have compiled the ActiveX EXE and later used tlbimp from dotnet to generate an Interop.MyProject.dll
Later I have included this dll as a reference in my C# project.
Now I am getting the namespace MyProject.MyInterface.
When I use the following code it says "true"
if (MyInterface.Windows.Exist(ref data) == true)
--> MyInterface.Windows.Exist(ref data) returns the MyInterface.Windows.Window as object
Because MyInterface.Windows.getItem(ref data).Form is returned as an object to me I am not able to Unbox it. I get an error :
System.InvalidCastException: Unable to cast COM object of type 'System.__ComObject' to class type 'VB.Form'. COM components that enter the CLR and do not support IProvideClassInfo or that do not have any interop assembly registered will be wrapped in the __ComObject type. Instances of this type cannot be cast to any other class; however they can be cast to interfaces as long as the underlying COM component supports QueryInterface calls for the IID of the interface.
Pls help.
Regards,
tvks
|
|
|
|
|
I want display a black background page in a IWebBrowser2. But it always flicker when it is refresh.
So I write following code to fix it.
::SetWindowLong(m_hBrowWnd, GWL_WNDPROC, (LONG)MyBrowWndProc);
m_pBrowWndProc=(WNDPROC)::SetWindowLong(m_hBrowWnd, GWL_WNDPROC, (LONG)MyBrowWndProc);
LRESULT CALLBACK CDlgTest::MyBrowWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
CDlgTest* pThis=(CDlgTest*)g_pIeTestDialog;
if(!pThis)
return FALSE;
if(message == WM_ERASEBKGND)
{
return NULL;
}
return CallWindowProc(pThis->m_pBrowWndProc, hWnd, message, wParam, lParam);
}
It work well at IE 8, but crash at once at IE 6.
Who can help me?
|
|
|
|
|
Will I be able to address all the requirements with a free threaded model? Assuming I have an efficient synchronization mechanism in place. Single,Multi apartments can ever be avoided?
----------------------------
286? WOWW!
|
|
|
|
|
_8086 wrote: Will I be able to address all the requirements with a free threaded model?
Ummm, what requirements?
_8086 wrote: Single,Multi apartments can ever be avoided?
A COM server resides in either a Single Threaded Apartment or a MultiThreaded Apartment. To avoid the use of them you should not use COM at all....
I guess you have to clarify your question (a lot, probably).
"It's supposed to be hard, otherwise anybody could do it!" - selfquote "High speed never compensates for wrong direction!" - unknown
|
|
|
|
|
What about Free-Threaded model? Which is analogous to a background thread? Free-Threaded model is Multi-threaded model?
----------------------------
286? WOWW!
|
|
|
|
|
Ok let me try to explain better.
I write a COM component that runs multiple threads inside. A simple CreateThread used.
I use critical sections to protect objects inside the thread function. What is this model called? I think this is free threaded model.
Also, when I read about STAs they say it deals with UI messages. It makes me tried. After all these brain squeezing efforts to understand COM, when I felt I'm okay with the concepts, a thunder on the head again. What the frack UI messages have got to do with a COM component. I know the dumbness is on my side, but I really don't understand. May be they are talking about Active-x? Understanding this threading models looks like nightmare. If you can help me with a casual explanation. I'd be grateful.
----------------------------
286? WOWW!
|
|
|
|
|
Okay.
So how about starting with the articles here at CP?
Lim Bio Liong has written a nice article series that can be found here[^].
There's a lot to be learned about COM and especially the understanding of the concept of apartments.
In short it boils down to that a thread that creates a COM server must always pump messages; it has to do with marshalling and RPC (deep technical stuff).
Free-threading looks a little bit different depending on whether the server is an in-process or an out-of-process server. But in both cases it means that the server will be called in different thread contexts and thus thread synchronization is essential inside the server. To use free-threading you have to create the server inside an MTA. Creating the server inside an STA guarantees that the server will nly be called from the same thread context as long as you obey the COM rules and marshal interfaces properly across apartment boundaries.
"It's supposed to be hard, otherwise anybody could do it!" - selfquote "High speed never compensates for wrong direction!" - unknown
|
|
|
|
|
Understanding threads inside COM looks like a litmus test for my IQ. Anyway lemme give a try . I will go through those articles your pointed out. Also thanks for the explanations.
----------------------------
286? WOWW!
|
|
|
|
|
Hi,
At first, we insert an object, a .mp3 file, in a Word .doc file footer.
And then insert a Windows Media Player object in it,too.
How to set the URL property of this WMP object in order that we can play this embeded .mp3?
Thank you in advance.
|
|
|
|
|
I'm looking for good, useful resources, both recipe-style step-by-step instructions as well as deep examinations of how one builds .NET assemblies for use in COM/ActiveX environments. Links to articles and web sites that are accessible from behind a well-protected corporate firewall would be most desirable; also, I'd like to hear about books that you yourself have used extensively for this purpose. My languages of preference are VB or C#, as my business environment is not C++-friendly. Thanks in advance for your help with this.
|
|
|
|
|
|
I call 'COleDispatchDriver::CreateDispatch' from my client EXE and it will start my server EXE if it is not already running or it will connect to an already started server EXE. If there are more then one server EXE started, then it always connects to the EXE that was started first.
I want to be able to select which server EXE process it connects?
I have tried using CoCreateInstance, CoGetClassObject, but I can't seem to figure out a way to override how these functions connect. It appears that 'CreateDispatch' calls 'OleRun' which does this functionality.
How is the IUnknown getting attached to a certain process? If I could figure that out, then I think I could call CoCreateInstance to get the uninitialized IUnkown, then do the missing piece to initialize the IUnkown and then I can query for the IDispatch.
Any help would be appreciated!
|
|
|
|
|
Do you need multiple servers? Is this an out-of-process server? The server isn't on a remote machine is it? Did you write them both?
You could call: CoRegisterClassObject[^], which associates the registered class object with the apartment of the caller. You can then obtain another pointer to the running object by using a Class Moniker[^].
Explanation from Don Box: "A process becomes the server process for a particular class by explicitly registering itself with the COM Service Control Manager (SCM). Upon registering with the SCM, any activation requests for the class that require out-of-process activation will be dispatched to the registered server process."
"The SCM is the central rendezvous point for all activation requests on a particular machine. The services of the SCM are exposed to programs as high-level moniker types (Monikers are COM locator objects that hide the details of an activation or binding algorithm), and as low-level API functions, all of which are implemented in what the Component Object Model Specification calls the COM library."
You might also read up on the: IRunningObjectTable Interface[^]. The Running Object Table (ROT) is a facility of the SCM that maps arbitrary monikers onto running instances on the local host machine.
If this isn't what you need, you could probably set up a policy by adding a registry key/value to your CLSID key, and read that specific key with all subsequent server instance activations.
By the way, this line from your post:
How is the IUnknown getting attached to a certain process? If I could figure that out, then I think I could call CoCreateInstance to get the uninitialized IUnkown, then do the missing piece to initialize the IUnkown and then I can query for the IDispatch.
...doesn't make alot of sense. If you can get a copy of Essential COM. by Don Box, I would recommend it highly. This book will give you a basic understanding of COM, and why COM does what it does.
|
|
|
|
|
Do you need multiple servers? Is this an out-of-process server? The server isn't on a remote machine is it? Did you write them both?
You could call: CoRegisterClassObject[^]which associates the registered class object with the apartment of the caller. You can then obtain another pointer to the running object by using a Class Moniker[^]
Explanation from Don Box: "A process becomes the server process for a particular class by explicitly registering itself with the COM Service Control Manager (SCM). Upon registering with the SCM, any activation requests for the class that require out-of-process activation will be dispatched to the registered server process."
"The SCM is the central rendezvous point for all activation requests on a particular machine. The services of the SCM are exposed to programs as high-level moniker types (Monikers are COM locator objects that hide the details of an activation or binding algorithm), and as low-level API functions, all of which are implemented in what the Component Object Model Specification calls the COM library."
You might also read up on the: IRunningObjectTable Interface[^]The Running Object Table (ROT) is a facility of the SCM that maps arbitrary monikers onto running instances on the local host machine.
If this isn't what you need, you could probably set up a policy by adding a registry key/value to your CLSID key, and read that specific key with all subsequent server instance activations.
|
|
|
|
|
I wrote both of them and they are both running on a local machine. Let me see if I can explain a little better.
The main program 'MyProgram.exe' can be ran by a user at anytime. They will run this program and use its interface. I have another program, 'MyManager.exe'. They are both writen in VC++ using MFC. 'MyManager' uses COM to connect to 'MyProgram'. However, I do not want 'MyManager' using the instance the user loaded, but to always use its own instance, so I need it to start its own instance if one is already running. Problem: When 'MyManager' does the CreateDispatch, it will always connect to 'MyProgram' of the instance that was started first. If there are no instances of 'MyProgram' running it will start a new one.
I want to be able to control what instance of 'MyProgram' to connect to when calling CreateDispatch. I have looked into the ROT, but it seems to require the IUnknown, but I do not know how to get that for a process that is already running.
I can have multiple instances of 'MyProgram' running, but I want to control which instance is used for 'MyManager'.
I can get the ProcessID of all instances of 'MyProgram', but I do not know how to get its IDispatch or IUnknown, so that I can use that to have 'MyManager' connect. I don't want to use the default functionality of 'OleRun' called from the CreateDispatch.
Thanks for helping.
|
|
|
|
|
Unfortunately, I don't use MFC, because it hides the underlying implementation, often making it difficult to make alterations without problems.
But, I'll try to explain clearly. If your 'My Program' is instantiated by a user, and your 'My Program' calls CoRegisterClassObject (this is the default, and your MFC implemenatation may actually do this), you can locate this running instance with the creation of a Class Moniker (presumably, implemented in your 'MyManager'). The Class Moniker must be initialized with a Binding Context to work properly. And, you pass the CLSID of a COM class exported by 'MyProgam' to IMoniker->BindToObject (which is where all the work is done), also, passing the IID_IUnknown Interface ID (this is a system IID, and you must link to uuid.lib, for the symbol to be exported correctly) as the REFIID parameter, the function should return the IUnknown interface pointer to the CLSID from 'MyProgram' that you supplied to the CreateClassMoniker function.
(From Matt Pietrek, "If you've used OLE, COM, or ActiveX, you probably remember that there are .LIB files that are used for predefined class IDs (CLSIDs) and interface IDs (IIDs). Both CLSIDs and IIDs are forms of GUIDs, which are 16-byte unique values".)
IMoniker->BindToObject returns a COM typed interface pointer (to the IUnknown of whatever interface you passed to CreateClassMoniker. This can then be used with QueryInterface.) You can then call, IMoniker->GetObject to determine if the instance is already running. That's the basic idea.
To intialize the Binding Context, call, CreateBindCtx, and then, pass it a BIND_OPTS2 structure (which must also be initialized). You must call, GetBindOptions and then, SetBindOptions to do this correctly.
Here's what the code might look like:
IUnknown *ppvUnknown = NULL ;
CLSID YourClassCLSID ;
BIND_OPTS2 BindOptns ;
IBindCtx *BindContx = NULL ;
IMoniker *ClsMoniker = NULL ;
ZeroMemory (BindOptns, sizeof (BIND_OPTS2)) ;
HRESULT hrBnd = CreateBindCtx (0, &BindContx) ;
if (hrBnd != NULL)
{
BindContx->GetBindOptions (&BindOptns) ;
BindOptions.cbStruct = sizeof (BIND_OPTS2) ;
BindOptions.dwClassContext = CLSCTX_ALL ;
BindContx->SetBindOptions (&BindOptns) ;
HRESULT hrMonikr = CreateClassMoniker (YourClassCLSID, &ClsMoniker) ;
if (FAILED(hrMonikr))
{
}
HRESULT hrBndObj = ClsMoniker->BindToObject (BindContx, NULL, IID_IUnknown, reinterpret_cast<void**>(&ppvUnknown)) ;
if ((SUCCEEDED(hrBndObj) && (ppvUnknown != NULL))
{
HRESULT hrRunning = ClsMoniker->IsRunning (BindContx, NULL, NULL) ;
}
else
{
ClsMoniker->Release () ;
BindContx ->Release () ;
ppvUnknown ->Release () ;
}
}
'MyManager' can use this technique to determine if an instance of 'MyProgram' is already running, and instantiate another one for it's exclusive use. You should read up on exactly what is the default COM procedure for the MFC class that you are using.
However, COM does NOT allow you to implement IUnknown, QueryInterface to return a NULL interface pointer, conditionally, if it has already returned a valid interface pointer. In other words, you cannot rewrite the QueryInterface implementation of 'MyProgram' to return a NULL pointer based on some determination, unless it ALWAYS does that.
Also, you might want to read this article: The COM Macro-Architecture Topology[^], which explains the default COM behavior with activation requests.
|
|
|
|
|
Thank you for the information. One thing that I found was that 'ClsMoniker->IsRunning' is not supported on a class Moniker. I believe I understand the default COM behavior, but I am looking at a way to change that behavior. I think I understand the code you provided, but I am still not sure how it can help me.
I have more then 1 instance of 'MyProgram' running. I want to be able to have 'MyManager' connect to an instance, that I select, of already running 'MyProgram'. I am not sure how to tell COM which instance to use. It always uses the instance that was started first, but that may not be the one I want. I have tried getting the Runable object, but that does not seem to work.
You talked about having 'MyManager' instantiate a copy of 'MyProgram' for it's exclusive use. That would work, but I am not sure how to do that. It always connects to the instance of 'MyProgram' that was started first. I need 'MyManager' to instantiate 'MyProgram' and connect to that instance, even if there is already other 'MyProgram's running.
Thanks again for you help.
|
|
|
|
|
hi to all,
i have implemented an activex control which works fine on iis server. however, when i deployed my project under tomcat and called the page with ie activex is not displayed. moreover when the page is loading, i am getting the info message about loading the activex. i see the object under C:\WINDOWS\Downloaded Program Files on some machines and on some machines i do not. I both copied the .ocx and .cab files on the same folder of my .html file. The object definition in the html is as follows;
<object id="CSTimer1" width="456" height="49<br" mode="hold"> CODEBASE="CSTimer.ocx"
CLASSID="CLSID:01B5BC0F-A51D-4C47-B3E9-3DA1099750CE">
<param name="_Version" value="65536" />
<param name="_ExtentX" value="12060" />
<param name="_ExtentY" value="1291" />
<param name="_StockProps" value="0" />
is it related with tomcat? any suggestions??
thanx in advance...
|
|
|
|
|
Hi all,
I wonder if someone here can help me, I did not have much success on msdn forums with this question.
I have the Microsoft's WebBrowser control embedded in my application and I am having trouble with the IDocHostUIHandler::GetHostInfo ( http://msdn.microsoft.com/en-us/library/aa753257(VS.85).aspx ) method. According to documentation, I should be able to pass a custom CSS file to the WebBrowser. And it works fine with IE6 and IE7, but it is ignored when IE8 is installed.
Has anyone else encountered this behavior?
Thanks for any suggestions. I even tried an example code from codeproject.com and added the css piece, but it did not worked. I'll be grateful for any idea.
Have a nice day,
Vlasta
|
|
|
|
|
I wanted to find out if it was possible to use the COM in VB .NET to receive a cell that is being changed (based on time, user values, etc) into a VB .Net program to then log the changes every few msecs into a database that I can then analise at a later date. Any help would be greatly appreciated as I cannot find anything of this type anywhere else.
Thanks
|
|
|
|
|
hello,
i have successfully created a button in a toolbar of Outlook Express.
on the click of this button i should be able to get a email address of
the sender from the selected message.
i am getting the name of the sender but not the "Email-Address".
thanks,
Nikhil
|
|
|
|
|
Hi all,
I'm quite new in COM but unfortunately I have to talk to a Delphi Application which supports a COM interface to other applications.
Invoking Methods of this COM Server or reading some attributes works quite well in my test application, in pseudo code it looks like
<br />
CoInitialize( NULL );<br />
...<br />
CLSIDFromProgID( L"DVBViewerServer.DVBViewer", & clsid );<br />
...<br />
GetActiveObject( clsid, NULL, & pIUnknown );<br />
...<br />
pIUnknown->QueryInterface( IID_IDispatch, ( void * * ) & pIDispatch );<br />
...<br />
pDispatch->GetIDsOfNames( IID_NULL, & szProperty, 1, LOCALE_SYSTEM_DEFAULT, & DispId );<br />
pDispatch->Invoke(DispId, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, &dp, &vReturn, NULL, NULL);<br />
...<br />
vReturn.pdispVal->GetIDsOfNames( IID_NULL, & szMeth, 1, LOCALE_SYSTEM_DEFAULT, & dispID );<br />
...<br />
vReturn.pdispVal->Invoke( dispID, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, & dp20, & varRetVal, NULL, NULL );<br />
<br />
On the other hand, it doesn't seem so easy to get an own c++ function registered as a COM Eventhandler.
I've read all articles and tutorials, but i didn't found a small and simple tutorial how to get from the COM/Delphi interface description
<br />
type ICOMServerEvents = dispinterface(IDispInterface)<br />
procedure onAddRecord(ID: Integer);<br />
procedure onClose;<br />
...<br />
to something like
<br />
void CALLBACK onAddRecord( int iID) {}<br />
Do I have do define an interface
<br />
interface ICOMServerEvents : IUnknown<br />
{<br />
virtual void __stdcall onAddRecord( int iID) = 0;<br />
...<br />
}<br />
then derive a class
<br />
class CCOMServerEvent : public ICOMServerEvents<br />
{<br />
virtual void __stdcall onAddRecord( int iID) { TRACE("AddRecord"); }<br />
....<br />
}<br />
and use something like createinstance to get this connected to the server ?
What is the simplest way ?
BR,
Andi
|
|
|
|
|