|
Hi Everybody,
I want to take a Character string as a input parameter to a COM component created in VC++ using ATL.How do I perform this task.It would be better if the solution is also given for returning a character string as the output parameter of the COM component.
Thanks and Regards,
Abhishek.
Learning is a never ending process of Life.
|
|
|
|
|
Use a BSTR.
First pram below is how you pass it in, second is how you make it a return value.
HRESULT MyFunc(BSTR bstrParam, [out, retval]BSTR *bstrRetVal)
Jason Henderson quasi-homepage articles "Like it or not, I'm right!"
|
|
|
|
|
Just so I'm clear, what the best way to deal with this in a way that's "friendly" to both C++ and VB (I work exclusively in C++ myself)?
I'd envision a C++ calling sequence similar to:
BSTR* pbstrFoo = NULL;<br />
MyFunc(pbstrFoo);<br />
if(NULL != pbstrFoo)<br />
{<br />
::SysFreeString(pbstrFoo);<br />
pbstrFoo = NULL;<br />
}
Is that about right? So what would a similar calling sequence be for a VB programmer? Is there something I can do differently within my COM object to make it easier for both?
|
|
|
|
|
b_p_smith wrote:
BSTR* pbstrFoo = NULL;
MyFunc(pbstrFoo);
You forgot the first param in my example so it would look like this:
BSTR bstrFoo1;
BSTR* pbstrFoo = NULL;
bstrFoo1 = ::SysAllocString(L"Test")
MyFunc(bstrFoo1, pbstrFoo);
In C++ you must free both strings.
I don't use VB so I can't give an example, but when the string falls out of scope, VB should handle freeing the string.
So don't worry about your VB client app, it will just see this as a return value.
Jason Henderson quasi-homepage articles "Like it or not, I'm right!"
|
|
|
|
|
Thanks Jason. That's pretty clear, and I'll adjust my code accordingly.
|
|
|
|
|
Hi
I would like to establish a "connection" to another application. My code looks like this:
if (pBaanApp == NULL)
{
CoInitialize(NULL);
HRESULT hr = pBaanApp.CreateInstance("Baan4.Application");
....
....
This works fine when the Baan4 application is not allready started. If it is started, this will fail and hr=-2147467262. I then tried to use this line of code to "get hand on" the application:
HRESULT hr = pBaanApp.GetActiveObject("Baan4.Application");
This fails and hr=-2147221021.
Can anybody help me ?
Regards,
Evan
|
|
|
|
|
.CreateInstance(...) and .GetActiveObject(...) are not the right functions to use.
The one and only function to use is CoCreateInstance(CLSID, ..., IID, &IUnknown).
As for the error you get (-2147467262), it means "interface not supported". I believe that's because you're calling .CreateInstance() from a wrong context.
And I swallow a small raisin.
|
|
|
|
|
I created a simple COM object that uses connection points with ATL. My problem is that the book that I have creates a client example in VB!! I need info on how to respond to Callbacks/Events in C++. Unfortunatly, I don't want to spend another $50 dollars on any more COM books. Can anyone point me to an online example that is *very* simple so I can understand it? I looked for something here, but was unable to find an article on this. I just need a very simple C++ sample client for my COM object(If it works across a network using DCOM, it would be even better).
Thanks in advance all you COM gurus and Don Box's for pointing me towards a simple online tutorial on this.
|
|
|
|
|
Method 1:
Are you trying to catch the ActiveX-event? if yes, Visual Studio already allows you to intercept any event, you can use class wizard to do so. For each ActiveX control that you put on a dialog, you can select the event that you want to handle.
Method 2:
Now if you want to do that with C++ code (let's say MFC! is that okay?)
Follow these steps, we will create a 'proxy' class
1) Create a new class - derive from CCmdTarget and choose 'Automation' radio button
2) In the .cpp file, you need to replace the following with correct GUID of your object event.
static const IID IID_IMyevents =
{ 0x84946703, 0x496a, 0x40dd, { 0xb2, 0xb2, 0xb4, 0xe6, 0xa6, 0x60, 0x3d, 0x57 } };
3) Now you can add the event manually that you wish to handle, go again to class Wizard
and under the 'Automation' tab, you need to add the event handler like it is defined for your object. Let say, your event is: HRESULT MyEvent(short sEvent),
Add MyEvent in the name field and sEvent in the parameter list, and click 'OK'
Your .cpp file should look like this:
BEGIN_DISPATCH_MAP(CMyevents, CCmdTarget)
DISP_FUNCTION(CMyevents, "MyEvent", MyEvent, VT_EMPTY, VTS_I2)
END_DISPATCH_MAP()
void CMyevents::MyEvent(short uEvent)
{
}
4) Create an instance of this class and call CmdTarget::GetInterface(&IID_IUnknown)
to get pointer of this object.
5) Call AtlAdvise(m_pYourObjectPtr, pEventUnknownPtr, DIID__IIDYourEvents, &m_dwAdvise);
6) Call AtlUnadvise(m_pYourObjectPtr, DIID__IIDYourEvents, m_dwAdvise) to disconnect this event handler (WM_DESTROY or other places)
The dialog method is simpler as you can see. Complete C++ solution can be a lot more complicated. You still have to create ways to communicate with your 'Frame' or 'Dialog'.
Good luck!
VOTD: 27 "All things have been committed to me by my Father. No one knows the Son except the Father,
and no one knows the Father except the Son and those to whom the Son chooses to reveal him." - Mat 11:27(NIV)
|
|
|
|
|
There's a demo on MSDN called Fire something. Look for that.
Todd Smith
|
|
|
|
|
Does it do any harm or is it bad practice to Release a smart pointer's interface when you are finished with it?
MySmartPtr ptr = NULL;
ptr.CreateInstance("blah");
...
ptr.Release();
ptr = NULL;
I do this a lot and it seems ok (on the surface). Release releases the m_pInterface member and the smart pointer is set to null.
Examples I have seen just use
ptr = NULL;
Jason Henderson quasi-homepage articles "Like it or not, I'm right!"
|
|
|
|
|
Nothing wrong but if your object can be 'reset' differently or doesn't really this, I would suggest you to release it only when you no longer need that object. At the same time, if the event that causes you to do that is asynchronous (or user-driven), I will say it is fine since you have no control over the user. By the way, you just need to assign the pointer to 'NULL', you don't need 'Release' unless of course, you called 'AddRef' in your code.
VOTD: 27 "All things have been committed to me by my Father. No one knows the Son except the Father,
and no one knows the Father except the Son and those to whom the Son chooses to reveal him." - Mat 11:27(NIV)
|
|
|
|
|
|
Hi Everybody,
I need to send a ZIP file from a server to a client using ASP.To perform this task I may need a COM component which would transfer the file for me.It would be better if the COM component is developed in VC++.How can I develop such a component.Which API's do I need to use for the file transfer.Can anybody give me some idea.
Thanks and Regards,
Abhishek.
Learning is a never ending process of Life.
|
|
|
|
|
There you'll find an OCX implementation of the zip compression feature.
I haven't played with it but if it is an OCX without UI, it may be exactly what you are looking for. Because the OCX publishes COM interfaces, it is a COM server.
Otherwise, building a COM should not be that hard. Steps should be :
- get the zlib library (zlib.org)
- use VC++ ATL COM Wizard to build a COM skeleton component
- in the default interface, add the deflate method
- do the plummering between the actual interface implementation file and the zlib library
Disavantage : probably you'll only achieve synchronous compression. In other words the server thread will be freezed during the whole compression process. Turning your COM thread-safe is a little bit harder : I would suggest to do it using C# as threads are for easier to handle.
Let's swallow a small raisin.
|
|
|
|
|
Have you checked out Franky Braem's SawZip control? You can find it at http://www.codeproject.com/atl/sawzip.asp
'My capacity for happiness', he added, 'you could fit into a matchbox without taking out the matches first'.
- Marvin, the robot.
Amit Dey
sonork: 100:18407
msn: visualcdev
|
|
|
|
|
It sounds like you just need to initiate a download to the client. If that's the case then you don't need a COM component. Some simple javascript can start a download.
Do you need to create the zip file dynamically?
Save this to a test.htm file and open it
<html>
<script language="javascript">
function download()
{
window.open('http://www.codeproject.com/useritems/multidoctemplateex/mdtex_src.zip');
}
</script>
<body onload="download();">
</body>
</html>
<b>Todd Smith</b>
|
|
|
|
|
I downloaded one free dll from website.i copy that dll in to my program folder.I also included the header file in to my project.But when iam running the program it is giving linker error like this.
Linking...
save.obj : error LNK2001: unresolved external symbol "int __stdcall MetaGifPic(void *,char *,struct tagRECT *,int,int)" (?MetaGifPic@@YGHPAXPADPAUtagRECT@@HH@Z)
I think i have to include the library file.But the library file is not given.So i want to know wheather library file should be included or any other way to do this.
pl explain.Thanks in advance.
|
|
|
|
|
add this in one of the headers of your code :
extern "C"
{
int MetaGifPic(void *,char *,struct tagRECT *,int,int);
}
|
|
|
|
|
Does anybody know about where the DLL is loaded when the DLL is registered on both the server and client computers (two separate computers), but client instantiatews this DLL remotely.
1.Is the DLL loaded in the client process becuase it is inprocess so it must load in the client. or
2.DLL is loaded in the server's memory space whereby a surrogate is used on the server side and whole communication is through proxy and stub.
Regards
Muhammad Nauman Khan
|
|
|
|
|
Hi All,
I need to create a COM Object in VC++ that should return some value.Taking up a simple example,suppose the COM component is created to add 2 numbers using ATL, then the implementation of methods in C++ files would look something like this.
// Util.cpp : Implementation of CUtil
#include "stdafx.h"
#include "Object.h"
#include "Util.h"
/////////////////////////////////////////////////////////////////////////////
// CUtil
STDMETHODIMP CUtil::Addnum(int x,int y, int *z)
{
// TODO: Add your implementation code here
*z = x + y;
return S_OK;
}
Now I need to use this COM Object in an ASP code, for which the code I've written is as follows:-
===========================================================================
ASP Code
<%
Dim objTest
Set objTest = CreateObject ("Object.Util")
Dim lngReturnValue
objTest.Addnum 10, 91, lngReturnValue
Response.Write "Random number from Scriptlet = " & lngReturnValue
%>
But this code isn't working.Is this code correct or is there some other way to implement the requirements.
Do I have to adopt some other way to create COM component or
Some other way to use the component in ASP.
(Note: The same code works perfect in VB but not in ASP)
Can Anybody Help Me.
Abhishek.
Learning is a never ending process of Life.
|
|
|
|
|
I do not know ASP, so I cannot help you with the current way that you are trying to do it. However if you change your definition in the IDL file that describes your interface for that function, and declare one of the options for your z value as retval as well as out like this:
HRESULT Addnum([in] int x, [in] int y, [out, retval] int *z);
It will make the z value a return value in langauges like VB, scripting languages and probably ASP. so instead of this:
objTest.Addnum x, y, IngReturnValue
you could write:
IngReturnValue = objText.Addnum(x,y)
I hope this helps,
Good Luck
Build a man a fire, and he will be warm for a day Light a man on fire, and he will be warm for the rest of his life!
|
|
|
|
|
Thanks Kilowatt,
You have solved my problem.The method is working now.
Thanks Once again,
Abhishek.
Learning is a never ending process of Life.
|
|
|
|
|
Hello, first of all, it would be of interest to know whether your COM component gets instantiated or not.
Here are reasons why you have problems :
- you should use Server.CreateObject(progid) instead of CreateObject(progid)
- the fact that you use ATL is not enough a way to ensure that your COM component can be used by VBScript. In other words, you must make sure that the default interface exposed is either a dispinterface with adequate DISPIDs facing each property and each method, or derives from IDispatch, also with DISPIDs.
You have prebuilt samples in the Devstudio CD-ROM, and probably in this site too.
- your COM component is not properly registered
- your server has default security launch permissions that prevents to launch COM components. Whether your COM component is a DLL or an EXE varies a lot in behaviours. You must use DCOMCNFG.EXE to handle that.
Good luck!
|
|
|
|
|
I have been reading articles on using COM+ in .NET, however most of them discourage its use for new applications. What is the recommended alternative(s)? I am building a client/server app and was going to make the Server a COM+ object and access it through .NET Remoting. Should I be using a Windows Service or something else. I would prefer to stay away from webservices due to the sensitive nature of the application. Thnaks.
Steve
Not all who wander are lost...
|
|
|
|
|