|
You generally will want to setup if/else logic from within DllGetClassObject to test for the different CLSID's in your server.(The only interfaces you will want to return through DllGetClassObject are IID_IClassFactory or IID_IUnknown since the class factories QueryInterface logic will only be checking for those two identifiers).
For example:
<br />
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void** ppv)<br />
{<br />
HRESULT hr;<br />
if (rclsid == CLSID_MyFirstCoClass)<br />
{ <br />
MyFirstCoClassFactory* pCF1 = new MyFirstCoClassFactory();<br />
hr = pCF1->QueryInterface(riid, ppv);<br />
if (FAILED(hr))<br />
{<br />
delete pCF1;<br />
}<br />
}<br />
else if (rclsid == CLSID_MySecondCoClass)<br />
{<br />
MySecondCoClassFactory* pCF2 = new MySecondCoClassFactory();<br />
hr = pCF2->QueryInterface(riid, ppv);<br />
if (FAILED(hr))<br />
{<br />
delete pCF2;<br />
}<br />
}<br />
else<br />
{<br />
hr = CLASS_E_CLASSNOTAVAILABLE;<br />
}<br />
return hr;<br />
}<br />
Hope this answers your question!
-John
|
|
|
|
|
Thanks a lot John..
The information you provided was certainly helpful..But i wanted to know that if i have 5 or 6 interfaces already defined with me and i want to determine which of them is cocreateable..how do i know that??
If i know that a specific interface is createable only then will i call it and check for it in the DllGetClassObject..
regards
|
|
|
|
|
hi there..
i am working on an ole control and need to implement the method DllGetClassObject..
ne ideas???? what to do?
thanks
|
|
|
|
|
DllGetClassObject is one of four DLL server exports that are required.
DllGetClassObject exposes class factories for all objects in a given server. This export will return an IClassFactory pointer to the client.
Instantiate a class factory object (using the C++ new operator) and then call QueryInterface to obtain an IUnknown or IClassFactory interface pointer. Check the return value of the QueryInterface invocation with the FAILED or SUCCEEDED macros. If the call failed delete your class factory object and then return the HRESULT.
Regards,
|
|
|
|
|
hello,
i want to do some IE programming. in .net
but i am not able to have the componet that i should add.
can someone guide me on this.
ASIM
Asim
|
|
|
|
|
Hi all, i'm writting a Add-in to the visual studio 6, and i need to catch event before the document is being saved, while the IApplicationEvents supplies DocumentSave which is fired after it was saved.
Does anyone knows how to solve my problem?
Amir Harel
My boss always tell me: Why we always search for the generic solution for a specific problem...
|
|
|
|
|
|
hi there
i needed help regarding the first paramenter of the method ITypeInfo::Invoke(
VOID FAR* pvInstance,
MEMBERID memid,
unsigned short wFlags,
DISPPARAMS FAR* pDispParams,
VARIANT FAR* pVarResult,
EXCEPINFO FAR* pExcepInfo,
unsigned int FAR* puArgErr
);
from where or how do i get pvInstance?
thanks
regards
|
|
|
|
|
safeeullah wrote:
from where or how do i get pvInstance?
Generally ITypeInfo::Invoke is used to implement IDispatch::Invoke . So, the pvInstance parameter should be the implementing class' this . Something like:
HRESULT __stdcall IDispatch_Derived_Class::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult,
EXCEPINFO* pExcepInfo, UINT* puArgErr)
{
return m_pTypeInfo->Invoke(this, dispIdMember, wFlags,
pDispParams, pVarResult, pExcepInfo, puArgErr);
} or the equivalent
HRESULT __stdcall IDispatch_Derived_Class::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult,
EXCEPINFO* pExcepInfo, UINT* puArgErr)
{
return DispInvoke(this, m_pTypeInfo, dispIdMember,
wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
}
rechi
|
|
|
|
|
thanks a lot..
got it..
kindest regards
safee
|
|
|
|
|
Hi
I've COM exe server. It registers on WinNT based platforms.
I can't register it under Win98.
It is possible to do this ?
I've error in
_Module.UpdateRegistryFromResource(IDR_AtlExe, TRUE);
hRes is 0x80040154 (class not registered).
In all others calls before _Module.UpdateRe... are ok (hRes is 0).
I use VC 6 with sp5 and simple code generated from ATL wizard with one interface with one method.
Thx 4 Hlp
|
|
|
|
|
InvokeHelper() function...
//MSDN says
This method calls the object method or property specified by dwDispID, in the context specified by wFlags. The pbParamInfo parameter specifies the types of the parameters passed to the method or property. The variable list of arguments is represented by ... in the syntax declaration.
well, that is what MSDN says about InvokeHelper method of COleDespatcher class.
Now My confusion is....
I am trying to understand a project, which is an activex control whose purpose is to display some graphical interface to the data given from a server.
Here the OCX project is using another library which is a wrapper for another library, customized to the requirements of OCX project.
When I tried to trace how the flow of function call is going on..
it is happening like this..
my ocx project is calling method from wrapper project which is using InvokeHelper(..).
my collegue says "it is all com funda".. and he showed me a method in another project where actual code is present.
The function call is something like this.
InvokeHelper(0xa, DISPATCH_METHOD, VT_BOOL, (void*)&result, parms,<br />
iTraceNumber, &strTraceId, strSource);<br />
But How do I come to know what is happening here..
it is all confusing.
any ideas..?
meanwhile I try to go thru the COM section of codeguru and codeproject.
Thanx in advance
Harinath
Harinath Reddy
HOneywell Technology Solutions Lab,
Bangalore,
India-560076
|
|
|
|
|
Hello,
is there a simple way to call the javascript escape function from c++ app (mfc)?
I need to generate a html slideshow from a selection into a database, but it seems that certains strings (valid in c++) can be invalid in the html file.
For ex : "\\test\\" in c++ are generated into "\test\", so the last \" break the string
So my idea is to add an unescape into the generated html, but the counterpart is a call to escape in the c++ part...
I already embed an IE browser in my application.
Another bad point is that all calls are in a loop, so I want to avoid slow calls !
Thanks in advance
Thierry
Isotools Software Engineer
|
|
|
|
|
Could someone enlighten me on how to retrieve the name of an object implementing IDispatch? With the name I mean the coclass-name as specified in the IDL-file.
--
"It's a condition of mental divergence, I find myself on the planet Olgo part of a intellectual elite, prepared to subjugate the barbarian hordes on Pluto, but even though this is a totally convincing reality for me in every way, nevertheless Olgo is actually a construct on my psychee. I am mentally divergent in that I am escaping certain unnamed realities that plague my life here."
|
|
|
|
|
See the implementation of XYDispDriver::LoadTypeInfo in XYDispDriver.cpp from this article[^]'s sources. It's not exactly what you need but could be a good starting point.
rechi
|
|
|
|
|
hi there..
i am quite a situation here..
how do i get to the outer unknown of the controlling Unknown?
HELP..
regards
|
|
|
|
|
Hi everyone,
I get the following error message from Outlook when I try the saveas command: “Unable to coerce parameter value: Cannot translate your string”.
Code example:
szFunc = OLESTR("SaveAs");
hr = m_pDisp->GetIDsOfNames(IID_NULL,
&szFunc,
1,
LOCALE_SYSTEM_DEFAULT,
&dispID);
if (FAILED(hr))
{
cout << "GetIDsOfNames failed on SaveAs";
return;
}
CComVariant vPath(strPath.GetString());
CComVariant vType(Outlook:lMSG);
VARIANT pVal[2];
dp.cArgs = 2;
dp.cNamedArgs = 0;
dp.rgdispidNamedArgs = 0;
dp.rgvarg = pVal;
pVal[1].vt = VT_ERROR;
pVal[1].scode = DISP_E_PARAMNOTFOUND;
pVal[0].vt = vPath.vt;
pVal[0].bstrVal = vPath.bstrVal;
EXCEPINFO excep;
hr = m_pDisp->Invoke(dispID,
IID_NULL,
LOCALE_SYSTEM_DEFAULT,
DISPATCH_METHOD,
&dp,
NULL,
&excep,
NULL);
if (FAILED(hr))
{
cout << "Invoke failed on SaveAs";
ErrHandler(hr, excep);
return;
}
Any help would be greatly appreciated.
Thanks,
Ken
|
|
|
|
|
Hi, I have an application with some disptach interfaces. I can access these interfaces via vb-script without any problems, but when I use constants (I defined an enum) vb-script does not seem to recognize them. The weird part is that I have a function that returns an enum value and that value is received correctly in my vb-script, but when I do a compare with the enum constants, all constants are 'Empty'.
Anyone knows what the problem is? Must I do someting other than just declaring an enum in my idl file?
|
|
|
|
|
You can't access anything from the idl but some of the coclasses. Probably the enum constants are implicit variables; have you declared Option Explicit in the script?
Brian van der Beek wrote:
The weird part is that I have a function that returns an enum value and that value is received correctly in my vb-script
It works because the enumeration is VARIANT -compatible. Try with a struct and see how it fails.
rechi
|
|
|
|
|
I'm relatively new to scripting and did not know about Option Explicit , it makes this a lot more clear.
I did some more digging and found out that you indeed cannot use constants/enums from a idl/tlb. You should be able to do this when you do early binding (e.g. Dim excel as exec.application), but I don't think you can do this in vb-script.
|
|
|
|
|
Anonymous wrote:
you indeed cannot use constants/enums from a idl/tlb
I'm not sure about this issue. According to MSDN, ITypeInfo supports enum type description so it should be available even by late binding. VBScript doesn't support it, that seems to be true.
rechi
|
|
|
|
|
I am working on a COM Server with numerous C++ classes in it . I was trying to use the Multimedia timer . I found that I couldnt access class pointers from the Timer callBack function. That is when I decided I need to perform Marshalling . I just know that I need to Use CoMarshalInterface and CoUnMarshalinterface.
I was wondering if someone could point to some useful examples or links that contain tutorials about this as these calls involve these parameters
IStream *pStm,
REFIID riid,
IUnknown *pUnk,
I d like to know as to how to create these parameters and pass them .
|
|
|
|
|
well, in overview, it's pretty simple.
On the beginning, you have to have some interface pointer you want to marshall - say, it's IMyInterface .
You have then to call CoMarshalInterface , but for that you need to have some IStream available. This one, you can create by calling:
CreateStreamOnHGlobal(NULL, TRUE, &_pStream);
then you can call
CoMarshalInterface(_pStream, IID_IMyInterface, IMyInterface*, ctx, NULL, flags );
So referring to your question:
IStream - it is some stream pointer created before calling the marshall method. Into this stream will be written all info required for later re-construction of the interface. You can use anything what supports IStream , even your own object. The marshaller just writes some info to the stream during marshalling and later during unmarshaling he reads the info back. The CreateStreamOnHGlobal creates a built-in object that provides IStream over the memory.
REFIID - it is an IID of the interface you want to marshal. You can use even IID_IUnknown , but then after unmarshalling you'll get the IUnknown back
IUnknown* - it is a pointer to the interface you want to marshal. It is IUnknown , because all COM interfaces are derived from it, so you can cast any COM interface to IUnknown .
Then you have to deliver the IStream to the another thread (or application or whatever - depending on flags), and call
CoUnmarshalInterface( stream, IID_IMyInterface, (void**)&_pMarshalledPointer );
and you are done.
If you doing it in-process and using ATL , consider using
AtlMarshalPtrInProc
and
AtlUnmarshalPtr + AtlFreeMarshalStream
They does the IStream creation for you (but they are only in-process)
I hope this helps you a bit. In case if something is unclear, don't hesitate to ask
|
|
|
|
|
Thanks for the info . Very useful.
I am developing a COM Server(COM A) that has numerous classes within
and also interacts with another COM Server(COM B) housed within this
Server .
I was able to use the MultiMedia timer in a class of COM A fine but have trouble when i try to accessCOM B related pointers from the TimerCallBack which normally I was able to access within COM A.
That is the point where Marshalling comes in .
I read about the functions and have certain questions .
1. Where should I do Marshalling .
there is a class(CBridge) in A that exposes COM B component. Can I
perform the call to CoMarshallInterface when CBridge comes up .
2. Do I have to write something into the IStream while Marshalling .This question is governed by what I need in the TimerCallback func . I
need to successfully be able to call COM B pointer from within COM A .
I created a Stream using
CreateStreamOnHGlobal(NULL, TRUE, &_pStream);
Do I have to do a Write on this Stream
3. I assume I have to UnMarshall in my timerCallback func . I have the
stream available , the RIID , I am unclear about the 3rd Parameter .
4. Finally after UnMarshalling how would I use COM B pointer from within
the TimerCallback !
|
|
|
|
|
1. Well, you can marshal only the COM interfaces, not normal classes. If I understood it correctly - the CBridge is a part of COM A . Then I'll keep the marshaling details inside the CBridge and call the CBridge methods as usual. When there's a need to return pointer to COM B from CBridge , it should be already marshaled.
2. No. The COM subsystem writes everything he needs inside the CoMarshal...
3. The third parameter is a pointer to pointer to the interface you want to unmarshal - this is the result of all the pain - marshaled interface . You have to simply:
IMyInterface* ipInterface = NULL;<br />
CoUnmarshal( stream, RIID, (void**)&ipInterface );<br />
if( ok && ipInterface )<br />
ipInterface->Method();
4. as any other pointer. The process is somehow transparent - the marshaled pointer looks exactly the same, only pointing to diferent object (some internal stuff of COM).
Only I would add, is that if you need behavior marshal once, unmarshal more times, you have to look at the GIT (as someone in thread mentioned). The read from IStream inside CoUnmarshal is destructive and you cannot use the IStream any more.
As the marshaling stuff is quite complicated, don't worry to ask more
|
|
|
|
|