Tuesday, December 16, 2008

Microsoft Office Word Navigation

On CodeProject I've just wrote an article on navigation(like the one in Visual Studio - Navigate foreward and Navigate Backword) inside a Word document.
The article is found here and the source code here.

Monday, October 27, 2008

Using MFC ActiveX in other technologies

Hello...
For a while now, I've been using a Microsoft MFC ActiveX in diffrent tehnologies like .NET, web - JavaScript and MFC.

For the first two is kind of easy to import an activex inside yout project...

For .NET you either add a reference to a COM.. that is the ActiveX that is using a .NET Framework tool - aximp - to create two wrappers.
Inside Javascript, you will use the <object> tag and after that you can call diffrent methods exposed by that activeX...
For catching an event in JS you have to write this code...
<script for="ActiveX_ID" event="EventName()">...code here...</script>

What about MFC? How can we call a method inside a MFC Application.
The answer is very simple if you used MFC and COM before.
A CWnd or a COleControlSite object has a InvokeHelper method.
virtual void AFX_CDECL InvokeHelper(
DISPID dwDispID,
WORD wFlags,
VARTYPE vtRet,
void* pvRet,
const BYTE* pbParamInfo,
...
);

You should look inside MSDN for details... Here I'm going to show you how can you invoke a property or a method.
For getting a field inside a property:
VARIANT vtResult;
this->GetDlgItem(IDC_ACTIVEXCTRL)->InvokeHelper(propertyId, DISPATCH_PROPERTYGET, VT_VARIANT, (void*)&vtResult, NULL);

where propertyId is the ID of the property(the same is for setting a value of a property).

For invoking a method, with one or more than one parameter, you can use:
static BYTE params[] = VTS_BSTR VTS_BSTR;
unsigned long result = 0;
this->GetDlgItem(IDC_ACTIVEXCTRL)->InvokeHelper(methodId, DISPATCH_METHOD, VT_I4, (void*)&result, params,
(LPCSTR)parameter1, (LPCSTR)parameter2);

where parameter1 and parameter2 are two BSTRs.

Well.. that's about it...
Happy coding!!!

Thursday, October 23, 2008

Complementary Knapsack problem

Hello..
Every programmer (or almost every programmer) heard of the faimos problem called, The knapsack problem. This problem can be formulated in math way: Having a set of numbers, find a subset of numbers this set and their sum are under or equal than a given value?
The solution of this is very simple and there are many web-sites where you can find the implementaion or the pseudo-code.

We name "Complementary Knapsack problem" the problem where we must find a subset that sum is greater than a given value and the difference of the sum and the given number is minimum.
I've done some research using Google and I found nothing(maybe I haven't searched enough).

The solution of this problem is solving the Knapsack problem for the a value equal with: sum of all numbers in set minus the given value. Because this problem offers an optimal solution, if we remove from out set of numbers the result of this problem, we find our subset and if we sum them we get a number grater that the given value and the difference is minimum.

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!

Tuesday, August 19, 2008

Visual Studio 2008 Unit test GUI


Hi there...

Fot thouse who are using unit tests build with Visual Studio 2008, I've created a Windows Forms application for running unit tests inside multiple .NET assemblys.

The project is on Codeplex.

Tuesday, August 12, 2008

Alternate log shrink in MS SQL 2005 - empty the database log

Hello...
Today I wanted to install VSTS 2008 and the installer "told" that I have no space on my HDD. After a quick look inside ProgramFiles folder, I saw that the SQL Databases have very large log files... So I've decided to empty them... After some Google solutions - without any succes - I've combined to results from thouse search results...
  1. detach a database
  2. attach a data base without the log file...

The first one is simple... Right click on the DB and choos Detach...

The second one is more tricky... You'll have to use the SP:

sp_attach_single_file_db @dbname= 'databasename', @physname= 'C:\Databases\databasefile.mdf'

The results of this SP is the following...

File activation failure. The physical file name "C:\Databases\databasefile_log.ldf" may be incorrect.
New log file 'C:\Databases\databasefile_log.LDF' was created.

So... we now have a new log with a size of 504KB...

Enjoy!

Sunday, July 27, 2008

The Ecstasy Of Gold

On 23rd of July Metallica was in Bucharest...
These are some pictures from the concert...





















Friday, May 23, 2008

Invoke method with ref and out parameters

The other day I was tryin to load an assembly using .NET Reflection and invoke a method from a given class that had an ref parameter.

After a Google-search I've found this article : http://iamacamera.org/default.aspx?section=home&id=62.

In this article, the author used basic .NET types (common types) like int32 and string. But what if I have an enum that is Int32 or some other custom class?... As you can see in the article, the key is to load the "System.String&" type and get the method using the obj.GetMethod(arguments, types);

If you'll try the following code, will not work:

Type.GetType(typeof(MyNameSpace.MyClass).FullName + "&");
Type.GetType("MyNameSpace.MyClass&");

But there is a solution...

I've made a generic method that I can use over and over again... It looks like this...

public static void InvokeMethod(string assemblyName, string className, string methodName, out object result, ref object[] arguments)
{

Assembly assembly = Assembly.LoadFrom(assemblyName);
// Walk through each type in the assembly
foreach (Type type in assembly.GetTypes())
{
// Pick up a class
if (type.IsClass == true && type.Name == className)
{
// Dynamically Invoke the Object
MethodInfo info = type.GetMethod(methodName);
ParameterInfo[] pars = info.GetParameters();
Type[] types = new Type[arguments.Length];
for (int i = 0; i < types.Length; ++i)
types[i] = pars[i].ParameterType;
info = type.GetMethod(methodName, types);
result = info.Invoke(null, arguments);
return;
}
}

return null;
}
For my need, MyClass was a static class and that's why I used info.Invoke(null, arguments);... To create an instance you have to user the Activator class like this...

object ibaseObject = Activator.CreateInstance(type);
result = info.Invoke(ibaseObject, arguments);

As you can see I'm fooling .NET and make him think I can load a refrence type like "MyNameSpce.MyClass&". The solution here was the use of ParameterInfo class from where I can get the REAL runtime type of an parameter.

Hope this helps someone some day... it sure helped me...:D

Monday, April 21, 2008

T-SQL datalength (image size or length)

Sometimes you have to insert into a database some binary information(like images). The MS SQL data type for this kind of data is image. Very often you want to know the exact size or length of the data you have in that comlumn.

The SQL function that returns the "number of bytes used to represent any expression" is DATALENGTH ( expression ) .

As an example:
SELECT DATALENGTH(MyImage), ImageID
FROM MyImagesTable

Sunday, April 20, 2008

Creation of Joukowski airfoils

One of the most nice and usefull airfoils constructions is the creation of the Joukowski airfoils. This construction uses conformal map theory.

The airfoil obtained with this method is also named Joukowski-Ceaplîghin airfoil.

The method is described below:


To obtain a Joukowski airfoil, with one face concave, we take a circle K, with the center in the first dial and let K’ be the transformed circle obtained using the transformation - the circle inversion with the following formula:
We notice that the upper transformation is a geometric sum of two transformations : (the circle K is transforme in itself), and , a inversion. The last transformation will rezult into a circle K' that intersects the Ox axis in a point B(-l,0), because the inverse is . If we draw the simetric radius OP and OP’, P on the base circle K and P’ on the transformed circle, the point P’’ on the airfoil, is obtained making the vectorial sum . These kind of airfils are used as the base airfoils for the aircrafts wings.

The following source code generates a airfoil in Matlab.

function profil = draw_airfoil(ox,oy,rho)
%point index
persistent index;
if isempty(index)==1
index = 1;
end

%transform factor-the intersection of the base circle with Ox
l=abs(ox-sqrt(rho^2-oy^2));

%obtinere cerc de baza
theta = 0:0.1:360;
theta=theta*pi/180;
px = ox + R*cos(theta);
py = oy + R*sin(theta);

cla;
grid on;
box on;
axis equal;
plot(px,py);%base circle
plot(px(index),py(index),'--bs','LineWidth',2,...
'MarkerEdgeColor','k',...
'MarkerFaceColor','b',...
'MarkerSize',10); %point on the circle
line('XData', [0 px(index)], 'YData', [0 py(index)], 'LineStyle', '--');

hold on;

%circle inversion
z=px+i*py;
csi = (l^2)./z;
plot(real(csi), imag(csi), 'Color','red'); % transformed circle
plot(real(csi(index)),imag(csi(index)),'--rs','LineWidth',2,...
'MarkerEdgeColor','k',...
'MarkerFaceColor','r',...
'MarkerSize',10);%point on the inverse circle
line('XData', [0 real(csi(index))], 'YData', [0 imag(csi(index))], 'LineStyle', '--');

hold on;
if index >= length(z)
index = 1;
end
%the resulted airfoil
plot(real(z(1:index))+real(csi(1:index)),imag(z(1:index))+imag(csi(1:index)), 'Color', 'green');
plot(real(z(index))+real(csi(index)),imag(z(index))+imag(csi(index)),'--gs','LineWidth',2,...
'MarkerEdgeColor','k',...
'MarkerFaceColor','g',...
'MarkerSize',10);
line('XData', [real(z(index))+real(csi(index)) real(z(index))], 'YData', [imag(z(index))+imag(csi(index)) imag(z(index))], 'LineStyle', '--');
line('XData', [real(z(index))+real(csi(index)) real(csi(index))], 'YData', [imag(z(index))+imag(csi(index)) imag(csi(index))], 'LineStyle', '--');

legend('Base circle','Point on the base circle','Line 1',...
'Inverted circle', 'Point on the inverted circle', 'Line 2',...
'Airfoil', 'Point on the airfoil');

index=index+50;


The output of this code is :