|
First of all thanx a lot,
then... it's right what you say (about project architecure) but if I try to only #import my MIDL result (thats .TLB, not .h, I think) in my DLL, I have the error on ATL_NO_VTABLE. Do I have to #import all .idl files in my DLL? Or creating my CComObject<cmyclass>& can work well?
Thanx a lot again, I'm neither a COM nor a DLL expert (my last COM written was about in 1998... my last DLL in 1997...)
Best regards,
Morenz
|
|
|
|
|
hm, as I could understand the ATL_NO_VTABLE problem, when you're including the object.h file, the code generated with #import never contain the ATL macros. You probably forgot to remove the object.h include.
I always used #import "blahblah.tlb" no_namespace named_guids for including COM objects to my projects. Problem is, that this doesn't import the object as-is from the C++ point of view. It defines all interfaces the object is derived from and all Guids required for the object - Guids of interfaces and of the object itself. If you look into your debug (or release) directory, you'll see object.tlh and object.tli (optional), that contains code generated by the #import .
Well, when you have the interfaces imported, you can use one of them as a controlling interface. General interface is IUnknown . From this you can QueryInterface to get any other interface exported by the object.
The CComObject thing is when you decide not to import interfaces, but the C++ object definition.
The method I would choose depends on what you want to achieve, but generally I'd prefer to
a) create a special interface for controlling the DCOM object, passed to the .dlls
b) create a third c++ object, that is included in the DCOM as well as in the .dlls. It's purpose is only for exchanging the information - the DCOM object creates one instance and passes it to all calls to the .dlls. Or even considering the implementation to be in the C++ object and only calls from outside will be proxied through the DCOM object.
Then the DCOM object will be only very thin wrapper - generally only thing it will does will be to create the third object (or derive from) and then simply proxy all calls from DCOM to the C++ object. I hope the explanation is clear, here's 7:00 morning
The a) and b) are more or less equal, the a) is more COMish, while the b) is more C++ish.
|
|
|
|
|
Yeah, I know what you meant, it was 7.00 here, too!
I read this only now, and tomorrow I will give it a shot.
I 'll make you know.
For now, many thanks.
|
|
|
|
|
Hi,
I have a COM object that exports a couple of interfaces and some enums. I need to access this from JScript, and everything works expect for the enums.
Here's the idl file:
in myCOM.dll
typedef [uuid(someIDHere.....)] enum tagEnum
{
a = 0xFFF,
b = 0,
c = 1,
}enumType;
[
object,
uuid(..................),
dual,
helpstring("IMyInterface"),
pointer_default(unique)
]
interface IMyInterface : IDispatch
{
[id(1), helpstring("test")] HRESULT Test();
};
[
uuid(E0691460-B804-11D5-ADF6-00C04F029739),
version(1.0),
helpstring("MyCOM 1.0 Type Library")
]
library MyCOMLib
{
importlib("stdole32.tlb");
importlib("stdole2.tlb");
[
uuid(....................),
helpstring("MyCOM Class")
]
coclass MyInterface
{
[default] interface IMyInterface;
};
};
The JScript code looks something like this:
var mycom = WScript.CreateObject("MyCom.MyInterface");
mycom.Test();
etc.
I tried to access the methods and the enum from VB and it works fine. So there's nothing wrong with myCOM.
How can I access the enum from JScript?
Thanks!
|
|
|
|
|
My DCOM program works in a local network,
but if connect to some computer via VPN,
DCOM is not working ,
what is the reason ?
If this is a security - which settings I must configure,
that VPN become true transparent for DCOM ?
thanks you.
|
|
|
|
|
Hi,
I developed application for handling incoming call using Tapi 3.0 (COM base)
now i want to convert that application in to DLL. but i don't know how to
create COM DLL. because in that application i used COM interface.
I will use that DLL in VB. but i don't how to create DLL .
Please help me.
if anyone knows, send me source code for that.
waithing for +ve reply
Regards,
Riya jain
|
|
|
|
|
Usually you can not convert exe to DLL,
but it is usually fast to create new COM DLL envelope
using (your language VB or C++) application wizard,
- create there new interface with same methods and transfer code to it.
It is suitable for all.
- or if your more experienced,
when created new DLL - transfer just COM to it, if you know how to it for VB.
- or - ugly solution -create new DLL that makes simple one COM method,
that return interface pointer IDispatch*
with it create your EXE COM and return interface - each time you call this method for DLL,
exe COM will be created and returned - and will use as if it is placed in DLL.
This method is good when you already created complexsolution and do not whant rewrite
COM interfaces and transfer code - but use tested EXE unit as fast as possible.
|
|
|
|
|
Hi,
I am also new to COM and I manage to create my 1st DLL from this article.
http://www.codeproject.com/atl/SimpleATLCom.asp
Hope it is useful to you.
Regards
w_logan
|
|
|
|
|
Hi,
I developed application for handling incoming call using Tapi 3.0 (COM base)
now i want to convert that application in to DLL. but i don't know how to
create COM DLL. because in that application i used COM interface.
I will use that DLL in VB. but i don't how to create DLL .
Please help me.
if anyone knows, send me source code for that.
waithing for +ve reply
Regards,
Riya jain
|
|
|
|
|
I am using a .NET library from VB6 using COM interop. Functions / subs etc. can be called from the VB6 code and work as expected. However, I want to get VB6 to handle events generated in the VB.NET code. When I declare the library as "withevents", I get this error:
Runtime Error 459
Object or class does not support the set of events
The code is below, sorry if it is not that clear - the issue is the first few declarations etc. - the sink interface does not seem to connect to the class!!!
Imports System.Runtime.InteropServices
Imports CommsModulePC
', GuidAttribute("{ECB60CBD-42D7-4a93-9DB7-E6F4F0FEE3BA}")> _
'Public Event CommandReceived(ByVal theCommand As DeskCommands, ByVal args As String)
Public Delegate Sub CommandReceivedDelegate(ByVal theCommand As DeskCommands, ByVal args As String)
' Step 1: Defines an event sink interface (ButtonEvents) to be
' implemented by the COM sink.
<guidattribute("1a585c4d-3371-48dc-af8a-affecc1b0967"), _
interfacetypeattribute(cominterfacetype.interfaceisidispatch)=""> _
Public Interface CommandEvents
Sub CommandReceivedDelegate(ByVal theCommand As DeskCommands, ByVal args As String)
End Interface
' Step 2: Connects the event sink interface to a class
' by passing the namespace and event sink interface
' ("EventSource.ButtonEvents, EventSrc").
'ClassInterface(ClassInterfaceType.AutoDual),
'<comsourceinterfaces("hwmoduleplugin.commandevents, hwmoduleplugin")=""> _
<comsourceinterfaces(gettype(commandevents))> _
Public Class PluginOwner
Public Event CommandReceived As CommandReceivedDelegate
Dim WithEvents theCommsOwner As CommsOwner
Public Function Startup(ByVal theIP As String, ByVal thePort As Int16)
theCommsOwner = New CommsOwner(theIP, thePort)
theCommsOwner.Startup()
End Function
Public Property target() As String
Get
Return theCommsOwner.ToEndPoint.Address.ToString
End Get
Set(ByVal Value As String)
theCommsOwner.ToEndPoint.Address.Parse(Value)
End Set
End Property
Public Sub Connect() 'note that CommsOwner just assumes it has connected! change handshake routine!
If Not theCommsOwner.GetConnectionStatus Then theCommsOwner.Connect()
End Sub
Public Sub DisConnect()
If theCommsOwner.GetConnectionStatus Then theCommsOwner.Disconnect()
End Sub
Public Sub Shutdown()
If theCommsOwner.GetConnectionStatus Then theCommsOwner.Disconnect()
theCommsOwner.Shutdown()
End Sub
Public Sub triggereventtest()
MsgBox("trigger called")
RaiseEvent CommandReceived(DeskCommands.nmCmdAxis, "test")
End Sub
Private Sub theCommsOwner_NewData1(ByVal type As CommsModulePC.MessageTypes, ByRef mBody As String) Handles theCommsOwner.NewData
'ListBox1.Items.Insert(0, "REC " & mBody)
Dim resultarraylist As ArrayList
resultarraylist = ParseTokens(mBody)
Dim todo As DoList
Select Case type
Case MessageTypes.COMMAND
For Each todo In resultarraylist
RaiseEvent CommandReceived(System.Enum.GetName(GetType(DeskCommands), todo.Ident), todo.args)
'ListBox1.Items.Insert(0, System.Enum.GetName(GetType(DeskCommands), todo.Ident) & ": " & todo.args)
Next
'send some commands on
Case MessageTypes.DATA
For Each todo In resultarraylist
'ListBox1.Items.Insert(0, System.Enum.GetName(GetType(KETOPDataOutputs), todo.Ident) & ": " & todo.args)
Next
'send some data on
Case Else
'ListBox1.Items.Insert(0, "Some other stuff has arrived")
End Select
End Sub
End Class
|
|
|
|
|
Hi
I have a program that loads some activex components. When I run it as an administrator, there is no problem but when I run it in limitted user accounts, the "ActiveX Component Can't Creat Object." error raises.
I tried to search group policy to solve this problem for the limitted user groups, but I couldn't find anything helpful.
Please help me with that...
Is it possible for a program run in a limitted user account, to load activex components?
Thanks in advance
|
|
|
|
|
Hi MohammadAmiry,
You need to register the activex control in restricted user mode(windows
would not allow you to do so). To register the activex control in restricted
user mode, pls. refer to the following article.
http://www.codeproject.com/w2k/regsvrex.asp[^]
OR if you have written the activex control for your program you can modify the
registration routine for that using "RegOverridePredefKey" API.
>>Is it possible for a program run in a limitted user account, to load activex components?
Offcourse it is possible.
Happy programming !
Cheers,
Vishal
|
|
|
|
|
Hi,
I have a C# windows application which is already running. I have another C++ application. I want to use the C++ application to send parameters or call functions in that running C# windows application. What should I do?
I am new in COM. I guess the C++ application uses something like getObject to get the running C# windows application object. Am I correct?
But how can I expose the COM interface in that running C# windows application, as it is not a componenet.
Thanks
|
|
|
|
|
Hello scchan1984,
You would definitely need COM interop for a C++ COM application to connect with a C# object. The normal scenario in which this is achieved involves C# components housed in libraries.
However, the catch is that your C# object is contained inside a C# application (.exe). One way you can possibly achieve interop in this case would be through .NET Remoting. To do this, you would need to make your C# class derive from MarshalByRefObject.
It would also help if you could define an interface for the methods and properties that are to be exposed from your C# class to the C++ COM client.
Your COM client would then need to connect with your C# class (via Remoting) by using CLR hosting. I'll see if I can come up with some example code that can achieve all this.
Regards,
Bio.
|
|
|
|
|
Hello scchan1984,
I managed to develope and run a sample C++ app that creates a C# object (in a C# exe app) as a COM object. .NET Remoting can definitely do the job.
However, I must indicate that the development process is quite involved. If you are interested in my sample app, pls email me :
bio_lim_2004@yahoo.com
Best Regards,
Bio.
|
|
|
|
|
Dear engineer,
I don't know how to connect modem(sms gateway engine)by using visual basic,please help me.
Is there anyone have source sms gateway for CDMA modem which is developed by using visual basic.I need it right away.Please help me,thankyou...
|
|
|
|
|
Hi,
sorry if this has been asked before, but i read the two articles on COM Addins for Outlook 2000/2003:
http://www.codeproject.com/com/outlookaddin.asp[^]
http://www.codeproject.com/atl/outlook2k3addin.asp[^]
and have to implement an Addin for Outlook 2003.
Seemingly, i have not been able to create the Addin properly, as i experienced the following problem:
When it comes to importing the Office & Outlook typelibraries i face the problem of not knowing which DLLs are appropriate.
You know, the articles use Outlook 2000 DLLs, even the one on Outlook 2003...
<br />
#import "C:\Program Files\Microsoft Office\Office\mso9.dll" \<br />
rename_namespace("Office") named_guids <br />
using namespace Office;<br />
<br />
#import "C:\Program Files\Microsoft Office\Office\MSOUTL9.olb" <br />
rename_namespace("Outlook"), raw_interfaces_only, named_guids <br />
using namespace Outlook;<br />
I manage to find the second file, the appropriate *.olb file, but not the also needed MSOXXX.dll file of my Office installation, as the dll is renamed in Office 2003.
I tried several DLLs in the directory, but none has worked as i get a failure when i build the project (in MS Visual C++ 6.0).
Any ideas?
Regards,
Harry
|
|
|
|
|
Hi,
I am trying to a COM DLL with multiple objects but I only want to expose one interface to the user.
I would like to achieve something similar to the ADODC object in VB. User can only declare a new instant of the ADODC but not the Recordset object in it. That is "Dim Ado as ADODC" is ok but "Dim rs as Recordset" is not ok.
When user is writing a code in VB, I would like the user to be able to see the method and properties in the inner objects. Like the AddNew method or Field properties in recordset. That is
Dim MyObj as MyProject--------------Dim ADO as ADODC
MyObj = new MyProject---------------ADO = new ADO
MyObj.Inner.InnerMethod/Prop--------------ADO.Recordset.Addnew
While searching, I have come across terms like containment and Aggregation. I think containment is closer to what I am looking for but seems to be missing some finer details. From what I see Recordset "seems" to be a property field in ADODC.
Am I heading in the right direction? Can someone help me with my "missing links" please....
|
|
|
|
|
Just implement the COM classes as you normally would, but without registering them. It requires you however to internally create the COM objects by other means than CoCreateInstance, but that's no biggie if you are using ATL. CComObject<T> can help you out there. You can new the objects as well, but IIRC, there are some obscure pitfalls with that method.
--
An eye for an eye will only make the world blind.
|
|
|
|
|
Hi,
Thanks for replying. I can see that you are pretty active in this topic.
I am currently doing COM using ATL. So I may have problem implementing the COM class without registering them but that should not be too big a problem to solve.
I picked up COM by using ATL directly, so I keep having this feeling that my fundamental is wrong and I am really struggling to understanding any code in genertated code at all.
Do you know of any means where I can have a good read up on the internet. I know that the book Essential COM is highly recommended but before I get that I would like to read up more.
Thanks again.
Truth is not always popular, but it is always right.
|
|
|
|
|
Sorry, I don't have any handy internet references available. I have not solved your problem before either. Well, I did it the lazy way by not including the coclasses in the IDL file. Had I not been on vacation right now, I could've experimented on your behalf to find a smart solution, because it is not unlikely that I will face this problem myself.
One really bad "hack" I can think of right now, is to make the rgs-script associated with your COM class, an empty script. That should ensure that it is not registered at all. But please make sure that you use the CComObject<> template to instantiate the objects, otherwise the COM module's lock count will not be incremented (IIRC, that's the problem with just new -ing the objects). As I have not tried this hack at all, I can't say for certain that it will work. It could be the case that the rgs script parser doesn't allow empty script, in which case all you have to do is add some "dummy script" in your rgs file. Your mileage may vary.
Good music: In my rosary[^]
|
|
|
|
|
Oh yeah.. in case you have not used the CComObject template, this is the way you use it:
CComObject<CYourClass>* pObj;
HRESULT hr = CComObject<CYourClass>::CreateInstance(&pObj);
pObj->AddRef();
CComObject will however stabilize the refcount during the construction phase (temporarily incrementing it). I think. (It should!)
Good music: In my rosary[^]
|
|
|
|
|
Thanks for the quick reply and thanks for taking the trouble to reply even when you are on vacation.
One last question, how do you think the VB recordset example I use is implemented?
Currently what I feel is that recordset is a get_property under ADODC and when this is call the pointer to the recordset object is in my COM is passed returned.
But I found a project in code project that use a method to implement this, It does return the pointer of the inner object.
Please dun take too much of your time on this, just give me your nbest guess. Thanks and enjoy your holiday.
|
|
|
|
|
Hi
I am trying to use the EM_GETLINE message to get the text of a particular line but i am not able to send the last parameter i.e the lpram..for the SendMessage function... anyone plz let me know how to do this... i am doin in the following way
char[] buffer = new char[255];
buffer[0] = (char)255;
Message msg = Message.Create(this.Handle, EM_GETLINE, (IntPtr)Index, (IntPtr)buffer[0]);
base.DefWndProc(ref msg);
return msg.Result.ToInt32();
but it gives me a error like.. "Attempted to read write protected memory. This is often indication that other memory is corrupt." F1! F1!
cheers
Chettu
|
|
|
|
|
Hi Every one
Can any body guide me that how one can set Launch Permissions Programmatically for any DCOM Component through vc++ or VB.
actually i want to give specific groups lauch permission to one of my DCOM
component while installation of application.
Thanks and Regards.
Mohammad Kamran
|
|
|
|
|