Posts Tagged C/C++/C#

Draw on stretched, zoomed, or centered images in PictureBox in C#

When I wrote an application, eDigitizer 2.0 and its new release eDigitizer 2.10,  that allows user to draw lines on images in the PictureBox control, I encountered a problem that lines or shapes I drew on the image are off the place, that is, not positioned in the place I clicked. The problem does not occur if I show images in “normal” SizeMode. I googled a long time and saw people were asking the very question again and again but not any useful solutions. Since the problem irritated me, I decided to write my own method to solve the problem.

The fact is the size of PictureBox control and the size of image are not same. We have to project the x,y coordination of the mouse click on PictureBox control to the x’,y’ coordination of the loaded image. For the different SizeMode type, the projection is different.

For the PictureBoxSizeMode.StretchImage mode, the loaded image is stretched to fill PictureBox control. The ratio to stretch image in the x axis is based on the width of the image and PictureBox control while the ratio to stretch image in the y axis is based on the height of the image and the PictureBox control. The two ratios are independent.

For the PictureBoxSizeMode.CenterImage mode, the center of the loaded iamge will overlap with the center of the PictureBox control. If the image is smaller than the PictureBox control, it will be inside the control. Otherwise, only the center potion with the same size as the control shows. There is no skew and distortion.

For the PictureBoxSizeMode.Zoom mode, it is a little bit complicated. The ratio to shrink or enlarge the image is same in both of the axes. We can get an x_ratio that is the ratio of width of the image and the control and y_ratio that is the ratio of height of the image and the control. The ratio to be used in the zoom is the larger one in the two ratios. If the x_ratio is the larger one, the image will fill the control in the x axis. Otherwise the image will file the control in the y axis. The tricky part is how to get the right projection in the direction where the image does not fill the control. We have to project the width or height of the image in the ratio first and then calculate the border space between the image and the control.

The above ideas were put into one method that needs three input arguments: the image object, and x and y value of the mouse click point in the control. The output is an array with two elements projected x and y values in the image object. The algorithm works well for images loaded in a PictureBox control. Here is the source code.

int [] xy_projection(Bitmap myBitmap2, int x, int y)
{
	int heightB = myBitmap2.Height;
	int heightP = pictureBoxBoard.Height;
	int widthB = myBitmap2.Width;
	int widthP = pictureBoxBoard.Width;
	double xRatio = (double) widthB / (double)widthP;
	double yRatio = (double) heightB / (double)heightP;
	int [] xy = new int[2];
	if (pictureBoxBoard.SizeMode == PictureBoxSizeMode.StretchImage)
	{
		xy[0] = (int) (x * xRatio);
		xy[1] = (int) (y * yRatio);
	}
	else if (pictureBoxBoard.SizeMode == PictureBoxSizeMode.CenterImage)
	{
		int borderHeight = (heightP -heightB) / 2;
		int borderWidth = (widthP - widthB) / 2;
		xy[0] = x - borderWidth;
		xy[1] = y - borderHeight;
	}
	else if (pictureBoxBoard.SizeMode == PictureBoxSizeMode.Zoom)
	{
		double ratio = xRatio;
		bool x_filled = true;
		if ( ratio < yRatio)
		{
			ratio = yRatio;
			x_filled = false;
		}
		if (x_filled)
		{
			heightB = (int) (heightB / ratio);
			int borderHeight = (heightP - heightB) / 2;
			xy[0] = (int) (x * ratio);
			xy[1] = (int) ((y - borderHeight) * ratio);
		}
		else
		{
			widthB = (int) (widthB / ratio);
			int borderWidth = (widthP - widthB) / 2;
			xy[0] =(int) ((x - borderWidth) * ratio);
			xy[1] =(int) (y * ratio);
		}
	}
	else
	{
		xy[0] = x;
		xy[1] = y;
	}
	return xy;
}

To draw on the image in the PictureBox control, you have to get the image from the control. Then generate a Graphics object from it. Now you can draw on the image based on mouse clicks. Whenever you get the mouse point x, y values, we have to use the above function to project the values to the image axes. To be nice, you have to release the memory that the Graphics object uses. In the following code snippet, we draw a cross at the mouse click location and connect the point with the previous mouse click point.

Color color = Color.Black;
Color veryTransparentColor = Color.FromArgb(77,color.R, color.G, color.B);
Bitmap myBitmap2 = (Bitmap)pictureBoxBoard.Image;
Graphics g = Graphics.FromImage(myBitmap2);

//Brush myBrush = new SolidBrush(color);
//g.DrawString(heightB.ToString()+","+widthB.ToString()+";"+heightP.ToString()+widthP.ToString(),this.Font, myBrush, mvPoint);

// draw a small cross
int penWidth = 2;
Pen myPen = new Pen(veryTransparentColor, penWidth);
int [] xy = xy_projection(myBitmap2, mvPoint.X, mvPoint.Y);
g.DrawLine(myPen, new Point(xy[0]-5,xy[1]), new Point(xy[0]+5,xy[1]));
g.DrawLine(myPen, new Point(xy[0],xy[1]-5), new Point(xy[0],xy[1]+5));

// connect two adjacent points if there are more than one points
// the position is not right.
if (myPoints.Count > 1)
{
	int myPos = myPoints.Count-1;
	int [] xy1 = xy_projection(myBitmap2, ((Point)myPoints[myPos-1]).X,((Point)myPoints[myPos-1]).Y);
	int [] xy2 = xy_projection(myBitmap2, ((Point)myPoints[myPos]).X,((Point)myPoints[myPos]).Y);
	g.DrawLine(myPen,xy1[0],xy1[1],xy2[0],xy2[1]);
}
pictureBoxBoard.Invalidate();
g.Dispose();
Share

Tags: , , , , , , , , , , , , ,

Use libcurl.net at C# project – a complete solution

Introduction

When I am working on TwitterGIFT project, I need find how to use Twitter API in my C# project. I know CURL is really good at Linux environment. My PERL script use it to access Twitter API functions. It is powerful and convenient and easy to use. How can I use it in my C# project? Through system calling. That will be pretty bad. I explore the curl’s official site and find out they provide library to different development environments. One of them is for .NET, which is what I am looking for. I download it and try hard to find how to use it. At the same time, I searched the internet to find some useful example. Yes, I found some thing and use them as my start point. Then I developed a complete solution for my C# project. I publish it here to share with developers worldwide.

Source code

/*
 * Author: Zhanshan Dong
 * Website: http://www.sunfinedata.com/
 * Date: 4/3/2009
 * Modified: 9/18/2009
 */

using System;
using SeasideResearch.LibCurlNet;
using System.IO;  

namespace TwitterGIFT
{
	/// 
	/// This is a complete C# class to utilize LibCurlNet
	/// You can use it in your project freely as long as 
	///    1) keep the identity of the class
	///    2) keep the authorization information
	///    3) use it in open source
	///    4) do not use it in commercial environment
	/// 
	public class GiftCURL
	{
		private StreamWriter giftWriter;
		private string outputFilename;
		private string username;
		private string password;

		public GiftCURL( string userName, string passWord)
		{
			username = userName;
			password = passWord;
		}
		
		private void giftWriterOpen() 
		{
			giftWriter = new StreamWriter(outputFilename);
		}
		
		private void giftWriterClose() 
		{
			giftWriter.Close();
		}

		private Int32 OnWriteData(Byte[] buf, Int32 size, Int32 nmemb, Object extraData)
		{
	        	giftWriter.Write(System.Text.Encoding.UTF8.GetString(buf));
	        	return size * nmemb;
		}

		public void DownloadURL(string url, string urlPostFields, string OutputFilename, bool isPost)
		{
			outputFilename = OutputFilename;
			if ( outputFilename != "") { giftWriterOpen(); }
			try 
			{
            	Curl.GlobalInit((int)CURLinitFlag.CURL_GLOBAL_ALL);
	            Easy easy = new Easy();
	            Easy.WriteFunction wf = new Easy.WriteFunction(OnWriteData);
	            easy.SetOpt(CURLoption.CURLOPT_WRITEFUNCTION, wf);
	            easy.SetOpt(CURLoption.CURLOPT_POST, isPost);
	            if (urlPostFields != "") 
	            {
	            	easy.SetOpt(CURLoption.CURLOPT_POST, true);
	            	easy.SetOpt(CURLoption.CURLOPT_POSTFIELDS,urlPostFields);
	            }
	            easy.SetOpt(CURLoption.CURLOPT_USERAGENT,
	                "Mozilla 4.0 (compatible; MSIE 6.0; Win32");
	            easy.SetOpt(CURLoption.CURLOPT_FOLLOWLOCATION, true);
	            if (url != "") { easy.SetOpt(CURLoption.CURLOPT_URL,url); }
	            if ((username !="") && (password != "")) 
	            {
	            	easy.SetOpt(CURLoption.CURLOPT_USERPWD,username + ":" +password);
	            }
	            easy.Perform();
	            easy.Cleanup();
	            Curl.GlobalCleanup();
	        }
	        catch(Exception ex) { }
			if ( outputFilename != "") { giftWriterClose(); }
		}
	}
}

Download

you can download the source code in file – GiftCURL.cs

Reference

Share

Tags: , , ,

A C# class to control Excel – A core class used in TWE 2.0

Introduction

This class was developed from the basic framework Vahe Karamian created in 2005. It is a complete solution to control Microsoft Excel from C#.Net. It allows you to create an Excel object and control a lot of the Excel functionalities such as getting worksheet information, extracting data from the worksheet given a range, and manipulating data in many ways. You can use this class freely in your C# project. If you find and fix bugs please write comments to this post. Read Karamian’s original article to find out how to use the code. You can download all source code in a zip file through the link at the end of the post.

Source code

using System;
using System.IO;
using System.Collections;
using System.Threading;
using Excel;
using System.Diagnostics;

namespace TWE
{
	/// <summary>
	/// Project:	A complete set of gadgets to control excel
	/// Author:		Vahe Karamian, Zhanshan Dong
	/// Date:		01/16/2006
	/// Modified:   09/13/2009
	/// Version:	0.5
	/// Description:	To create a class that includes most useful methods to handle Excel
	/// </summary>
	public class ZDExcel
	{
		private const int columnLimit = 255;
		private const int rowLimit = 65536;

		private Excel.Application	xlApp = null;
		private Excel.Workbooks		xlWorkbooks = null;
		private Excel.Workbook		xlWorkbook = null;
		private Excel.Sheets		xlSheets = null;
		private Excel.Worksheet		xlWorksheet = null;

		private static object zd_missing	= System.Reflection.Missing.Value;

		private static object zd_visible	= true;
		private static object zd_false		= false;
		private static object zd_true		= true;

		private bool zd_app_visible = false;
		private bool zd_app_running = false;

		private object	zd_filename;

		#region OPEN WORKBOOK VARIABLES
		private object zd_update_links					= 0;
		private object zd_read_only						= zd_true;
		private object zd_format							= 1;
		private object zd_password							= zd_missing;
		private object zd_write_res_password			= zd_missing;
		private object zd_ignore_read_only_recommend = zd_true;
		private object zd_origin							= zd_missing;
		private object zd_delimiter						= zd_missing;
		private object zd_editable							= zd_false;
		private object zd_notify							= zd_false;
		private object zd_converter						= zd_missing;
		private object zd_add_to_mru						= zd_false;
		private object zd_local								= zd_false;
		private object zd_corrupt_load					= zd_false;
		#endregion

		#region CLOSE WORKBOOK VARIABLES
		private object zd_save_changes	= zd_false;
		private object zd_route_workbook = zd_false;
		#endregion

		/// <summary>
		/// Vahe Karamian - 03/04/2005 - Excel Object Constructor.
		/// </summary>
		public ZDExcel() {}

		/// <summary>
		/// Vahe Karamian - 03/04/2005 - Excel Object Constructor
		/// visible is a parameter, either TRUE or FALSE, of type object.
		/// </summary>
		/// <param name="visible">Visible parameter, true for visible, false for non-visible</param>
		public ZDExcel(bool visible)
		{
			this.zd_app_visible = visible;
		}

		public int ColumnLimit
		{
			get
			{
			   return columnLimit;
			}
		}


		public int RowLimit
		{
			get
			{
			   return rowLimit;
			}
		}

		/// <summary>
		/// Zhanshan Dong - 01/17/2006 - Return the Excel.application object
		/// </summary>
		#region EXCEL APPLICATION
		public Excel.Application xlApplication
		{
			get
			{
				return xlApp;
			}
		}
		#endregion

		/// <summary>
		/// Vahe Karamian - 03/04/2005 - Start Excel Application
		/// Zhanshan Dong - 01/16/2006 - To avoid open more than one Excel window,
		/// the method first search for any running Excel window
		/// </summary>
		#region START EXCEL
		public void startExcel()
		{
    		this.zd_app_running = false;
			try
	    	{
		    	if (System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application") != null)
		    	{
		    		xlApp = (Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
		    		this.zd_app_running = true;
		    	//	return "Old";
		    	}
	    	}
	    	catch (Exception e) 
			{
				//return e.Message;
			}
			finally
			{
				if (this.xlApp == null)
				{
					this.xlApp = new Excel.ApplicationClass();
				}
			}
			// Make Excel Visible
			this.xlApp.Visible = zd_app_visible;
			//return "New";
		}
		#endregion

		/// <summary>
		/// Vahe Karamian - 03/23/2005 - Kill the current Excel Process
		/// Zhanshan Dong - 01/16/2006 - Modify the declaration of the method
		/// to assure the Excel windows closed completely
		/// </summary>
		#region STOP EXCEL
		public void stopExcel()
		{
			if( (this.xlApp != null) && (!this.zd_app_running) )
			{
				bool Changed = false;
				for (int i=0; i<this.xlApp.Workbooks.Count; i++)
				{
					Workbook mybook = this.xlApp.Workbooks.get_Item((object)(i+1));
					if (! mybook.Saved)
					{
						Changed = true;
					}
				}
				if (! Changed)
				{
					this.xlApp.Quit(); // this statement will make sure to close Excel window
					Process[] pProcess;
					pProcess = System.Diagnostics.Process.GetProcessesByName("Excel");
					pProcess[0].Kill();
				}
			}
		}
		#endregion

		/// <summary>
		/// Vahe Karamian - 03/09/2005 - Open File function for Excel 2003
		/// The following function will take in a filename, and a password
		/// associated, if needed, to open the file.
		/// </summary>
		/// <param name="fileName"></param>
		/// <param name="password"></param>
		#region OPEN EXCEL FILE
		public string OpenFile(string fileName, string password)
		{
			zd_filename = fileName;

			if( password.Length > 0 )
			{
				zd_password = password;
			}

			try
			{
				// Open a workbook in Excel
				this.xlWorkbook = this.xlApp.Workbooks.Open(
					fileName, zd_update_links, zd_read_only, zd_format, zd_password,
					zd_write_res_password, zd_ignore_read_only_recommend, zd_origin,
					zd_delimiter, zd_editable, zd_notify, zd_converter, zd_add_to_mru);
			 /*
				this.xlWorkbook = this.xlApp.Workbooks.Open(
					fileName, zd_update_links, zd_read_only, zd_format, zd_password,
					zd_write_res_password, zd_ignore_read_only_recommend, zd_origin,
					zd_delimiter, zd_editable, zd_notify, zd_converter, zd_add_to_mru,
					zd_local, zd_corrupt_load);
			*/
			}
			catch(Exception e)
			{
				this.CloseFile();
				return e.Message;
			}
			return "OK";
		}
		#endregion

		/// <summary>
		/// Vahe Karamian - 03/09/2005 - Close Excel file
		/// </summary>
		#region CLOSE EXCEL FILE
		public void CloseFile()
		{
			xlWorkbook.Close( zd_save_changes, zd_filename, zd_route_workbook );
		}
		#endregion

		/// <summary>
		/// Zhanshan Dong - 01/16/2006 - Get Excel Workbooks
		/// Get the collection of workbooks in the running Excel instance
		/// </summary>
		#region GET EXCEL WORKBOOKS
		public void GetBooks()
		{
			if( this.xlApp != null )
			{
				xlWorkbooks = xlApp.Workbooks;
			}
		}
		#endregion

		/// <summary>
		/// Zhanshan Dong - 01/16/2006 - Get an list of Excel workbook names
		/// </summary>
		#region GET A WORKBOOK LIST
		public string[] WorkbookList()
		{
			string [] arrayS = new string[xlWorkbooks.Count];
			if( this.xlWorkbooks != null )
			{
				for (int i =0; i<xlWorkbooks.Count; i++)
				{
					object j = i+1;
					Excel.Workbook mybook = ((Excel.Workbook)xlWorkbooks.get_Item(j));
					arrayS[i] = mybook.Name;
				}
			}
			return arrayS;
		}
		#endregion

		/// <summary>
		/// Zhanshan Dong - 01/16/2006 - Return a workbook object
		/// </summary>
		#region GET A WORKBOOK
		public Excel.Workbook GetABook(int Index)
		{
			object myIndex = new object();
			myIndex = (object)Index;
//			return ((Excel.Workbook)xlApp.Workbooks.get_Item((object)Index));
			return ((Excel.Workbook)xlApp.Workbooks.get_Item(myIndex));
		}
		#endregion

		/// <summary>
		/// Zhanshan Dong - 01/17/2006 - Find a workbook and return it if found
		/// </summary>
		/// <returns>Excel.Workbook</returns>
		#region FIND A WORKBOOK
		public Excel.Workbook FindWorkbook(string workbookName)
		{
			Excel.Workbook ABook = null;
			if( this.xlWorkbooks != null )
			{
				// Step thru the workbook collection and see if a sheet is available
				for( int i=1; i<=this.xlWorkbooks.Count; i++ )
				{
					ABook = (Excel.Workbook)xlWorkbooks.get_Item((object)i);
					if( ABook.Name.Equals(workbookName) )
					{
						return ABook;
					}
				}
			}
			return null;
		}
		#endregion

		/// <summary>
		/// Vahe Karamian - 03/20/2005 - Get Excel Sheets
		/// Get the collection of sheets in the workbook
		/// </summary>
		#region GET EXCEL SHEETS
		public void GetSheets()
		{
			if( this.xlWorkbook != null )
			{
				xlSheets = xlWorkbook.Worksheets;
			}
		}
		#endregion

		/// <summary>
		/// Zhanshan Dong - 01/16/2006 - Get a list of Excel worksheet name
		/// </summary>
		#region GET A WORKSHEET LIST
		public string[] SheetList()
		{
			string [] arrayS = new string[xlSheets.Count];
			if( this.xlSheets != null )
			{
				for (int i=0; i<xlSheets.Count; i++)
				{
					Excel.Worksheet mysheet = ((Excel.Worksheet)xlSheets.get_Item((object)(i+1)));
					arrayS[i] = mysheet.Name;
				}
			}
			return arrayS;
		}
		#endregion

		/// <summary>
		/// Zhanshan Dong - 01/16/2006 - Return a worksheet object
		/// </summary>
		#region GET A WORKSHEET
		public Excel.Worksheet GetASheet(int Index)
		{
			return ((Excel.Worksheet)xlSheets.get_Item((object)Index));
		}
		#endregion

		/// <summary>
		/// Vahe Karamian - 03/21/2005 - Find a worksheet, return TRUE if found
		/// </summary>
		/// <returns>bool</returns>
		#region ACTIVATE A WORKSHEET
		public bool ActivateWorksheet(string worksheetName)
		{
			bool SHEET_FOUND = false;

			if( this.xlSheets != null )
			{
				// Step thru the worksheet collection and see if ATP sheet is
				// available. If found return true;
				for( int i=1; i<=this.xlSheets.Count; i++ )
				{
					this.xlWorksheet = (Excel.Worksheet)xlSheets.get_Item((object)i);
					if( this.xlWorksheet.Name.Equals(worksheetName) )
					{
						this.xlWorksheet.Activate();
						SHEET_FOUND = true;
						return SHEET_FOUND;
					}
				}
			}
			return SHEET_FOUND;
		}
		#endregion

		/// <summary>
		/// Zhanshan Dong - 01/17/2006 - Find a worksheet and return it if found
		/// </summary>
		/// <returns>Excel.Worksheet</returns>
		#region FIND A WORKSHEET
		public Excel.Worksheet FindWorksheet(string worksheetName)
		{
			Excel.Worksheet ASheet = null;
			if( this.xlSheets != null )
			{
				// Step thru the worksheet collection and see if a sheet is available
				for( int i=1; i<=this.xlSheets.Count; i++ )
				{
					ASheet  = (Excel.Worksheet)xlSheets.get_Item((object)i);
					if( ASheet.Name.Equals(worksheetName) )
					{
						return ASheet;
					}
				}
			}
			return null;
		}
		#endregion

		/// <summary>
		/// Vahe Karamian - 03/22/2005 - Get Range from Worksheet
		/// Return content of range from the selected range
		/// </summary>
		/// <param name="range">Range parameter: Example, GetRange("A1:D10")</param>
		#region GET RANGE
		public string[] GetRange(string range)
		{
			Excel.Range workingRangeCells = xlWorksheet.get_Range(range,Type.Missing);
			//workingRangeCells.Select();
			System.Array array = (System.Array)workingRangeCells.Cells.Value2;
			string[] arrayS = this.ConvertToStringArray(array);
			return arrayS;
		}
		#endregion

		/// <summary>
		/// Vahe Karamian - 03/22/2005 - Convert To String Array
		/// Convert System.Array into string[]
		/// </summary>
		/// <param name="values">Values from range object</param>
		/// <returns>String[]</returns>
		#region CONVERT TO STRING ARRAY
		private string[] ConvertToStringArray(System.Array values)
		{
			string[] newArray = new string[values.Length];

			int index = 0;
			for ( int i = values.GetLowerBound(0); i <= values.GetUpperBound(0); i++ )
			{
				for ( int j = values.GetLowerBound(1); j <= values.GetUpperBound(1); j++ )
				{
					if(values.GetValue(i,j)==null)
					{
						newArray[index]="";
					}
					else
					{
						newArray[index]=(string)values.GetValue(i,j).ToString();
					}
					index++;
				}
			}
			return newArray;
		}
		#endregion

		/// <summary>
		/// Zhanshan Dong - 01/20/2006 - Get the dimension of the used range in a given sheet
		/// </summary>
		/// <param name="mySheet">A given worksheet</param>
		/// <returns>int []</returns>
		#region GET THE DIMENSION OF USED RAGNE
		public int[] GetUsedRangeDim(Excel.Worksheet mySheet)
		{
			int [] myDim = new int[4];
//			myDim[0] =(mySheet.UsedRange.Cells.Row>1)?
//								mySheet.UsedRange.Cells.Row-1:mySheet.UsedRange.Cells.Row;
//			myDim[1] = (mySheet.UsedRange.Cells.Column>1)?
//								mySheet.UsedRange.Cells.Column-1:mySheet.UsedRange.Cells.Column;
			myDim[0] = mySheet.UsedRange.Cells.Row;
			myDim[1] = mySheet.UsedRange.Cells.Column;
			myDim[2] = mySheet.UsedRange.Rows.Count;
			myDim[3] = mySheet.UsedRange.Columns.Count;
			return myDim;
		}
		#endregion

		/// <summary>
		/// Zhanshan Dong - 04/15/2006 - Get the dimension of a selected range in a given sheet
		/// </summary>
		/// <param name="mySheet">A given worksheet</param>
		/// <returns>int []</returns>
		#region GET THE DIMENSION OF THE SELECTED RANGE
		public int[] GetSelectedRangeDim(Excel.Worksheet mySheet)
		{
			Excel.Worksheet tWksht = (Excel.Worksheet)xlApplication.ActiveSheet;
			mySheet.Activate();
			Excel.Range mySelection = (Excel.Range)mySheet.Application.ActiveWindow.RangeSelection;
			int [] myDim = new int[4];
			int [] myUsedDim = new int[4];
			myUsedDim = GetUsedRangeDim(mySheet);
			int lastRow = (myUsedDim[0]+myUsedDim[2]-1);
			int lastColumn = (myUsedDim[1]+myUsedDim[3]-1);
			myDim[0] = mySelection.Cells.Row;
			myDim[1] = mySelection.Cells.Column;
			myDim[2] = mySelection.Rows.Count;
			myDim[3] = mySelection.Columns.Count;
			tWksht.Activate();
			// use used range dimension to check the boundaray of selected range
			// check if the selected cells is not in the used range
			// used range can be like D10:J20
			if (myDim[0]<myUsedDim[0])
			{
				if (myDim[0]+myDim[2]-1>myUsedDim[0])
				{
					myDim[0] = myUsedDim[0];
				}
				else
				{
					myDim[0] = -1;
				}

			}
			if (myDim[0]>lastRow)
			{
				myDim[0] = -1;
			}
			if (myDim[1]<myUsedDim[1])
			{
				if (myDim[1]+myDim[3]-1>myUsedDim[1])
				{
					myDim[1] = myUsedDim[1];
				}
				else
				{
					myDim[1] = -1;
				}

			}
			if (myDim[1]>lastColumn)
			{
				myDim[1] = -1;
			}
			// if selected number of rows is greater than the possible rows of the used range
			// let the number of selected rows equals to the number of rows in the used range
			if ((lastRow - myDim[0] + 1>0) && (lastRow - myDim[0] + 1 < mySelection.Rows.Count))
			{
				myDim[2] = lastRow - myDim[0] + 1;
			}
			// if selected number of columns is greater than the possible columns of the used range
			// let the number of selected columns equals to the number of columns in the used range
			if ((lastColumn - myDim[1]+1>0)&&(lastColumn - myDim[1]+1 < mySelection.Columns.Count))
			{
				myDim[3] = lastColumn - myDim[1]+1;
			}
			return myDim;
		}
		#endregion

		/// <summary>
		/// Zhanshan Dong - 04/17/2006 - Convert a number to letters for column head
		/// </summary>
		/// <param name="mySheet">A number</param>
		/// <returns>A string</returns>
		#region GET THE HEAD LETTERS OF A GIVEN COLUMN
		public string GetHeadString(int aNumber)
		{
			string myChars = "";
			int tens = aNumber / 26;
			int ones = aNumber % 26;
			if (ones==0)
			{
				tens--;
				ones = 26;
			}
			if (tens<1)
			{
				myChars = ((char)(64 + aNumber)).ToString();
			}
			else
			{
				myChars = ((char)(64 + tens)).ToString() + ((char)(64 + ones)).ToString();
			}
			return myChars;
		}
		#endregion

		/// <summary>
		/// Zhanshan Dong - 04/29/2006 - chech a sheet existing or not
		/// </summary>
		/// <param name="myBook">A workbook</param>
		/// <param name="mySheetName">A worksheet name</param>
		/// <returns>A boolean value</returns>
		#region Check if a sheet exists in the the given workbook
		public bool existingSheet(Excel.Workbook myBook, string mySheetName)
		{
			for (int i=0; i<myBook.Worksheets.Count; i++)
			{
				Excel.Worksheet mySheet = ((Excel.Worksheet)myBook.Worksheets.get_Item((object)(i+1)));
				if (String.Compare(mySheet.Name, mySheetName, true) == 0)
				{
					return true;
				}
			}
			return false;
		}
		#endregion

	}
}

Reference

How to automate Microsoft Excel from Microsoft Visual C# .NET
Automating MS Excel Using Visual Studio .NET
Table with Excel – TWE 2.0

Download the source code – zdexcel.zip

Share

Tags: , , ,

A web-based html page editor in C#/VB.Net

I wrote a web-based html page editor in C#/VB.Net a while ago when I used to use Windows IIS web server. The idea in the C#/VB.Net is still good. You may find it useful and borrow ideas from it. The C# code is more advanced than VB.NET code because it was developed from VB.Net code. I used them to generate Delphi Programming Technologies and Tips. Just want to share the code with friends.

Source code of htmlbuilder.cs

using System;
using System.IO;
using System.Text;
using System.Collections;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using Microsoft.VisualBasic;

public class HBPage : Page {
public DropDownList path;
public TextBox cssfile, jsfile, fname, title, ctext, chapter, page;
public LinkButton submit;
public Label result;
public RadioButton plaintext;
public HyperLink preview;

public void Page_Load(Object sender, EventArgs e) {

// Explicitly set the encoding to UTF-8.
Response.ContentEncoding = Encoding.UTF8;

if (IsPostBack==false) {
foreach (string subdirectory in Directory.GetDirectories(Server.MapPath("."))) {
string dirname;
int lastslash = subdirectory.LastIndexOf("\\");
dirname = subdirectory.Substring(lastslash+1);
path.Items.Add(new ListItem(dirname,dirname));
}
submit.Text="Save the current HTML file";
result.Text = "No file was saved yet.";
jsfile.Text = "../delphitips.js";
cssfile.Text = "../delphitips.css";
plaintext.Checked = true;
fname.Columns = 68;
cssfile.Columns = 68;
jsfile.Columns = 68;
title.Columns = 68;
ctext.Columns = 68;
ctext.Rows = 15;
preview.NavigateUrl = "";
preview.Text = "Preview";
}
}

public void submit_click(object sender, EventArgs e) {

string tempstr;
Encoding chnen = Encoding.GetEncoding(936);

if (fname.Text=="") preview.NavigateUrl = "";
if (ctext.Text != "") {
tempstr = "<html>" + "\n";
tempstr += "<head>" + "\n";
tempstr += "<meta http-equiv=Content-Type content=\"text/html; charset=gb2312\">" + "\n";
if (cssfile.Text != "") {
tempstr += "<link rel=\"stylesheet\" type=\"text/css\" href=\"" + cssfile.Text + "\">" + "\n";
}
if (jsfile.Text != "" ) {
tempstr += "<script language=\"javascript\" src=\"" + jsfile.Text + "\"></script>" + "\n";
}
tempstr += "<title>" + StrFilter(title.Text) + "</title>" + "\n";
tempstr += "</head>" + "\n";
tempstr += "<body>" + "\n";
tempstr += "<h2>" + StrFilter(title.Text) + "</h2>" + "\n";
if (plaintext.Checked) {
tempstr += StrFilter(ctext.Text);
}
else {
tempstr += ctext.Text;
}
tempstr += "<div class=\"footer\">" + "\n";
tempstr += "<script language=\"javascript\">nextpage("+chapter.Text+","+page.Text+");";
tempstr += "prevpage("+chapter.Text+","+page.Text+");chaptertoc("+chapter.Text+");booktoc();</script&ggt;" + "\n";
tempstr += "</div>" + "\n";
tempstr += "</body>" + "\n";
tempstr += "</html>" + "\n";
string whichfile = Server.MapPath(path.SelectedItem.Value + "/" + fname.Text);
//string whichfile = path.SelectedItem.Value + "/" + fname.Text;
FileStream fs = new FileStream(whichfile,FileMode.Create,FileAccess.Write);
StreamWriter f = new StreamWriter(fs,chnen);
f.WriteLine(tempstr);
f.Close();
f = null;
fs = null;

// midify the javascript file
whichfile = Server.MapPath("./delphitips.js");
fs = new FileStream(whichfile,FileMode.Open,FileAccess.Read);
StreamReader fr = new StreamReader(fs, chnen);
fr.BaseStream.Seek(0, SeekOrigin.Begin);
string chstr = "ch" + chapter.Text + "toc";
string temp = "";
bool chfound,chend;
chfound = false;
chend = false;
while (fr.Peek() > -1) {
tempstr = fr.ReadLine();
if (tempstr.IndexOf(chstr)>0) { chfound = true; }
if (chfound) {
if ( ! chend ) {
if ((tempstr.IndexOf("\"")>0) & !(tempstr.IndexOf("\",")>0)) {
tempstr += ",\r\n" + "\t\"" + fname.Text + "::" + title.Text + "\"";
chend = true;
}
}
}
temp += tempstr +"\r\n";
}
fr.Close();
fr = null;
fs = new FileStream(whichfile,FileMode.Create,FileAccess.Write);
StreamWriter fw = new StreamWriter(fs,chnen);
fw.WriteLine(temp);
fw.Close();
fw = null;
fs = null;
preview.NavigateUrl = path.SelectedItem.Value + "/" + fname.Text;
result.Text = "The HTML file, " + fname.Text + " ,was saved.";
fname.Text = "";
ctext.Text = "";
title.Text = "";
page.Text = (double.Parse(page.Text) + 1).ToString();
}
}

private string StrFilter(string AStr) {
string TempStr;
TempStr = AStr;
TempStr = TempStr.Replace("'", "&#39;");
TempStr = TempStr.Replace("\"", "&quot;");
TempStr = TempStr.Replace("<", "&lt;");
TempStr = TempStr.Replace("$gt;", "&gt;");
TempStr = TempStr.Replace("\n","
");
return TempStr;
}
}

You can download the APSX and C#/VB.NET code here – htmlbuilder.

Share

Tags: , , , ,

Create PowerPoint slide in C#

There are situations we need control MS Office components in our program, for example, manipulate data in Excel workbook, generate PowerPoint slides, intracte with Access database etc. In this article, I will provide detail information about how to control PowerPoint in C# program.

First of all, how can use use MS Office components in our standalone program in general? Since MS Office provide Office Primary Interop Assemblies, for example, Microsoft.Office.Interop.Excel and Microsoft.Office.Interop.PowerPoint. In you program that intends to control MS Office components, you have to add reference to these interop assemblies. To contol MS PowerPoint, you need add a reference pointing to Microsoft.Office.Interop.PowerPoint. You can use Add Reference function the GUI environment to achieve this.

The following code snippets provide some methods to control PowerPoint, mainly create new slides automatically. It is a method in a large program and is not a generic procedure. You can use ideas and methods presented in the code to generate yours.

Code snippet

private void CreatePresentation()
{
	string BasePath = Path.GetDirectoryName(myFilename) + "\\";
	string BaseFilename = "";

	String strTemplate = BasePath + "Calendar.ppt";
	//bool bAssistantOn;

	PowerPoint.Application objApp;
	PowerPoint.Presentations objPresSet;
	PowerPoint._Presentation objPres;
	PowerPoint.Slides objSlides;
	PowerPoint._Slide objSlide;
	PowerPoint.TextRange objTextRng;

	//Create a new presentation based on a template.
	objApp = new PowerPoint.Application();
	objApp.Visible = MsoTriState.msoTrue;
	objPresSet = objApp.Presentations;
	objPres = objPresSet.Open(strTemplate, 
		MsoTriState.msoFalse, MsoTriState.msoTrue, MsoTriState.msoTrue);
	objSlides = objPres.Slides;

	//Build Slide #1:
	//Add text to the slide, change the font and insert/position a 
	//picture on the first slide.
	objSlide = objSlides.Add(1,PowerPoint.PpSlideLayout.ppLayoutTitleOnly);
	objTextRng = objSlide.Shapes[1].TextFrame.TextRange;
	objTextRng.Text = "Remote sensing calendar";
	objTextRng.Font.Name = "Comic Sans MS";
	objTextRng.Font.Size = 48;

	// insert a PowerPoint table
	// use data from a file
	PowerPoint.Table objTable = null;
	using (StreamReader sr= new StreamReader("summary.csv"))
	{
		int nLine = 1;
		int nStartLine = 0;
		while (!sr.EndOfStream)
		{
			string line = sr.ReadLine();
			if (line.Trim() == "")
			{
				if (nStartLine == 0) 
				{
					nStartLine = nLine;
					objTable= objSlide.Shapes.AddTable(nStartLine-1,9,36,138,648,294).Table;
				}
				else
				{
					break;
				}
			}
			if ((nStartLine > 0) && (nLine>nStartLine))
			{
				string [] cells = line.Split(',');
				for (int i=1; i<=cells.Length; i++)
				{
					int k = i;
					if (i>1) k = i+2;
					objTable.Cell(nLine-nStartLine,k).Shape.TextFrame.TextRange.Text = cells[i-1];
					objTable.Cell(nLine-nStartLine,k).Shape.TextFrame.TextRange.Font.Size = 12;
				}
			}
			nLine++;
		}
	}

	// build more slides
	// add pictures to the slides
	for (int i=0; i=1) System.Threading.Thread.Sleep(100);

//Reenable Office Assisant, if it was on:
if(bAssistantOn)
{
	objApp.Assistant.On = true;
	objApp.Assistant.Visible = false;
}
Share

Tags: , ,