Tuesday, December 1, 2009
Type conversion of C++ and C#
Wednesday, October 21, 2009
listview imagelist resource leakage
ListView may leak with ImageLists
Tuesday, October 13, 2009
Use Web Browser control to print and preview a html document
After that put the web browser control to form.
In your code it looks like:
private AxSHDocVw.AxWebBrowser axWebBrowser1;
You can get HTML content and show it so:
object flags=null;
object postData=null;
object header=null;
object targetFrame=null;
axWebBrowser1.Navigate("www.namip.ru", ref flags, ref targetFrame, ref
postData, ref header);
When the fetching will be finished you can do so:
object pv = null;
object pva = null;
axWebBrowser1.ExecWB(SHDocVw.OLECMDID.OLECMDID_PRINTPREVIEW,SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DODEFAULT,ref
pv, ref pva);
===========================
Friday, September 25, 2009
How to create a trigger to insert a record in a backup table when a record is modified or inserted in one table
Thursday, September 24, 2009
Open Source Bug track software in ASP.Net
Tuesday, September 22, 2009
How to trace down memory leakage in C++ code
Thursday, July 23, 2009
webbrowser control DocumentCompleted triggered multiple times
Thursday, July 16, 2009
Cross-thread Operation Not Valid
The following is a solution that I can found from web.
http://www.astahost.com/info.php/Needed-Cross-thread-Operation-Valid_t15008.html
However, I noticed that even I can remove the exception, I can not solve the problem of performance because the time consuming operation is still executed in the main thread with invoke.
The following is the code.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Timers;
namespace UIThread
{
class SampleThread
{
public delegate void TestEventHandler(string sParameter);
public event TestEventHandler TestEvent;
protected System.Timers.Timer TestTimer = new System.Timers.Timer();
protected ISynchronizeInvoke SyncObject;
public SampleThread(ISynchronizeInvoke SyncObject)
{
this.SyncObject = SyncObject;
TestTimer.Elapsed += new ElapsedEventHandler(Tick);
TestTimer.Interval = 300;
}
protected delegate void TickDelegate(object source, ElapsedEventArgs e);
private void Tick(object source, ElapsedEventArgs e)
{
if (SyncObject.InvokeRequired)
{
SyncObject.BeginInvoke(new TickDelegate(Tick), new object[] { source, e });
//the following funciton are executed in the parellel thread
string sParameter = "";
for (int i = 0; i < 2000000; i++)
{
sParameter = sParameter + (i * i * i).ToString();
}
}
else
{
TestEvent(DateTime.Now.ToString());
}
}
public void Go()
{
TestTimer.Enabled = true;
}
}
public partial class Form1 : Form
{
SampleThread sampleThread;
public Form1()
{
InitializeComponent();
sampleThread = new SampleThread(this);
sampleThread.TestEvent += new SampleThread.TestEventHandler(FunctionInMainThread);
}
void FunctionInMainThread(string sParameter)
{
//basically this funciton is called from other thread by executed in main thread.
this.Text = sParameter;
//If following lines are turned on, the UI will become very slow in response.
//for (int i = 0; i < 2000000; i++)
//{
// sParameter = sParameter + (i * i * i).ToString();
//}
}
private void Form1_Load(object sender, EventArgs e)
{
sampleThread.Go();
}
}
}
Friday, July 3, 2009
Communication between managed c++ dll and C# form application
Step 1:
Create a new C++ dynamic library project by default and name it as MCDLL. The default class will be as following.
First file:
// MCDll.h
#pragma once
using namespace System;
namespace MCDll {
public ref class Class1
{
// TODO: Add your methods for this class here.
};
}
Second file:
// This is the main DLL file.
#include "stdafx.h"
#include "MCDll.h"
Step 2:
Now we can add a class in the empty dll as following
// MCDll.h
#pragma once
using namespace System;
namespace MCDll {
public ref class Class1
{
// TODO: Add your methods for this class here.
public:
array<double>^ m_adTestArray; // array that can be passed to C#
//function to return double array
array<double>^ GetTestArray(int iLength);
};
}
Second file:
// This is the main DLL file.
#include "stdafx.h"
#include "MCDll.h"
array<double>^
MCDll::
Class1::
GetTestArray(int iLength)
{
m_adTestArray = gcnew array<double>(iLength);
for(int i=0;i<iLength;i++)
{
m_adTestArray[i] = i*i*i;
}
return m_adTestArray;
}
Compile the MCDLL project and you will see how it works.
Step 3:
Now we can create a simple window Form application with C#, and the project MCDll as a project reference to our C# form application in order to access the function defined in C++.
The following is a simple code to demo the use of the c++ class.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace CSApp
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click( object sender, EventArgs e )
{
MCDll.Class1 class1 = new MCDll.Class1();
double[] adFromC = null;
adFromC = class1.GetTestArray( 5 );
for ( int i = 0; i < adFromC.Length; i++ )
{
Console.WriteLine( adFromC[ i ].ToString() );
}
}
}
}
Compile above application and execute it, we will see that the double array is initialized in C++ dll but is accessible from C# application.
A few more cases are demoed here to show how to pass parameters by reference, how to return a dimensional array back and how to return a string array. Full code can be found at following
// MCDll.h
#pragma once
using namespace System;
namespace MCDll {
public ref class Class1
{
// TODO: Add your methods for this class here.
private:
array<double>^ m_adTestArray; // array that can be passed to C#
array<double,3>^ m_adDimensionalArray;
public:
//function to return double array
array<double>^ GetTestArray(int iLength);
//funciton to return a string array
array<System::String^>^ GetTestStringArray( int iLength );
//function to return double array with dimension
array<double,3>^ GetMultiDimensionArray(int iLength);
//pass parameter by reference
double PassParameterByReference( double dInput, double% dOutput1, double% dOutput2);
//pass parameter by reference
double PassParameterByReference2( double dInput, double% dOutput1, double% dOutput2);
};
}
// This is the main DLL file.
#include "stdafx.h"
#include "MCDll.h"
array<double>^
MCDll::
Class1::
GetTestArray(int iLength)
{
m_adTestArray = gcnew array<double>(iLength);
for(int i=0;i<iLength;i++)
{
m_adTestArray[i] = i*i*i;
}
return m_adTestArray;
}
array<System::String^>^
MCDll::
Class1::
GetTestStringArray(int iLength )
{
array<System::String^>^ astrArray = gcnew array<System::String^>(iLength);
for ( int i = 0; i < iLength; i++ )
{
System::String^ str;
str = gcnew System::String( i.ToString() );
astrArray[i] = str;
}
return astrArray;
}
array<double, 3>^
MCDll::
Class1::
GetMultiDimensionArray(int iLength )
{
m_adDimensionalArray = gcnew array<double,3>(iLength, iLength, iLength);
for(int i=0;i<iLength;i++)
{
for(int j=0;j<iLength;j++)
{
for(int k=0;k<iLength;k++)
{
m_adDimensionalArray[i,j,k]=i*100+j*10+k;
}
}
}
return m_adDimensionalArray;
}
// pass parameters by reference
double
MCDll::
Class1::
PassParameterByReference( double dInput, double% dOutput1, double% dOutput2)
{
dOutput1 =dInput * dInput;
dOutput2 =dInput * dInput *2;
return PassParameterByReference2(dInput,dOutput1,dOutput2);
}
// pass parameters by reference and called
double
MCDll::
Class1::
PassParameterByReference2( double dInput, double% dOutput1, double% dOutput2)
{
dOutput1 =dInput * dInput * dInput;
dOutput2 =dInput * dInput * dInput*2 ;
return dOutput2 *2;
}
The following code shows how to call the dll functions.
private static void TestFunctions()
{
MCDll.Class1 class1 = new MCDll.Class1();
double[] adFromC = null;
adFromC = class1.GetTestArray( 5 );
for ( int i = 0; i < adFromC.Length; i++ )
{
Console.WriteLine( adFromC[ i ].ToString() );
}
string[] astrArray = class1.GetTestStringArray( 10 );
for ( int i = 0; i < astrArray.Length; i++ )
{
Console.WriteLine( astrArray[ i ] );
}
int iLength = 5;
double[ , , ] adDimensionArray = class1.GetMultiDimensionArray( iLength );
for ( int i = 0; i < iLength; i++ )
{
for ( int j = 0; j < iLength; j++ )
{
for ( int k = 0; k < iLength; k++ )
{
Console.Write( adDimensionArray[ i, j, k ] );
Console.Write( "\t" );
}
Console.Write( "\n" );
}
Console.Write( "\n" );
}
double dInput = 3.0;
double dOutput1 = 0;
double dOutput2 = 0;
double dReturn = class1.PassParameterByReference( dInput, ref dOutput1, ref dOutput2 );
Console.WriteLine( "Input: " + dInput.ToString() );
Console.WriteLine( "dOutput1: " + dOutput1.ToString() );
Console.WriteLine( "dOutput2: " + dOutput2.ToString() );
Console.WriteLine( "dReturn: " + dReturn.ToString() );
}