Monday, September 22, 2008

Invoke .NET from MFC(COM object - ActiveX)

Hi there...
A couple of days ago I wanted to use a .NET assembly from a MFC application. You can see other post where I explain how to make an interface in .NET and expose it to COM.

In this post I want to show you how to call a method from that assembly that has a byte[] parameter. and how to get a parameter from a COM object. As you can see(if you've made that .tbl file and imported in C++), the byte[] parameter from .NET is exposed as a SAFEARRAY*.
The trick is to create a SAFEARRAY* like this:
BYTE* myBuffer = ... ; // the length of the buffer is len
SAFEARRAYBOUND sabdBounds[1] = { {len, 0} };
LPSAFEARRAY psa = SafeArrayCreate(VT_UI1, 1, sabdBounds);
memcpy(psa->pvData, myBuffer, len);
//call the method from .NET assembly

To call a method or get a property from a COM object, you can use the InvokeHelper method:

//get signature BSTR string
VARIANT vtResult;
this->GetDlgItem(IDC_MyActiveXID)->InvokeHelper(propertyId, DISPATCH_PROPERTYGET
DISPATCH_METHOD, VT_VARIANT, (void*)&vtResult, NULL);

After this call, you should check on vtResult.vt to see the return type.

Have fun!

Friday, September 19, 2008

Exposing .NET Components to COM

Looking on MSDN website you'll find this:
http://msdn.microsoft.com/en-us/library/zsfww439.aspx
So as you can see, you can't expose static components to COM.

C# code:
namespace ClassLibrary1{
[Guid("4322F88E95-DD27-4ae6-B6DE-054440FC70AA")]
[InterfaceType (ComInterfaceType.InterfaceIsIDispatch)]
[ComVisible(true)]
public interface _Class1
{
[DispId(1)]
int Add(int i);
}

[Guid("13FE123D-4D34-495F-AB4D-909BBB463EEA")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("ClassLibrary1.Class1")]
[ComVisible(true)]
[ComDefaultInterfaceAttribute(typeof(_Class1))]
public class Class1 : _Class1
{
public int Add(int i)
{
return i + 10;
}
}
}


C++ code:
#include "stdafx.h"
//the location must point to the tlb file
#import "D:\\ClassLibrary1\\bin\\Debug\\ClassLibrary1.tlb"
int _tmain(int argc, _TCHAR* argv[])
{
ClassLibrary1::_Class1 *com_ptr;
CoInitialize(NULL);
ClassLibrary1::_Class1Ptr p(__uuidof(ClassLibrary1::Class1));
com_ptr = p;
long a = com_ptr->Add(1);
CoUninitialize();
return 0;
}

To make this work, you have to Register the .NET library to COM from Properties-Build tab and run the command : regasm ClassLibrary1 /tbl:ClassLibrary1.tlb

To deploy this, you'll have to gacutil the assembly.
gacutil /i ClassLibrary1.dll but first you'll have to strong-name sign it.

Wednesday, September 3, 2008

WPF 3D View


Hello...

A little while ago, I tried Xceed datagrid view... and I saw there a 3D view... You can check it out on their website. A simillar application is on Apple iPhone.

So, I started to make a WPF control simillar to that list.


The control can be found at : www.codeplex.com/3dView


Have fun!