|
If it works in VB, then it should work in C++, because the C++ is more powerful than VB (VBS etc). But not vice versa .
Can you give some VB code working well for you?
With best wishes,
Vita
|
|
|
|
|
Hello, I would have though that C++ wouldn't have this problem. A sample bit of code that they give, and that I have tested (in VB script) is this:
Dim bt As Object
Set bt = GetObject ( "BACtalk.ActiveX.Interface" )
bt.SendTimeSync
I just can't make the same thing work in C++. Is there some magic function I should be using? I thought I was getting somewere with CoGetObject(), but no. Any further help would be aprecciated. If I had a choice, I would probably do this in C# and it would work.
Nathan Brown
|
|
|
|
|
Try to use this fragment of code. If it doesn't work, try to check the hr value and tell this value to us.
BIND_OPTS bind_op;
REFIID riid = IID_IDispatch;
IDispatch* p_ibac = NULL;
HRESULT hr = CoGetObject(OLESTR("bactalk.activex.interface"), &bind_op, rrid, (void **)&p_ibac);
if( SUCCEEDED(hr) )
{
LPOLESTR lpsz = OLESTR("SendTimeSync");
DISPID dispid;
hr = p_ibac -> GetIDsOfNames(IID_NULL, (LPOLESTR*)&lpsz, 1, LOCALE_USER_DEFAULT, &dispid);
if( SUCCEEDED(hr) )
{
DISPPARAMS dispparams = { NULL, NULL, 0, 0};
VARAINT varRet;
VariantInit(&varRet);
hr = p_ibac -> Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT,
DISPATCH_METHOD|DISPATCH_PROPERTYGET, &dispparams, &varRet, NULL, NULL);
VariantClear(&varRet);
}
}
With best wishes,
Vita
|
|
|
|
|
Thanks for the help and encouragement. What ended up working is calling CoGetObject() with IID_IUnknown first, then querying for the IID_IDispatch interface. For whatever reason, I can't have the IID_IDispatch in the CoGetObject and expect anything to work, even an IUnknown level function.
Nathan Brown
|
|
|
|
|
Is the COM object you are trying to connect to via the ROT an out-proc server? If so, make sure you've registered the proxy server dll for that server.
I meddled with the ROT a week ago, and experienced similar strange behaviors. I access the ROT directly with monikers and the IRunningObjectTable interface, but that's basically what happens inside the CoGetObject() function anyhow. Anyway, it seemed to me that I got either a malfunctioning proxy or a proxy for the wrong interface. Don't ask how I have these clues, long story.. But one would think that I'd get a E_XXX back from the ROT if it can't give me a correct proxy.
Anyhow, I built a proxy server dll for the out-proc server, registered and everything worked just fine.
--
If there was a problem, Yo, I'll solve it!
Check out the hook while my DJ revolves it.
|
|
|
|
|
I had seen your message on that before I posted, but I wasn't sure if it was the same problem. Also, I don't understand exactly what you were explaining.
How does a proxy DLL work? More importantly, are there any examples of one available?
If you are talking about something that came with the application I am trying to interface, then I don't know of any proxy DLLs. I tried registering any DLLs that looked like they might register, and also the .exe (with -RegServer), but none of that worked.
Thanks for any help.
Nathan Brown
|
|
|
|
|
Nathan Brown wrote:
How does a proxy DLL work? More importantly, are there any examples of one available?
A proxy DLL contains code for the proxy and stub for one or more interfaces. Whenever you make a COM call across an apartment boundary (between "threads" and processes (local or network)), the data passed back and forth must be marshalled - especially between processes since they do not share memory. Now, there's a lot of details here which I will not go into (mainly because I don't I'm competent enough to give a good explanation, and a forum post is way too short). I advise you to pick up a book on the subject - Don Box' Essential COM is a good read.
Nathan Brown wrote:
If you are talking about something that came with the application I am trying to interface, then I don't know of any proxy DLLs.
Ah, so you haven't written this app yourself? I see. Well, I've read that sometimes the proxy/stub DLL is not needed. The system itself should be able to "compile a proxy/stub" on the fly for any OLE automation compatible interface described in a TLB (.DLL, .EXE, .OCX, or .TLB). But contrary to this statement (can't remember if I read it in MSDN or Don Box' Essential COM), it does not always work. So basically, for your particular problem (no source for the application/automation server), I do not know a solution.
However, the proxy/stub DLL I was talking are normally built with DLL-servers by default. Try generating such a project and take a look at the proxy/stub project which is automatically attached to the solution.
--
If there was a problem, Yo, I'll solve it!
Check out the hook while my DJ revolves it.
|
|
|
|
|
I want to write user name and password in login window of Yahoo messenger from my application.
Till now I am able to get Handle to Login window using Getclass and GetwindowText.My plan is to get the handle of Login window , then that of edit boxes of Login window. Then to paste text into edit boxes. The problem is how to know whether this login (which is a dialog box) or edit boxes belongs to Yahoo messenger or a particular window.
|
|
|
|
|
I'm trying to add a property to a "COleControl" derived control. The problem is that the type of that property is another ATL Class in the same project, and I don't seem to know how to do that.
Anyone has any ideas?
Gush
|
|
|
|
|
I'm working on a background UI plugin for WMP9, and I'm wanting to add custom hotkeys. Looking through the documentation, it appears that the IWMPPluginUI::TranslateAccelerator(LPMSG lpmsg) function would work the best for that; but, unfortunately, I have no idea how to notify WMP9 of my accelerator table. How should one go about doing that?
|
|
|
|
|
HEllo people,
I am a begineer at COM and i am facing difficulties in understanding it. I wanna learn to make components without using ATL and MFC first. CAn anyone direct me to some good resource no the net, which along with the theory guides you how to make a component step by step. Most of the articles that i have come across are in theory too much and implemetation is not dicussed in that detail.
Thank you...
|
|
|
|
|
Check out MindCracker.
http://www.mindcracker.com/mindcracker/c_cafe/com.asp
Check out MSDN.
Kuphryn
|
|
|
|
|
Hi,
I'm working on a VB.NET project and my objects should be reachable using COM. My problem is that these objects have overloaded methods, properties, which seems problematic.
For example I have a collection class with two item properties:
Default Public ReadOnly Property Item(ByVal Key As String) As Object
and
Default Public ReadOnly Property Item(ByVal Index As Integer) As Object
When I try to use an object of this class in a COM only environment - like MS Word - there only one Item can be seen, and allways the first. So using the order above I can query collection items only by Key, when I change the order I can query only by Index.
This problem does not occour under .NET.
My question is: how to do VB.NET overriding, polymorphism to satisfy COM requirements?
(K)
(K)
|
|
|
|
|
Because overloading isn't supported in COM, hence a COM-Callable Wrapper (CCW) can't be created properly. Choose one or the other, but not both.
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
What's the VARIANT equivalent type?
--
You're entertaining at least.
|
|
|
|
|
|
Is this always true: object <=> VARIANT?
--
I am perpetual, I keep the country clean.
|
|
|
|
|
If you don't know what type, and specify none, the default is Object, in non-.NET VB ( ) that was Variant.
However, do not convert "As Any" in API declaratioins to "As Object", because you'll get an error like "not set to an instance of an object"..., use the most convenient type instead, if you are using more of them, define different functions referring to the same alias
greetz
*Niels Penneman*
Software/Dev Site Personal Site
|
|
|
|
|
I have a COM DLL written in C++/ATL. I added a new method to one of the interfaces and altered my testbed to call this new method.
I then went and registered an earlier version of the DLL which doesn't contain the new method. Not surprisingly, an exception is raised when the testbed tries to call the method. I can catch this with a try/catch handler, but I still get an unrecoverable exception when the calling function exits (see code snippet below).
Is there anyway of interrogating the interface to see if the method exists?
If not, is there I way my app can continue to run gracefully? This final 0xC0000005 exception is a bit of a showstopper.
Thanks,
Gary
---
void func()
{
::CoInitialize(NULL);
try
{
CComPtr<IMyInterface> MyInt;
MyInt.CoCreateInstance(CLSID_MyInterface);
MyInt->NewMethod();
}
catch(...)
{
AfxMessageBox("eek");
}
} // exception 0xC0000005 thrown here
|
|
|
|
|
Gary Chapman wrote:
Is there anyway of interrogating the interface to see if the method exists?
You need to call GetIDsOfNames after CoCreateInstance to determine if a method exists on a given interface.
The way your code is written will not work because even if the method exists, you cannot call it as if it is early-bound (you are doing late-binding). What you need to call is the Invoke method of IDispatch.
[Edit] As Bo Hunter pointed out, I was wrong in saying the code won't work. [/Edit]
COM programming is very complicated without help from libraries like ATL or MFC. However, you can reuse some of my code[^] to save a lot of time.
My articles and software tools
|
|
|
|
|
The interface would have to implement IDispatch would'nt it?
If CLSID_Myinterface is a valid coclass then this code should
work.
This is perfectly valid code here.
BOOL OpenLinkUsingCom(TCHAR* pLink, int how, HWND hWnd)
{
IUniformResourceLocator* pLocator;
HRESULT hr = ::CoCreateInstance(CLSID_InternetShortcut, NULL, CLSCTX_INPROC_SERVER, IID_IUniformResourceLocator, (LPVOID*)&pLocator);
if (SUCCEEDED(hr))
{
hr = pLocator->SetURL(pLink, IURL_SETURL_FL_GUESS_PROTOCOL);
if (SUCCEEDED(hr))
{
URLINVOKECOMMANDINFO ivci;
ivci.dwcbSize = sizeof(URLINVOKECOMMANDINFO);
ivci.dwFlags = 0;
ivci.hwndParent = hWnd;
switch (how)
{
case OPEN:
ivci.pcszVerb = _T("open");
break;
case EDIT:
ivci.pcszVerb = _T("edit");
break;
case PRINT:
ivci.pcszVerb = _T("print");
break;
default:
ATLASSERT(0);
}
hr = pLocator->InvokeCommand(&ivci);
}
}
if (pLocator)
pLocator->Release();
return (SUCCEEDED(hr));
}
Please tell me if I am wrong.
Thank You
Bo Hunter
|
|
|
|
|
|
If interface being tested is derived from IDispatch, the GetIDsOfNames is a simplest way to see it.
The second way is the ITypeInfo::GetIDsOfNames for non-dual interface if the Type Library is accessible (either by LoadRegTypeLib or by LoadTypeLib).
PS
It is a bad practice to change the contents of interface without the changing of its IID.
With best wishes,
Vita
|
|
|
|
|
If the interface had already been published then yes
you should give it a new name but for testing I don't
think that is really relevent.
Thank You
Bo Hunter
|
|
|
|
|
Hello,
i am a beginner at COM. Please tell me if its necessary to create class factory to make a COM object. If not then when is it exactly necessary.
Thank you
|
|
|
|
|