|
COM objects are stateful. The very notion of object in OOP is a black box with some state, which is observed and manipulated using its public operations.
An object which is not stateful, is not an object.
--
So let's just walk from place to place, as long as we don't talk face to face.
|
|
|
|
|
We've turned our application into a DCOM automation server, which works well. The problem we have is that we need this application to execute once per client, and we need the app to run as a certain user. If I log on to the server machine as this user, and have the applications identity set to 'interactive user' in dcomcnfg.exe, everything works well. If I use 'this user' however (regardless of being logged on as that user) the application launches and functions properly twice (concurrently), but no more then twice.
When I debug into the third instance, I find that it is unable to load the main frame, it actually falls over in CMDIFrameWnd::CreateClient and GetLastError returns 'invalid window handle'.
Has anyone got any idea what is happening here, or could you point me in the right direction for more information?
Dylan
|
|
|
|
|
I have a com object in which there are different properties. When i get these values through it works well when property is returning long or some other integer but it crashes when property is returning bstr. Take a look at my code and guide me that what i did wrong.
VARIANT pvResult;
memset(&pvResult, 0, sizeof pvResult);
VariantInit(&pvResult);
DISPID dispID=this->pColl->getMemberID(index);
DISPPARAMS dispParamsNoArgs={NULL,NULL,0,0};
HRESULT hr=pDispatch->Invoke(dispID,IID_NULL,LOCALE_USER_DEFAULT,
DISPATCH_PROPERTYGET,&dispParamsNoArgs,
&pvResult,NULL,&nArgErr);
Thanx in advance
Inam
|
|
|
|
|
u have forgotten the last line
return pvResult.bstrval;
(offcourse after making your method of the type returning bstr)
and if u already have it there in your code..then take a look at the following code, also if it doenot work then try looking into the dispatch map..have u given the correct VTs there for the return type??
//*******************************
//body of a method returning BSTR
DISPPARAMS * DispParam1 = new DISPPARAMS();
EXCEPINFO excep;
UINT nArgErr;
VARIANT *pVarRes = new VARIANT();
DispParam1->cArgs = 0; //number of arguments
DispParam1->cNamedArgs = 0;// Number of named arguments.
DispParam1->rgdispidNamedArgs = NULL; // Dispatch IDs of named arguments.
IF1BookImpl::Invoke(DISPID_F1_Text,
IID_NULL ,
::GetUserDefaultLCID(),
DISPATCH_PROPERTYGET,
DispParam1,
pVarRes ,
&excep,
&nArgErr);
delete DispParam1;
return pVarRes->bstrVal;
//*******************************
regards
safee
|
|
|
|
|
Infact program crashes when it executes the function invoke and in pVarRes there is coming bstr through get property but if long or int is coming it works well.
Now i am not understanding what to do
Regards
minamkhan
Inam
|
|
|
|
|
Try
VARIANT *pVarRes = new VARIANT();
V_VT(pVarRes) = VT_BSTR;
and see if that helps....
Steve S
|
|
|
|
|
Hi. I was using Inside COM by Dale Rogerson book and I dont have the CD, so I kinda guess how to register the component.
But when I do "regsvr32 /s Cmpnt.dll" , the entry for "InprocServer32" is garbage.
Can someone help me out with this?
Registry.cpp:
#include <atlbase.h>
extern "C" HRESULT RegisterServer(HMODULE g_hModule,
const CLSID& CLSID_Component1,
const char* g_szFriendlyName,
const char* g_szVerIndProgID,
const char* g_szProgID)
{
CComModule cm;
return cm.RegisterClassHelper(CLSID_Component1, g_szProgID, g_szVerIndProgID, NULL, THREADFLAGS_BOTH);
}
cmpnt.def:
;
; Cmpnt1 module-definiteion file
;
LIBRARY Cmpnt.dll
DESCRIPTION '(c)1996-1997 Dale E. Rogerson'
EXPORTS
DllCanUnloadNow @1 PRIVATE
DllGetClassObject @2 PRIVATE
DllRegisterServer @3 PRIVATE
DllUnregisterServer @4 PRIVATE
DllMain @5 PRIVATE
|
|
|
|
|
Please tell me whether it is possible to finalize CD using IMAPI interface.
Thanks,
Igor.
|
|
|
|
|
wt actually working of queryinterface function?
sdfsdfsdfhsdfh
|
|
|
|
|
QueryInterface is a discovery mechanism. Let's say you have an interface (any interface, it doesn't matter) to a COM component. You can, using a method in the interface, ask the component if it supports another interface that you know about.
For instance, you might have an IFrooble interface on an object, and you want to know if it supports automation using the 'classic IDispatch' method.
You say something like:
HRESULT hr;
IDispatch* pDisp = NULL;
hr = pFrooble->QueryInterface( IID_IDispatch, reinterpret_cast<void**>(&pDisp));
if (SUCCEEDED(hr))
{
// Yep, it does dispatch, and we now have that interface as well
// as the IFrooble one.
}
else
{
// No, it doesn't or can't provide that interface
}
Does that help?
Another scenario is versioned interfaces, where a client will ask for successive interfaces (eg IFooBar4, IFooBar3, IFooBar2, IFooBar) until it gets one it's happy with.
Steve S
|
|
|
|
|
If you look from the C++ point of view,
All you interfaces to COM object are abstract base classes with pure virtual functions. And your COM object gives implementation of all these functions.
So when you call QueryInterface, it simple casts the COM object(this) into the interface pointer, increase a reference count and return that pointer. This way you can only call the functions declared in that interface.
|
|
|
|
|
Wt diffrence between simple dll and COM dll?
sdfsdfsdfhsdfh
|
|
|
|
|
[fx: deep breath]
a COM dll will provide code for registration/deregistration, as well as a mechanism to create lifetime-managed components. In general, it provides a published binary interface (which should be immutable) to allow use of the component(s) in languages other than the one it was written in.
It follows a standard mechanism for requesting component creation, and includes mechanisms for lifetime management (IUnknown::AddRef, IUnknown::Release) as well as a mechanism for capability discovery (IUnknown::QueryInterface) which is extensible.
(Guys, did I miss anything?)
Steve S
|
|
|
|
|
DrCOM Monitor
http://www.ddevel.com/DrCOM/DrCOMMonitor.asp
I'm trying to externally control a target app that is built on COM.
I have read
http://www.codeproject.com/com/automatingwindowsapps.asp
However, this technique looks way too comlicated in my case to realize what I'd like to do, and in fact, looking at the DrCOM folder at least, it seems simpler than the preject above.
Using DrCOM, the whole COM analyzed by the tool is marked as 'Automated', and I actually could 'Invoke' the API function from DrCOM, such as 'Object.SendLogout()' which actually made the target app. behave that way. The target application received the message from the external tool, and was controled right way. Wonderful, I felt.
What I'd like to do is to 'Invoke' the command of COM that is the server of the target application from the external application that I will code in C#.
I posted on C# board, too.
Any comment? Thank you very much in advance.
Best,
Ken
|
|
|
|
|
hello,
i am developing an addin for outlook to insert an image to outlook email body but my problem when i insert image on top of a text (using DOM) the text splits into two sides and image got placed between the text but this is not allowed i have to place image on top of the text without the splitting. Is there any way in VC++,COM,DHTML.
|
|
|
|
|
hi all,
am developing a Outlook Addin in VC++,i have added a button to the Inspectors window and now i want to retrieve the from address and subject from the inspector window (the window which gets opened when we click the message in the inbox!).how will i do it?
with regards,
chakkaradeep.
|
|
|
|
|
How can i get back a string from a COM method call?
I use this dispatch params:
DISPPARAMS DispatchParams;
DispatchParams.cArgs=3;
DispatchParams.rgvarg = new VARIANTARG[3];
DispatchParams.rgvarg[0].vt = VT_BYREF|VT_BSTR;
DispatchParams.rgvarg[0].pbstrVal = &bstrDocId;
DispatchParams.rgvarg[1].vt = VT_BYREF|VT_I4;
DispatchParams.rgvarg[1].plVal = &llngFlags;
DispatchParams.rgvarg[2].vt = VT_I4;
DispatchParams.rgvarg[2].lVal = 0;
DispatchParams.rgdispidNamedArgs=NULL;
DispatchParams.cNamedArgs=0;
if the bstrDocId is a BSTR then the invoke returns No such interface supported, if i use CComBSTR then the invoke succeeds but the result is that the bstrDocId becomes NULL. I don't understand this, how can it be NULL if it is not a pointer? If i initialize the CComBSTR with an exact length then the invoke also returns the "Nos such interface supported" error.
If anybody knows how to get back a string i would be pleaseful to see it.
dzsigit
|
|
|
|
|
Looking at this, the signature for the method you're calling is:
HRESULT somename([in,out]BSTR* docID, [in,out]long* flags, long x)
Is this correct?
Steve S
|
|
|
|
|
|
AFAIK, you're using the illegal order of the arguments for Invoke - it should be the REVERSED order.
MSDN: "The arguments are passed in the array rgvarg[ ], with the number of arguments passed in cArgs. The arguments in the array should be placed from last to first, so rgvarg[0] has the last argument and rgvarg[cArgs -1] has the first argument. The method or property may change the values of elements within the array rgvarg, but only if it has set the VT_BYREF flag. Otherwise, consider the elements as read-only."
So your called function looks like
HRESULT somename(long x, [in,out]long* flags, [in,out]BSTR* docID)
instead of your function
long SelectDoc([in, out] BSTR* tstrDocID, [in, out] long* tintFlags, [in] long tintWindow);
With best wishes,
Vita
|
|
|
|
|
Doh!
I should have spotted that too! I blame the painkillers.
Steve S
"Of all the things I've lost, I miss my mind the most"
|
|
|
|
|
Thanks for your help, but it still doesn't work. I've tried with MFC and it throws the same error.
Here is the code, maybe you can see something in it.
HRESULT hr;
OLECHAR FAR* szMember = L"SelectDoc";
DISPID DispatchID;
IDispatch * pDispatch;
IUnknown * pUnknown;
long llngFlags=0;
BSTR bstrDocId=SysAllocStringLen((OLECHAR*)"xxx", 256);
long llngReturn;
DISPPARAMS DispatchParams;
DispatchParams.cArgs=3;
DispatchParams.rgvarg = new VARIANTARG[3];
DispatchParams.rgvarg[0].vt = VT_I4;
DispatchParams.rgvarg[0].lVal = 0;
DispatchParams.rgvarg[1].vt = VT_BYREF|VT_I4;
DispatchParams.rgvarg[1].plVal = &llngFlags;
DispatchParams.rgvarg[2].vt = VT_BYREF|VT_BSTR;
DispatchParams.rgvarg[2].pbstrVal = &bstrDocId;
DispatchParams.rgdispidNamedArgs=NULL;
DispatchParams.cNamedArgs=0;
CoInitialize(NULL);
CoCreateInstance(..)
pUnknown->QueryInterface(..)
pDispatch->GetIDsOfNames(..)
hr = pDispatch->Invoke(DispatchID, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &DispatchParams, (VARIANT*)&llngReturn, NULL, NULL);
MFC code
COleDispatchDriver disp;
COleException* e=new COleException();
IDispatch *pdisp;
DISPID dispid;
OLECHAR FAR* szMember[1];
HRESULT hresult;
disp.CreateDispatch(..)
static BYTE parms[] = VTS_PBSTR VTS_PI4 VTS_I4;
pdisp = disp.m_lpDispatch;
szMember[0] = L"SelectDoc";
pdisp->GetIDsOfNames(IID_NULL, szMember, 1, LOCALE_SYSTEM_DEFAULT , &dispid);
long llngReturn;
long llngFlags;
BSTR bstrDocId=SysAllocString(..);
disp.InvokeHelper(dispid, DISPATCH_METHOD, VT_I4,(void*)&llngReturn, parms,&bstrDocId , &llngFlags, (long)0);
dzsigit
|
|
|
|
|
dzsigit wrote:
long llngReturn;
...
hr = pDispatch->Invoke(..., &DispatchParams, (VARIANT*)&llngReturn, ...);
I think that it's a bad practice to make the ambiguous casting to avoid the compiler error.
In any case the E_NOINTERFACE can be a valid HRESULT which can mean that there is no such Document as you specify.
With best wishes,
Vita
|
|
|
|
|
What kind of Document do you mean? I only want to call my function that is written in .Net.
My function's return type is long, how can i get back a long value if i don't cast it to VARIANT *? I've read a lot of articles and the return value was everywhere casted like that.
dzsigit
|
|
|
|
|
If your function's return type is long, then it isn't an HRESULT.
Conventionally, automation methods all return an HRESULT to indicate success or failure, and if there is a 'logical' return value, it can be indicated by using the [retval] attribute on the appropriate value.
What is the actual IDL/ODL code for your method please...
Steve S
|
|
|
|
|