|
I want to pass byte data from VB into a VC++ COM.
In a setData(VARIANT msgdata), I write the code below, but it has error in pdata[i] = *padata[i]. What's wrong ?
<br />
if ((msgdata.vt & VT_ARRAY) == 0)<br />
return E_INVALIDARG;<br />
if ((msgdata.vt & VT_UI1) == 0)<br />
return E_INVALIDARG;<br />
<br />
SAFEARRAY *psa = msgdata.parray;<br />
PBYTE *padata;<br />
<br />
SafeArrayAccessData(psa, (void **) &padata);<br />
<br />
int nsize = psa->rgsabound->cElements;<br />
PBYTE pdata = new BYTE[nsize];<br />
for (int i=0; i< nsize; i++)<br />
{<br />
pdata[i] = *padata[i];<br />
}<br />
<br />
SafeArrayUnaccessData(psa);<br />
In VB, I'm doing some testing code like:
<br />
Dim ba(2) As Byte<br />
<br />
ba(0) = 5<br />
ba(1) = 7<br />
ba(2) = 19<br />
<br />
compSSM.setData(ba)<br />
|
|
|
|
|
I think that you do not need the dereference of pointer. In padata you will have a pointer to some BYTE values after SafeArrayAccessData().
BYTE *padata;
SafeArrayAccessData(psa, (void **) &padata);
//only one directly, no of element is the data length
int nsize = psa->rgsabound->cElements;
PBYTE pdata = new BYTE[nsize];
for (int i=0; i< nsize; i++)
{
pdata[i] = padata[i];
}
or yet
memcpy( pdata, padata, nsize*sizeof(BYTE) );
With best wishes,
Vita
|
|
|
|
|
Thanks, it's working now. Even I don't have the loop to copy the array. I can use it directly within the block SafeArrayAccessData() and SafeArrayUnaccessData().
|
|
|
|
|
I am back to C++ at least for one project and need a quick solution to this problem:
I have a MathLib component, written in ATL, with two COM classes: MathLib.Matrix and MathLib.Vector. For those of you who have no background in math, vector is an array and matrix is 2 dimensional array (i.e. int a[3][3] is a matrix whereas int b[3] is a vector). I only encapsulated functionality to objects because I am going to use these two classes from SQL server and it does not support COM & arrays very well.
Now I would like to perform some quantitative analysis (mathematical operations) on these two classes.
Suppose I have MathLib.Fn COM class. This COM class has function that adds the contents of two arrays and returns array of sums.
For example, I have
[1 2 3] + [4 5 6] = [5 7 9]
(because 1+4=5, 2+5=7, 3+6=9)
My function name is AddVectors, it takes two vector object as input parameters and return vector object as output. This function is in the same C++ dll as the two other ATL classes.
Now I need to know what is the easiest way to declare this function? Don't forget that the Vector and Matrix object will most likely be generated by SQL server transact SQL and only then passed, so I'll be dealing with late binding.
Basically, this is how they'll be used:
SQL SERVER
m=create object mathlib.matrix <--- will probably create IDispatch *
populate m with some values
fn=create object mathlib.fn
n=new matrix
n=fn.execute_some_function(m) <--- will pass object to my COM object
And the second question is how to use these pointers in the function, do I need any marshalling? Anyone has sample of such code?
Kind Regards,
Tomaz
|
|
|
|
|
You can provide the such COM class, named as MathLib.Fn, like the MathLib.Matrix and MathLib.Vector. This class must expose the own interface. Let it be a IFn interface with several functions. For example,
HRESULT AddVectors([in] IVector* v1, [in] IVector* v2, [out,retval] IVector* *vsum );
HRESULT AddMatrices([in] IMatrix* m1, [in] IMatrix* m2, [out,retval] IMatrix* *msum ); and so on, as you want.
You could use it on manner, something like
Set n = fn.AddVectors(v1,v2) ' for some Vectors
With best wishes,
Vita
|
|
|
|
|
Hello to everybody.
I'm making a COM object which receive a VARIANT type, I recover this value from database in an ASP page as a Byte Array (it's a bitmap), the COM object must draw something over this bitmap and send again to the ASP page. My problem comes because I need extract the data from the VARIANT in a CLongBinary* but I haven't idea how can I do it.
Can you help me?
Thanks.
|
|
|
|
|
Hi,
I've been reading the Inside COM / Microsoft Press book and got to page 20 or so. The whole book so far states, that COM is language-free, vendor-free (combinig vendors), etc etc, everything withh evrything, just keep the standard and then something like
"calling conventions: MS uses __stdcall (in C++) for their component's methods (interface methods, ok) and __cdecl for variable parametr count methods. You don't have to follow it (and as state, with some languages (aka compilators) you don't even have a chance to follow it) but you have been warned that your application will no longer be able to use MS COMPONENTS...
what's that????????
anybody knows how to use OLE without MFC? I'd love a snippet!
|
|
|
|
|
Hi,
I'm a beginner in Com and I need help.
I don't manage to get my specific C++ object in my COM client.
I have a C++ DLL that contains this object :
Class CDDSR_MON;
I have a COM server that contains this coclass:
class ATL_NO_VTABLE CoDDSR_CORE
public:
CDDSR_MON * m_pDDSRCORE;
BEGIN_COM_MAP(CoDDSR_Monitoring)
COM_INTERFACE_ENTRY(IDDSR_Monitoring)
COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()
I'd like to pass this pointer m_pDDSRCORE to my COM Client so I do that :
In my COM server :
STDMETHODIMP CoDDSR_CORE::getMonitoringInfo(IDDSR_Monitoring **mon){
CDDSR_Mon * ddsrMon;
IDDSR_Monitoring * iddsrMon;
HRESULT hr = ::CoCreateInstance(CLSID_DDSR_Monitoring, NULL,CLSCTX_LOCAL_SERVER,IID_IDDSR_Monitoring, (void**)&iddsrMon);
CComObject<coddsr_monitoring> *pmon;
HRESULT hRes = CComObject<coddsr_monitoring>::CreateInstance(&pmon);
pmon->m_pDDSRMonitoring = ddsrMon;
pmon->QueryInterface(IID_IDDSR_Monitoring, (void**)iddsrMon);
mon = iddsrMon;
return S_OK;
}
In my COM client :
CDDSR_Monitoring* ddsrMonitoring = NULL;
// Now we will intilize COM
hr = CoInitialize(0);
// Use the SUCCEEDED macro and see if we can get a pointer
// to the interface
if(SUCCEEDED(hr))
{
IDDSR_CORE* pDDSR_CORE;
hr = CoCreateInstance( CLSID_DDSR_CORE, NULL, CLSCTX_LOCAL_SERVER,
IID_IDDSR_CORE, (void**) &pDDSR_CORE);
if(SUCCEEDED(hr))
{
IDDSR_Monitoring* iMon;
hr = ::CoCreateInstance(CLSID_DDSR_Monitoring, NULL, CLSCTX_LOCAL_SERVER,IID_IDDSR_Monitoring, (void**) &iMon);
if(FAILED(hr))
pDDSR_CORE->getMonitoringInfo(&iMon);
}
// Uninitialize COM
CoUninitialize();
|
|
|
|
|
Since Nobody can tell me how to use thumbctl. I have to find another way.
I dont want to popup new window or run any script in my Browser control.
how to do it?
thanks a lot.
<--MFC-->
|
|
|
|
|
This is the problem: I have a third party control. I'd like to add more functionalities to the control. So, I created a composite control and drop the third party control onto my newly created composite control. Then I tried to use :
LPUNKNWON pUnknown = GetDlgItem(IDC_THIRD_PARTY_CONTROL_ID);
pUnknown->QueryInterface();
The problem is that GetDlgItem() did not return a CWnd pointer. Therefore, I could call QueryInterface().
Would someone help me?
How do I instantiate the third party control?
|
|
|
|
|
I have two dialog based programs. one is Microsoft Automation. and the other one calls first dialog-based app.
To call first dialog-based app ( let me just say it app2) from first dialog-based app ( app1), I used ShellExecute();
anyway, It is working fine if you compile and execute app1.exe within VC++ 6.0.
if you go to mycomputer-> right click-> window explore->go to app1 folder->debug-> app1.exe, and it is not working anymore.
the error at, which is in app2
<br />
_Application application;<br />
if(!application.CreateDispatch("Word.Application)<br />
{<br />
AfxMessageBox("Couldn't create Word.Applicaiton");<br />
<br />
}<br />
if I go back to run and execute app1.exe it works again. but not from double clicking on app1.exe in window explore.
I know that's OLE initialization problem where i declare
<br />
if(!AfxOleInit())<br />
{<br />
AfxMessageBox("Couldn't create OLE COM");<br />
}<br />
<br /> it is in BOOL Capp2App::InitInstance(). From my knownladge, if OLE libs didn't get initialized, I couldn't createDispagech("Word.Application");
How can I initialize OLE Lib evertime i use so i don't have to execute app1.exe inorder to get Word.Application?
|
|
|
|
|
I want to keep all the urls to whome users navigated for this purpose I have to implement the DWebBrowserEvents2 (sinking interface) in my ATL COM based dll but I do not exactly know how to write that dll and to advice internet explorer to call that function on event firing if some one know then tell me or guid me on this problem I will be very much thankful
|
|
|
|
|
I want to keep all the urls to whome users navigated for this purpose I have to implement the DWebBrowserEvents2 (sinking interface) in my ATL COM based dll but I do not exactly know how to write that dll and to advice internet explorer to call that function on event firing if some one know then tell me or guid me on this problem I will be very much thankful
|
|
|
|
|
Now I want to made a dialog which can preview some image files such as bmp,jpg and so on.
Then I found an ActivexContol named Thumbctl which looks very good. but it dosent work. I cant insert it to my VC++ project. the Error is"unable to open the activex control,make sure the control contains a valid type library", I have tried this in diffrent pc and got the same result.
my system" windows XP, IE 6.0"
I need help. thanks a lot
If I need a new version. where can I find it?
<--MFC-->
|
|
|
|
|
Hi.
I too get the same error when I try to insert the ActiveX control. I'm running Windows2000. VC++ 6.0
I have posted a message abt. extracting thumbnails using the Shell's IExtractImage interface. But without success.
Why don't you try it out?
http://www.codeproject.com/script/comments/forums.asp?forumid=1648&select=237898#xx237898xx
Logic is a systematic method of coming to the wrong conclusion with
confidence.
|
|
|
|
|
I'm unsure if this is a "correct" solution (COM threading is still a bit mysterious to me):
* I have COM object which needs to live asynchronously from a certain point in time (i.e. after the host has called a "start" method)
* I want it to be able to send events to the host
* I want it to be able to serve the host at any time (i.e., the host should be able to call any method during the COM objects life time)
Is this is viable solution? (Pseudo-code follows)
coclass MyThreadedClass : ISomeInterface, IConnectionPointImpl<...> {
STDMETHODIMP Start() {
CreateThread(..., BootStrapFunc, this);
}
STDMETHODIMP Stop() {
}
private:
static DWORD WINAPI BootStrapFunc(LPVOID param) {
MyThreadedClass* pThis = (MyThreadedClass)param;
pThis->ThreadLoop();
return 0;
}
void ThreadLoop() {
}
};
If I get this to work, there will be an article about it
FreeBSD is sexy.
<< This space for rent >>
|
|
|
|
|
The COM Mailslot object that I develop in this article does that kind of stuff. It has it's own thread and fires async events into VB whilst allowing VB to call into it whenever it likes...
Len Holgate
www.jetbyte.com
The right code, right now.
|
|
|
|
|
Thanks for the reply! I'll check out the article right away.. (I can sleep when I die.. )
FreeBSD is sexy.
<< This space for rent >>
|
|
|
|
|
I think I've understood how to implement my asynchronous object(s). I seriously need to buy some hard core COM-books. I should have known about marshalling interfaces.
Thanks alot for your article! Now if I get some time over this week, I'll complete what I've started so that I write an article about it. (About time I gave something back for all the stuff I've downloaded and used here.. )
FreeBSD is sexy.
<< This space for rent >>
|
|
|
|
|
I am considering developing some COM based Office Add-ins using ATL, and was wondering if my following understanding is reasonably correct.
To develop add-ins there is an interface called IDTExtensibility2, which features functions such as OnConnection, OnDisconnection etc. As parameters to these functions there are pointers to the main application, which is what enables the developer to access the application, manipulate toolbars etc.
If this is the case, all I have to do is find out the structure of these interfaces etc. (which from what I remember is in a type library) and then build in my own code correct?
Once I've done that its a case of running regsvr32 and putting in the relevent registry keys and off we go? I presume ATL is the best way to go for developing such objects?
As I said, I'm new to this COM thing So any encouragement that I'm on the right lines is appreciated!
Paul
|
|
|
|
|
You are definetly on the right track.
although I have almost no experience with COM Add-ins, from my previous experience with COM it looks good.
a few comments:
you can try to work with VB for a start. it helps to get familiar with unknowm (...) interfaces.
A great article about add-ins (if I remeber it corectly) is Developing COM Add-Ins for Microsoft Office 2000 in the MSDN.
have fun
Noam
Noam Ben Haim
Web Developer
Intel
noam.ben.chaim@intel.com
|
|
|
|
|
Is there any tool like java2idl that can directly change MFC code into ATL code???
I am now modify some MFC code ,in order to change it into a COM .But there are lots of problems, such as,type dismatch, return value .
Anyone have some ideas about the steps how to proceed .
I will preciate it.
regards.
|
|
|
|
|
Changing from MFC to ATL is a complicated procedure as you have found out. You don't need to go through the pain. You can make a MFC COM object although that has it's own pains.
|
|
|
|
|
I plan to copy all the MFC Class ,Including GUI Class ,such as Frmae,View, to the Atl Project .And it can be complied successfully. Then I can further modify the Atl project based on that. I will add some interface in Atl project to call function instead of the automation message loop . In this way , I think I could let the Atl dll run in VB GUI,with his own GUI (Frame ,view,Dialog ) just loaded in memory and not shown.
This is my idea . What do you think of it ? I just want to get a general structrue ,and then I can modify the Atl code into more simple project,such as change Frame,view into other substitutes. In this way ,I can achieve my goal.
Expecting your advice.
Now I have copied all the MFC Class ,Including GUI Class ,such as Frmae,View,from the MFC Project to the Atl Project .And it can be complied successfully.
But when I attempt to register the DLL I get the following error:
Debug Assertion Failed!
Program: C:\WINNT\System32\regsvr32.exe
File: D:\Program Files\Microsoft Visual Studio\VC98\MFC\SRC\APPCORE.CPP
Line: 85
Expression: ASSERT(AfxGetThread() == NULL);
So what does this really tell me and what can I do to correct it?
Any ideas???
|
|
|
|
|
Bliven wrote:
Is there any tool like java2idl that can directly change MFC code into ATL code???
I am now modify some MFC code ,in order to change it into a COM .But there are lots of problems, such as,type dismatch, return value .
There is no tool that I know of, because it is *difficult*
What kind of MFC code do you want to change to ATL ? It is a simple COM object, ActiveX control, or full blown MFC app ?
In any case, I wish you luck
V
|
|
|
|
|