|
Damm... I was aware of this thing, that parameters should passed in reverse
order. Nways good to hear that u finaly done it !
See the pseduo code for context menus prob:
VARIANT v1,v2,v3;
While( i > 88)
{
v1.vt = VT_I4; v1.lVal = i;
Invoke(pDispWord,"CommandBars",0,DISPATCH_PROPERTYGET,1,v1,v2)
v3.vt = VT_BOOL; v3.boolVal = 0;
Invoke(v2.pdispVal,"Enabled",0,DISPATCH_PROPERTYPUT,1,v3,NULL);
i++;
}
That's al !
Gud luck !
Cheers,
Vishal
|
|
|
|
|
Hie,
I've created:
- an ATL/COM DLL containing an ActiveX sending events;
- an HTML page instantiating this ActiveX and receiving its events;
- an MFC executable instantiating this ActiveX also.
BUT when I launch both clients, I have 2 instances of the DLL in memory!
How to have only one instance?
Thanks
pinch'
|
|
|
|
|
The browser and the MFC executable run in completely separate processes. Each process runs independently and runs in it's own memory space. DLLs are always loaded directly into a given process's memory space. That's why you get two instances of the DLL.
You cannot do what you are trying to do with a DLL, period.
Instead you will have to create a threadsafe ActiveX exe singleton to make sure both applications get a reference to the same instance. That's about all I could tell you based on the information given.
Robert
|
|
|
|
|
Robert, thanks a lot for your answer.
In fact, I had first created an ActiveX exe (loaded only once in memory) but then the HTML page did not receive any ActiveX events. Is it a Microsoft bug or a question of DCOM configuration or what?
Pascal
|
|
|
|
|
Well by their nature, ActiveX components instantiated from an HTML page ultimately run on the client, not the webserver. Assuming your MFC application is also running on the same client it should not be a DCOM issue.
If I understand what you are trying to do, basically you have two applications that you wish to subscribe to, and respond to, the same events raised from some class in an ActiveX component.
The fact that an ActiveX exe creates only one instance of the server itself does not entirely solve your problem. A single ActiveX exe server component can still create multiple instances of a given class.
For example, suppose your HTML page initially creates some object, "MyEventsClass" from the ActiveX componet (and thereby causes an instance of the ActiveX EXE to be launched). When your MFC application is launched, it requests an instance of the same "MyEventsClass" object. Since the server alrready exists, the same, single instance of the ActiveX EXE server will supply the MFC app with the class instance requested HOWEVER, it will not be the same instance of the class already supplied to the HTML page.
So with an ActiveX EXE you will no longer have two instances of the same component, but you will still have two instances of the class which both applications request - one instance for each application.
Assuming you want both applications to have a reference to a shared, single instance of the class created by the AtiveX component, first you will have to add code to ensure the class is created as singleton. If you code the object as a singleton, the first application to request the class from the ActiveX EXE will cause an instance of "MyEventsClass" to be created and the first app will receive a reference to the new instance. When the second application requests an instance of the same class, you have to have code that prevents the ActiveX EXE from creating a new instance. Instead the ActiveX EXE should just return a reference to the same instance the first app has already created. (I hope that makes sense).
The net result is that only the first application to request the class will receive a reference to a class that it instantiates. All subsequent requests for instances of the class will receive a reference to the same, single class instance that has already been created by the first request.
If this is what you want to happen, coding a singleton class is not difficult - you just create a mutex, and check in the class constructor if the mutex already exists. If so, the constructor returns a reference to the already existing class instance to the second client app that requests the object.
Now, getting both apps to sink the same events from a single, shared instance of a class may be a different story, because ATL is essentially templates that hide a lot of the COM architecture in macros.
My understanding of the intricacies of what happens in the ATL COM wrapper framework is not extensive enough to speculate on what is required to sink the same set of events from a ActiveX EXE in two different apps.
I would suggest that you refine your question and post it on the ATL forum and see if some ATL guru can provide you with the details.
Sorry, that is about as much info as I can provide ...
Good Luck!
Robert
|
|
|
|
|
Robert,
Regarding to your complete explanation and to my ATL/COM book, I've just implemented a solution that works!
Thanks a lot
Pascal
|
|
|
|
|
Cool! What did you have to do? Just brief descript will be fine ...
|
|
|
|
|
Sure, here is the architecture of the solution:
- an ATL/COM executable server which transfers messages from a client (an MFC executable) to another client (an ActiveX) via the method and the event of an interface;
- a standard MFC executable (dialog based) connected to the COM server and sending messages to it via its interface method;
- an ATL/COM ActiveX connected to the (same!) COM server and receiving events from it (then messages from the MFC executable client) via its interface event sink;
So, both clients communicate together via this COM server loaded only once in memory!
"Et voilà"
Thanks again Robert
Pascal
|
|
|
|
|
Hi Pascal,
I am wondering if you could explain a little bit more.
As I understand Client1 creates an intance of the server calss. Client2 shares the referance to the single instance of the server class. How do you stop Client2 from creating a second instance of the server class.
Thanks
|
|
|
|
|
I have been trying to write a Method on my COM interface that takes an [in, out] parameter. I expected that this would act like a I was passing in a reference.
In the idl file the function is:
[id(1), helpstring("method Select")] HRESULT Select([in, out] System** System);
In the appropiate hear file the function is defined as:
STDMETHOD(Select)(System** System);
I use the function as below:
//In some cases the pSystem object is created other times it will be null
ISystemPtr pSystem(CLSID_System);
//or
ISystemPtr pSystem = NULL;
//The Select Method will display a dialog with a set of options, if the object being passed in is //NOT NULL the dialog should have the correct / relavent options selected. If it is NULL the //pSystem object will be created with the selected options and passed back to the client.
TheObjectWithTheMethod->Select(&pSystem);
The problem is that when an valid (not NULL) pointer is passed into the function the & operator actually releases the pointer to the pSystem and returns a NULL interface pointer. So inside the implimentation of the Select function we always get a NULL pointer.
Does anubody have any ideas?
Cheers
Andy
|
|
|
|
|
Use a ** when you want to pass a pointer to an object and you might want it to return a pointer to a different object. Consider:
HRESULT Select( System** pSystem )
{
if ( pSystem != NULL )
(*pSystem)->Release();
*pSystem = new System();
}
pSystem = new System();
HRESULT hr = Select( &pSystem );
If you don't want to change the value of the pointer you pass in, but instead change the value of the object, use a single *.
I think that you actually do want to pass the pointer by reference, but your ISystemPtr smart pointer class has an override of operator & which I assume is releasing the held pointer. Without seeing this class, or what the typedef is, it's difficult to help.
The documentation for _com_ptr_t , the environment's own smart pointer, suggests that operator&[^] releases the pointer then NULLs it. IIRC, using #import generates smart pointer typedefs of _com_ptr_t .
If this is what you're using, I think all you can do is Detach the pointer, call Select, then Attach the resulting pointer to the smart pointer object.
ATL's CComPtr allows direct access to the raw pointer through the public p member. Its operator& ASSERTs if the contained pointer is not NULL.
Stability. What an interesting concept. -- Chris Maunder
|
|
|
|
|
Mike Dimmick wrote:
*pSystem = new System();
*ahem*
You forgot an AddRef()
--
My name in Katakana is ヨルゲン.
My name in German is Jörgen.
I blog too now[^]
|
|
|
|
|
Hi all,
I am developing a COM object. Because I have one "base"-object (responsible for communication with one object), and a different object (an array of "base"-objects, I need to develop 2 COM objects.
The best solution would be:
MyCOMObject->GetABaseObject()->PerformAction();
But I think this is not possible in one COM object. So I thought, maybe, if I develop 2 COM objects, it is possible.
My architecture looks like this:
COMObject1 (base class) <-- bi-directional communication --> COMObject2 (array class)
And an application, which can choose what COM to use. If he only needs 1 connection, it can use COMObject1, otherwise COMObject2.
But, can I call functions withing COMObject1 from COMObject2???
Thanks!
Geert
[url]http://geert.yoki.org[/]
|
|
|
|
|
Is there a way in .NET applications to programmatically find all registered com components (or .NET components) that implement a given interface?
|
|
|
|
|
At me such problem:
When the standard page of properties (Property Page) is created - that everything is all right,
And when I try to create it manually - it is not displayed.
I hands finish such in CoClass.h:
BEGIN_PROP_MAP (COpenGL)<br />
PROP_DATA_ENTRY ("_cx", m_sizeExtent.cx, VT_UI4)<br />
PROP_DATA_ENTRY ("_cy", m_sizeExtent.cy, VT_UI4)<br />
PROP_ENTRY ("FillColor", DISPID_FILLCOLOR, CLSID_StockColorPage)<br />
<br />
PROP_ENTRY ("Dialog", 2, CLSID_PropDlg)
<br />
END_PROP_MAP ()
And in a result the Property Page created in manual is not displayed (and that standard "FillColor" - is displayed)......... (are displayed only standard - FillColor, and one more)
What to make, that it worked?
And all over again I received the message, that CLSID_PropDlg is in general a unknown piece (but then itself has passed)
That I receive in a idl-file:
import "E:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\include\prsht.idl";
import "E:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\include\mshtml.idl";
import "e:\program files\microsoft visual studio .net 2003\vc7\platformsdk\include\dimm.idl";
import "E:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\include\mshtmhst.idl";
import "e:\program files\microsoft visual studio .net 2003\vc7\platformsdk\include\docobj.idl";
import "E:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\include\exdisp.idl";
import "E:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\include\objsafe.idl";
[
object,
uuid(BB2EEEBB-B474-4CBC-9B70-697E4ECC1EE8),
dual,
helpstring("IOpenGL Interface"),
pointer_default(unique)
]
#line 49 "d:\\d\\c7\\com\\atlgl\\atlgl\\opengl.h"
interface IOpenGL : IDispatch {
#line 52 "d:\\d\\c7\\com\\atlgl\\atlgl\\opengl.h"
[propput,bindable,requestedit,id((-510))] HRESULT FillColor([in] OLE_COLOR clr);
#line 54 "d:\\d\\c7\\com\\atlgl\\atlgl\\opengl.h"
[propget,bindable,requestedit,id((-510))] HRESULT FillColor([out,retval] OLE_COLOR *pclr);
[id(1),helpstring("method GetLightParams")] HRESULT GetLightParams([out] int *pPos);
[id(2),helpstring("method SetLightParam")] HRESULT SetLightParam([in] short lp, [in] int nPos);
[id(3),helpstring("method ReadData")] HRESULT ReadData();
[id(4),helpstring("method GetFillMode")] HRESULT GetFillMode([out] DWORD *pMode);
[id(5),helpstring("method SetFillMode")] HRESULT SetFillMode([in] DWORD *nMode);
[id(6),helpstring("method GetQuad")] HRESULT GetQuad([out] BOOL *bQuad);
[id(7),helpstring("method SetQuad")] HRESULT SetQuad([in] BOOL bQuad);
};
[ version(1.0), uuid(4CA16C3B-D4B6-434D-9648-2E419FF79F15), helpstring("ATLGL 1.0 Type Library") ]
library ATLGL
{
importlib("stdole2.tlb");
importlib("olepro32.dll");
[
uuid(9D2FB6B9-6797-45D0-A331-A6DE808F9A82),
helpstring("_IOpenGLEvents Interface")
]
#line 72 "d:\\d\\c7\\com\\atlgl\\atlgl\\opengl.h"
dispinterface _IOpenGLEvents {
properties:
methods:
};
[
version(1.0),
uuid(35435006-DA95-4B34-9988-5A0A512E3F3C),
helpstring("OpenGL Class")
]
#line 88 "d:\\d\\c7\\com\\atlgl\\atlgl\\opengl.h"
coclass COpenGL {
interface IOpenGL;
[default, source] interface _IOpenGLEvents;
};
[
version(1.0),
uuid(F2FBEB23-A2C0-4C9D-B049-6E14D8A3E8CF),
helpstring("PropDlg Class")
]
#line 19 "d:\\d\\c7\\com\\atlgl\\atlgl\\propdlg.h"
coclass CPropDlg {
[default] interface IUnknown;
};
[
version(1.0),
uuid(CD2867E6-F4C7-48A6-8D06-D1856D501B2E),
helpstring("tMy Class")
]
#line 19 "d:\\d\\c7\\com\\edf\\atlgl\\tmy.h"
coclass CtMy {
[default] interface IUnknown;
};
}
|
|
|
|
|
Do not pay attention to this post, I have already found a mistake
|
|
|
|
|
I have DOTNET project that connect to excel through RTD. After some time say 2 week the excel lose the connection to RTD component
I will be thankful if any body guide me how to solve this problem or how to fiend the reason of it
And thank of all any way
note:
the excel use interop dll to connect to the assembly dll
Aswanee
|
|
|
|
|
Am getting the error "A Tool returned Error,Performing registration" during linking of my interface implementation project file.
can anyone help me out of this???
Hariharan.T
|
|
|
|
|
I have an application downloaded and installed by user.
The main GUI executable uses a secondary COM EXE Server.
During installation (Installshield) I put 2 values into the registry to tell Windows I want this COM EXE Server to run as the 'Interactive User'.
* The reason why this is done isn't the clearest thing to me, apparently It's been done in the past so that this COM EXE Server can run as a service, this isn't the case now.
The application is deployed onto thousands of computers.
Recently I have this guy who installs but fails to run my application on 3 of his computer (4'th one succeeds), my application spits back the error '0x8000401a'.
0x8000401a = The server process could not be started because the configured identity is incorrect. Check the username and password.
From what I understand Windows doesn't really want to allow him to create an instance of my COM EXE Server.
My question is what can be causing this ?
He said he's both a local and network Administrator, nothing problematic (that he can see).
Can someone give me a clue/hint/direction about this error ?
thanks
|
|
|
|
|
How do you derive a class from more than one interface where two or more of the interfaces have methods with the same name, parameters and return type?
class CSomeClass : public IInterfaceA, IInterfaceB
{
public:
CSomeClass();
// IUnknown
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID FAR* ppvObj);
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();
// IIntefaceA
HRESULT STDMETHODCALLTYPE DoStuff(VOID);
// InterfaceB
HRESULT STDMETHODCALLTYPE DoStuff(VOID); <-- Compiler generates an error
};
error C2535: 'HRESULT CSomeClass::DoStuff()' : member function already defined or declared
If its as simple as only having one copy of the function then how do you know which interface the function is serving? QueryInterface() handles this by passing in an IID but the functions I'm dealing with have no such parameters.
Systems AXIS Ltd - Software for Business ...
|
|
|
|
|
One way around this problem would be to build intermediate C++ classes that derive from a single interface and impliments the clashing method by making a pure virtual call on a nonclashing name.
For example:
struct IXInterfaceA : public IInterfaceA
{
//Add new non clashing method as a pure virtual
virtual HRESULT STDMETHODCALLTYPE DoStuffOnA(void) = 0;
//impliment the clashing method
STDMETHODIMP DoStuff(void)
{
return DoStuffOnA();
}
}
If you do the same for your other interface IInterfaceB
Your CSomeClass would look like this.
class CSomeClass : public IXInterfaceA, public IXInterfaceB
{
public:
CSomeClass();
// IUnknown
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID FAR* ppvObj);
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();
// IIntefaceA
HRESULT STDMETHODCALLTYPE DoStuffOnA(VOID);
// InterfaceB
HRESULT STDMETHODCALLTYPE DoStuffOnB(VOID);
};
Hope this help, it helped me.
Regards
Andy
|
|
|
|
|
i got a doubt in sink interface implementation... whether i need to specify a CoClass in the sink interface IDL file??
without coclass decleration how does it knows about where it is implemented??
can anyone help me??
Hariharan.T
|
|
|
|
|
Hi,
I want to POST datas and at the same time open the default browser
so I found code that do the thing :
First I call CoCreateInstance with CLSID_InternetExplorer as argument
Then I call NaviGate with the url and the datas to post as arguments
So InternetExplorer opens and I see the result of the datas I posted.
But now I want to open the defaultbrowser and not only InternetExplorer.
How should I do ?
Thanks.
lasterix
|
|
|
|
|
you will get Default Browser Location here in this registry KEY.
HKEY_CLASSES_ROOT\HTTP\shell\open\command
"I Think this Will Help"
<h5
alok gupta="" <br=""> visit me at http://www.thisisalok.tk
|
|
|
|
|
Ok thanks, but I don't know how to use it in my case.
|
|
|
|
|