Limit ActiveX to single instance

I wrote an ActiveX control that reads/writes to a COM port and updates global variables based on information received over port.  Since there is only one COM port, I want multiple applications to be able to use a single instance of the control (which "owns" the COM port).  Teh control updates its variables and multiple calling apps can read the properties from the same instance of the control.

How do I do this?

rosborn051498Asked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

galkinCommented:
What you can do is add code to register your control into OLE Running object Table when first instance is created. when the second instance is about to be created it looks up into ROT and if it finds moniker associated with control it extracts first instance interface pointer and paases it back to client instead of its own. I guess if your control doesn't have visual implementation the better way is to implement it as out of process server then inproc ActiveX control
0
rosborn051498Author Commented:
I'm not yet familiar with monikers, do MFC-generated ActiveX controls support the IMoniker interface?  How is the interface pointer passed back?  In short, do you have sample code?

Can you please elaborate on the "out of process server then inproc ActiveX control"?  I hope I don't have to be out of process, as this may cause a substantial preformance hit.  Right?  By the way, I am not yet thread safe.  I imagine this would be fairly important for an out of process server.

Thanks, this is great help.
0
galkinCommented:
No MFC doesn't generate Moniker but you can avoid using this. Use OLE global wrappers RegisterActiveObject, GetActiveObject and RevokeActiveObject.
I still advise you implementing it as out of process server. MFC provides excellent support for it. If you are going to implement it as DLL you may face a problem when application that loaded this DLL into memory exits, it automatically unloads DLL. Out of proces(or local server) is EXE. You can generate this server by creting AppWizard project and checking server check box. You can always make server main window invisible to hide its UI.  
0
Rowby Goren Makes an Impact on Screen and Online

Learn about longtime user Rowby Goren and his great contributions to the site. We explore his method for posing questions that are likely to yield a solution, and take a look at how his career transformed from a Hollywood writer to a website entrepreneur.

rosborn051498Author Commented:
This may be a dumb question, but can an ActiveX control (OCX) be an out of process server?  I want to encapsulate my functionality in an OCX so Visual C++/Visual Basic programmers can easily use it.
0
mikeblasCommented:
Out of process controls are possible, but are impractical because of the very serious performance penalties the out-of-proc marshalling causes.

.B ekiM
0
galkinCommented:
Actually ActiveX control in new Microsoft implementation must implement IUnknown four OLE exported functions and other functionality as needed. The problem is what to name ActiveX control. I have never heard of out of process ActiveX controls. Recently it was not possible since ActiveX(OLE that time) control must have implemented IViewObject interface that is not marshalled across process boundaries. Not requirements to ActiveX control have been dropped down so minimal out of process server can be referred to as ActiveX control also.
0
rosborn051498Author Commented:
Your help has definitely pointed me in the right direction, but I still don't know exactly how to do it.  

Nice to hear from you, Mike.  I just saw you at the VCDJ in Boston.  The penalty of marshalling was discussed frequently there.

Let me just add (or reiterate) a few things:
       * the control has no UI at run-time
       * the control talks to a proprietary device on a COM port
         and must alert all container apps (via events) when
         a property changes
       * containers can get/set properties, which are
         global to all containers.  When one container changes
         a property, the others must be made aware of the
         change.
       * all containers will be on the same machine

Registering in the ROT seems easy, but I'm not sure how to pass back an interface pointer.  Also, would I have to write code to keep track of how many containers are using me?  Would I need to fire individual events to each container?  Would get/set methods be thread safe?

Automation server is sounding like the way to go.  All references I have seen to Automation Servers have been "*.EXE"s.  Does that mean that in order to provide an out-of-process server that I must create an executable that uses my ActiveX control, and that also exposes an interface, which could include a way to call the control's properties directly?

By making it an automation server, I seem lose some of the "traditional" ActiveX control features, such as easy integration into Visual C++/Visual Basic apps.  We don't specific plans to distribute the control for developers, but I don't want to make the process difficult for our other in-house developers.  What to do, what to do?


0
galkinCommented:
The only one problem that prevents you from designing inproc server is that you must control only one instance of your object and module where this object resides must be alive until all all its clients are connected to it. This leads to conclusion that out of proc server(EXE) is the only solution despite all desadvantages it has over inproc server.
Concerning getting pointer to existing instance of the object more correctly that each client before trying to create a new instance of the object server would check with GetActiveObject if such an instance is already running and if so would try to connect to the running one. But if you do not have control over all client which are supposed to use you object you can do what I suggested. Namely when new instance is created it fitst checks in ROT and if it finds running instance it extracts its pointer and passes its to the client instaed of its own Then it terminates itself(since it is EXE).
You can implement IDispatch interface. In this case you can add properties and methods and no marshaling is needed since OLE itself provides marshaling for IDispatch interface. Since OLE implements local/remote transparency client doesn't care if your object is inproc or local.
0
rosborn051498Author Commented:
Thanks.  I missed notification of your last comment, so haven't responded sooner.  Sounds like out-of-proc server is the way to go.  Your last comment is helpful, but I'm still a little confused about how to do it.  Do I create an EXE that uses my control, then design a custom interface for clients to use?  Or is there a way to pass the control's interfaces directly to clients?  I have control over what all clients do, since (for now) they are all in-house.  Basically, I need a little more high-level help for writing an automation server that resembles a "traditional" ActiveX control.  Such as, how do I fire events to all clients?  
0
galkinCommented:
You can create skeleton out of process server using AppWizard. When stepping through the wizard and aked what type of compound document you would like to support choose either mini server or full server. Mini server cannot run stand alone just serve othe clients. Full server can. There is one MFC sample demonstrating using connection points in MFC out of process server. Serach microsoft knowledge base.
0
rosborn051498Author Commented:
I will search the KBase.  I believe your answers lead me in the right direction, but have not directly answered my questions.  While I do appreciate your help, I don't think I got a complete answer.  

I'm sorry if I have have a bad attitude.  I'm sure you are more than capable of helping me, but I just don't think you've provided the answers I expected.

I guess I'll research automation servers and try to find the KBase example.  I still don't know for sure what the architecture looks like (do I write an auto server EXE that uses my control?  How do I fire events to multiple clients? etc.)



0
galkinCommented:
Foget about control. What you need is to write an EXE that would be a OLE server. I cannot write you a complete tutorial what OLE out of process server is and what interfaces it must expose. Foturnately MFC AppWizard generate you minimum needed to build this server .You part is to add properties/methods and eventc. Property and methos can be added using ClassWizard and using MFC DISPATCH maps. To implement event in your server you need to implement connection points. Serach for knowledge base technical articles and samples how to do this in MFC OLE server.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
rosborn051498Author Commented:
Thanks for your help.  I will research as suggested.  I was hoping to use my control, since it has already been written and tested.  Maybe I can port some of the code over.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.