You are on page 1of 394

Documents downloaded from www.funducode.com Article: .C# - The whole new way of programming...

If you are a C++ or a Java programmer you would find lot of things similar when you take a first look at C# code. However, apart from the initial similarity you will find C# a lot easier than C++ and Java. It offers simplicity of Visual Basic, power of C++ and platform independence of Java, all bundled into one language. The highlighting features of C# are as follows: a. b. c. d. e. Full support for object-oriented programming In-built support for automatic generation of XML documentation. Automatic cleanup of dynamically created memory. Access to .Net class library as well as Windows API. Can be used to create a ASP.Net dynamic web pages.

Most of these features are available on VB.Net as well as VC++.Net. However, since C# is designed from the start to work with .Net, it uses .Net features with ease and efficiency that would be found wanting in VB.Net and VC++.Net. C# has been developed by a team led by Anders Hejlsberg who was also the leader of the J++ team. Hence you will find the design and syntax of C# much similar to Java. However, as of now Java has one strong advantage over C#-platform independence. The same Java code can be executed on any platform that has a Java Runtime (JVM) implementation. Since JVM's are already in existence for most major platforms Java is truly portable today. Same is not true about C#-at least not as of now. In contrast, C# has two advantages over Java. These are as under: a. C# supports operator overloading. If required C# programs can use pointers by enclosing them within 'unsafe' blocks. b. C# can interoperate with code written in other .Net languages. Without much ado lets get on with C# programming. Here we go The First C# Program All that you need to program in C# is Microsoft VisualStudio.Net Beta 2, .Net SDK Beta 2. (These you can either download from msdn.microsoft.com or you can get it along with your MSDN subscription.) You need to install it on a machine running under Windows 98, Windows 2000 or Windows XP. namespace Simple { using System ; class Class1 { static void Main ( string[ ] args ) { Console.WriteLine ( "Hello C#" ) ; } } } Before we understand how the program works, let us first see the steps involved in creating it.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


a. Start Microsoft Visual Studio.NET 7.0 from Start | Program | Microsoft Visual Studio.NET 7.0 menu option. b. Create a new C# project from File | New | Project menu option. A New Project dialog as shown in the following figure would appear.

c. From the New Project dialog box select project type as Visual C# Projects. d. Select Console Application from the list of Templates. e. Select a location (directory/folder) where this project should get saved. Give name to the project as Simple. Click on OK button. f. A Class1.cs file would get created. This file would contain skeleton program. The VisualStudio.Net environment automatically creates this program. It contains a class called Class1 containing the function Main( ) . g. Add the following line to the skeleton code. Console.WriteLine ( "Hello C#" ) ; h. To compile and execute the program use Ctrl + F5. On execution the message "Hello C#" would be displayed on the screen. Now a few useful tips about the program a. C# is a pure object oriented language. It doesn't allow global variables or functions. All variables and functions should be defined inside a class. b. All C# programs start from Main( ). Since Main( ) cannot be global it is enclosed in a class called Class1. void before the word Main specifies that Main( ) does not return anything. The static modifier used with Main( ) indicates that it can be called without creating an object of the class Class1. c. string is a data type used to store strings. string[ ] represents an array of strings. Thus args is an array of strings. It stores the command line parameters, if specified by the user while executing the program. d. To display anything on the screen we need to call the WriteLine( ) function. To this function we can pass strings, integers, floats, etc. Since the WriteLine( ) function belongs to the Console class we have to call it using Console.WriteLine( ). A function within the class can be accessed using the '.' Operator. Console class is used to perform input from keyboard and output to screen. e. In C#, namespaces provide a way to group classes. Console class belongs to the System namespace. Hence to be able to use the Console class we need to import it from the System namespace. This has been done through the using System statement. The way the Console class has been enclosed within the System namespace, likewise

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


our class Class1 has been enclosed in the Simple namespace. The namespace concept is similar to packages in Java. C# is a case-sensitive language. The naming convention used by .NET is that class names would start with a capital letter. If a single class name contains multiple words, each word's starting letter would be capital. The same applies to function names also. All keywords are in small case.

f.

Let us now write another program that would show how to receive input from the keyboard. Here it is namespace Simple { using System ; class Class1 { static void Main ( string[ ] args ) { string s ; s = Console.ReadLine( ) ; Console.WriteLine ( s ) ; } } } To receive input from the keyboard we have used the ReadLine( ) function. This function returns a string. This function is also a static member function of the Console class, hence we have called it using Console.ReadLine( ). Note that C# does not have its own class library. It uses the class library provided by the .Net Framework. The .Net Framework provides the class library in the form of .Net Base Classes. Thus Console is a .Net base class. This class can be used by any other .Net-aware language. Command-line Arguments Instead of receiving input from keyboard we may want to supply input to it in the form of command-line arguments. Following program shows how to receive these arguments and print them out. using System; namespace cmdline { class Class1 { static void Main ( string[ ] args ) { foreach ( string str in args ) { Console.WriteLine ( str ) ; } } } }

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


To supply command-line arguments we have to open the properties window of the project from the "Solution Explorer". A window will pop up. This window consists of properties that appear on the left pane of the window. We have to select "Configuration Properties" from it. As soon as we select this it expands into a tree with more underlying properties. Now we have to select the "Debugging" property. On doing this all fields related to the "Debugging" property appear on the right pane of the window. We then need to fill in the command-line arguments in the "Command Line Arguments" option. Press OK to finalize the option. In this program we have set commandline arguments as Nagpur Mumbai Bangalore. On executing the program it would output these arguments. We can run this program from the Run dialog box that appears when we select 'Start | Run' option. To do so we must specify the command line arguments after the name of the EXE file. FileHandling .Net offers two classes for file operations-the File class and the FileInfo class. Both these classes are defined in System.IO namespace. The File class is derived from the Object class. It contains static methods and never gets instantiated. The FileInfo class is derived from FileSystemInfo class, which represents the file system. We can instantiate this class. The hierarchy of these classes is shown in the following figure:

Let us now understand the objective of creating two classes for file operations. The static functions of the File class can be called to perform various file operations without creating an object. This avoids the overhead of instantiating objects. As against this, to call the member functions of the FileInfo class it is necessary to create an object. This is because FileInfo class contains non-static member functions. So if we wish to carry out a single operation on the file we can use the File class, avoiding the object creation overheads thereby. On the other hand if we wish to carry out multiple operations on the file (with the preservation of state of the object) we can use the FileInfo class. When we create a FileInfo object all the relevant information like size, attributes, authentication permissions are read in through the constructor. This information is then shared by other functions while carrying out multiple operations. If we use the File class for carrying our multiple operations then this information will have to be read in each time we perform a new operation. Also, at times we are required to pass the file information to another application. In such a case it is necessary to create a FileInfo object and then pass its state to other application (this process is known as marshalling). Marshalling of object is possible only if the class in derived from the MarshalByRefObject class. Since the object of the File class cannot be created it has not been inherited from MarshalByRefObject class. Reading And Writing To A Text File

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


In the following program we will perform reading and writing operations on a text file. We plan to write a few strings to a text file and read the strings back from it. namespace fileoperation { using System ; using System.IO ; class Class1 { static void Main ( string[ ] args) { string str1 = "The .NET Revolution" ; string str2 = "Long live C# " ; string str3 = "Targeting the internet" ; StreamWriter sw = new StreamWriter ( "C:\\file2.txt", false ) ; sw.WriteLine ( str1 ) ; sw.WriteLine ( str2 ) ; sw.WriteLine ( str3 ) ; sw.Close( ) ; StreamReader sr = new StreamReader ( @"C:\file2.txt" ) ; // @ ensures that we don't have to use C:\\ string str ; do { str = sr.ReadLine( ) ; Console.WriteLine( str ) ; } while ( str != null ) ; sr.Close( ) ; } } } To understand this program we must first know what a Stream is. A stream is a sequence of bytes traveling from source to destination or traveling over a communication link. Two basic types of streams exist: Input stream and Output stream. An input stream is used for read operations while an output stream is used for write operations. The System.IO namespace contains functions to perform input and output operations. Here we have created a new StreamWriter object and have passed 'false' to the constructor of the StreamWriter class along with the path. Here 'false' specifies that if the file exists, it should be overwritten. If we pass a true and if the file exists, it should be appended. In either case if the file does not exist, a new file is created. The WriteLine( ) member function of the StreamWriter class is overloaded to write out entities like object, boolean, int, etc. to a file. Next, we have used a StreamReader class to perform the reading operation. Its ReadLine( ) function reads a line of characters from the current stream and returns the data as a string. This process is repeated till the end of file is reached. The hierarchy of stream I/O classes is shown in the following figure:

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

We have taken the first few toddling steps in C#. Imbibe the matter presented here. We would take a peek below the hood of C# and explore its internal working next time.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Article: .C# - WinForms, Win App development made simple...


For building Windows applications the .NET Framework provides two things-classes for managing the user-interface controls and an Integrated Development Environment (IDE) to design the Windows applications visually. Any window displayed in an application is created as a form. WinForms is a programming model used for building Windows applications through a form designer. Using the form designer we can create standard windows, borderless windows, MDIs, dialog boxes, etc. We can add controls, set properties, create event handlers, and add programming logic to our form. A separate class governs each control that is added to a form. All the control classes are derived from the Control class. The classes are present in the System.Windows.Forms namespace. The classes remain same no matter which .NET language we use. If you have used the Resource Editor of VB or VC++ you will have to spend little time to get familiar with the way the IDE works. You simply have to drag controls from a toolbox and drop them onto a form. Once inserted you can set the properties of the form as well as the controls using the IDE. The IDE generates only source code and not resource files as in VC++. The basic program to create a form looks like this: using System; using System.Window.Forms public class myform : Form { public myform ( ) { } static void Main ( ) { myform a = new myform( ) ; Application.Run ( a ) ; } } In Main( ) the Run( ) method of the Application class is called. To this method we have passed an instance of the form. The Application class provides static methods and properties to manage an application, such as methods to start and stop an application, to process Windows messages, and properties to get information about an application. The Run( ) method starts a standard application message loop on the current thread. If we execute this program it would merely show a blank form. Let us now see how to attach a menu to this blank form. Carry out the following steps: a. Drag in the 'MainMenu' control from the toolbox and release it on the blank form. b. Click on the control and type the menu item name as 'File'. c. Add the items 'New', 'Open', 'Save', 'Generate' and 'Exit' to the 'File' menu in a similar manner. The resultant form is shown in the following figure.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Each menu item is governed by a control variable of the type MenuItem. We can change the names of these variables through the 'Properties' window. For the program that follows we have used the names as filemenu that will hold the other menu items, newmenu, openmenu, savemenu, generatemenu and exitmenu. Let us now decide what should happen when these menu items are selected. When we select the 'Generate' menu item, shapes like rectangle, ellipse and line should get generated at random and in random colors. On selecting the 'Save' menu item these shapes should be saved in a file. We must be able to load this file and display the shapes again. This would be achieved through the 'Open' menu item. When we click the 'New' menu item the earlier shapes should vanish and we must get a new form to draw new shapes. While saving the shapes we should not save the image of the shape. Instead we should save the relevant information of the shape using which we should be able to regenerate the shape again when the file is loaded. This means we must write the object onto the disk while saving it and load it back while opening the file. This process of writing the state of an object is called serialization and reading it back is called deserialization. To make all these activities to happen we need to add handlers for these menu items. The Windows Forms programming model is event based. When we click on a menu item it raises an event. In order to handle an event, our application should register an event-handling method. For adding these handlers click on the menu item for which we wish to add the handler. Then go to the 'Properties' window and select the 'Events' tab (shown by a yellow lightening icon). From the list of events select 'Click'. As a result an event handler called say, openmenu_Click( ) would get added to our code. On similar lines rest of the handlers can be added. All these handlers will get added to the Form1 class, which is the default class name. Before we add code to these menu handlers let us insert four new classes. The first amongst these is an abstract class called shapes. In this class we will store the color of the shape in variables r, g, b, representing red, green and blue components of the color. The other three classes that we would add are line, rectangle and ellipse. These classes are derived from the shapes class. In these classes we will store the coordinates of the shapes. Each of these three classes would have a constructor to initialize the data members. Each class would have a function draw( ) which would contain the logic to draw the respective shape. This function would be declared as abstract in the base class shapes. To make all the classes capable of carrying

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


out serialization/desrialization we need to add the attribute Serializable as shown in the program listing given below. using System ; using System.Drawing ; using System.Collections ; using System.ComponentModel ; using System.Windows.Forms ; using System.Data ; using System.IO ; using System.Threading ; using System.Runtime.Serialization ; using System.Runtime.Serialization.Formatters.Binary; namespace myapp { [Serializable] abstract class shapes { protected int r, g, b ; Random rd = new Random( ) ; public shapes( ) { r = rd.Next ( 255 ) ; g = rd.Next ( 255 ) ; b = rd.Next ( 255 ) ; // put the thread to sleep for next 5 // milliseconds to ensure proper color // generation Thread.Sleep ( 5 ) ; } public abstract void draw ( Graphics g ) ; } [Serializable] class line : shapes { int x1, y1 ; int x2, y2 ; public line ( int i, int j, int k, int l ) { x1 = i ; y1 = j ; x2 = k ; y2 = l ; } public override void draw ( Graphics gg ) { Color c = Color.FromArgb ( r, g, b ) ; Pen p = new Pen ( c, 4 ) ; gg.DrawLine ( p, x1, y1, x2, y2 ) ; } } [Serializable]

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


class rectangle : shapes { int x1, y1 ; int width, height ; public rectangle ( int x, int y, int h, int w ) { x1 = x ; y1 = y ; height = h ; width = w ; } public override void draw ( Graphics gg ) { Color c = Color.FromArgb ( r, g, b ) ; Pen p = new Pen ( c, 4 ) ; gg.DrawRectangle ( p, x1, y1, width, height ) ; } } [Serializable] class ellipse : shapes { int x1, y1 ; int width, height ; public ellipse ( int x, int y, int h, int w ) { x1 = x ; y1 = y ; height = h ; width = w ; } public override void draw ( Graphics gg ) { Color c = Color.FromArgb ( r, g, b ) ; Pen p = new Pen ( c, 4 ) ; gg.DrawEllipse ( p, x1, y1, width, height ) ; } } public class Form1 : System.Windows.Forms.Form { private System.Windows.Forms.MainMenu mainMenu1 ; private System.Windows.Forms.MenuItem filemenu ; private System.Windows.Forms.MenuItem newmenu ; private System.Windows.Forms.MenuItem openmenu ; private System.Windows.Forms.MenuItem savemenu ; private System.Windows.Forms.MenuItem generatemenu ; private System.Windows.Forms.MenuItem exitmenu ; private System.ComponentModel.Container

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


components = null ; ArrayList s = new ArrayList( ) ; BinaryFormatter b = new BinaryFormatter ( ) ; public Form1( ) { InitializeComponent( ) ; } protected override void Dispose ( bool disposing ) { if( disposing ) { if ( components != null ) { components.Dispose( ) ; } } base.Dispose( disposing ) ; } [STAThread] static void Main( ) { Application.Run ( new Form1 ( ) ) ; } private void openmenu_Click ( object sender, System.EventArgs e ) { OpenFileDialog od = new OpenFileDialog( ) ; od.Filter = "dat files ( *.dat )|*.dat" ; if ( od.ShowDialog( ) == DialogResult.OK ) { FileInfo f=new FileInfo ( od.FileName); Stream st = f.Open ( FileMode.Open ); while ( st.Position != st.Length ) s.Add ( b.Deserialize ( st ) ) ; st.Close ( ) ; } Invalidate( ) ; } private void savemenu_Click ( object sender, System.EventArgs e ) { SaveFileDialog sd = new SaveFileDialog( ); sd.Filter = "dat files ( *.dat ) | *.dat" ; if ( sd.ShowDialog( ) == DialogResult.OK ) { FileInfo f = new FileInfo(sd.FileName); Stream st = f.Open ( FileMode.Create, FileAccess.ReadWrite ) ; foreach ( shapes ss in s ) b.Serialize ( st, ss ) ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

st.Close ( ) ; } } private void generatemenu_Click ( object sender, System.EventArgs e ) { Size sz = ClientSize ; Random rd = new Random( ) ; for ( int i = 0 ; i < 10 ; i++ ) { int shapeno = rd.Next ( 3 ) ; int x1 = rd.Next ( sz.Width ) ; int y1 = rd.Next ( sz.Height ) ; int x2 = rd.Next ( sz.Height - y1 ) ; int y2 = rd.Next ( sz.Width - x1 ) ; switch ( shapeno ) { case 0: s.Add ( new line ( x1, y1, x2, y2 ) ) ; break ; case 1: s.Add ( new rectangle ( x1, y1, x2, y2 ) ) ; break ; case 2: s.Add ( new ellipse ( x1, y1, x2, y2 ) ) ; break ; } } Invalidate( ) ; } private void exitmenu_Click ( object sender, System.EventArgs e ) { Dispose( ) ; } private void Form1_Paint ( object sender, System.Windows.Forms.PaintEventArgs e ) { Graphics g = e.Graphics ; foreach ( shapes ss in s ) ss.draw ( g ) ; } private void newmenu_Click ( object sender, System.EventArgs e ) { s.Clear( ) ; Invalidate( ) ; } } }

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


When we click the 'Generate' menu item its handler gets called. In this handler an object of the Random class is created. The Next( ) method of this class generates a positive random number less than the specified number passed to it. We have used this function to not only decide which shape should be generated but also the coordinates of this shape. Using these coordinates we have created an object of rectangle, ellipse or line class. While creating these objects the constructors of the respective classed get called. Since all these classes are derived from the shapes class, firstly the base class constructor gets called. This constructor selects a random color. The references of objects of line, rectangle and ellipse are stored using a collection class called ArrayList. The object s of this class now consists of references of objects of the line, rectangle and ellipse classes. As these classes are derived from shapes, it is perfectly legitimate for a reference to shapes to be set up to point to either shapes or one of its derived classes. Next we have called the Invalidate( ) method which results in the Form1_Paint( ) method getting called. Here we have collected back each reference from the array s into a reference ss of type shapes. Using this reference it has then called the draw( ) method. Depending upon which (line, rectangle or ellipse) reference is present in ss the draw( ) function of that class gets called. The resulting form is shown below.

If we wish to save the file we can click on 'Save' menu item. When we do so savemenu_Click( ) gets called. We have created an object of the SaveFileDialog class and used a "*.dat" filter for it. When we type in a file name and click Ok, a FileInfo object gets created with the selected name. The Open( ) function returns a Stream object associated with the file. We have collected it in a Stream reference. We have used the BinaryFormatter object to serialize the objects. The BinaryFormatter serializes and deserializes an object, in binary format. We have added a BinaryFormatter object b to our class. The Serialize( ) method of this class serializes the object to the given stream. After serializing all the elements of the array we have closed the stream using the Close( ) method. When we click 'Open' menu item an OpenFileDialog is popped with the appropriate filter. Here also we have created a FileInfo object and collected the corresponding Stream of the specified file. Next we have used a while loop to deserialize the objects until the end of stream is reached. The Deserialize( ) method deserializes the specified stream into an object. We have collected

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


these objects into our array, closed the stream and called Invalidate( ) function for painting these shapes. When we click 'New' menu item the array is cleared by deleting all the elements in the array. After this we have called Invalidate( ). This time the method Form1_Paint( ) draws nothing as the array is empty, thereby resulting a clean form. On clicking the 'Exit' menu item the Dispose( ) method gets called and the form is disposed.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

The earliest form of reuse was in the form of Static Libraries. These libraries contained object code of functions. During linking the object code of the library functions (usually stored in .Lib file(s)) was linked with the object code of the program calling those functions to form an executable file. The linking phase used to precede execution. This way the library functions could be reused by different applications calling them. This however led to wastage of storage space as the object code from the function library used to get replicated into every application using it. This is shown in Figure 1.

Figure 1 In multitasking environments if two applications are running in memory each calling the same library function then two copies of the same function would be running in two different processes. This led to wastage of precious memory space. Also if a bug was found in the library functions the library as well as the client program using it had to be re-compiled and re-distributed. A recipe for disaster for sure! To avoid the wastage of memory and disk space Microsoft suggested the concept of Dynamically Linked Libraries (DLLs). Functions from these libraries never became part of an application trying to call them. Instead they used to get linked with the applications calling them at run-time. Moreover, multiple applications calling them used to share the same copy of the library function present in memory. A developer could simply place the DLL in Windows directory, Windows\System directory or in the same directory as the EXE file using that DLL and then rely on the operating system to do the linking at run-time. This to begin with was a welcome change from the static libraries of the past. However, as programmer's started building DLLs they realized that the concept though apparently promising is infested with several problems listed below: Name mangling - To permit function overloading C++ compilers mangle (decorate) the name of each function called/defined in the program. Since the C++ language doesn't lay down any rules about how name mangling should be done, each compiler writer adopted his own strategy to

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


create mangled names. As a result, if one is to load the DLL explicitly as shown in the following code it was difficult to mention the mangled name. HMODULE h = :: LoadLibrary ( "myfunctions.dll" ) ; fptr = getProcAddress ( h, "mangled function name" ) ; // call the function using the function pointer fptr Thus the DLL created using one C++ compiler was not of much use to another C++ program that is compiled through another compiler. As a remedy to this it was suggested that we should use ordinal numbers in place of function names. Easier said than done! Ask yourself ids of how many of your co-employees you remember and you would get the answer why this scheme was not practical. Cross-Language Usage - Instead of storing exported functions we can create a DLL that would hold a C++ class. But this class is of little use to a C programmer (as C doesn't understand a class) or to a Java programmer (as Java doesn't understand the C++ syntax). Thus a crosslanguage usage was a no-no in DLLs. DLL Hell - Imagine a DLL containing some classes. Over a period of time we might be required to change the signature of the methods present in classes for implementing additional functionality. If we create this DLL and overwrite the existing DLL with the new one then the clients using the older version of the DLL would break. To avoid this we need to maintain both the DLLs leading to versioning problems. Location Transparency - DLLs did not offer location transparency, as the clients using the DLL were not independent of the path where the DLL was stored. Component Object Model Component software is a paradigm for designing and implementing an application by putting together independent pieces of software instead of writing one big monolithic application. COM components have unique characteristics that make them very attractive as building blocks for larger applications. They can be distributed either as DLLs or as EXEs. Clients can bind to the components at run-time and don't have to be recompiled due to any upgrades to the components. The components can be transparently relocated on a remote computer without affecting the clients i.e. local and remote components are treated in the same manner. This makes distributed computing very easy. The components can be written in any programming language as long as they follow a standard memory layout prescribed by the COM specifications. Additionally COM is object-oriented. COM components along-with COM interfaces support the concept of encapsulation and polymorphism. These smaller units with well-defined behavior can be reused across any language. Thus a COM component written in VisualBasic could be reused by a Visual C++ client and vice versa. COM imposed a binary standard. Under this standard, components communicated with each other via interfaces. COM identified components via Globally Unique identifiers (CLSIDs or GUIDs). Components were registered in the system registry. The benefit of registering was that it was very easy to see what components were available on one machine. With COM it became easy to write a component in any of the languages supporting COM and to call it from other languages. But this ease was topped up with complexity. COM was difficult to learn. Moreover storing information about all components in the registry made the process of installing software quite complex. Side-By-Side

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Windows 2000 introduced a feature called side-by-side that lets us install DLLs in the application's directory. We can install two versions of the same DLL in a system. Applications are then free to use the specific version for which they were designed and tested. This way different applications can use different versions on the same system. This arrangement allows developers to build and deploy more reliable applications because developers are able to specify the version they will use for their application, independent of other applications on the system. However, the down side of this arrangement is that un-installation of these versions becomes complicated. Assemblies If an application is to use a COM component it needs the methods and properties stored in COM component, the type library information and the registry entry of the component. If for any reason any of these is unavailable the component is rendered unusable. Let us now see how .Net overcomes this problem using Assemblies. Assemblies is the .NET's approach to code reuse. It has taken some concepts from its predecessors, namely, DLLs and COM/COM+. Any .Net code on compilation is stored in an Assembly. In addition to the IL code an assembly also contains metadata that describes the assembly as well as any resources that are used by the IL code.

Figure 2 The metadata include the types (classes, methods and properties) exported from the assembly and a manifest. A manifest is a data structure. It serves the same purpose as the type library and associated registry entries do for a COM component. Manifest contains more information than a type library. The details of the manifest structure would be discussed in the next article. Assemblies can be loaded using the side-by-side technique. This means a different version of the same assembly can be used inside a single process. Assemblies support Zero-impact installations. Installations can be as easy as copying the files that belong to an assembly. An assembly may represent one file or might be spread across several files. Shared and Private Assemblies There are two types of assemblies available: private assemblies and shared assemblies. A private assembly is used by only one application while a shared assembly is shared amongst different applications. By default when we compile a C# program, the assembly produced will be a private assembly. This assembly (DLL/EXE) should be placed in the same folder as the calling application. With a private assembly it's not necessary to think about naming conflicts with other classes or versioning problems because each application has its own copy of the assembly.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


In shared assemblies we must be careful that the assembly must be unique, and therefore, have a unique name (called strong name). Building Private Assemblies Now we will see how to build a private assembly. We plan to write a class library consisting of a function called display( ). We will call this function in a client program, which we will create later. To build a library start VisualStudio.NET and create a Visual C# project with template type as 'Class Library'. Name the project as fontassembly. By default the assembly created for this project would be private. Add the following code to the Class1.cs file. using System ; using System.Drawing ; using System.Windows.Forms ; namespace fontassembly { public class mytext { public void display ( Form fr, String s, Color c, String fname, int size, Point pt ) { Graphics g = fr.CreateGraphics( ); Font myfont = new Font ( fname, size ) ; SolidBrush mybrush = new SolidBrush (c); g.DrawString ( s, myfont, mybrush, pt ) ; } } } The display( ) function simply draws text with the specified Font and Brush. On building the project a fontassembly.dll file would get created in the fontassembly\bin\Debug subfolder. Building the client Let us now build a client that would use the private assembly that we have created. We plan to make a from-based client. To create the client select a 'Windows Application' project. When we click on the form some text should be displayed at the position where we click. This can be achieved by calling the display( ) function from fontassembly.dll in the myform_MouseDown( ) handler. The client code is shown below: using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; using fontassembly ; // to be added namespace fontclient {

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


public class myform : System.Windows.Forms.Form { private System.ComponentModel.Container components = null; mytext t = new mytext( ) ; public myform( ) { InitializeComponent( ) ; } protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose( ) ; } } base.Dispose( disposing ); } [STAThread] static void Main( ) { Application.Run(new myform( ) ) ; } private void myform_MouseDown ( object sender, System.Windows.Forms.MouseEventArgs e ) { if ( e.Button == MouseButtons.Left ) { Point pt = new Point ( e.X, e.Y ) ; t.display ( this, "Hello", Color.Red, "Comic Sans MS", 30, pt ) ; } } } } Note that the mouse event handler should be added separately. For this go to the 'Properties' window and select the 'Events' tab (shown by a yellow lightening icon). From the list of events select 'MouseDown'. An event handler called myform_MouseDown( ) would get added to our code. In the myform_MouseDown( ) event handler we have first checked whether the left mouse button has been clicked. If so then we have called the display( ) method of the mytext class from the fontassembly assembly. We have created a mytext object in our form class. For the mytext class to become available we have added the statement using fontassembly. However this is not enough. We also need to add a reference to the library. To do this we should right click on 'References' in the Solution Explorer window and select 'Add References'. On doing so the following window appears.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Since our assembly is a private assembly (and not a shared one) it would not be listed in this window. So click on 'Browse' and select the fontassembly.dll from the fontassembly\bin\Debug directory. As a result the DLL would get copied into the fontclient\bin\Debug subfolder of the client. Now we can refer to this class in the client code. On executing the client you would get the window shown below. Click on the form anywhere using the left mouse button and a string "Hello" would appear there.

With the first assembly under your belt, you are ready to get into the more complicated stuff like shared assemblies, versioning, application domains, etc. But that would have to wait till the next article.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Article: The .Net Revolution


If you take a peep into the future you would see .Net written all over it. .Net offers a whole new paradigm that will change the way you think about writing software. This chapter would help you to understand the .Net vision. Though it might be difficult to imagine today the world was still in the mainframe era two decades ago. Few people had access to or used computers. Home computing was unheard of and computers were used only through an IT department at work. The three most influential factors that were responsible for changing this scenario are the PC, the Graphical User Interface and the World Wide Web. With their arrival millions of more users started using computers. The ability of handling graphics, audio and video with ease was sufficiently exciting for an average user to get drawn towards computing. They were responsible for democratizing computing for hundreds of millions of people and for transforming computer into a mass-market product. Computing has now become a key activity in the daily lives of business employees and home users. What will the next generation of computing look like? It would be an online world where millions of PCs, servers, PDAs (Personal Data Assistants), email devices, mobile phones, digital diaries, digital copiers, etc, would collaborate with each other through internet based services. It would make available the information that you and your business needs irrespective of the place where you are and the computing device, platform or the application that you are using. This vision however is yet to be achieved. Let us now see what are the major hurdles that current computing world needs to cross to achieve this vision. Server-Centric Model Today's Internet is still the reflection of mainframe era's server-centric model. Most of the information your business needs is locked up in centralized databases and served to you a page at a time. The browser largely plays the role of the dumb terminal. Web pages provide a "picture" of data, not the data itself. Integrating this data with your business's existing systems and that of your partners is not only costly but often frustrating. Poor Integration Though today's standalone applications and web sites provide good functionality and data most of the time they still work in isolation. One has to navigate manually between websites, devices and applications, rarely being able to integrate the functionality and data. An apparently simple task of arranging a meeting with colleagues and automatically updating every attendee's calendar still remains a complicated computing job. As a result, productivity suffers. Device-Centric View As the software engineering matured the demand on productivity, scalability and robustness increased. This led to developing software in the form of reusable components. With the widespread availability of network the concept of componentization was extended to Distributed Computing. The DCOM (Distributed Component Object Model) from Microsoft, CORBA (Common Object Request Broker Architecture) from Object Management Group and the RMI (Remote Method Invocation) from Sun became popular models for developing software in the form of components that would work in the distributed environment. To help build these reusable components two frameworks came into existence-the DNA (Distributed Network Architecture) framework and the J2EE (Java Enterprise Edition) from the Java camp. However, both these frameworks were built around the platform that is connected to the Internet. This promotes a device-centric view of the world.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Web-Centric View What is needed today is to change the framework from device centric to Internet/Intranet/Webcentric. Under this framework software will be available as a set of distributed services with the devices (PC, PDA, Mobile, etc.) acting as mere points of delivery of services. These services are known as Web Services. Like components they are programmable and reusable. They are available anywhere via the Internet. Programs built using this model will run across multiple websites extracting information from each of them and combining and delivering it in a customized form to any device anywhere in the world. The potential of Web Services is unlimited. For example, a software company may provide a Web Service to calculate income tax. Any company that wants to calculate income tax can subscribe to this Web Service. The customer company need not deploy the income tax calculator. It simply needs to access the Web Service. The company offering the service can dynamically update it to accommodate new taxation rates. The subscribers won't have to do anything to get the new updates. In future a collection of such Web Services may replace packaged software. Other Web Services that can be developed include weather information; stock quotes, shipping status, news items, etc. I think you get the picture now. How will businesses and their customers benefit from Web services? As Web services break down the distinctions between the Internet, standalone applications and computing devices of every kind, they enable businesses to collaborate to offer and unprecedented range of integrated and customized solutions--solutions that enable their customers to act on information any time, any place and on any device. The following figure captures the essence of the .Net vision. To meet the challenge of next generation of internet-based computing Microsoft has come up with the .Net platform. This platform simplifies the process of building these solutions and provides a framework for integration and interoperability. This platform is based on open standards like (XML and SOAP) so that it can work across all programming languages and operating systems. It helps you to combine the power of PCs and smart devices with the richness of Internet. To make Web services a reality Microsoft has addressed the problem at three levels. It has provided a framework to help build the web services, development tools and languages to make this development easy and a server infrastructure to deploy and operate the web services. Let us take a brief look at each of these. Development Tools and Technologies A productive set of tools is critical to carry out successful development on a new platform like .Net. Visual Studio.net provides a complete solution for building, deploying, and running Web services. It helps you to maximize the performance, realiability, and security of your Web services. Visual Studio.Net helps developers quickly build Web services and applications that scale easily, using the language of their choice. This multi-language development tool has been built especially for .Net. You can use programming languages like Visual Basic, C++ and the new language C# for your development work under .Net. Visual Basic was not object oriented, hence it has been spruced up and christened into VB.Net. Visual C++ has been extended to build Web services. You can continue to use it build traditional desktop Windows application s too. A brand new language called C# (pronounced as C sharp) has also been introduced. This language combines RAD (Rapid Application Development) feature of Visual Basic, OO of Visual C++ and portability and platform independence of Java. In addition to these languages provided by Microsoft, there will be over 20 languages provided by partners, including Perl, Python, COBOL, and Eiffel from which developers can choose. For server side programming instead of using nonOO scripting languages like VB SCript we can use C#, VB.Net or C++. Access to databases has also been improved by providing ADO.Net.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Framework The .Net framework is a high productivity, standards-based, multi-language application execution environment that handles essential plumbing chores and eases deployment. It provides an application execution environment that manages memory, addresses versioning issues and improves the reliability, scalability, and security of your application. The .Net framework consists of several parts, including the Common Language Runtime and a rich set of class libraries. Microsoft has also provided a set of core Web services that releases developers from the burden of building everything themselves. By integrating with these core services to perform routine tasks, developers can concentrate on building high-value, business-critical Web services. Microsoft Passport is the first such service which provides authentication services. Microsoft and many other companies plan to develop more core services for users and enterprises. Server Infrastructure Web services should be built on a infrastructure that offers developers the benefits of modular architecture, economical and linear scaling, security, reliability, manageability, and high availability. The .Net Enterprise Servers and the Windows 2000 Server family make up the Microsoft .Net server infrastructure for deploying, managing, and orchestrating Web services. Designed with mission-critical performance in mind, they provide enterprises with the agility they need to integrate their systems, applications, and partners through Web services, and the flexibility to adapt to changing business requirements. The .NET Enterprises Servers are: Application Center 2000 to deploy and manage highly available and scalable Web applications BizTalk Server 2000 to build XML-based business process across applications and organizations Commerce Server 2000 for quickly building scalable e-commerce solutions Content Management Server 2001 to manage content for dynamic e-business Web sites Exchange 2000 Server to enable messaging and collaboration Host Integration Server 2000 for bridging data and application on legacy systems Internet Security and Acceleration Server 2000 for secure, fast Internet connectivity Mobile Information 2001 Server to enable application support by mobile devices like cell phones SharePoint Portal Server 2001 to find, share and publish business Information SQL Server 2000 to store, retrieve and analyze structured XML data.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Article: The .Net Framework


.Net is a platform that would help us to build service-oriented applications to meet the demands of today's Internet businesses. These applications typically gather information from, and interact with, a wide variety of sources regardless of the platforms or languages in use. Integration of services available through different sources and platforms calls for an open standard for describing data and a development platform to help developers create and deploy distributed applications (services). To this effect Microsoft has decided on XML (Extensible Markup Language) for describing the data and the .Net framework as the development platform. The .Net framework is very versatile and addresses many problems that the developers commonly face. This article would discuss these problems and the solutions offered by .Net.

OS Usage In the older days of DOS programming calling the ROM-BIOS or DOS routines was a messy affair. These functions did not have names hence to call these functions it was necessary to pick up these addresses from Interrupt Vector Table (IVT). Moreover to communicate with these functions it was necessary to setup the CPU registers. And if you managed to master this you were required to content with the hardware dependencies. That is the process of a simple operation like drawing a line varied from one type of display adapter to another. To minimize these difficulties several libraries came into existence. They were useful but were language dependent. With Windows things improved to the extent that the Application Programming Interface (API) functions could be called like any other library function. Moreover with the introduction of device independence the programmer was not bothered to worry about the device on which the programmer would finally run. It was Windows Graphical Device Interface (GDI) that adjusted the drawing according to the capability of the device. Also, the same API functions could be called easily through different languages. However the Windows API functions typically needed several parameters to be passed during the call as shown in figure 2.1. Also, API being merely a library of functions could not support the object-oriented programming paradigm. To

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


bring the benefits of object-oriented programming to Windows programming Microsoft created the Microsoft Foundation Class (MFC) library. Likewise, Borland came up with Object Windows Library (OWL). However thought these libraries were very powerful they were not usable across languages. Thus, a good MFC class meant nothing for a Visual Basic programmer. Similarly, a Visual Basic library function meant hardly anything for a VC++ programmer. The .Net framework attempts to resolve these difficulties by providing a Common Language Runtime (CLR) and a set of base classes that can be accessed through any .Net compliant language.

Little Reuse In procedural languages like C reuse was limited to calling the same library functions from different programs. These functions however were not extensible. They were required to be use on a "as is, where is" basis. Also structured programming languages did not model the real world very well. For example, if a C program is used to create a window then there were no language elements that could be identified with the window or its elements like toolbar, menu, status bar, etc. In the procedural programming paradigm the whole emphasis was on dividing a job into several smaller jobs and then implementing these jobs through the individual functions. Importance was given to the operations rather the data on which these operations are performed. While dealing with complex systems this was found to be an unrealistic programming model. World is object-oriented and programmer being the part of the world should also deal with a system that he is trying to program in the form of objects and their inter-relationship. Objectoriented languages embrace these concepts and hence have become immensely popular amongst programmers. C++ and Java are good examples of these. These languages promoted reuse by letting you inherit features of one class into another and then providing additional features in the new class. This was possible even if the source code of the first class was not available. This reuse was a big step forward. However the reuse was restricted within the language. Thus, a Java class was not of much use to a C++ programmer and vice-versa. To promote language independent reuse Microsoft came up with a bold new technology called Component Object Model (COM). COM was a binary specification and components built as per this specification could be used by not only the conventional languages like C or C++ but also by scripting languages like VBScript and JavaScript. To accommodate these wide range of languages a lot of plumbing code was required to be built. Also, COM didn't support crosslanguage inheritance or cross-language debugging. Instead of adopting a philosophy of letting all kinds of languages to use COM components and requiring a lot of plumbing code to be written in

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


the process .Net adopts a different philosophy. In .Net the capabilities of languages itself is raised in such a manner that they can use COM components without being required to write lot of plumbing code.

Messy Runtime DOS was a single tasking operating system, which could run only one program at a time in memory. With the dramatic increase in the computing power it was unrealistic to expect that a user will like to use the entire power to run only one program. Windows could utilize this computing power by letting users run several programs at a time by creating a powerful runtime. However this runtime had the following problems: Poor error handling - Windows returned error codes which is not the object oriented way of handling errors. It has now become a common norm that errors should be handled through exceptions and nit through error codes. Costly Inter Procedure Calls (IPC) - When multiple processes are running in memory Windows runtime ensures that no process barges into the memory of the other. However there is often a need to communicate between processes. This calls for marshalling (conversion of parameters being passed to a function into a byte stream) and unmarshalling (conversion of byte stream into data types). There is a severe overhead in this as lot of copying of parameters takes place. If this is to be avoided then the second process can be made as a DLL and then made to run in the same address space as the first. This has a disadvantage that if the DLL fires the process in whose address space it is running also fires. .Net overcomes this limitation by using a concept called Application Domains.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Changing World In the last decade or so computing has moved from the confines of an organization to a model where computing takes place in a distributed environment spread across multiple branches/offices present at different geographical locations. Also, integration becomes a major issue when your computing model has to work in tandem with that of your partners, customers and suppliers. This involves complexities like different computers, different operating systems, different languages used for development, etc. Let's elaborate on this. Suppose we wish to develop an Internet application that allows businesses to communicate vital information with each other across existing communication lines. Let's look at typical solution that can be offered to this problem using Microsoft technologies. If the application is an n-tier application then we would need HTML, DHTML & Java Script in the front-tier; VBScript, ASP, MTS, C++, VB, COM in the middle-tier and SQL, ADO in the back-tier. Developers possessing sufficient skill in all of these areas are few and costly. In short, a perfect recipe for development nightmare. Even if the developers are able to successfully develop the applications, they would be required to spend hours battling component version conflicts (popularly known as DLL Hell) when the time comes to install their products. Assured distribution nightmare, in short. Sun's solution to this problem could be to use Java applets and servlets in the front-tier, Enterprises Java Bean (EJB) or CORBA or RMI in the middle-tier, and JDBC and a suitable database in the back-tier. The common theme here is every developer should learn Java language. This is a far-fetched dream. Though an attempt to make every programmer a Java programmer has met with more than a lukewarm success, the ground reality is that there would be several languages in existence, each camp having its own faithful band of programmers. .Net has understood this reality and hence lets you use language for your taste for carrying out the development.

Deployment Nightmare DLLs are created with a motive to share them between different applications. Hence while installing them instead of placing them in any particular application's directory they are installed either in Windows directory or in Windows\System directory. Thus whichever application wants to use a DLL file it can load it from one of these directories. This, on the face appears to be pretty straightforward. But when a new version of the DLL is released it should not be copied on top of the earlier version. Otherwise the clients that were using the earlier DLL might break. Thus the DLLs have to have different names if the two versions are to coexist. These versioning problems are popularly known as DLL hell.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


COM has overcome this versioning problem by storing two different versions of the component in two different directories and then registering these components in the Windows registry using two unique IDs (popularly known as globally unique id or GUID). However, the installation of a COM component was a little unrealistic because the COM component used to get stored in one directory, its CLSID used to be in registry and its interface (through which the functions of the COM component can be accessed) used to be in the type library of the component. If any of these used to go bad the component used to be rendered useless.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Article: Thinking in C#
C# (pronounced as 'C Sharp') is a new object-oriented language designed at Microsoft by Anders Hejlsberg. This language would help programmers create secure, robust, portable, distributed object-oriented applications for the internet. But that is hardly a definition that would impress a programmer. What he would be most interested in knowing is how this language is going to make a difference to his daily work and how is it different than existing popular languages like C++, Visual Basic and Java. The answer is simple-it combines the power of C++ with productivity of Visual Basic and elegance of Java. That's a tall promise. We need to examine this claim with a thick lens. Power of C++ - C# brings with it object-oriented paradigm of C++. It implements the same through encapsulation, inheritance and polymorphism. Productivity of Visual Basic - Promotes Rapid Application Development through simpler GUI programming with easy drag & drop support. Properties & Events are part of the language itself. Elegance of Java - No pointers (unless explicitly mentioned), fixed-size primary data types, Unicode characters, Type-safety, No multiple-inheritance, Garbage collection, Platform independence.

The C# language is disarmingly simple. C# is the first language that has been designed from ground up with Internet in mind. Using C# we can create a whole gamut of applications including Windows-based applications (WinForms), server-side applications (Dynamic Web Pages, Web Services), client-side applications (Web Forms & Web Controls), enterprise applications (ADO.NET), mobile applications, components (Assemblies), etc. The First C# Program Best way to learn a new language would be by writing programs and then comparing them feature by feature with popular existing languages like C++, Visual Basic and Java. So let us begin with the first program that displays a message "Hello C#". Here is the program namespace Simple { using System ; class Class1 { static void Main ( string[ ] args ) { Console.WriteLine ( "Hello C#" ) ; } } } On execution, this program prints a message "Hello C#" on the screen. To create this program we would use the Visual Studio.NET environment in the steps mentioned below: a. Start Microsoft Visual Studio.NET 7.0 from Start | Program | Microsoft Visual Studio.NET 7.0 menu option. b. Create a new C# project from File | New | Project menu option. A New Project dialog as shown in the following figure would appear.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

c. From the New Project dialog box select project type as Visual C# Projects. d. Select Console Application from the list of Templates. e. Select a location where this project should get saved. Give name to the project - Simple. Click on OK button. f. A Class1.cs file would get created. g. Type the program in Class1.cs file h. To execute the program, programmers using Visual Studio.NET should use Ctrl + F5. Those who do not have Visual Studio.NET should go to DOS prompt and execute the command C>csc Class1.cs. Here csc stands for C Sharp Compiler. The output of this command would be an EXE file. To execute the .EXE file just type its name on the command prompt. (From now onwards we would build applications using Visual Studio.NET.) Here we have used console application from several templates. As we go along we would use other templates also. The program execution starts from the Main( ) function. Since C# is a pure object-oriented language it does not allow us to create global variables and functions. Instead, all variables and functions should be defined inside a class. Hence it is necessary to define the Main( ) function in some class, say Class1. Except for the line marked out in bold in the above program the rest of the code shown in the program is generated by the Wizard. A class is a blue-print from which specific objects can be created. A class is similar to a data type and an object is similar to a variable. The way we can create several variables from an int type, likewise we can create several objects from a class like Class1. The class, like structure in C, allows us to create our own (user-defined) data types by combining intrinsic or other user-defined data types. Unlike structures in C a class can hold data as well as functions. Thus a class indicates what kind of data an object of its type can hold and what operations (like addition, subtraction, display, etc.) can be performed on this data. In short, the class specifies what data and what functions will be included in objects of that class. We would learn more about this in the Chapter "Classes and Objects".

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


The void keyword before Main( ) specifies that this function does not return any value. We would later discuss what static really means. But for now it is necessary and removing it would result in an error. The string is a data type used to hold a string. The string[ ] represents an array of strings. As you can see args, the argument of Main( ) has been declared to be of type string[ ]. It can be used to store command-line arguments, if supplied by the user. To send output to the screen we have used the WriteLine( ) function. To this function we can pass strings, integers, floats, etc. Since WriteLine( ) belongs to the Console class we have to use the form Console.WriteLine( ) to call it. .NET organizes its classes by grouping several related classes in one namespace. The Console class belongs to the System namespace. To be able to use the Console class in any program we need to import it from the namespace, which has been done in our program through the statement using System. Like the Console class our class is also enclosed in the Simple namespace. This namespace is generated by the Wizard from the project name that we had specified while creating the project. Remember that C# is a case-sensitive language. The naming convention used by .NET is that class names should start with a capital letter. If a single class name contains multiple words, each word will have its starting letter in capital. The same applies to function names as well. All keywords are in small case. Printing Command-Line Arguments We can stretch the first program done above to add the ability of printing the command-line arguments that may be supplied while executing the program. The enhance program is given below: namespace Simple { using System ; class Class1 { static void Main ( string[ ] args ) { for ( int i = 0 ; i < args.Length ; i++ ) Console.WriteLine ( args [ i ] ) ; } } } The for loop walks through the args[ ] array printing each command-line argument in the process. Command-line arguments can be supplied through the 'Start | Run' menu item by following the program name with the arguments that we intend to provide. To find out the number arguments supplied by the user we have accessed the Length property of the array. The Length property returns the number of elements in the array, which is then used to govern the conditional statement in the for loop. Now that we have the capability to print messages on the screen let us now turn our attention to the basic building blocks of a language, namely, Data types. Data Types The data types in C# can be divided into different groups. Every data type has a strictly defined size and range. This size would remain same irrespective of the platform being used. These groups are shown in the following tables:

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Integers Data Signed/Unsigned Size Type sbyte signed 1 byte byte unsigned 1 byte short signed 2 bytes ushort unsigned 2 bytes int signed 4 bytes uint unsigned 4 bytes

Range

-128 to 127 0 to 255 -32768 to 32767 0 to 65536 -2147483648 to 2147483647 0 to 4294967295 -9223372036854775808 to long signed 8 bytes 9223372036854775807 ulong unsigned 8 bytes 0 to 18446744073709551615 Any whole number value can be an integer value. The data types in this group cannot hold fractional values. Floating Points Data Signed/Unsigned Size Range Type float signed 4 bytes 1.5 x 10 -45 to 3.4 x 10 38 double signed 8 bytes 5.0 x 10 -324 to 1.7 x 10308 The data types in this group can hold Floating-point numbers representing decimal values with a fractional component. Character Data Signed/Unsigned Size Range Type char unsigned 2 bytes The data type in this group can hold a character with a 16-bit Unicode value. Unicode defines fully international character set that can represent all of the characters found in all human languages. It is the unification of dozens of character sets such as Latin, Greek, Arabic, Cyrillic, Hebrew, Katakana, Hangul and many more. For this purpose it requires 16 bits to represent each character. Boolean Data Signed/Unsigned Size Range Type Bool NA 1 byte true or false This type can hold logical values. It can have only one of the two possible values, true or false. Decimal Data Signed/Unsigned Size Range Type 16 decimal signed 1.0 x 10 -28 to 7.9 x 10 28 bytes This data type is a dedicated type for financial calculations. It represents higher precision floating-point numbers. It allows us to specify currency amounts. C# imposes some rules while using these data types. These rules are explained below with the help of code snippets: Rule 1: Before using any variable it must be initialized with a value.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


int i ; Console.WriteLine ( i ) ; This would result in an error since before printing the value of i it has not been initialized. Unlike C/C++ there is no concept of garbage values. Rule 2: The variable can be initialized with a value that is within the range of its type. short s = 40000 ; This would result in an error. Here, since s is of 2 bytes it can store a maximum value of 32767. Unlike C and C++ the value would not get wrapped to the other side of the range. Rule 3: While initializing the destination type must be larger that the source type. short s = 40 ; byte b ; b=s; Here, the value of a short variable is being assigned to the variable of type byte. Since, size of a short is larger than that of a byte this results in narrowing of the value. Narrowing conversions are not supported implicitly by C#. To make this work we need to do an explicit conversion like, b = ( byte ) s ; C# supports implicit wider conversion. Hence the statement s = b would work. Rule 4: sbyte and short are converted to an int type, whereas, byte and ushort are converted to a uint type while performing arithmetic operations on them. short s1 = 40, s2 ; byte b = 6 ; s2 = s1 + b ; Here, s1 and b would be converted to an integer type before performing addition. The resultant value would be an integer. Assigning an integer value to a short variable would result in an error. To make this work we have to write s2 = ( short ) ( s1 + b ). Character type can be converted into integers and manipulated with the integer operators such as the addition and subtraction operators. For example, char c = 'a' ; int i ; i=c; i=c+1; Rule 5: Boolean type is incompatible with rest of the data types. int i = 40 ; bool b = true ; i=b; b = ( int ) i ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


The bool type is returned by all relational operations such as a < b. The bool is also a type required by the conditional expressions that govern the control statements such as if, while and for. It solves the problem where programmers mistakenly use = instead of == resulting in unexpected behaviour. This distorted type safety. For example, several years ago, a space bound rocket crashed just minutes after launch costing NASA millions of dollars. Upon investigation, it was discovered that the crash was a result of a software failure. Specifically the fault was traced to a buggy line of C code in which the programmer had mistakenly used = at a place where == was needed. Let us see with an example how C# solves this problem. int a = 10, b = 50 ; if ( a = b ) a = 70 ; This code would result in an error because the result of the assignment statement a = b is not a bool value. Control Statements Statements like for, return, goto, break, and continue work in the same way in C# as they do in C and C++. But there are differences in the way if, while, do..while and switch statements work. Moreover an additional looping instruction called foreach has also been added in C#. Let us now understand the improvements that have been made to the control instructions. switch Statement Unlike C and C++, control in a switch statement in C# is not permitted to "fall through" to the next case if a case gets satisfied. For example: switch ( grade ) { case 'A' : Console.WriteLine ( "In A" ) ; case 'B' : Console.WriteLine ( "In B" ) ; case 'C' : Console.WriteLine ( "In C" ) ; case 'F' : Console.WriteLine ( "In F" ) ; } This statement gives an error. This happens because of absence of the break statement. In C and C++, if such a switch statement is written we do not get an error. Instead the cases present after the one that gets satisfied are executed. In C#, if we want some other case to get executed after the one that gets satisfied then we must explicitly use a goto statement as shown below: switch ( grade ) { case 'A' : Console.WriteLine ( "In A" ) ; goto s1: case 'B' : Console.WriteLine ( "In B" ) ; break ; case 'C' :

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


s1: Console.WriteLine ( "In C" ) ; break ; case 'F' : Console.WriteLine ( "In F" ) ; break ; } If we want that the same code should get executed if any of the two cases is satisfied then we can write the following code: case 'a' : case 'A' : Console.WriteLine ( "In A" ) ; In this example since the case 'a' is empty there is no need for a break statement in it. The switch statement can check integer, character and string types. foreach Loop The foreach statement lets us iterate over elements in arrays. If we want to iterate through an int array arr we can do so through the following statements: int[ ] arr = { 1, 2, 3, 4, 5 } ; foreach ( int i in arr ) { Console.WriteLine ( i ) ; }

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Article: Registry
The registry is used to store information about Windows setup, user preferences, and installed software and devices. All the COM components place their CLSIDS, ProgIDs, paths of the DLLs, versions in the registry. This helps the clients to load the component from any directory. The registry is a hierarchical structure whose top-level nodes represent the registry hives. To view or modify the registry we execute the utility regedit through Start | Run Dialog. The number of hives in the registry is fixed. There are seven of them. We cannot see all the hives. HKEY_CLASSES_ROOT - Contains details of the types of files present on the system and information about applications that are able to open those files. It also consists of registration information for all COM components. HKEY_CURRENT_USER - Contains details of user preferences for the user currently logged on to the machine. HKEY_LOCAL_MACHINE - Contains details of all software and hardware installed on the machine. HKEY_USERS - Contains details of user preferences for all users. HKEY_CURRENT_CONFIG - Contains details of configuration of hardware devices on the machine. HKEY_DYN_DATA - Contains information about volatile data. HKEY_PERFORMANCE_DATA - Contains information concerning the performance of running applications.

Each root key consists of data as well as keys. The data is present as values. The value is divided into 3 parts: name, type and data. The key may have a default value, which is unnamed. The type of value may be formatted as one of the three data types namely, REG_SZ, REG_DWORD, REG_BINARY. REG_SZ corresponds to a string. REG_DWORD corresponds to a uint. REG_BINARY corresponds to an array of bytes.

The .NET Framework offers two classes in the Microsoft.Win32 namespace: A RegistryKey class and a Registry class. Microsoft.Win32 namespace contains classes related to those that handle events raised by the operating system and those that manipulate the system registry. These classes are not included in the System namespace because they are specific to Windows operating system. The RegistryKey class represents a Registry key. This class has methods to browse, to create new keys and to read or modify the values in the keys. The Registry class contains only seven public static fields, which expose the actual keys to the programmer. These fields are read-only fields and cannot be modified. These fields expose the instances of the root RegistryKeys found in the registry. The seven fields are CurrentUser, LocalMachine, ClassesRoot, Users, PerformanceData, CurrentConfig, and DynData . This class is never instantiated and it only provides us with instances of top-level registry key instances. Creating a Test Version Application.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

In the following program we plan to write an application that keeps a count on the number of times the application has executed as well as the amount of time the program spent in execution. If the application crosses a specified limit, it becomes unavailable. Many softwares, especially the ones that we download freely from the Net have an expiry period. When we run such softwares a dialog is popped up which informs us that we can use the software only for a specific number of days. And this count keeps reducing every day. In our program we have kept a limit on number of days as well as time. The Logic used is as follows: When we run our application for the first time, we add a registry entry in the HKEY_CURRENT_USER | Control Panel. Hence we have added a key for our application along with two values, one for maintaining the number of executions and another for maintaining the count on time. Next time when we open the application it checks these values and accordingly allows or disallows the program to execute. The limitation that we have kept in the program is that it should work for a maximum of 5 hrs or can execute only 50 times. To keep a count on time, we have added a timer control in our application. This is done by dragging in the control from the toolbox. We have changed its name from timer1 to mytimer. Every time we start the application a 'staring form' is displayed which indicates the time expired, time remaining, number of times the application was executed, and remaining number of times it can be executed.

Here we have added 9 labels, 4 for displaying the static text and four for displaying the time expired, time left, executions completed, and executions remaining. We have named them as texp, tleft, execom, and exerem respectively. The last label is used to display a message besides the start button. The start button indicates that the actual application will start, the earlier form is just a starting indication, and it does not start the real application. When we click the start

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


button, the timer starts and number of executions increases by one. But before this we have to add in registry entries. We plan to add our key in the HKEY_CURRENT_USER | Control Panel. We can add this somewhere else also. We have done this in the constructor of the form. We have added the following data members to the form RegistryKey top, r, demo ; int min, numexe, timercounts ; In top we will have the RegistryKey instance of HKEY_CURRENT_USER key. In r we will have instance of Control Panel key and in demo we will have the key of our application. min will contain a count of minutes, numexe will contain a count of number of executions and timercounts will contain a count on seconds. public Form1( ) { InitializeComponent ( ) ; top = Registry.CurrentUser ; r = top.OpenSubKey ( "Control Panel" , true ) ; demo = r.OpenSubKey ( "softdemo" , true ) ; if ( demo == null ) { demo = r.CreateSubKey ( "softdemo" ) ; demo.SetValue ( "Minutes", ( object ) min ) ; demo.SetValue ( "Executions", ( object ) numexe ) ; } else { min = ( int ) demo.GetValue ( "Minutes" ) ; numexe =(int) demo.GetValue ( "Executions" ); } texp.Text = min / 60 + " hours " + min % 60 + " minutes" ; int m = 300 - min ; tleft.Text = m / 60 + " hours " + m % 60 + " minutes" ; execomp.Text = numexe + " " ; exerem.Text = 50 - numexe + " " ; msg.Text = " Click Start Button To Start Application " ; if ( numexe >= 50 || min >= 300 ) { msg.Text = "Trail Version expired" ; start.Enabled = false ; } } Firstly we have collected the top-most RegistryKey in top using the Registry.CurrentUser field of the Registry class. Next we have initialized r with the key of Control panel using the OpenSubKey( ) method. Then we have initialized demo with the key of our application using the same function. If we get a null in demo, it means that this is the first time the application is running and no key is present. In this case we have added a new sub-key using the CreateSubKey( ) method. To this key we have added two values Minutes and Executions and have set both the data fields to 0 using the SetValue( ) method. The SetValue( ) method takes the second parameter as an object and hence we have type-casted it.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

If demo does not contain a null it means that the application is not running for the first time and the key and its values already exist. In this case we have retrieved the values using the GetValue( ) method. While retrieving the value we have to type cast it back in whichever data type we have used amongst a string, an int or a byte array. Here we have used an int. Next we have set all the text fields of the labels to the appropriate values by calculating the time in hours and minutes from the extracted key values. If the extracted minutes happened to be more that 300 (5 hours) or the number of executions happened to be more that 50, we have disabled the start button and flashed an appropriate message. We have kept a count on time with the help of the timer. The timer starts when we click the Start button: private void start_Click ( object sender, System.EventArgs e ) { numexe++ ; demo.SetValue( "executions", ( object ) numexe ) ; mytimer.Start ( ) ; MessageBox.Show ( "Write Your Application Logic Here" ) ; } When we press 'Start' the number of executions is increased and the new value is set. We have added the Tick( ) handler with a time interval of 1000 milliseconds. This means after every 1000 milliseconds (1 second) this event will be fired. We can change this value in the 'Properties' window of the timer control. This is the place where we can write the logic of our actual application. private void mytimer_Tick ( object sender, System.EventArgs e ) { if ( ++timercounts >= 60 ) { min++ ; texp.Text = min / 60 + "hours " + min % 60 + "minutes" ; int m = 300 - min ; tleft.Text = m / 60 + "hours " + m % 60 + "minutes" ; demo.SetValue ( "Minutes", ( object ) min ) ; timercounts = 0 ; } if ( min >= 300 ) { mytimer.Stop ( ) ; Dispose ( ) ; } } Here we have first checked if timercounts is greater than 60 (1 min). If it is, we have increased min by one and we have written the new value in the registry as well as in the text filed of the labels accordingly. Next we have checked the min field. If it happens to be greater than 300 (5 hours), the timer should stop and the program should terminate. To do so, we have called the Dispose( ) method. In this method we have disposed all the objects we created. protected override void Dispose( bool disposing ) { top.Close ( ) ; r.Close ( ) ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


demo.Close ( ) ; if ( disposing ) { if ( components != null ) { components.Dispose ( ) ; } } base.Dispose ( disposing ) ; if ( min >= 300 || numexe >= 50 ) MessageBox.Show ( "You can no more use this software, time elapsed!!!!" ,"Sorry" ) ; } Here we have checked the min and numexe values and if they exceed the specified limit we displayed a dialog box with an appropriate message.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Article: DirectX - Direct Is Better


Hats off to the game developers of DOS era! They suffered so much and complained so little. To be able to write a game they were required to know what colors are available on the PC, how to produce them, how much memory does the PC have, what are the sound capabilities of the PC, which video card is installed in the PC, which different graphics mode does it support, what are the input devices attached to the machine, etc. But they were brave people. They acquired this knowledge and used assembly language and later C to develop games that met user's taste and demands. One day all this changed. That was when Microsoft Windows operating systems came into being. No longer were the programmers required to worry about the new and changing capabilities of graphics cards, joysticks, graphics accelerators, etc. Now the game programmers were not required to spend time in creating and understanding the hardware specifications of display adapters. They could rely on Microsoft to do all that for them and package it for their use in the operating system. This was a big step forward. Still the game programmers were not happy to change from DOS to Windows as their game development platform. This was because though Windows could make it easier to develop games it stifled the creativity of the game designer and compromised the performance of the game by not letting the programmer have a direct access to the device capabilities. No longer was the scrolling smooth, the animation crisp and the sound explosive. So much so that many game developers simply abandoned the idea of using Windows as their game development platform. They continued their game programming in DOS and simply used Windows capability to shell out to DOS. Such are the times that separate men from the boys. Microsoft didn't get disappointed with the lukewarm response that Windows received from game programmers. Microsoft knew that their strategy was right. They simply had to ensure that the performance of their model should be improved to match the performance that the game programmers had become accustomed to in DOS. Microsoft went back to the drawing board and came up with a Game Software Developer's Kit (Game SDK). This was the first version of DirectX. It consisted of fast, low-level libraries that did not impose constraints on the game design. It met and at times even exceeded the performance of DOS. Lastly, DirectX ensured that the burden of hardware support shifted from the developers to the hardware manufacturers. After all, the hardware manufacturers were eminently capable of creating drivers for their products and it was their responsibility to make the latest advance in their hardware accessible to the developers. As the years have gone by DirectX too has evolved and has continuously increased its capabilities. Today it boasts of network support, force-feedback support and 3D graphics capabilities. So much so that it is no longer being used only for writing games, though that remains its predominant use. It is now also being used to show off your latest products, to create a virtual stereo to listen to the difference in types of sound systems that companies offer, to create screen savers and to build applications like instant messenger and voice chat that allows users to talk with one another on the internet. What's Direct In DirectX DirectX has been based on the philosophy of 'Directness'. There is no beating around the bush. It understands that all said and done if DirectX doesn't provide speed and takes the approach "we know what is best for you" there won't be many takers for it at the end of the day. It achieves its directness through: Speed

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


To achieve speed DirectX uses the hardware features where they are available and emulates them where they are not available. For example, if hardware provides a operation like memory swap DirectX uses this feature thereby allowing the developer to get maximum out of parallel architecture that multimedia hardware can provide. Reduced Latency If we hit a key in a Windows application a message called WM_KEYDOWN is sent to the message queue of the application. When its turn comes the message is picked up from the queue and then processed by calling a suitable function. This process has been abstracted away from the programmer and he is required to bother only about the functionality that must be provided in the function that would get called when the key is pressed. This is all very good for normal Windows application, but it is a strict no no for game programming. Imagine a typical situation in a 2-player game. If one user places a punch on your nose, you would want to square it off right there. In this situation it would be unacceptable if Windows takes a long time to process your keyboard message. DirectX attempts to reduce this latency between "thinking of doing" and "actual doing". Non-Interference While building a library, one is often tempted to do things in a way one thinks is right and best. This can be dangerous and counter-productive. For example, if DirectX evolves a communication model that works same for a car-racing game and for a Chinese-checker game it would be inappropriate because the communication requirements of these games are different. So DirectX doesn't try to generalize things and provide automatic models for different gaming operations. Instead, it concentrates on the basics and seeks to enrich Windows by providing a set of low-level tools for building better games and multimedia applications. It does the basic operations well and leaves it to the imagination and innovativeness of game developers to exploit these features for their gaming product. Fair enough! Components Of DirectX DirectX made its debut as a Game SDK. But this SDK had a life span of only one version. There are a lot of 'DirectSomethings' in existence today. The chart Figure 1.1 shows their names and the subsequent discussion explains their purpose.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

DirectX Components DirectX Graphics This component includes various functions that are used for handling graphics. This component is further divided into DirectDraw (2D Graphics) and Direct3D (internally uses DirectDraw). The DirectX Graphics component also includes Direct3DX utility library which helps in simplifying complex mathematical operations useful to Direct3D. DirectInput This component supports variety of input devices like keyboard, mouse, joystick, etc. It also provides force-feedback effect in input devices like motor mounted joystick by generating push or resistance. Force-feedback technology helps make the gaming environment more realistic. For example, if we are flying an aircraft in a game and if the aircraft crashes then due to forcefeedback we would feel the jerkiness of the explosion. (push effect) . Or if we are driving a car with the help of a force-feedback joystick, the more we push the joystick the more the car accelerates. If the car collides with another car/obstacle then the joystick will try to resist our action of pushing to simulate an obstacle. DirectInput removes delay in receiving input data by bypassing the Windows messaging architecture. DirectX Audio This component consists of DirectSound and DirectMusic. DirectSound is used to generate sounds like car doors slamming, horns honking and birds chirping thereby making games more realistic. It also removes delay in generating sound effects. DirectMusic is used to compose music at runtime. DirectPlay This component facilitates multi-player gaming on the network or Internet. It provides functionality

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


needed to organize and launch a multi-player game. This component can also be used to create messaging applications similar to MSN Messenger Service. DirectShow This component is used to playback multimedia streams like MPEG, AVI, WAV, QuickTime, etc, from local files or Internet servers. Using this component we can create variety of effects that are seen in PowerPoint and many more such applications. DirectSetup This component enables us to distribute DirectX runtime with our application. With this component our application can be packaged into a nice setup program. When it is installed all the libraries and support files are available when the user needs them.

Article: C# - Shared Assemblies


In the article on 'Assemblies' we saw how to build a private assembly. We shall extend that discussion and see how to build and use shared assemblies this time. We will convert the same assembly we made last time into a shared assembly. Recall that a private assembly is private to an application and every application using it has its own copy of the assembly. There is no need for the private assembly to be unique. A shared assembly on the other hand is available to all clients and hence must be unique. To be uniquely identified, a shared assembly must have a strong name. The combination of a file name, a public key, a version number and culture gives an assembly a strong name, which is guaranteed to be unique. To understand these terms we must first know what is a public and private key. Public Key Cryptography Public and private keys are nothing but algorithms used for encryption and decryption of data. The main principle used in public / private encryption / decryption is as follows: If something is encrypted using a public key, it can be decrypted using the corresponding private key, but not with the public key. This also works the other way round too, i.e. if something is encrypted using a private key it can be decrypted using the corresponding public key, but not the private key.

Public and private keys are always created in pairs. The public key is made available to everybody and the private key is kept safe and secure. How it works on Assemblies? First a public-private key pair is generated at random for the assembly using the sn utility. How to generate the keys using the sn utility is discussed later. We then provide these keys to the compiler. The compiler takes a cryptographic hash of the names and contents of the files in the assembly. This hash is taken using a very simple algorithm. This cryptographic hash is then encrypted using the private key for the assembly by the compiler, and placed in the manifest. The compiler also creates the strong name and writes it in the manifest. As said earlier a strong name consists of a combination of a file name, a public key, a version number and culture. So along with the strong name the public key also gets written in the manifest. The strong name does not contain the private key. This ensures that the private key is not written in the manifest

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


and hence not made available to everybody. So in all two things are written inside the manifest, the strong name and the encrypted hash of the names and contents of the files. This is called signing of assembly. Whenever an application wants to load an assembly, the runtime decrypts the hash of the files using the assembly's public key. The public key is available as it is stored in the manifest as part of the strong name. Then the runtime reads the names and files of the assembly and calculates the hash for itself. These two hashes are then checked, if they match, the assembly is loaded or else its not. Any changes made to the files in the assembly after it is installed will make the application not work because the calculated hash won't match with the decrypted hash and the runtime will not load the assembly. If somebody tries to change the manifest, the .NET runtime will again detect a problem and refuse to load the assembly. All the shared assemblies available on a system are stored in a folder called the Global Assembly Cache. This store is located in the '<drive>:\Windows\Assembly' folder. Using the sn utility We plan to convert the same DLL i.e. fontassembly.dll into a shared assembly. To convert it into shared assembly we have to first use the sn utility (strong name utility). This utility generates a public / private key pair. The public key created using this utility will be used to define a strong name. To create the key pair we must type the following on Command Prompt C:\CSharp\fontassembly>sn -k mykey.snk On executing the utility a file mykey.snk gets created. This file contains the public and private keys. We must now use this file in our project. To do so open the 'AssemblyInfo.cs' file of the project. In this file we would have to set the AssemblyKeyFile attribute. The attribute must be set to an absolute path to the key file. Following are the changes ( shown in bold ) to be made in 'AssemblyInfo.cs' [ assembly: AssemblyDelaySign ( false ) ] [ assembly: AssemblyKeyFile ("mykey.snk") ] [ assembly: AssemblyKeyName ( "" ) ] We also have to change the version number of our assembly as shown below [ assembly: AssemblyVersion ("1.0.1.1") ] The reason behind this will be clear when we discuss versioning in the next article. On rebuilding this, the assembly along with the strong name associated with it gets created and also the encrypted hash is written in the manifest. This is known as signing of the assembly. Installing the Shared Assembly After signing the assembly, it's possible to install the assembly in the global Cache. To install a shared assembly in the global cache we have to use the Global Assembly Cache utility tool called the gacutil tool. At the command prompt we have to use it with a /i option. Here /i stands for install. This what we must type at the command prompt

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


C:\CSharp\fontassembly\bin\Debug>gacutil /i fontassembly.dll Microsoft (R) .NET Global Assembly Cache Utility. Version 1.0.2914.16 Copyright (C) Microsoft Corp. 1998-2001. All rights reserved. Assembly successfully added to the cache We can now open the Global assembly cache and we will find that our assembly gets added to it as shown in following figure.

Using the Shared Assembly We will use the same client we made last time for using 'fontassembly.dll'. To do so first we have to be sure of two things: We must delete the private 'fontassembly.dll' version we created last time from the directory of the client and secondly we must remove its reference by right clicking on fontassembly under 'References' in the 'Solution Explorer' window and selecting 'Remove'. To use the shared assembly we will have to again add the reference of the shared assembly in the same way as for the private assembly. But this time the assembly does not get copied into the local directory because the CopyLocal property of the reference is automatically set to False by the compiler. This can be seen in the 'Properties' Window of the assembly. On compiling the client we get the same results. We can now use the same DLL in any client we want and every time the assembly installed in the Global cache will be used. Structure of an Assembly So now lets look at how the assembly looks like. The assembly is made up of metadata , IL code and resources. The Metadata consists of type metadata and assembly metadata. Assembly Metadata describes the assembly and is called the Manifest. A manifest contain: a. The identity of the assembly, consisting of its name, version and culture.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


An assembly has a four part version number e.g. 1.0.1.1. The parts are <Major> . <Minor> . <Build> . <Revision> The use of these numbers is dependent on the configuration of our application. If the new version created is compatible with the older version we must not change the major or minor numbers. On the other hand if the versions are incompatible we must change the major and minor numbers. The build number is the number of days since Jan-1, 2000, and revision is the number of seconds since midnight local time. Culture is b. Names of all the files in the assembly. c. Details of all the types defined in the assembly. d. Whether all the types defined in the assembly are visible to other assemblies or private to one. e. A hash of all files in the assembly f. Names and hashes of other assemblies that an assembly in turn will need to reference when run g. Details of any security permissions that clients need to have in order to be able to run the assembly Type metadata consists of metadata describing the exported types and methods. To view the assembly and manifest Microsoft has provided us with the ILDASM tool. The ILDASM Tool The ILDASM, the MSIL disassembler, is used to view assemblies. We can run this tool by starting ildasm from the command line, with the assembly as argument or by selecting the 'File / Open' menu. This is how the ildasm window looks after opening our 'fontassembly.dll' in it:

The tool shows the Manifest, Namespace, Class and Method in the assembly. It can also show Interfaces, Value types, Static methods, Fields, Static Fields, Events and Properties if present.

Article: C# - Versioning

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Continuing the analysis of Assemblies from the last article, we shall see how you use the new features to solve versioning problems. With DLLs, a new version would always overwrite the older version breaking the clients using the older version. Assemblies bypass this problem. We never do versioning on private assemblies. Every client has its own copy of the private assembly and installing a newer version would mean overwriting the existing version. This would not affect or break clients using the older version because they would still have their copy of the older version in their local directories. Versioning is always done on assemblies with strong names i.e. shared assemblies. We can install multiple versions of the same assembly in the Global Cache simultaneously. The older versions do not get overwritten and hence clients using the older version do not fails. If we want we can also redirect old clients to start using the new version. This is all done with the help of configuration files. Last time we had created an assembly and stored it in 'fontassembly.dll'. What we plan to do here is to create a new version of 'fontassembly.dll'. To do so we would have to create a new copy of the code and make the following change in 'Class1.cs' file. Font myfont = new Font ( fname, size, FontStyle.Italic ) ; And the following in 'AssemblyInfo.cs' file. [ assembly: AssemblyVersion ( "1.1.1.1" ) ] On rebuilding this, the assembly along with a strong name associated with it gets generated. Next we have to install this version in the Global assembly cache. This is done using the gacutil tool. After installing it in the Global assembly cache we find that both the versions of 'fontassembly.dll' (1.0.1.1 and 1.1.1.1) stand installed.

Figure 1 : Global Assembly List


Now client applications can be created that use any of the two versions installed. We just have to add a reference of the assembly we want to use.But this leaves us with one question. What about already existing clients who want to shift to a newer version without being recompiled? The answer is redirection.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


We can specify redirection in a configuration file of the client. We will have to first create a configuration file for that. With the configuration file we can specify that the binding should happen to a different version of a shared assembly without rebuilding the client application. To achieve this .NET provides us with a .NET Admin Tool which is a MMC Snap-in called 'mscorcfg.msc'. It is present in the C:\WINNT\Microsoft.NET\Framework\v1.0.2914 directory.

Figure 2 : .Net Admin Tool


To create a configuration file we will have to right click on 'Applications' on the left side, choose 'Add' and select 'fontclient.exe'. The .NET Admin Tool shows all the dependencies of the selected assembly. Also, we here we can alter and configure the dependencies of of the assembly from the dependency list. The list shows assemblies our client depends on. The highlighted entry in the following figure is the version of 'fontassembly.dll' that our client is using presently.

Figure 3 : Default Assembly Versions


We plan to request for a new version. To do so we have to right click on 'Configured Assemblies' and select 'Add'. Next we have to select 'Choose an assembly from the assembly cache' and click 'Choose Assembly'. Then select 'fontassembly.dll' with the new version and click 'Select'. On selecting 'Finish' we get the 'Properties' sheet. In this sheet we will have to specify the old and new version of 'fontassembly.dll'. Now we can find an application configuration file 'fontclient.exe.config' in the directory of the 'fontclient.exe'. The 'fontclient.exe.config' file that gets created is in XML format is as shown below

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


<?xml version="1.0"?> <configuration> <runtime> <assemblyBinding xmlns="urn:schemasmicrosoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="fontassembly" publicKeyToken = "a97ce0a468973397" /> <bindingRedirect oldVersion="1.0.1.1" newVersion="1.1.1.1" /> </dependentAssembly> </assemblyBinding> </runtime> </configuration> When we run the client with this configuration file the redirected version 1.1.1.1 is used instead of the older version.

Article: C# - Events And Delegates - I


Each action the user makes such as clicking the mouse button, selecting a menu item, pushing a button, etc. raises an event. Events notify that something has happened, as a result, some action should take place. The action is performed in a method called an event handler. All the event handlers are called with the help of delegates. Hence to understand events and event handlers we must first know what delegates are. Delegates We normally pass a value or a reference of an object to a method. Situations may arise where we may need to pass an address of some method to another method. This was done previously with the help of function pointers. This approach is not type safe and certainly not object-oriented. C#'s alternative for function pointers is delegates. Here, the word delegate means a representation of a function. A delegate is implemented as an object that stores address of method in it. The class of this object is called a delegate class and is derived from System.MulticastDelegate class. To store the address of a method, bool fun ( string ) { } in a delegate we have to carry out two steps: a. Declare a delegate class b. Create a delegate object and store the address of the method in it Declaring A Delegate Class Here is a single delegate class declaration

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


public delegate bool del1 ( string ) ; When the compiler encounters this statement it creates a class named del1 and derives it from the System.MulticastDelegate class. The compiler also inserts a two-argument constructor in the del1 class. Note that we are never required to define a delegate class. Later when an object of the delegate class del1 is created, it can hold address of a method that receives a string and returns a bool. Creating A Delegate Object To store address of the fun( ) method inside a delegate object need to first create a delegate object. This is how it can be done. del1 f = new del1 ( fun ) ; Here f is a reference to an object of del1. The address of the fun( ) method is passed to the constructor of the delegate class which is created by the compiler. The constructor stores this address in the delegate object. To call the wrapped method we can write the following statement: bool b = f ( "Hi" ) ; Here f delegates (represents) fun( ) in true sense. Delegates are very flexible. It does not matter whether the method to be wrapped by the delegate is a static method or an instance method. Also, these methods can belong to any class. Consider the following program: using System ; namespace Sample { public delegate void click( ) ; public class MyForm { public click c1 ; public void mouseclick( ) { c1( ) ; } } class MyForm1 : MyForm { public MyForm1( ) { c1 = new click ( MyForm1_click ) ; mouseclick( ) ; c1 = new click ( button_click ) ; mouseclick( ) ; } static void Main ( string[ ] args ) {

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


MyForm1 f = new MyForm1( ) ; } public void MyForm1_click( ) { Console.WriteLine ( "Form clicked" ) ; } public static void button_click( ) { Console.WriteLine ( "Button clicked" ) ; } } } In the above program we have declared a delegate class called click. Later when an object of this class is created it can hold address of any method that does not accept or return anything. We have created two classes in the program: a MyForm class and a MyForm1 class derived from MyForm. The MyForm class contains a reference c1 of the type click and a method called mouseclick( ). Besides the zero argument constructor and Main( ), the MyForm1 class contains an instance method called MyForm1_click( ) and a static method called button_click( ). Both MyForm1_click( ) and button_click( ) methods are eligible to be wrapped inside the delegate object, because prototypes of both the methods match the prototype mentioned in the delegate declaration. In Main( ) we have created an object of the MyForm1 class resulting in the constructor being called. In the constructor we have stored the address of the MyForm1_click( ) method in the reference c1. Thus, c1 delegates (represents) the method MyForm1_click( ). Next we have called the mouseclick( ) method which in turn calls the MyForm1_click( ) method via c1. The next statement in the constructor makes c1 to refer to the static method and hence a call to the mouseclick( ) method results in calling the static method. This program was a little odd but it would help you to understand the event-handling model of WinForms programming in C#. Multiple Methods In A Delegate A delegate can wrap even more than one method. For this, it maintains a linked list. The delegate then points to the head of such a linked list. This means that when such a delegate is invoked it calls all the methods that form the linked list. Hence, instead of the statements c1 = new click ( MyForm1_click ) ; mouseclick( ) ; c1 = new click ( button_click ) ; mouseclick( ) ; we can simply write

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


c1 += new click ( MyForm1_click ) ; c1 += new click ( button_click ) ; mouseclick( ) ; The delegate c1 inside the mouseclick( ) method would now call both the methods. Here we are simply adding both the methods in a list and hence both would be called. Rest of the program remains same. Events As said earlier, the Windows GUI programming requires that the program must respond to events. An event in C# is a multicast delegate having a predefined prototype. The prototype is such that every event (actually a multicast delegate) would, by convention return a void and always accept two parameters. The first parameter is always a reference to an object of System.Object class and the second parameter is always a reference to an object of the System.EventArgs class or a class derived from it. The EventArgs object contains information about the event. The object that raises an event is called an 'event raiser' and the object that receives an event is called an 'event receiver'. Whenever an event is raised a method is called that handles the event (hence called an event handler). The event raiser class always declares the event and the receiver class must have an event handler to handle that event. The first parameter collected by the event handler is always a reference to an event raiser object. The addresses of event handlers are stored inside the events (remember that events are actually delegates) and hence they also must have the same signature as the event. Such kind of a delegate is declared using the keyword event.

Article: C# - Events And Delegates - II


Continued from last week... To understand events, consider the following program: using System ; namespace Sample { public class mouseeventargs { public int x, y ; public mouseeventargs ( int x1, int y1 ) { x = x1 ; y = y1 ; } } public delegate void click ( object m, mouseeventargs e ) ; public class MyForm { public event click c1 ; public void mouseclick( ) {

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


mouseeventargs m = new mouseeventargs ( 10, 20 ) ; c1 ( this, m ) ; } } class MyForm1 : MyForm { public MyForm1( ) { c1 += new click ( button_click ) ; mouseclick( ) ; } static void Main ( string[ ] args ) { MyForm1 f = new MyForm1( ) ; } public void button_click ( object m, mouseeventargs e ) { Console.WriteLine ( "Mouse Coordinates: " + e.x + " " + e.y ) ; Console.WriteLine ( "Type is: " + m.GetType( ).ToString( ) ) ; } } } The output of the program would be Mouse Coordinates: 10 20 Type is: Sample.MyForm1 In this program we have declared 3 classes-mouseeventargs, MyForm and MyForm1 derived from MyForm. The mouseevntargs class corresponds to the EventArgs class. This class contains two int variables x and y and a constructor to initialize them. We have declared a multicast delegate click whose signature is same as the event handler button_click( ). The MyForm class here is an event raiser class and hence contains an event as a data member called c1 of the type click. It also contains a method called mouseclick( ). In this method we have created an object of the mouseeventargs class. In the statement, c1 ( this, m ) ; c1 represents (is a delegate for) button_click( ). this contains the reference of MyForm object (event raiser) and m is a reference of the mouseeventargs object. In the MyForm1 class, we have defined the method button_click( ) (i.e. event handler). When the compiler encounters the statement c1 += new click (button_click) it creates an event object (delegate object) that wraps up button_click( ) method. So whenever the c1 event is raised (or called, as in this program), the method button _click( ) will get executed. Now back to WinForms. WinForms event handling model follows the same arrangement that we discussed above. The difference is that Event programming in WinForms is very easy and we need not think about these underlying concepts every time. The Wizard automatically generates

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


code for us and we have to just write logic in the event handlers. Let's take a look at what the wizard generates for us every time we add an event handler to our form. Create a 'Windows Application' which should display a message box when the user clicks on the form. The following code would get generated. using System ; using System.Windows.Forms ; namespace SampleClick { public class Form1 : System.Windows.Forms.Form { public Form1( ) { InitializeComponent( ) ; } #region Windows Form Designer generated code private void InitializeComponent( ) { this.Click += new System.EventHandler ( this.Form1_Click ) ; } #endregion static void Main( ) { Application.Run ( new Form1( ) ) ; } private void Form1_Click ( object sender, System.EventArgs e ) { MessageBox.Show ( "Hello C#" ) ; } } } We have erased the comments and some extra code added by the wizard for the sake of clarity. We just have to type the code which is given in bold letters above and compile the program. On executing the program and clicking on the form we get the output as shown in Figure 1.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Figure 1 Here, Click is a reference to an event of the type System.EventHandler and is already defined in the System.Windows.Form class. Realize that System.EventHandler is a delegate used to wrap an event handler. A delegate that dispatches an event is called an 'event delegate'. The event handler Form1_Click( ) is wrapped inside the Click event. This method is written in the Form1 class and it accepts two references. One of them is of object type and contains reference of the event raiser (Form1 here) and the other is of type EventArgs. Here we have not written any statement to explicitly raise the event Click( ). Whenever the user clicks on the form the .NET runtime raises this event for us. .NET runtime then informs the base class, Form about this event. The Form class would call the event handler using the statement like Click ( reference of sender, reference of EventArgs ) ; Here, Click represents (is a delegate for) Form1_Click( ) event handler. And so, this statement would call the Form1_Click( ) handler.

Article: C# - Properties And Indexers - I


Bashing Structured paradigm and glorifying OO has been the computing industry's favourite past time for almost a decade now. OO programming has also grown old now. Today is the era of modern OO languages, which take the OO paradigm further. Properties, indexers and events are first class citizens of modern OO languages like C#. Nothing great if C# supports encapsulation, inheritance and polymorphism. It being an OO language this was expected of it. It being a modern OO language, it supports features like properties, events, indexers, delegates etc. Of these this article would cover properties and indexers. Properties

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Properties of a class are actually methods that work like data members. We have already used the Length property of the System.Array and System.String class in an earlier article. The properties are used to store and retrieve the values to and from the data members of the class. For example, to store and retrieve the length data member of the string class the Length property is used. Conventionally the data members are given names starting with a lower case letter and the corresponding properties are given names starting with a capital letter. Manipulating data using properties is done through two special methods known as accessors. There can be two accessors: a get accessor and a set accessor. The following code shows both of them. using System ; namespace properties { public class sample { int length ; public int Length { get { return length ; } set { length = value ; } } } class Class1 { static void Main ( string[ ] args ) { sample m = new sample( ) ; m.Length = 10 ; int len = m.Length ; Console.WriteLine ( "Length: " + len ) ; } } } Here we intend to access and modify the length data member of the sample class. Since it is of the type int we have used public int Length to declare the property to be of the type int. As a result, the get accessor would return an int type and the set accessor would collect the int type. The get accessor never accepts any value and the set accessor never returns any value. The value collected by the set accessor is stored in an implicit parameter called value. value is a keyword and would always have a type corresponding to the property. We should be careful not to give any data member a name value. The statement m.Length = 10 would invoke the set accessor automatically. The statement int len = m.Length would invoke the get accessor automatically. In general the get accessor is invoked when we want to retrieve the value of the property, whereas the set accessor is invoked when we assign a value to the property. We cannot explicitly

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


call the accessors using the get and set keywords. If only get accessor is present the property is called a read only property. If only set accessor is present then the property is called a write-only property. If both accessors are present, the property is said to be a read-write property. If we write a statement, m.Length = m.Length + 20 both the get and set accessors would get called. When the addition operation is performed the get accessor would get called. The get accessor will return the value of length. Next 20 would be added to it. Now using the set accessor, the resulting value would be assigned to length. A Few Subtleties Let us now look at a few subtleties associated with accessors: a. The advantage of using properties as against public data member is that if we want, we can perform some functionality in the accessor body. For example, we can check range for the length variable in the set accessor as shown in the following code snippet. set { if ( value > 10 ) length = value ; } b. If we derive a class from a base class which has a public property declared in it, the object of the derived class can also access the property of the base class. If the property of the base class is declared as virtual the derived class can override the base class property with its own version of the property. c. Properties can also be declared abstract. If we declare the property as abstract, it is necessary to declare the class containing the property as abstract. Since we cannot create the objects of the abstract class, it becomes necessary to derive a class from it and implement the property. For example, in the following program the class dimensions has one abstract property Height. public abstract class dimensions { protected int height ; public abstract int Height { get ; set ; } } To declare the property abstract we have to write the get and set keywords without any accessor body. The derived class must implement the property as shown below. public class window : dimensions { public override int Height {

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


get { return height ; } set { height = value ; } } } d. The static modifier can be used to create properties that belong to a class and not to an individual object. We can write static properties for static data members only. To access these properties we have to use the class name instead of an object. For example, using System ; namespace sample { public class window { static int height ; public static int Height { get { return height ; } set { height = value ; } } } class Class1 { static void Main ( string[ ] args ) { window.Height = 10 ; Console.WriteLine ( "Window height: " + window.Height ) ; } } } e. A class can contain multiple properties.

Article: Properties And Indexers- II


Continued from last week... Indexers An Indexer is a special type of property. If a class contains an array as a data member, an indexer lets us access the array within the class using an object as though the object itself were an array. This is done using the [ ] operator. For example, consider a class myclass which has an

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


int array as a data member and we create an object a of that class. Here we can access the elements of the array by using the expressions a[0], a[1], a[2] and so on. The following code snippet shows how to declare an indexer: public int this [ int index ] { get { // code } set { // code } } Like properties we use the get and set accessors in indexers. The difference between a property and an indexer is that an indexer is nameless. This means it does not have a name like Height, Length, etc. instead the this keyword is used to declare an indexer. The this reference refers to the object we are indexing. The first int in the indexer declaration specifies type of the array. The second int within the square brackets specifies the type of argument we would be using to index into an array. The following example shows how we can make an object behave like an array: using System ; namespace sample { public class array { float[ ] arr = new float [ ] { 12.5f, 34.3f, 5.2f, 6.1f, 7.5f, 88.8f, 22.9f } ; public float this [ int index ] { get { return arr [ index ] ; } set { arr [ index ] = value ; } } } class Class1 { static void Main ( string [ ] args ) { array a = new array( ) ; a [ 3 ] = 43.2f ; Console.WriteLine ( a [ 3 ] ) ; } } }

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Here arr is a float array and it belongs to the same class in which we have declared the indexer. When we write the statement a [ 3 ] = 43.2f the set accessor gets called. The index 3 would get collected in the variable index and 43.2f would get collected in the variable value. When we write the statement, Console.WriteLine ( a [ 3 ] ) ; the get accessor gets called. The index 3 would get collected in the variable index and the element at fourth place would be returned. We can also declare an indexer for a multi-dimensional array. In the following program we have used two indexers one for 1D array and another for 2D array. Such indexers are known as overloaded indexers. using System; namespace sample { public class array { int [ ] arr1 = new int [ ] { 12, 34, 5, 6, 7, 88, 22 } ; int [ , ] arr2 = new int [ , ] { { 12, 34, 5, 6 }, { 7, 88, 22, 2 } }; public int this [ int index ] { get { return arr1 [ index ] ; } set { arr1 [ index ] = value ; } } public int this [ int index1, int index2 ] { get { return arr2 [ index1,index2 ] ; } set { arr2 [ index1,index2 ] = value ; } } } class Class1 { static void Main ( string[ ] args ) {

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


array a = new array( ) ; a [ 3 ] = 43 ; a [ 0, 2 ] = 89 ; } } } The two int variables specified within brackets in the statement, public int this [ int index1, int index2 ] Specify the two indexes used to access an element of the 2D array. When we write i [ 3 ] = 43 , the set accessor with one argument gets called and when we write i [ 0, 2 ] = 89, the set accessor with two arguments gets called. It is not possible to write indexers for jagged arrays because a statement such as public int this [ int index1] [ int index2 ] is an error. Lastly, indexers can not be declared as static. Indexers work in the same way as properties when declared as virtual.

Article: C# - Arrays And Strings - I


Arrays and Strings are perhaps as old as programming languages themselves. They have been around for so long that they are almost taken for granted. Don't make this mistake while learning C#. In C# they are different and more powerful. That's bound to happen when a language is developed from ground up without being required to shoulder the responsibility of backward compatibility An array is a collection of similar elements stored in adjacent memory locations. These similar elements could be all ints, all floats, all chars, etc. For example, int[ ] arr1 = { 1, 2, 3 } ; float[ ] arr2 = { 1.5f, 2.5f, 3.5f } ; char[ ] arr3 = { 'a', 'b', 'c' } ; All elements of an array must be of the same type, i.e. we cannot have an array of 10 numbers, of which 5 are ints and 5 are floats. Arrays in C# are reference types and are implemented as objects. They are derived from the abstract class System.Array. The following code shows how to declare references to an int array: int[ ] a ; // declare an int array reference int[ ] a1, a2 ; // declare two array references

Here a, a1, a2 are references to an int array. Thus we are not declaring an array. Instead, we are declaring a reference to it. This merely sets aside space for reference to an array. Once we have declared an array reference, we can construct an array through the statement:

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


a = new int [ 5 ] ; Following figure shows how the array and reference would appear in memory:

To initialize an array we need to write the following statement: int[ ] arr1 = new int[ ] { 3, 5, 7, 9, 1 } ; Or int[ ] arr1 = { 3, 5, 7, 9, 1 } ; Here the array gets allocated on the heap and all its elements store a value. By default, all the elements of this array are initialized with a value 0. We can also create an array of objects. This is explained with an example, sample[ ] s = new sample [ 5 ] ; Here s is a reference to an array of references. The array gets created on the heap. Each element of the array in itself is a reference to the sample object. Hence, each reference would hold address of an object and not its value. By default, all the elements are initialized with a null reference. The in-memory view of the array is shown below:

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

To assign the array element with the addresses of the objects we need to write the following statements: s [ 0 ] = new sample ( 1 ) ; s [ 1 ] = new sample ( 2 ) ; s [ 2 ] = new sample ( 3 ) ; s [ 3 ] = new sample ( 4 ) ; s [ 4 ] = new sample ( 5 ) ; Or sample s[ ] = { new sample ( 1 ), new sample ( 2 ), new sample ( 3 ), new sample ( 4 ), new sample ( 5 ), } Like C and C++, C# also uses a zero-based scheme to access array elements. This means that the first element in the array is considered to be at 0th position. Multidimensional Arrays In C# multidimensional arrays are of two types - Rectangular and Jagged. C# has a different syntax for both. Rectangular Arrays In rectangular arrays every row of the array is of the same length. This means if we have a two-

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


dimensional array, all the rows will have same number of elements. This property is similar to arrays in C or C++. The following code snippet will give you an idea about rectangular arrays: int [ , ] arr1 = new int [ , ] { { 3, 5, 7, 9 }, { 11, 13, 15, 17 } } ; Or int [ , ] arr1 = { { 2, 4, 6, 8 }, {10, 12, 14, 16 } } ;

To print the elements of the rectangular array we need to write the following code: foreach ( int i in arr1 ) Console.Write ( i + " " ) ; The foreach loop allows us to iterate through each item in an array. The foreach loop always travels through all elements of one row before moving to the next row. Using foreach we can never travel through a 2-D array column by column. Jagged Array A jagged array is an array of several 1D arrays each of different length. We cannot create the jagged array in the same way as we created the rectangular array. Suppose we are required to create a jagged array containing 2 rows where first row contains four integers and the second row contains 2 integers. We may try to define this array as follows: int [ , ] arr1 = new int [ , ] { { 3, 5, 7, 1 }, { 11, 13 } } ; Or int [ , ] arr1 = { { 3, 5, 7, 1 }, { 11, 13 } } ; Both these definitions are wrong, because the number of elements in each row is different and the complier never keeps track of how many elements are present in each row. Hence later on it would not be feasible for it to access the correct element when we use an array access expression, like arr [ 1, 2 ]. The correct way to initialize the jagged array is as follows: int[ ] [ ] arr1 = new int [ 2 ] [ ] ; arr1 [ 0 ] = new int [ 3 ] { 3 , 5, 7, 1 } ; arr1 [ 1 ] = new int [ 2 ] { 11, 13 } ; The in-memory view of this jagged array is as follows:

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

The way to create a 3D jagged array is as follows: int[ ] [ ] [ ] arr = new int [ 2 ] [ ] [ ] ; arr [ 0 ] = new int [ 3 ] [ ] ; arr [ 0 ] [ 0 ] = new int [ 3 ] ; arr [ 0 ] [ 1 ] = new int [ 4 ] ; arr [ 0 ] [ 2 ] = new int [ 5] ; Here the 3D array consists of two 2D arrays. The first 2D array would consist of three 1D arrays, and finally all the three 1D arrays have different number of elements. From the above discussion it is clear that in a rectangular array all indices are within one set of brackets. for a jagged array each element is within its own bracket. For a 2D rectangular array we have to write int [ , ] whereas, for a 2-D jagged array we have to write int[ ][ ].

Article: C# - Arrays And Strings - II


Continued from last week... The System.Array type The System.Array class automatically becomes the base class of any type of array. Hence we can store the reference to an array into the reference to the System.Array class. Unlike in C or C++, the .NET runtime performs bounds checking on all arrays and throws a System.IndexOutOfRangeException when the bounds of array are exceeded. The array class provides methods for creating, manipulating, searching, and sorting arrays. The following programs illustrate usage of some of the System.Array methods. using System ; class onedarray { static void Main ( string[ ] args ) { int[ ] arr1 = new int [ 5 ] { 1, 4, 7, 8, 9 } ; int[ ] arr2 = new int [ 10 ] ; arr1.CopyTo ( arr2, 0 ) ; Console.WriteLine ( "Elements of arr2: " ) ; foreach ( int i in arr2 ) Console.Write ( i + " " ) ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Console.WriteLine( ) ; arr2.SetValue ( 5, 0 ) ; Console.WriteLine ( "Elements of arr2: " ) ; foreach ( int i in arr2 ) Console.Write ( i + " " ) ; Console.WriteLine( ) ; Console.WriteLine ( "Number of elements in arr1:" + arr1.Length ) ; Console.WriteLine ( "Number of elements in arr2:" + arr2.Length ) ; Array.Copy ( arr1, 2, arr2, 6, 2 ) ; Console.WriteLine ( "Elements of arr2: " ) ; foreach ( int i in arr2 ) Console.Write ( i + " " ) ; Console.WriteLine( ) ; Array.Reverse ( arr2 ) ; Console.WriteLine ( "Elements of arr2: " ) ; foreach ( int i in arr2 ) Console.Write ( i + " ") ; Console.WriteLine( ) ; Array.Sort ( arr2 ) ; Console.WriteLine ( "Elements of arr2: " ) ; foreach ( int i in arr2 ) Console.Write ( i + " " ) ; Console.WriteLine( ) ; Console.WriteLine ( "Index of 8 is " + Array.IndexOf ( arr2, 8 ) ) ; Array.Clear ( arr2, 3, 3 ) ; Console.WriteLine ( "Elements of arr2: " ) ; foreach ( int i in arr2 ) Console.Write ( i + " " ) ; Console.WriteLine( ) ; } } In this program we have created two one-dimensional int arrays called arr1 and arr2. We have then initialized arr1 with 5 elements and left arr2 uninitialized. The compiler will, hence, initialize arr2 with zeros (i.e. the default value for int types). The CopyTo( ) method is used to copy elements from arr1 to arr2 starting from index 0. Using the foreach loop we have printed the elements in arr2. The output would be, Elements of arr2: 1478900000 Since we have copied the first five elements from arr1 into arr2 the rest of the elements remain zero. The SetValue( ) method sets a value ( mentioned as the first parameter ) in an array at a specified index ( specified by the second parameter). Here we have set the 0th element in arr2 to value 5. After setting the value we get the output as follows: Elements of arr2: 5478900000

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Length is a property that specifies the total number of elements in an array. Properties are similar to methods and are used to manipulate data. The Length of arr1 in our program is 5, whereas, the Length of arr2 is 10. The Copy( ), Reverse( ), Sort( ), and Clear( ) methods are static methods of the System.Array class. The Copy( ) method is used to copy a group of elements from one array to another. This method has two overloaded versions, which are as follows: public static void Copy ( Array, Array, int ) and public static void Copy ( Array, int, Array, int, int ) The first version accepts a reference to the source array, a reference to the destination array and number of elements to be copied. The second version accepts a reference to the source array, the index in the source array from where copying should begin, a reference to the destination array, the index in destination array from where elements should be stored and lastly the number of elements to be copied. We have used the second version in our program. We have specified that copying should start from element at index 2 in arr1. The elements should be copied from the 6th index in arr2 and in all 2 elements should be copied. After this operation the output is as follows: Elements of arr2: 5478907800 The Reverse( ) method reverses the elements of an array. It has one more overloaded version that accepts a reference of an array to be reversed, the index from where the reverse operation should begin and the number of elements to be reversed starting from the index specified as the second parameter. The result of this operation is shown below. Elements of arr2: 0087098745 The Sort( ) method sorts the array in an ascending order. If we want the array to be sorted in the descending order we would have to sort it and then reverse it. After sorting the array we would get the following result: Elements of arr2: 0004577889 The IndexOf( ) method returns the index of a given element in an array. In our program we have printed the index of element 8, which happens to be 7. If 8 occurs more than once in the array then the index of the first would be returned. The Clear( ) method clears all the elements in an array from an index specified as the first parameter. We also have to specify the number of elements to be cleared as the second parameter. If the elements are of value types they get reinitialized to zeros, whereas, if they are of reference types they get reinitialized to null. The result is as follows: Elements of arr2: 0000007889 Let us now see how to apply the functions provided by the System.Array class on a rectangular 2D array.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


using System ; class rectarray { static void Main ( string[ ] args ) { int [ , ] arr1 = new int [ 2, 3 ] { { 1, 2, 3 }, { 4, 5, 6 } } ; int [ , ] arr2 = new int [ 2, 3 ] ; Console.WriteLine ( " Elements of arr1: " ) ; for ( int i = 0 ; i <= arr1.GetUpperBound ( 0 ) ; i++ ) { for ( int j = 0 ; j <= arr1.GetUpperBound ( 1 ) ; j++ ) Console.Write ( arr1 [ i, j ] + " " ) ; Console.WriteLine( ) ; } Console.WriteLine ( "Number of elements in arr1: " + arr1.Length ) ; Array.Copy ( arr1, 2, arr2, 2, 3 ) ; Console.WriteLine ( " Elements of arr2: " ) ; foreach ( int i in arr2 ) Console.Write ( i + " " ) ; arr2.SetValue ( 5, 0, 1 ) ; Console.WriteLine ( " Elements of arr2: " ) ; foreach ( int i in arr2 ) Console.Write ( i + " " ) ; Array.Clear ( arr2, 0, arr2.Length ) ; Console.WriteLine ( " Elements of arr2: " ) ; foreach ( int i in arr2 ) Console.Write ( i ) ; } } In the above program we have created two rectangular 2D arrays arr1 and arr2 both having 2 rows and 3 columns. We have initialized arr1 with 6 elements and left arr2 uninitialized. Hence, the compiler will initialize arr2 with zeros. To print the elements in a matrix format we have used two nested for loops instead of foreach. The GetUpperBound( ) method gives index of the last row if 0 is specified as its parameter, hence we would get 1. If 1 is specified it would return us the index of the last column, hence we would get 2. The output after this loop is as follows: Elements of arr1: 123 456 The Length property has a value 6 as there are totally 6 elements in arr1. The Copy( ) method works in the same way for a 2D array as it works for a 1D array. After the copy operation we would get the output as shown below. Elements of arr2: 003450 The SetValue( ) method that operates on a 2D array accepts the value to be set followed by two ints specifying indices for each dimension in the array. Likewise, the System.Array class provides an overloaded version for a 3D array, which accepts 3 indices. For an array with

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


dimensions more than 3, an array has to be created, filled with indices and passed to the SetValue( ) method as the second parameter. Let us now see how the methods in System.Array can be applied to a jagged 2D array. using System ; class jaggedarray { static void Main ( string[ ] args ) { int [ ][ ] arr1 = new int [ 2 ] [ ] ; arr1 [ 0 ] = new int [ 3 ] { 1, 2, 3 } ; arr1 [ 1 ] = new int [ 2 ] { 4, 5 } ; Console.WriteLine ( "Elements of arr1: " ) ; for ( int i = 0 ; i < arr1.Length ; i++ ) { for ( int j = 0 ; j < arr1[ i ].Length ; j++ ) Console.Write ( arr1 [ i ] [ j ] ) ; Console.WriteLine( ) ; } } } In this program we have created a jagged two-dimensional array called arr1. arr1[0] has 3 elements while arr1[1] has 2 elements. We have printed the entire array using two nested for loops. We cannot use a foreach loop on jagged arrays because the number of elements in each 1D array of a jagged array is not same. Now as a jagged array is considered to be an array of 1D arrays, all the methods that we called on 1D arrays can be called on each 1D array that make up a jagged array.

Article: C# - Arrays And Strings - III


Continued from last week... Strings The string type is a predefined data type in C# and is an alias of the System.String class. Hence they can be used interchangeably. Instances of the string type represent Unicode character strings. The following statement shows how to assign a value to a string object: string s = "Hello" ; Here a reference s gets created on the stack while the object referred to by s gets created on the heap. C# supports two types of string variables, quoted and @-quoted. Quoted strings are normal strings that support escape sequences. If we do not want the compiler to process escape sequences we can use an @-quoted string. These strings are formed by prefixing the string with an '@' symbol. The main advantage of an @-quoted string is that, it simplifies the expression of path names. For example, string s2 = @"C:\Articles\text.txt" ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


If @ symbol is not prefixed to this string then, its necessary to replace each '\' with '\\'. But the string shown below cannot be prefixed by the @ symbol if we want that the escape sequence should be processed. string s1 = "hi \t there" ; Whenever the compiler sees a '\t', it prints out a tab. Hence the output would become, hi there

When we use an assignment operation between two reference variables, the reference to the first object gets copied into the other reference variable. But this is not the case with strings. In spite of being a reference type an assignment operation on two string variables results in creation of a new object. The value of the right-hand side string object gets copied into the new object and the reference to this new object gets assigned to the reference variable on the left-hand side of the assignment operator. This is shown in the following example. using System; namespace sample { class Class1 { static void Main ( string[ ] args ) { string s1 = "Good Morning" ; string s2 ; s2 = s1 ; s1 = "Wake Up" ; Console.WriteLine ( s1 ) ; Console.WriteLine ( s2 ) ; } } } The output of the program would be, Wake up Good Morning In this program we have created two string references - s1 and s2. We have initialized s1 with a reference to an object containing "Good Morning" and kept s2 uninitialized. Then we have assigned s1 to s2. Normally both being references only the reference should have assigned to s1. But this does not happen. Instead a new object gets created that holds the same value contained in the object referred by s1. Like System.Array, System.String class too defines various methods to perform routine operations on strings. The following programs illustrate use of the System.String methods. using System ; namespace sample { class Class1 {

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


static void Main ( string[ ] args ) { string s1 = "kicit" ; string s2 = "Nagpur" ; Console.WriteLine ( "Char at 3rd position: " + s1 [ 2 ] ) ; string s3 = string.Concat ( s1, s2 ) ; Console.WriteLine ( s3 ) ; Console.WriteLine ( "Length of s3: " + s3.Length ) ; s3 = s3.Replace ( 'p', 'P' ) ; Console.WriteLine ( s3 ) ; s3 = string.Copy ( s2 ) ; Console.WriteLine ( s3 ) ; int c = s2.CompareTo ( s3 ) ; if ( c < 0 ) Console.WriteLine ( "s2 is less than s3" ) ; if ( c == 0 ) Console.WriteLine ( "s2 is equal to s3" ) ; if ( c > 0 ) Console.WriteLine ( "s2 is greater than s3" ) ; if ( s1 == s3 ) Console.WriteLine ( "s1 is equal to s3" ) ; else Console.WriteLine ( "s1 is not equal to s3" ) ; s3 = s1.ToUpper( ) ; Console.WriteLine ( s3 ) ; s3 = s2.Insert ( 6, "Mumbai" ) ; Console.WriteLine ( s3 ) ; s3 = s2.Remove ( 0, 1 ) ; Console.WriteLine ( s3 ) ; int fin = s1.IndexOf ( 'i' ) ; Console.WriteLine ( "First index of i in s1: " + fin ) ; int lin = s1.LastIndexOf ( 'i' ) ; Console.WriteLine ( "Last index of i in s1: " + lin ) ; string sub = s1.Substring ( fin, lin ) ; Console.WriteLine ( "Substring: " + sub ) ; int i = 10 ; float f = 9.8f ; s3 = string.Format ( "Value of i : {0} \nValue of f : {1}", i, f ) ; Console.WriteLine ( s3 ) ; } } } In this program we have created two string variables s1 and s2 and initialized them to "kicit" and "Nagpur" respectively. The [ ] operator accesses individual characters of a string. Hence to access the 3rd character we have to write s1[ 2 ] which in the string s1 happens to be character

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


'c'. The Concat( ) method is a static method which concatenates two strings and returns a new object which gets stored in s3. Hence the object referred to by s3 would contain "kicitNagpur". The Length property of a string returns the number of characters in a string. The length of s3 in our program is 11. The Replace( ) method replaces all the instances of a character ( mentioned as the first parameter) with the character given as the second parameter. Here we have replaced 'p' with a 'P' in string referred to by s3. The Copy( ) method is a static method that copies all the characters from one string object to another. If the destination string is smaller in length, its length is increased automatically. The CompareTo( ) method compares two strings alphabetically. This means a string with a starting alphabet 'a' will always be lesser than a string with starting alphabet as 'b'. This method returns a negative integer if the string object that has called the CompareTo( ) method contains a string which is lesser than the string contained in the object whose reference is passed as the method's parameter. It returns a positive number if the string objects are interchanged. It returns zero when both strings are equal. In the same way the == operator compares two strings and returns a bool - true if the strings are equal and false if they are not. The ToUpper( ) method creates a new object, stores in it the converted upper case string and returns the address of this object. This address is collected in s3. Note that s1 is not affected here. Hence we can draw a conclusion that the object which we use to call the methods to manipulates the string, does not affect the object. The Insert( ) method inserts a string specified as the second parameter at the index specified as the first parameter. Here too s1 does not get affected and the returned string is collected in s3. So we get "NagpurMumbai" in s3. In the Remove( ) method two arguments are passed. The first parameter is an index from where we wish to remove elements and the second parameter is the total number of elements to be removed. We have passed 0 and 1 meaning we wish to remove only the 0th element from s3. So the string s3 would now contain "agpur". The IndexOf( ) method returns the index of first occurrence of a given character in the string. Similarly, LastIndexOf( ) method returns the index of last occurrence of a given character in the string. In our program the first index of 'i' happens to be 1 whereas the last index is 3. The Substring( ) method returns a new string which starts at an index passed as the first parameter and ends at an index passed as the second parameter to the method. The Format( ) method replaces the format specifiers (such as {0}, {1}, etc.) into string representations. This is a static method that returns the formatted string. An important point to note is that the == operator is case insensitive. The Compare( ) and CompareTo( ) methods are two different methods in the string class. Compare( ) is a static method while CompareTo( ) is not. The Compare( ) method can be made case insensitive by passing true as the last parameter. Here's a code snippet that illustrates this. string str1 = "hello" ;` string str2 = "HELLO" ; bool chk1 = ( str1 == str2 ) ; //returns false int chk2 = ( String.Compare ( str1, str2, true ) ) ; // returns 0

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


A Few Subtleties Till now we have printed values using the WriteLine( ) method. What about taking the input from the user? The Console class provides a method ReadLine( ) that accepts a complete line entered (including spaces) by the user on the console. Then what about integers and floats? The same ReadLine( ) method can be used to accept numbers too. But it returns numbers in the form of a string object. The following program demonstrates how these numbers can be converted back to their numeric values: using System ; namespace sample { class Class1 { static void Main ( string[ ] args ) { Console.WriteLine ( "Enter an integer: " ) ; string s = Console.ReadLine( ) ; int i = int.Parse ( s ) ; Console.WriteLine ( "Enter a float: " ) ; s = Console.ReadLine( ) ; float f = float.Parse ( s ) ; float t = f + i ; Console.WriteLine ( t ) ; } } } In this program firstly we have used the ReadLine( ) method to accept an integer from the console. Then using the int data type (which is an alias of Int32 structure defined by .NET) we have called a static method Parse( ) of the Int32 structure. This method converts a string to an integer. Likewise, to convert a string to a float we have called the static method Parse( ) of the structure Single (of which the float data type is an alias). The numeric values can also be converted to strings. The following code snippet demonstrates how integers and floats can be converted to a string: int i = 10 ; float f = 3.14f ; Console.WriteLine ( "Integer to String : " + i.ToString( ) ) ; Console.WriteLine ( "Float to String: " + f.ToString( ) ) ; Here ToString( ) method is a non-static method of the structures Int32 and Single. There is one more way in which we can convert numbers to strings. This is as follows: string s = string.Format ( "Value of i: {0} \nValue of f: {1}", i, f ) ; Console.WriteLine ( s ) ; Here the Format( ) method is a static method of the String class.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com Article: C# - Management By Exception - I


Exception Handling Errors. Innocent errors. Silly errors. Fatal errors. Not so fatal errors. Performing errors is programmer's birthright. A typical programmer spends as much time in fixing errors as in programming. Different mechanisms have evolved to tackle these errors. Exception handling is the latest in the list. What is common amongst different programmers using widely varying languages? Their ability to create errors in the programs. Programmers of all kind are error prone. We can categorize the errors, that they perform, into 3 broad categories: (a) Grammatical/Syntax errors (b) Linker errors (c) Run-time errors Syntax errors occur only when syntax goes wrong. If the syntax goes wrong then it's the compiler, which reports the errors to us. Unless we correct these errors we cannot build the executable file of our program. Linker error occurs when we try to access some library function and for some reason or the other the function cannot be found. Most dangerous of these errors are the runtime errors. Runtime errors mean errors which occur at the time of execution of the program. Such errors are known as exceptions. Tackling these errors is the programmer's job. The reasons why exceptions occur are numerous. Some of the more common reasons are: (a) Falling short of memory (b) Dividing a value by zero (c) Inability to open a file (d) Exceeding the bounds of an array (e) Attempting to initialize an object to an impossible value When such exceptions occur, the programmer has to decide a strategy according to which he would handle the exceptions. The strategies could be, displaying the error messages on the screen, or displaying a dialog box in case of a GUI (Graphic User Interface, for example, Windows) environment, or requesting the user to supply better data or simply terminating the program execution. In non-object oriented programming languages exceptions are dealt by following the function calls with error checks on return values to find whether the function did its job properly or not. In C programs a function usually returns an error value if an error occurs during execution of that function. For example, file-opening functions return a NULL indicating their inability to open a file successfully. Hence, each time we call these functions we can check for the return value. This is shown for some fictitious functions fun1( ), fun2( ) and fun3( ) in the following code: if ( func1( ) == ERROR_VALUE ) // handle the error else // do normal things if ( func2( ) == NULL ) // handle the error else // do normal things

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

if ( func3( ) == -1 ) // handle the error else // do normal things There are three problems with this approach: (a) Every time we call a function we must check its return value through a pair of if and else. Easier said than done! Surrounding every function call with a pair of if and else results in increase in code size. Also, too many if - elses make the listing lose its readability. (b) This approach cannot be used to report errors in the constructor of a class, as the constructor cannot return a value. (c) It becomes difficult to monitor the return values in case of deeply nested function calls. Especially so, if the functions belong to a third-party library. C# uses a more systematic approach to tackle exceptions. The .NET CLR checks for the runtime errors and raises exceptions to inform the program that an error has occurred. It also handles these exceptions if the program has not handled it. In C# the exceptions are in the form of objects of exception classes. All exception classes are derived from the System.Exception class. An exception object cannot be "thrown" or "caught" unless their classes are inherited from the System.Exception class. When we say an exception is thrown, it means that the CLR creates an object of the class on heap and passes its reference to the program. There are several standard exceptions provided by the .NET framework. We can also create user-defined exceptions. The exception thrown by the code written in one .NET compliant language can be caught in another .NET compliant language. We can handle exceptions in C# using the following: a. The try block followed by one or more catch blocks. b. The try-catch blocks followed by finally block. Let us understand each of them. The try-catch Blocks The try block contains code expected to raise an exception. The code in the try block executes until a statement which raises an exception is encountered. When an exception is encountered, the program flow shifts to the catch block. The catch block handles the exception by executing the code written in it. For example, using System; namespace Sample { class Class1 { static void Main ( string [ ] args ) { int a, b = 0 ; try {

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


a = 10 / b ; } catch ( DivideByZeroException e ) { Console.WriteLine ( e ) ; } Console.WriteLine ( "Remaining program" ) ; } } } Here a 'divide by zero' exception is raised. The CLR creates an object of DivideByZeroException class and passes it to the catch block that accepts a reference to the DivideByZeroException object. We have then printed the exception by passing the reference e to the WriteLine( ) method. The output of the above program would be: System.DivideByZeroException: Attempted to divide by zero. at Exceptiontest.Class1.Main(String[] args) in c:\csharp\programs\Exceptiontest\class1.cs:line 51 Remaining program As shown in the output, passing e to the WriteLine( ) prints the name of the exception class, exception message, the filename and the method name in which exception is thrown, and the line number at which the exception is thrown. If we handle the exception, firstly the catch block gets executed and then the control goes to the statement following the catch block. The control never returns to the try block. On the contrary if we do not handle the exception the execution of the program would terminate abnormally as soon as the exception is thrown. We can write more than one catch blocks to handle different exceptions. This is shown in the following example: int b = 2 ; int [ ] a = new int [ 5 ] ; try { int i = 10 / b ; a [ 10 ] = 9 ; } catch ( DivideByZeroException e ) { Console.WriteLine ( "Divide by zero error" ) ; } catch ( IndexOutOfRangeException e ) { Console.WriteLine ( "Index out of bounds" ) ; } Here, the two catch blocks are written to handle the 'divide by zero' and 'index out of bounds' exceptions. The DivideByZeroException and IndexOutOfRangeException classes represent these exceptions respectively. Since b contains a non-zero value, divide by zero exception would not get thrown. So, the first catch block would not get executed. The statement a [ 10 ] = 9 is exceeding the array bounds and so the second catch block would get executed. In the catch block we have displayed our own message because the default messages are

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


difficult to understand. In this code two exceptions are being handled. If any one of them is raised, the suitable catch block would get executed. Instead of writing a catch block for every possible exception we can write a catch block that accepts pointer to an object of the System.Exception class. It is the base class of all exception classes and hence address of any type of exception object can be collected in it. This is shown in the following example: int b = 2 ; int[ ] a = new int [ 5 ] ; try { int i = 10 / b ; a [ 10 ] = 9 ; } catch ( Exception e ) { Console.WriteLine ( e ) ; }

Article: C# - Management By Exception - II


Continued from last week... The try-catch-finally Blocks The finally block is used to perform clean up operations before the program ends. The finally block is guaranteed to get executed regardless of whether an exception is thrown. So instead of writing the clean up code in both the try block (if the exception is not thrown) and catch block (if the exception is thrown) we should write the code in the finally block. This prevents duplication of code. The finally block must always be associated with the try block. The code written in the finally block gets executed after the catch block if the catch block is present and the execution of the program continues. The following code snippet shows how to use a finally block. using System; namespace Sample { class Class1 { static void Main ( string [ ] args ) { int b = 2 ; int[ ] a = new int [ 5 ] ; try { int i = 10 / b ; a [ 10 ] = 9 ; } catch ( DivideByZeroException e ) { Console.WriteLine ( "Divide by zero error" ) ; } catch ( IndexOutOfRangeException e ) {

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Console.WriteLine ( "Index out of bounds" ) ; } finally { Console.WriteLine ( "finally" ) ; } Console.WriteLine ( "Remaining program" ) ; } } } The output of the program would be: index out of bounds finally Remaining program If the catch block is absent the exception is handled by the CLR, then the code in the finally block is executed and the execution of the program is terminated. The throw Statement The throw statement is used to throw an exception explicitly. For example, consider the following program: using System ; namespace Sample { public class Class1 { static void Main ( string[ ] args ) { myclass m = new myclass( ) ; try { m.fun ( 20 ) ; } catch ( Exception e ) { Console.WriteLine ( e ) ; } } } class myclass { public void fun ( int i ) { if ( i > 10 ) throw new Exception ( "Value out of range" ) ; else Console.WriteLine ( i ) ; } } }

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


In Main( ) we have created an object m of the class myclass. Using this object we have called the fun( ) method of the class from within the try block. We have passed 20 to this method. Since 20 is greater than 10, an exception would be raised. So far we were handling the exception in the method itself by enclosing the statements that were expected to raise an exception in the try block followed by the catch block. Instead of enclosing the statements within the try block we can enclose the method call itself in the try block. This is what is done in this program. The method call in Main( ) has been enclosed within the try block and hence the exception is handled in the corresponding catch block. If the value received in fun( ) is greater than 10, we have thrown an exception explicitly by creating an object of the System.Exception class. (We can also create an exception object of a particular class such as IndexOutOfRangeException.) User-Defined Exceptions While programming you may encounter situations when the existing predefined exceptions fall short in fulfilling our need. At such times we need to define our own exception classes and throw user-defined exceptions if the rules are violated. Our exception class should be derived from the System.Exception class. This is shown in the following program: using System ; namespace Bank { class customer { string name ; int accno ; int balance ; public customer ( string n, int a, int b ) { name = n ; accno = a ; balance = b ; } public void withdraw ( int amt ) { if ( balance - amt <= 100 ) throw new bankexception ( accno, balance ) ; balance -= amt ; } public int getbalance( ) { return balance ; } } class bankexception : Exception { int acc ; int bal ; public bankexception ( int a, int b ) {

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


acc = a ; bal = b ; } public void inform( ) { Console.WriteLine ( "Account Number: " + acc + "Balance left: " + bal ) ; } } public class Class1 { static void Main ( string[ ] args ) { customer c = new customer ( "Rahul", 2453, 500 ) ; try { c.withdraw ( 450 ) ; } catch ( bankexception e ) { Console.WriteLine ( "Transaction Failed " ) ; e.inform( ) ; } } } } In this program we have declared a class called customer. In this class we have a string data member name, and two int data members, accno and balance. We have two methods in this class-withdraw( ) and getbalance( ). The withdraw( ) method deducts an amount, passed as a parameter, from balance and the getbalance( ) method returns the balance. Now we wish to apply the rule that any customer should not have a balance less than Rs. 100 in his/her account. This means an exception must be thrown whenever the customer tries to withdraw money which results in the balance to drop below Rs. 100. To tackle this we have written a user-defined exception class called bankexception having two int data members acc and bal. This class must be derived from the System.Exception class. This class has a twoargument constructor which accepts two ints. In the withdraw( ) method we have checked whether the balance after deduction drops below 100 or not. If it does we have raised an exception called bankexception. This exception is caught in the catch block which then proceeds to display a suitable message by calling the inform( ) method. If the condition in the withdraw( ) method is not satisfied then the balance is appropriately updated. .NET Exception Classes There are a number of standard exception classes provided by .NET Framework, all of which inherit from the System.Exception class. Given below is the list of some common exception classes. Exception Class AccessException ArgumentException Cause Failure to access a type member, such as a method or a data member. An argument to a method was invalid.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


A null argument was passed to a method that doesn't accept it. ArithmeticException Arithmetic over flow or underflow has occurred. An attempt to store the wrong type of object in ArrayTypeMismatchException an array. BadImageFormatException Image is in the wrong format. DivideByZeroException An attempt was made to divide by zero. FormatException The format of an argument is wrong. IndexOutOfRangeException An array index is out of bounds. An attempt was made to cast a class to an InvalidCastExpression invalid class. MissingMemberException An invalid version of a DLL was accessed. FileNotFoundException A file referenced is not found. NotFiniteNumberException A number is not valid. Indicates that a method is not implemented by NotSupportedException a class. NullReferenceException Attempt to use an unassigned reference. OutOfMemoryException Not enough memory to continue execution. StackOverflowException A stack has overflown ArgumentNullException

Article: C# - Collection Classes - I


Collection Classes Use of an appropriate Data Structure at appropriate place goes a long way in building efficient programs. If you use an array in place of a linked list or vice-versa, the program is likely to fire in some situation. But while writing a C# program the last thing on our mind is how to build a linked list. There are more important things to attend to. We can use the .NET Collection Classes to manage data structures. .NET provides the System.Collections namespace that contains various interfaces and classes representing the collections of objects. For example, lists, queues, arrays, hashtables and dictionaries. Let us discuss these classes and interfaces one by one. The ArrayList Class The ArrayList class is similar to the Array class except that its size can grow dynamically. Following code snippet shows how to use the methods of an ArrayList class. ArrayList arr = new ArrayList( ) ; arr.Add ( 'a' ) ; arr.Add ( 43 ) ; arr.Add ( 6.7 ) ; arr.Add ( "Rahul" ) ; arr.Insert ( 1, "Deepti" ) ; for ( int i = 0 ; i < arr.Count ; i++ ) Console.WriteLine ( arr [ i ] ) ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Since the Add( ) method takes a parameter of type object we can store values of any type in one array. Just like the Array class, the ArrayList class contains various methods to perform functions like adding, inserting, removing, copying, etc. By default, the capacity-number of elements the array list can hold-is of 16 elements. If the number of elements exceeds 16 then the capacity of the array list automatically gets doubled by allocating new area of memory. If we want, we can increase or decrease the capacity of the array list using the Capacity property of ArrayList class. The Capacity property indicates the number of elements the ArrayList object is capable of holding. If we increase the capacity by saying arr.Capacity = 32 the array list arr would automatically get reallocated. The BitArray Class The BitArray class represents an array of bool values. Each element of the BitArray contains either true or false. The BitArray class contains several overloaded constructors, except the zero-argument constructor. Following statements show how an object of the BitArray can be instantiated. int[ ] a = { 1, 2, 3 } ; BitArray b1 = new BitArray ( a ) ; BitArray b2 = new BitArray ( 5 ) ; BitArray b3 = new BitArray ( 5, true ) ; If we pass reference to another array as an argument to the BitArray constructor the bit values of every element of that array get copied as the elements of the BitArray. For example, the bit values (1 or 0) of the element 1 would become first 32 elements (1 being a 32-bit number) in the array b1. Either true or false would get stored in b1 depending upon whether the bit is 1 or 0. The array b2 would get created with 5 elements and by default all the elements would be set to false. The array b3 would contain 5 elements where all the elements would be set to the bool value true. Following code would display the elements of array b1. for ( int i = 0 ; i < b1.Count ; i++ ) Console.WriteLine ( "{0} ", b1 [ i ] ) ; The BitArray class contains several methods using which we can perform the bitwise operations on the array elements. For example, Not( ), Or( ), Xor( ), etc. Following code snippet shows how to use these methods. int[ ] a1 = { -10, -10 } ; int[ ] a2 = { 10, 10 } ; BitArray b1 = new BitArray ( a1 ) ; BitArray b2 = new BitArray ( a2 ) ; b1.And ( b2 ) ; b1.Or ( b2 ) ; b1.Xor ( b2 ) ; The functions performing bitwise operations need another BitArray using whose elements the bitwise operation is performed. Hence, we have instantiated two BitArrays b1 and b2 by passing the references of the int arrays. The elements of b1 would get ANDed, ORed and XORed with the elements of b2. Note that the arrays using which b1 and b2 are created must have same number of elements.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


We can change the values of the elements of a BitArray using the Set( ) or Setall( ) methods as shown below: b1.Set ( 1, true ) ; b1.SetAll ( true ) ; The Set( ) method sets the specified element to the specified bool value, whereas, the SetAll( ) method sets all the elements to the specified bool value. The Queue Class The Queue class is a collection of objects, which are stored and retrieved in 'First In First Out' manner. We can use the Queue class to develop an application that can receive the messages and display them on the basis of the date of receipt. The following program demonstrates how to implement the Queue class. using System ; using System.Collections ; namespace collect { class Class1 { static void Main ( string[ ] args ) { Queue q = new Queue( ) ; q.Enqueue ( "Message1" ) ; q.Enqueue ( "Message2" ) ; q.Enqueue ( "Message3" ) ; q.Enqueue ( "Message4" ) ; Console.WriteLine ( "First message: {0}", q.Dequeue( ) ) ; Console.WriteLine ( "The element at the head is {0}", q.Peek( ) ) ; IEnumerator e = q.GetEnumerator( ) ; while ( e.MoveNext( ) ) Console.WriteLine ( e.Current ) ; } } } We have used the Enqueue( ) method of the Queue class to add the elements at the end of the queue. We have added few messages in the queue. The Dequeue( ) method returns the element at the head of the queue and removes it. If we want to get the element at the head but do not want to remove it from the queue, we can use the Peek( ) method. Unlike the classes ArrayList and BitArray, the Queue class does not provide an indexer. Hence, we cannot use [ ] operator to access the queue elements. So, to access the queue elements we have used an interface called IEnumerator provided by the Collections namespace. The Queue class implements this interface. We have used the GetEnumerator( ) method of Queue class to obtain an IEnumerator reference e. Using this reference we have iterated through the queue. The Current property of the IEnumerator interface returns the element at the current position. The reference e can be used only to iterate through the collection, not to modify it. Other classes of the

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Collections namespace like ArrayList and BitArray also implement the IEnumerator interface. So, we can use it to enumerate these arrays also. To check whether a particular element exists in the queue or not, we can use the Contains( ) method as shown below: bool b = q.Contains ( "Message3" ) ; Console.WriteLine ( b ) ; The Contains( ) method returns true if the element 'Message3' exists in the queue, otherwise it returns false. The Queue object is not thread safe. It means that two different threads can access one Queue object at the same time, which can prove dangerous. To avoid such a situation the Queue class provides a static method Synchronized( ) that returns a synchronized wrapper around the specified object. Following statements show how to use the Synchronized( ) method. Queue q = new Queue( ) ; Queue sq = Queue.Synchronized ( q ) ; We can now safely use sq to perform various operations on the queue.

Article: C# - Collection Classes - II


Continued from last week... The Stack Class Since the Collections namespace provides Queue class, it is obvious that it would also provide Stack class. Needless to say that the Stack class provides 'Last In First Out' way to store and retrieve the elements. The following program shows how to use this class: using System ; using System.Collections ; namespace collect { class Class1 { static void Main ( string[ ] args ) { Stack st = new Stack( ) ; st.Push ( 10 ) ; st.Push ( 11 ) ; st.Push ( 12 ) ; st.Push ( 13 ) ; Console.WriteLine ( "Element popped: {0}", st.Pop( ) ) ; IEnumerator e = st.GetEnumerator ( ) ; while ( e.MoveNext( ) ) Console.WriteLine ( e.Current ) ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


} } } The Stack class provides the Push( ) and Pop( ) methods to store and retrieve the stack elements. The Pop( ) method returns the element at the top of the stack and then removes it. We have displayed the stack elements using the IEnumerator interface. We can use the Peek( ) method to obtain the element at the top without removing it from stack. The Hashtable Class In a hash table we can store pairs of values and associated keys. The values are organised on the basis of the keys. These keys can be used to get the respective values from the hash table. .NET has encapsulated the functionality of hash table in a class called Hashtable. Following program illustrates how we can initialise and use the Hashtable class. using System ; using System.Collections ; namespace collect { class Class1 { static void Main ( string[ ] args ) { Hashtable h = new Hashtable( ) ; h.Add ( "mo", "Monday" ) ; h.Add ( "tu", "Tuesday" ) ; h.Add ( "we", "Wednesday" ) ; h.Add ( "th", "Thursday" ) ; h.Add ( "fr", "Friday" ) ; h.Add ( "sa", "Saturday" ) ; h.Add ( "su", "Sunday" ) ; IDictionaryEnumerator e = h.GetEnumerator( ) ; while ( e.MoveNext( ) ) Console.WriteLine ( e.Key + "\t" + e.Value ) ; Console.WriteLine ( "The Keys are : " ) ; ICollection k = h.Keys ; foreach ( object i in k ) Console.WriteLine ( i ) ; Console.WriteLine ( "The Values are : " ) ; ICollection v = h.Values ; foreach ( object i in v ) Console.WriteLine ( i ) ; } } } The Hashtable class provides the Add( ) function to store the key and its value. Note that the key value pairs may not get stored in the hash table in the same sequence in which they are added. In which order they would get stored depends upon the hashing function used by the Hashtable class. The GetEnumerator( ) method of the Hashtable class returns the reference of the

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


IDictionaryEnumerator interface. We have displayed the value and the respective keys using the Value and Key properties of the IDictionaryEnumerator interface. We can use the ICollection interface to iterate through the keys and values. The sequence in which the values would get displayed is unspecified. The Hashtable class contains properties Keys and Values that return the reference of the ICollection interface To remove an item from the hash table we can use the Remove( ) function. The Remove( ) method removes the value from the hash table using the specified key. We can access the value of the specified key simply by using the indexer as shown below: h [ "su" ] = "Sun" ; h [ "mo" ] = "Mon" ; Console.WriteLine ( h [ "fr" ] ) ; The SortedList Class Like Hashtable, the SortedList class maintains pairs of keys and values. The difference between the two is that in the SortedList class, the values are sorted by keys and are accessible by key as well as by index.Consider the following program: namespace Sample { class Class1 { static void Main ( string[ ] args ) { SortedList s = new SortedList ( ) ; s.Add ( "Maharastra ", "Mumbai" ) ; s.Add ( "Karnataka ", "Bangalore" ) ; s.Add ( "Andhra Pradesh", "Hyderabad" ) ; s.Add ( "Tamilnadu ", "chennai" ) ; s.Add ( "Bihar ", "Patna" ) ; s.Add ( "Rajastan ", "Jaipur" ) ; s.Add ( "Orissa ", "Bhubaneshwar" ) ; Console.WriteLine ( "Elements in the SotredList: " ) ; IDictionaryEnumerator e = s.GetEnumerator ( ) ; while ( e.MoveNext( ) ) Console.WriteLine ( e.Key + "\t" + e.Value ) ; s.Remove ( "TamilNadu" ) ; Console.WriteLine ( "The Keys are : " ) ; ICollection k = s.Keys ; foreach ( object i in k ) Console.WriteLine ( i + " " ) ; Console.WriteLine ( "The Values are : " ) ; ICollection v = s.Values ; foreach ( object i in v ) Console.WriteLine ( i + " " ) ; Console.WriteLine ( "Value at 3rd Index 3: " + s.GetByIndex ( 3 ) ) ; Console.WriteLine ( "Key at 3rd Index: " + s.GetKey ( 3 ) ) ; Console.WriteLine ( "The Index of key Bihar" + s.IndexOfKey ( "Bihar" ) ) ; Console.WriteLine ( "The Index of value Jaipur" + s.IndexOfValue ( "Jaipur" ) ) ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


} } } Like Hashtable, the SortedList class also uses IDictionaryEnumerator interface to iterate through the list elements. To get the list of keys and values we have used the Keys and the Values properties respectively. The Remove( ) method deletes the value of the specified key. The methods GetByIndex( ) and GetKey( ) return the value and key respectively at the specified index. We can get the index of a key by using the IndexOfKey( ) method. To get the index of the value we can use the IndexOfValue( ) method.

Article: C# - Collection Classes - III


Continued from last week... The IComparer Interface The IComparer interface provides methods to compare two objects. Most of the classes implement this interface so that the user can easily compare two objects of the class. Let us create a program that shows how to implement the IComparer interface. In this program we would write a class emp maintaining the information of employees. Another class mysort would implement the IComparer interface. Here is the program using System ; using System.Collections ; namespace icomb { class emp { public string name ; public int id ; public float balance ; public emp ( int i, string n, float b ) { id = i ; name = n ; balance = b ; } public new string ToString( ) { return id + " " + name + " " + balance ; } } public class mysort : IComparer { public int Compare ( object a, object b ) { int i1 = ( ( emp ) a ).id ; int i2 = ( ( emp ) b ).id ; string n1 = ( ( emp ) a ).name ; string n2 = ( ( emp ) b ).name ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


if ( i1 == i2 ) { return n1.CompareTo ( n2 ) ; } if ( i1 < i2 ) return -1 ; return 1 ; } } public class Class1 { public static int Main ( string[ ] args ) { emp[ ] e = { new emp ( 2, "Sanjay", 3450 ), new emp ( 1, "Rahul", 2500 ) , new emp ( 10, "Kavita", 10000 ), new emp ( 9, "Mohit", 25000), new emp ( 6, "Sapna", 2500), }; mysort s = new mysort( ) ; Array.Sort ( e, s ) ; foreach ( emp s1 in e ) Console.WriteLine ( s1.ToString( ) ) ; return 0 ; } } } Here, we have firstly instantiated an array e of type emp and then an object of type mysort. In the mysort class we have defined the Compare( ) method of the IComparer interface and written our own sorting logic in it. Next, to sort the array e we have called the Sort( ) method of the Array class. To the Sort( ) method we have to pass the array to be sorted and reference to the IComparer interface. The Sort( ) method calls the Compare( ) method. The Compare( ) method returns 0, 1 or -1 indicating whether the objects being compared are equal or one is smaller than the other. In our case, since the mysort class is derived from IComparer we have passed reference to the mysort's object. Hence, the Compare( ) method of mysort class gets called. Once the array is sorted we have displayed the array elements. We have overridden the ToString( ) method in the emp class. This is because we wanted to display the sorted elements using the statement s1.ToString( ). Had we not overridden this method in emp class, ToString( ) of the base class would have got called, which we do not want. In the ToString( ) of emp class we have concatenated the values of the data members in a string and returned it. Other Collection Classes In addition to the collection classes that we have used in this chapter there are several more classes offered by the Collections namespace. These are listed along with the purpose of each in following table. Class CaseInsensitiveComparer Purpose Compares two objects of same type. If objects are strings,

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


comparison is case-insensitive Creates a hash code using a hashing algorithm that ignores CaseInsensitiveHashCodeProvider the case of strings Provides the abstract base class for creating custom CollectionBase collections Compares two objects. If objects are strings, comparisons Comparer are case-sensitive Provides the abstract base class for creating collection DictionaryBase class that uses collection of key-value pairs Provides the abstract base class for creating read-only ReadOnlyCollectionBase collections Similarly, the Collections namespace contains few more interfaces other than those we have covered in this article. They are listed in following table along with the purpose of each. Interface Purpose IDictionary Provides a collection of key-value pairs IDictionaryEnumerator Enumerates the elements of a key-value collection Provides the enumerator, which supports a simple iteration through a IEnumerable collection. It is implemented by all enumerator interfaces IHashCodeProvider Supplies a hash code for an object, using a custom hash function

Article: C# - Multithreading - I
Every application running under Windows constitutes a process. Each process can contain one or more threads of execution. A thread constitutes a part of execution through a program's code and a set of resource (like stack, register state, etc.) assigned by the operating system. When we execute a Win32 application it starts as a single thread but can spawn several additional threads. There is a scheduler program in the operating system kernel that divides the CPU time among active threads. As a result, all the threads appear to run simultaneously. Threads are popularly used for performing tasks in the background while processing user input in the foreground. However, usage of threads is not restricted to running tasks in the background. They can also be used for creating windows or other foreground processing. Though writing multithreaded programs is difficult, if used properly threads can dramatically improve an application's performance. Threads are basically asynchronous by nature. It takes time for the programmers to get used to this behavior. Let us now create an application where we can put multithreading to work. The application should display the list of files present in 'C' drive in the form shown in Figure 1.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Figure 1 The listing should begin when we click on the 'Start' button and it should stop when we click on the 'Stop' button. When we click on the 'Start' button, an event handler should get called. Another event handler should get called when we click on the 'Stop' button. If we do not run the event handler or the 'Start' button in a separate thread we would not be able to click the 'Stop' button unless control returns from the 'Start' button's event handler. A clear cut case where multithreading would make sense. Let us now proceed with creating the program. Create a form shown in Figure 1 Insert three buttons and a label in the form. The label would display file names. On clicking the 'Start' button an event handler would get called that would start a new thread to display the files on the disk in the label. After starting the thread the event handler would end. The process of displaying the files would continue and there would be no restriction on us to click the 'Stop' button. This is because the event handler written for the 'Start' button in the main thread would end and the main thread would be ready to receive other events. At the same time the new thread would be getting time slots for processing. To build such an application create a 'Windows application' and insert three buttons: 'Start', 'Stop' and 'Close' having names as start, stop and close respectively in the form. Also add a Label control having name file to the form. Add the event handlers for all the three buttons. Firstly we would see the start_Click( ) handler. This handler is given below: private void start_Click ( object sender, System.EventArgs e ) { string path = @"c:\" ; search s = new search ( file, path ) ; ThreadStart ts = new ThreadStart ( s.searchfiles ) ; t = new Thread ( ts ) ; t.Start( ) ; } Here, we have first created an object of the user-defined search class. We would see this class later. We have passed the reference of the label and the directory path to the constructor. Next, we have created a new thread. To start another thread we have created an object of the Thread class first. This object's reference is stored in t. The reference t (of type Thread) should be added as a data member of the form class. While creating a thread, we must specify which function should get executed when the thread gets started. We have specified that the searchfiles( ) method of the search class should get executed. For this, we have to wrap its address in a delegate and pass it to the constructor of the Thread class. We have used a predefined .NET delegate class called ThreadStart and created a delegate object ts. The delegate ts is passed to the constructor of the Thread class. So whenever the thread is started, the method wrapped inside ts would start executing. To start a thread we have called Start( ) method of the Thread

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


class. As soon as the 'Start' button is clicked, the label control starts displaying all the filenames. To be able to use this class we must write the statement using System.Threading in our program. The search class is given below: class search { Label file ; DirectoryInfo dir ; public search ( Label l, string p ) { file = l ; dir = new DirectoryInfo ( p ) ; } public void searchfiles( ) { FileSystemInfo[ ] f = dir.GetFileSystemInfos( ) ; foreach ( FileSystemInfo i in f ) { if ( i.Attributes == FileAttributes.Directory ) { dir = new DirectoryInfo ( i.FullName ) ; searchfiles( ) ; } else file.Text = i.FullName ; } } } The method searchfiles( ) present in this class would be called from the new thread. The prototype of the ThreadStart delegate is such that it can hold addresses of those methods that return a void and do not accept anything. So we cannot pass any parameters to the searchfiles( ) method. Hence the parameters that we need in this method have been added as data members of the search class and have been initialized using the constructor of the search class. The reference of label and directory path passed to the constructor from the start_Click( ) method are stored in the file and dir data members of type Label and DirectoryInfo classes respectively. In the searchfiles( ) method we have created an array f of the FileSystemInfo class. Then by using the GetFileSystemInfos( ) method, we have collected all the files and directories, present under the directory referenced by dir in the array. The FileSystemInfo class serves as the base class for the DirectoryInfo class and the FileInfo class. To use these classes we must add the statement using System.IO at the beginning of our program. Just like the File and FileInfo classes, .NET provides the Directory and DirectoryInfo classes. Both the Directory and DirectoryInfo classes represent a folder in a file system. The Directory class contains only static methods and is never instantiated. The DirectoryInfo class on the other hand can be instantiated. The hierarchy of these classes is shown in the Figure 2.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Figure 2 The FileSystemInfo class can hold the reference of any file system object, be it a file or a directory. After storing the reference of the array in f, we have iterated through the array using the foreach loop and checked whether each file system object is a file or a directory. This is done by comparing the Attribute property of the FileSystemInfo object with the Directory member of the FileAttribute enumeration. If the object turns out to be a directory, we have created a new DirectoryInfo object, stored its reference in dir and recursively called the searchfiles( ) method. If the file system object turns out to be a file, we have displayed its name in the label present in the form. To interrupt the process of displaying the files before all the files are displayed we have to click on the 'Stop' button. It is possible for us to click on the 'Stop' button because the execution of the searchfiles( ) method is taking place in a different thread. On clicking the 'Stop' button, the handler stop_Click( ) gets called. The code for the handler is shown below. private void stop_Click ( object sender, System.EventArgs e ) { t.Abort( ) ; } The Abort( ) method of the Thread class terminates a thread. If we wish to terminate the application, we have to click on the 'Close' button; the handler for the 'Close' button gets called that disposes the form. The handler is shown below. private void close_Click ( object sender, System.EventArgs e ) { Dispose( ) ; }

Article: C# - Multithreading - II
Continued from last week... Synchronization Software development is a team effort. Unless team members cooperate with one another, synchronize their work with the rest of the team, the team can't go far. Similarly if in a program

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


there are several threads running, unless their activities are synchronized with one another the disaster is not far away. For example, if a program instantiates two threads and if both the threads use the same resource and both of them change it simultaneously, the situation would become dangerous. To give you a more concrete example, suppose in a program there is a list of names that is to be sorted. We can also add new names to the list. Suppose we write one thread to sort the list and another thread to add a name to the list. Now if the sort thread has executed half way and if we try to add a new name in the list, the name may get added at the end but the result of the sort would be wrong.

In such cases we must make sure that if one thread is handling the list, the other should not work with it. This is achieved using synchronization.

Synchronization provides a lock on the object that is going to be shared amongst threads and makes a thread wait until the other thread finishes the job with the resource or object. Hence we can say that synchronization 'locks' the object or shared resource and prevents another thread from using it. C# provides us with a lock keyword to lock the shared object or resource. Whatever is written inside the parenthesis following the lock keyword gets locked for the current thread and no other thread is permitted to access that resource or object. To understand these concepts more thoroughly consider the following program. In this program the form consists of three buttons: 'Add', 'Sort' and 'Close' having names add, sort and close respectively and a list box control having the name list. The design of the form is shown in following figure.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Clicking the 'Add' button would start a thread to add a new name to the list, whereas, clicking the 'Sort' button would start another thread that would sort the list. The list box control would always display the names stored in an ArrayList object whose reference is added as a data member of the form class. We have initialized the array list object in the constructor of the form class with names contained in a file. The code to do so is shown in the following snippet: public Form1( ) { InitializeComponent( ) ; arr = new ArrayList( ) ; FileInfo f = new FileInfo ( "data.txt" ) ; StreamReader r = f.OpenText( ) ; string s ; while ( ( s = r.ReadLine( ) ) != null ) { arr.Add ( s ) ; list.Items.Add ( s ) ; } r.Close( ) ; } Here in the constructor we have initialized the array list object arr with names present in the 'data.txt' file. This file should be present in the 'synchronize' project folder. The methods that the threads would start are written inside a class called mythread. The declaration of the mythread class is given below. class mythread { ListBox list ; ArrayList arr ; string name ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

public mythread ( ListBox l, ArrayList a ) { list = l ; arr = a ; } public mythread ( ListBox l, ArrayList a, string n ) { list = l ; arr = a ; name = n ; } public void add( ) { lock ( arr ) { arr.Add ( name ) ; list.Items.Clear( ) ; foreach ( string i in arr ) list.Items.Add ( i ) ; } } public void sort( ) { lock ( arr ) { arr.Sort( ) ; list.Items.Clear( ) ; foreach ( string i in arr ) list.Items.Add ( i ) ; } } } In this program we cannot pass parameters to the sort( ) and add( ) methods because they are wrapped by the ThreadStart delegate. Hence we have added the parameters that we need in the methods as data members of the class and initialized these parameters using constructors. Hence this class contains two constructors. The two-argument constructor is used for initializing parameters for the sort( ) method, whereas, the three-argument constructor is used for initializing parameters for the add( ) method. We have locked the ArrayList object in this program, as it is used by both the threads. In the add( ) method after locking the arr object we have added the new name to the list by using the Add( ) method. Next we have deleted all the items of the list box by calling the Clear( ) method and then displayed all the names again including the new name. In the sort( ) method too we have first locked the object arr and then sorted the array using the Sort( ) method of the ArrayList class. The sorted list is then displayed in the list box. We have called the add( ) and sort( ) methods in the corresponding handlers. The handler for the 'Add' button is shown below. private void add_Click ( object sender, System.EventArgs e ) {

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


string n = name.Text ; name.Text = "" ; mythread m = new mythread ( list, arr, n ) ; ThreadStart ts = new ThreadStart ( m.add ) ; Thread t = new Thread ( ts ) ; t.Start( ) ; } Here firstly we have collected the name to be added in n and then cleared the text box. Then we have created an object of the mythread class passing three arguments to the constructor. Next we have started a new thread which would call the add( ) method. The handler for the 'Sort' button is shown below. private void sort_Click ( object sender, System.EventArgs e ) { mythread m = new mythread ( list, arr ) ; ThreadStart ts = new ThreadStart ( m.sort ) ; Thread t = new Thread ( ts ) ; t.Start( ) ; } Here we have created an object of the mythread class passing two parameters to its constructor. We have then created a new thread that would call the sort( ) method. From the close_Click( ) handler we have only called Dispose( ) method to close the form window. void close_Click ( Object *sender, EventArgs *e ) { Dispose( ) ; }

Article: C# - Multithreading - III


Continued from last week... Monitor Suppose a situation arises where we want to use the output of one thread as the input to another. Here we would have to use synchronization again. The need of synchronization would be clear in the following example. In this program we plan to create one thread that would generate information of shapes like coordinates, pen color, etc. randomly and another thread that would draw shapes using this information. Unless the generate thread generates some shapes, the draw thread would not have anything to draw. Hence the draw thread would have to wait for the generate thread to complete its execution because the output of the generate thread (shapes) would be used by the draw thread as input. On the other hand the generate thread must also wait for the draw thread to draw the shapes it previously generated. If the generate thread does not wait for the draw thread, it would overwrite its own data before the data is used by the draw thread.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Such a situation calls for alternate execution of both the threads and each thread must wait for the other thread. Both threads would share the same resource. The generate thread would use the resource to fill in shapes and the draw thread would use the resource to read the shapes. Hence the resource must not be used by both the threads at the same time. For such a sophisticated control over resources, we should use a monitor. A Monitor lets us decide when to enter and exit the synchronization. The class that represents a monitor in .NET is System.Threading.Monitor. Let us see how to use this class in our program. In this program we plan to generate shapes like lines, rectangles and ellipses and then draw them on the form. To accomplish this we have used two methods namely generate( ) and draw( ). These two methods would be called from two different threads. We have to make sure that in spite of them being in different threads, they should execute alternately. We have also created a structure called info that would store information about a shape including the shape number, its coordinates and the pen with which the shape would be drawn. The structure declaration is shown in the following snippet: struct info { public int shapeno ; public int x1, y1, x2, y2 ; public Pen p ; }; Next we have defined a class called shapes. The shapes class consists of four data members: They are as follows: info[ ] n ; Random r ; bool flag ; Form1 f ; The array n would be used to store the pointer to an array containing the shapes. The reference r would be used to generate random numbers. The bool data member flag would be used for controlling the alternate execution of the threads. The reference f would hold the address of the form. A one-argument constructor is used to initialize these data members. This is how we need to initialize the data members: public shapes ( Form1 ff ) { n = new info [ 10 ] ; r = new Random( ) ; flag = false ; f = ff ; } We have defined two methods called generate( ) and draw( ) in the shapes class: Along with these methods the shapes class also contains the generatedata( ) and drawdata( ) methods. Let us discuss them one by one. The generate( ) method is given below:

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


public void generate( ) { Monitor.Enter ( n ) ; if ( flag ) Monitor.Wait ( n ) ; Size sz = f.ClientSize ; for ( int i = 0 ; i < 10 ; i++ ) { n [ i ].shapeno = r.Next ( 3 ) ; n [ i ].x1 = r.Next ( sz.Width ) ; n [ i ].y1 = r.Next ( sz.Height ) ; n [ i ].x2 = r.Next ( sz.Height - n [ i ].y1 ) ; n [ i ].y2 = r.Next ( sz.Width - n [ i ].x1 ) ; Color c = Color.FromArgb ( r.Next ( 255 ), r.Next ( 255 ), r.Next ( 255 ) ) ; n [ i ].p = new Pen ( c, 3 ) ; Thread.Sleep ( 10 ) ; } MessageBox.Show ( "Generate" ) ; flag = true ; Monitor.Pulse ( n ) ; Monitor.Exit ( n ) ; } In the generate( ) method we have generated the shape number, coordinates and pen color randomly. After initializing every element of the array we have halted the thread with the help of the Sleep( ) method for 10 milliseconds to ensure proper generation of random numbers. We have done this in a loop to fill the 10 elements of the array n. After this we have indicated the user about the generation of random shapes with the help of a message box. When this operation is taking place, the array n should not be used by the draw( ) method in the other thread. Hence before starting the operation we have locked this object by passing it to the Enter( ) method of the Monitor class. This is equivalent to writing a lock statement, passing n to it and putting the whole code in a block. Then we checked that if flag is set to true or not. If it is true, it means that another thread having draw( ) method is using the resource n and so, the thread should wait. This is achieved by using the Wait( ) method. A waiting thread can always be activated using the Pulse( ) method. So until the thread is activated it would wait. If flag is set to false, the control skips past the Wait( ) method call and the remaining code gets executed which generates the shapes and initializes the array. Before exiting, the method sets the flag to true and sends a pulse to any other waiting thread. The Exit( ) method marks the end of the area controlled by the monitor. The draw( ) method is shown in the following code snippet: public void draw( ) { Monitor.Enter ( n ) ; if ( !flag ) Monitor.Wait ( n ) ; Graphics g = f.CreateGraphics( ) ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Thread.Sleep ( 100 ) ; for ( int i = 0 ; i < 10 ; i++ ) { switch ( n [ i ].shapeno ) { case 0 : g.DrawLine ( n [ i ].p, n [ i ].x1, n [ i ].y1, n [ i ].x2, n [ i ].y2 ) ; break ; case 1 : g.DrawRectangle ( n [ i ].p, n [ i ].x1, n [ i ].y1, n [ i ].x2, n [ i ].y2 ) ; break ; case 2 : g.DrawEllipse ( n [ i ].p, n [ i ].x1, n [ i ].y1, n [ i ].x2, n [ i ].y2 ) ; break ; } } MessageBox.Show ( "Draw" ) ; flag = false ; Monitor.Pulse ( n ) ; Monitor.Exit ( n ) ; } In this method we have simply drawn the shapes using the information present in the array n with the help of an object of the Graphics class. We have first checked the shape number and then drawn the shape accordingly. Here too we have used the Monitor.Enter( ) method to lock the array n. In this method we have checked whether the flag is set to false or not. If it is set to false, the thread would wait. Until the thread is activated by the executing thread, it would wait. If the flag is set to true, the control skips past the Wait( ) method call and the remaining code gets executed and draws the shapes. Before exiting, the method sets the flag to false. Now you can imagine what must be happening if both the methods are executed simultaneously on two different threads. Before initializing the threads, we have set the flag to false. This makes the thread in which the draw( ) method is executing to go in a wait state. The generate( ) method on the other hand skips the Wait( ) method call and gets executed. Before the control comes out of the generate( ) method, it sends a pulse which activates the thread in which draw( ) is called and sets the flag to true. Hence now the draw( ) method starts executing. Next time when the generate( ) method gets called, it goes into a wait state. This approach ensures that both the methods in spite of being in different threads, execute alternately. To see this effect we have called the generate( ) and draw( ) methods ten times. The generate( ) and draw( ) methods have been called from the generatedata( ) and drawdata( ) methods respectively. Theses methods would be called from two different threads. The generatedata( ) and drawdata( ) methods are shown below: public void generatedata( ) { int i = 0 ; while ( i != 10 ) { i++ ; generate( ) ; }

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


} public void drawdata( ) { int i = 0 ; while ( i != 10 ) { i++ ; draw( ) ; } } We have initiated the threads when the user clicks the mouse button in the form. The handler for the MouseDown event is shown below: private void Form1_MouseDown ( object sender, System.Windows.Forms.MouseEventArgs e ) { shapes s = new shapes ( this ) ; ThreadStart ts1 = new ThreadStart ( s.generatedata ) ; Thread t1 = new Thread ( ts1 ) ; t1.Start( ) ; ThreadStart ts2 = new ThreadStart ( s.drawdata ) ; Thread t2 = new Thread ( ts2 ) ; t2.Start( ) ; } Now if we run the program and click on the form we would get the "Generate" and "Draw" messages alternately. Following figure would make the functioning of this program clearer.

A point to note! Instead of using the if statement and making the thread wait until the other thread sends a pulse to it, we may think of using a while loop checking the flag every time. But this is not the correct way. The processor time would be wasted if we go on checking the flag manually. Hence to save processor time, it is always right to use the Wait( ) method and send a pulse to it every time.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com Article: C# - Reflections


Discovering Types Using Reflection Every managed application in .NET is deployed as an assembly and every assembly defines certain types. These types are revealed in the form of metadata. We can find the types - methods, fields, properties, and events defined in an assembly using reflection. .NET has provided the System.Reflection namespace containing various classes and methods for accessing the metadata. Interesting thing is we can use reflection to find out the types at run-time. While working in Visual Studio.NET we unknowingly use reflection many times. Visual Studio.NET uses reflection to display types in IntelliSense. Similarly, .NET framework uses reflection to obtain information at run-time about the assemblies that it loads. Using classes of System.Reflection namespace we can Obtain information about assemblies, modules and types they contain Obtain information about custom attributes

Retrieving Information about Assemblies, Modules and Types Here is a simple program that shows how to obtain information about an assembly and modules. It also displays the contained types of the assembly. To execute this program we must declare the namespace System.Reflection in the program. Here we have displayed information of the assembly System.Drawing.dll. static void Main ( string[] args ) { Assembly a = Assembly.LoadFrom ( "C:\\System.Drawing.dll" ) ; AssemblyName n = a.GetName( ) ; Console.WriteLine ( "Name of assembly: {0}", n.Name ) ; Version v = n.Version ; Console.WriteLine ( "Assembly Version: {0}.{1}.{2}.{3}", v.Major, v.Minor, v.Build, v.Revision ) ; Console.WriteLine ( "Modules: " ) ; Module[ ] ma = a.GetModules( ) ; foreach ( Module m in ma ) Console.WriteLine ( m.Name ) ; Console.WriteLine ( "Exported Types: " ) ; Type[ ] t = a.GetExportedTypes( ) ; foreach ( Type type in t ) Console.WriteLine ( type.Name ) ; } To reflect on an assembly System.Reflection namespace contains a class named Assembly. Before calling any methods of the Assembly class we must load the assembly. We have done this by calling the static method of the Assembly class called LoadFrom( ). To the LoadFrom( ) method we need to pass URL of the assembly. Once the assembly is loaded, we can obtain information like assembly name, version, modules in assembly, types exported by the assembly, etc. The GetName( ) method of Assembly class returns reference to an object of the AssemblyName class. Using this object we can get still more information about the assembly. We have used the Version property of the AssemblyName class to get the version of the assembly. The GetModules( ) method of the Assembly class returns an array of Module objects representing modules in the assembly. We have then obtained the module name by using the

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Name property of the Module class. We can get the list of exported types of the assembly by calling the GetExportedTypes( ) method. This method returns an array of objects of class Type. If we use the GetTypes( ) method instead of GetExportedTypes( ) method we will get list of all the types, not just exported types. Here we have used the object of Type class to store the information of a type in the assembly. The System.Type class resides at the center of the reflection system. It implements the System.IReflect interface. This interface allows querying of fields, methods, properties, etc. This Type class provides hoards of methods that can be used to create a utility like WinCV. (The WinCV utility is used to view all the members declared in a class). We would now take a look at how the Type class can be used. Here instead of browsing a predefined type, we would browse a user-defined type test. Here is the declaration of the test class. public class test { int i ; int prop ; public int Prop { get { return prop ; } set { prop = value ; } } public test( ) { } public test ( int x ) { i=x; } public int myfunc ( int x ) { Console.WriteLine ( "In myfunc " + x ) ; return 2 * x ; } } In this class we have declared a data member int i, a property called Prop, a zero-argument constructor, a one-argument constructor and a method called myfunc( ) that accepts an int and returns an int. Let us now retrieve information about this class. static void Main ( string[ ] args ) { Type t = typeof ( test ) ; Console.WriteLine ( "Type of class: " + t ) ; Console.WriteLine ( "Namespace: " + t.Namespace ) ; Console.WriteLine ( ) ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


ConstructorInfo [ ] ci = t.GetConstructors( ) ; Console.WriteLine ( "Constructors are:" ) ; foreach ( ConstructorInfo c in ci ) Console.WriteLine ( c ) ; Console.WriteLine ( ) ; PropertyInfo [ ] pi = t.GetProperties( ) ; Console.WriteLine ( "Properties are:" ) ; foreach ( PropertyInfo p in pi ) Console.WriteLine ( p ) ; Console.WriteLine( ) ; MethodInfo [ ] mi = t.GetMethods( ) ; Console.WriteLine ( "Methods are:" ) ; foreach ( MethodInfo m in mi ) { if ( t == m.DeclaringType ) { Console.WriteLine ( "Name: " + m.Name ) ; ParameterInfo [ ] pif = m.GetParameters( ) ; foreach ( ParameterInfo p in pif ) { Console.WriteLine ( "Type: " + p.ParameterType ) ; Console.WriteLine ( "Parameter Name: " + p.Name ) ; Console.WriteLine( ) ; } } } } Here we have first extracted the type of the class in a reference t of the Type class using the typeof operator. Then we have displayed this name on the console. The Namespace property of the Type class returns the name of the namespace in which the type is defined. The Type class consists of methods such as GetConstructors( ), and GetProperties( ). These methods return a reference to an array of references of types ConstructorInfo and PropertyInfo respectively. These classes are declared in the System.Reflection namespace. In our program we have called the GetConstructors( ) and the GetProperties( ) methods using the reference t of type Type and collected the reference to arrays of type ConstructorInfo[] and PropertyInfo[] in ci and pi respectively. Hence the returned values would contain information about the constructors and properties of the test class. We have then used a foreach loop on the arrays and displayed this information. On similar lines we have called the GetMethods( ) method. This method returns a reference to an array of references to the MethodInfo class objects. We have collected this returned reference in mi. Next we have used a foreach loop on the array. Here we have first checked if the method in the array belongs to the declaring class (test) or not. The property DeclaringType is used to check the condition. This is done because we wish to display only those methods that are defined in the test class and not the methods that are inherited in the test class from base class (object class). We have then extracted the name of the method using the Name property of the MethodInfo class and then displayed it. The GetParameters( ) method returns a reference to an array of references to the ParameterInfo type that contains all the parameters that the method accepts. Here we have collected this in an array called pif. Next we have used the ParameterType and Name property of the ParameterInfo class to extract the type and name of

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


the parameters. The get and set accessors, we know, are methods and hence they too are returned by the GetMethods( ) method. On similar lines the Type class has methods like GetEvents( ), GetFields( ), GetInterfaces( ) and GetMembers( ). These methods return arrays of types EventInfo[], FieldInfo[], InterfaceInfo[] and MemberInfo[] respectively. On the other hand, methods such as GetConstructor( ), GetEvent( ), etc. return a reference to a single object of the corresponding type. Retrieving Information about Custom Attributes Attribute is a new feature of .NET., which add some declarative information about a type in metadata. We can write our own attribute that are called as custom attributes. Using the MemberInfo class of the Reflection namespace we can read this additional information of a type written in metadata via custom attributes. Following code snippet shows how to read the custom attribute Readme. MemberInfo i = typeof ( Readme ) ; object[ ] a = i.GetCustomAttributes ( false ) ; foreach ( CodeRevisionAttribute att in a ) // use att to access various properties

Article: C# - File Input/Output - I


Perhaps the only thing that works faster than the computer is computing jargon. It moves veryvery fast. Often yesterday's rage is no longer todays inthing. Some jargon however has stuck around for long. GIGO (garbage in and garbage out) for instance. It has been a ground since the early days of computing. It has even matured over the years. Today GIGO happens automatically through a process called serialisation. A sure shot sign of man's progress! .NET offers two classes for file operationsthe File class and the FileInfo class. Both these classes are defined in the System.IO namespace hence we need to write the statement using System.IO in the program that uses File or FileInfo class. The File class is derived from the Object class. It contains only static methods. We are not allowed to create an object of the File class. The FileInfo class is derived from FileSystemInfo class. The FileSystemInfo class is derived from the MarshalByRefObject class which in turn is derived from the Object class. We can create an object of the FileInfo class. The hierarchy of these classes is shown in Figure 1.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Figure 1 Let us now understand the objective of creating two classes for file operations. The static functions of the File class can be called to perform various file operations without creating an object. This avoids the overhead of creating objects. So, if we wish to carry out single operation on the file, we can use the File class. As against this, to call the member functions of the FileInfo class it is necessary to create an object. This is because FileInfo class contains non-static member functions. So, if we wish to carry out multiple operations on the file (with the preservation of state of the object) we can use the FileInfo class. When we create a FileInfo object, all the relevant information of the file like size, attributes, authentication permissions are stored in the data members. This information can then be used by other functions while carrying out multiple operations. If we use the File class for carrying out multiple operations then this information will have to be read each time we perform a new operation. Also, at times we are required to pass the file information to another application. In such a case it is necessary to create a FileInfo object and then pass its state to other application (this process is known as marshalling). Marshalling of object is possible only if the class is derived from the MarshalByRefObject class. Since the object of the File class cannot be created, it has not been inherited from MarshalByRefObject class. Reading And Writing To A Text File In the following program we will perform reading and writing operations on a text file. We plan to write a few strings to a text file and then read them back from it. namespace fileoperation { using System ; using System.IO ; class Class1 { static void Main ( string[ ] args ) { string str1 = "The .NET Revolution" ; string str2 = "Long live C# " ; string str3 = "Targeting the internet" ; StreamWriter sw = new StreamWriter ( "C:\\file2.txt", false ) ; sw.WriteLine ( str1 ) ; sw.WriteLine ( str2 ) ; sw.WriteLine ( str3 ) ; sw.Close( ) ; StreamReader sr = new StreamReader ( @"C:\file2.txt" ) ; // @ ensures that we don't have to use C:\\ string str ; do { str = sr.ReadLine( ) ; Console.WriteLine( str ) ; } while ( str != null ) ; sr.Close( ) ; } }

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


} To understand this program we must first know what a Stream is. A stream is a sequence of bytes traveling from source to destination or traveling over a communication link. Two basic types of streams that exist are Input stream and Output stream. An input stream is used for read operations while an output stream is used for write operations. Here we have created a new StreamWriter object and have passed false to the constructor of the StreamWriter class along with the path. Here false specifies that if the file exists, it should be overwritten. If we pass a true and if the file exists, it would be appended. In either case if the file does not exist, a new file is created. The WriteLine( ) method of the StreamWriter class is overloaded to write out entities like objects, bools, ints, etc. to a file. Next, we have used a StreamReader class to perform the reading operation. Its ReadLine( ) method reads a line of characters from the current stream and returns the data as a string. This process is repeated till the end of file is reached. The hierarchy of these I/O classes is shown in Figure 2.

Figure 2

Article: C# - File Input/Output - II


Continued from last week... Serialization Serialization is the process of writing objects on a persistent storage media such as a file on the disk. At a later time we may restore these objects by using the process of deserialization. In the following program we have created a menu 'File' having the 'New', 'Open', 'Save', 'Generate' and 'Exit' menu items with names filenew, open, save, generate and exit respectively. When we select the 'Generate' menu item, shapes like line, rectangle, and ellipse should get generated at random and in random colors as well as at random positions. On selecting the 'Save' menu item these shapes should be saved in a file. We must be able to load this file and display the shapes again through the 'Open' menu item. When we click the 'New' menu item the earlier shapes should vanish and the form should get cleared. While saving the shapes, we should not save the image of the shapes. Instead we should save the relevant information of the shapes using which we should be able to regenerate them again

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


when the file is loaded. This means that we must write the object containing the information about the shape in the file while saving it and load it back while opening the file. This is done using serialization and deserialization. To make all these activities happen we need to add handlers for these menu items. Before we add code to these menu handlers let us insert four new classes. The first amongst these is the abstract class called shapes, which is shown below. [Serializable] abstract class shapes { protected int r, g, b ; public shapes( ) { Random rd = new Random( ) ; r = rd.Next ( 255 ) ; g = rd.Next ( 255 ) ; b = rd.Next ( 255 ) ; Thread.Sleep ( 5 ) ; } public abstract void draw ( Graphics g ) ; } In this class we have declared three data members r, g, and b representing red, green and blue components to store the color of the shapes. We have also declared an abstract method in this class called draw( ). The classes derived from shapes class would have to implement the draw( ) method to be able to create their objects. In the constructor we have generated random numbers using an object of the Random class. The Next( ) method of the Random class generates a positive random number less than the number passed to it. Using this method we have initialized the r, g and b data members. The Thread.Sleep( ) method is used to halt the execution for a specified amount of time. In our case it is 5 milliseconds. This is necessary because the Next( ) function uses a thread mechanism to generate a random number. Hence, before the Next( ) method returns a random number, the control moves on to the next statement in the constructor. So, unless we halt the execution of the current thread for 5 milliseconds, r, g, b would not be set up properly. Thus, the shape may not get drawn in a proper color. The statement [Serializable] written before the class declaration is known as an attribute. Attributes are attached to classes, methods, data member or any such entities. Attributes are discussed at the end of this article. For the time being it is enough to understand that any class that is attached with this attribute indicates that all the data members of the class can be serialized i.e. can be written in a file, except for the data members that are marked with [NonSerialized] attribute. We have not marked any data members as [NonSerialized] hence all data members of the class would get written in a file. The other three classes that we would add are line, rectangle and ellipse. These classes would inherit the shapes class. The following code shows the declaration of the line class.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


[Serializable] class line : shapes { int x1, y1 ; int x2, y2 ; public line ( int i, int j, int k, int l ) { x1 = i ; y1 = j ; x2 = k ; y2 = l ; } public override void draw ( Graphics gg ) { Color c = Color.FromArgb ( r, g, b ) ; Pen p = new Pen ( c, 4 ) ; gg.DrawLine ( p, x1, y1, x2, y2 ) ; } } In this class we have declared four ints that are used to store the coordinates of the line. It also consists of a constructor used to initialize these data members. We have implemented the draw( ) method in this class that contains the logic to draw the line. We have attached the [Serializable] attribute to this class also indicating that objects of this class can be serialized. On similar lines the other two classes, rectangle and ellipse, are declared as follows: [Serializable] class rectangle : shapes { int x1, y1 ; int width, height ; public rectangle ( int x, int y, int h, int w ) { x1 = x ; y1 = y ; height = h ; width = w ; } public override void draw ( Graphics gg ) { Color c = Color.FromArgb ( r, g, b ) ; Pen p = new Pen ( c, 4 ) ; gg.DrawRectangle ( p, x1, y1, width, height ) ; } } [Serializable] class ellipse : shapes { int x1, y1 ; int width, height ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


public ellipse ( int x, int y, int h, int w ) { x1 = x ; y1 = y ; height = h ; width = w ; } public override void draw ( Graphics gg ) { Color c = Color.FromArgb ( r, g, b ) ; Pen p = new Pen ( c, 4 ) ; gg.DrawEllipse ( p, x1, y1, width, height ) ; } } After declaring the classes we need to add handlers for the menu items. The handler for the 'Generate' menu item is as shown below. private void generate_Click ( object sender, System.EventArgs e ) { Size sz = ClientSize ; Random rd = new Random( ) ; for ( int i = 0 ; i < 10 ; i++ ) { int x1 = rd.Next ( sz.Width ) ; int y1 = rd.Next ( sz.Height ) ; int x2 = rd.Next ( sz.Height - y1 ) ; int y2 = rd.Next ( sz.Width - x1 ) ; int shapeno = rd.Next ( 3 ) ; switch ( shapeno ) { case 0: s.Add ( new line ( x1, y1, x2, y2 ) ) ; break ; case 1: s.Add ( new rectangle ( x1, y1, x2, y2 ) ) ; break ; case 2: s.Add ( new ellipse ( x1, y1, x2, y2 ) ) ; break ; } } Invalidate( ) ; } When we click the 'Generate' menu item this handler gets called. In this handler an object of the Random class is created. We have used the Next( ) method of this class to not only decide which shape should be generated but also the coordinates of this shape. The coordinates of the shapes to be generated should not be greater than the coordinates of the form. Hence the coordinates are generated using the Size of the form, which is available in the ClientSize property of the form. Using these coordinates we have created ten random objects of rectangle, ellipse or line class. While creating these objects the constructors of the respective classes get called. Since all these classes are derived from the shapes class, firstly the base class

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


constructor gets called. This constructor selects a random color. The references of objects of line, rectangle and ellipse are stored in a collection class called ArrayList. The object of the ArrayList class is added as a data member of the form class by writing the following statement, ArrayList s = new ArrayList( ) ; Using the Add( ) method we have stored all the objects of the line, ellipse and rectangle class in the array list. Next we have called the Invalidate( ) method, which results in the Form1_Paint( ) event handler getting called. This event handler is shown below. private void Form1_Paint ( object sender, System.Windows.Forms.PaintEventArgs e ) { Graphics g = e.Graphics ; foreach ( shapes t in s ) t.draw ( g ) ; } Here we do not know in what order the references of line, ellipse and rectangle classes are stored in the array list. Hence we have extracted references from the array s one by one into a reference t of type shapes. As the line, rectangle and ellipse classes are derived from shapes, it is perfectly legitimate for a reference of shapes such as t to hold a reference of the derived class. Using this reference we have called the draw( ) method. To this method we have also passed an object of the Graphics class. Depending upon which (line, rectangle or ellipse) reference is present in t, the draw( ) method of the appropriate class gets called and the corresponding shape gets drawn. This was the reason behind deriving all the three classes from a common class shapes. After clicking the 'Generate' menu the form appears as shown in the following figure.

Article: C# - File Input/Output - III


Continued from last week... If we wish to save the file we can click on 'Save' menu item. When we do so, save_Click( ) handler gets called. The handler is shown below:

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


private void save_Click ( object sender, System.EventArgs e ) { SaveFileDialog sd = new SaveFileDialog( ) ; sd.Filter = "dat files ( *.dat ) | *.dat" ; if ( sd.ShowDialog( ) == DialogResult.OK ) { FileInfo f = new FileInfo ( sd.FileName ) ; Stream st = f.Open ( FileMode.Create, FileAccess.ReadWrite ) ; foreach ( shapes t in s ) b.Serialize ( st, t ) ; st.Close( ) ; } } Here we have created an object of the SaveFileDialog class and used a "*.dat" filter for it. When we type in a file name and click OK, a FileInfo object gets created with the selected filename. The Open( ) function returns a Stream object associated with the file. We have collected it in a Stream reference. Then we have used a BinaryFormatter object to serialize the objects. This binary formatter is added as a data member of the form class as shown below: BinaryFormatter b = new BinaryFormatter( ) ; BinaryFormatter serializes and deserializes an object, in binary format. The Serialize( ) method of this class serializes the object to the given stream. After serializing all the elements of the array, we have closed the stream using the Close( ) method. When we click 'Open' menu, the open_Click( ) event handler gets called. This handler is given below: private void open_Click ( object sender, System.EventArgs e ) { OpenFileDialog od = new OpenFileDialog( ) ; od.Filter = "dat files ( *.dat )|*.dat" ; if ( od.ShowDialog( ) == DialogResult.OK ) { FileInfo f =new FileInfo ( od.FileName ) ; Stream st = f.Open ( FileMode.Open ) ; while ( st.Position != st.Length ) s.Add ( b.Deserialize ( st ) ) ; st.Close( ) ; } Invalidate( ) ; } Here firstly we have created an object of the OpenFileDialog class and displayed the dialog using the ShowDialog( ) method. In this method too we have created a FileInfo object and collected the corresponding Stream object of the specified file. Next we have used a while loop to deserialize the objects until the end of stream is reached. The Deserialize( ) method deserializes the specified stream into an object. We have collected these objects into our array by using the Add( ) method, closed the stream and called Invalidate( ) function for painting these

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


shapes. When we click 'New' menu item the following handler gets called: private void filenew_Click ( object sender, System.EventArgs e ) { s.Clear( ) ; Invalidate( ) ; } Here we have cleared the array list by deleting all the elements in it using the Clear( ) method. After this we have called Invalidate( ). This time the method Form1_Paint( ) draws nothing as the array is empty, thereby resulting in a clean form. On clicking the 'Exit' menu item the Dispose( ) method gets called and the form is disposed. private void exit_Click ( object sender, System.EventArgs e ) { Dispose( ) ; } Attributes Attributes add extra information to a class, a method, data members, properties or any element to which they are attached. The element to which we can attach an attribute is called the target of the attribute. Attributes are attached using brackets and are written just before declaring the target. For example, to mark any data member as non-serializable in the above program we would use the [NonSerialized] attribute. In our program, suppose we add a static data member called count to the shapes class to keep a count of shapes generated. We would increment this data member in the constructor. Since there is no need to serialize count we can declare it as non-serializable by attaching an attribute [NonSerialized] with it. This ensures that when objects of the shapes class are written in a file, all the data members of every object except count would get written in a file. This is how the class declaration would look like: [Serializable] abstract class shapes { protected int r, g, b ; [NonSerialized] static int count ; public shapes( ) { Random rd = new Random( ) ; r = rd.Next ( 255 ) ; g = rd.Next ( 255 ) ; b = rd.Next ( 255 ) ; count++ ; Thread.Sleep ( 5 ) ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


} public abstract void draw ( Graphics g ) ; } Also, if we want to mark an int variable as dead or not in use, we have to mark it with an Obsolete attribute: [ Obsolete ] int i ; This marks i as obsolete and any use of i will result in an error. This example is not very practical but it helps to understand what attributes are and how to attach an attribute to some element. Attributes are aliases for their corresponding classes defining them. For example, Obsolete is an alias for the System.ObsoleteAttribute class. All the functionality of the attribute is written in the class. Some attributes accept parameters that are supplied inside pair of parenthesis immediately after the name of the attribute. In the same way we have many predefined attributes in .NET programming. .NET also allows us to write our own custom attributes.

Article: C# - Visual Inheritance


In Visual Studio 6.0, to display a dialog box, we derive a class from a pre-defined MFC class. The event handlers and variables associated with controls get added to this user-defined class. All the information about controls get stored in a separate '.rc' file. The compiler creates and displays controls using information stored in the '.rc' file. Visual Studio 6.0 IDE provides facilities for adding controls, variables for controls and handlers. So far so good. Now, consider a situation where an extensive user interface on a dialog comprising of several controls exists and we want to reuse this user interface in other application. What we would try is to inherit the dialog class creating the user interface to create a new class. Major problem with this is that although we get access to the base dialog class members, we don't get controls placed on the new dialog. This is because IDE of Visual Studio 6.0 has no means to access the '.rc' file and render the controls according to the information stored in it. So, our next step would be to copy all the controls from existing dialog template and to paste them on the new dialog. Now we get the controls and the variables and event handlers. But the problem here is that the code that associates controls with their variables and handlers remains missing. So, reusing an existing user interface is far more different and difficult than reusing an existing class. Through 'Inheritance' we create a new class by using an existing class. Through 'Visual Inheritance' we create a new form by using an existing form. When we inherit a form from an existing form we also inherit controls, their properties, events and methods. So, the user interface that is already created can be reused in a new application thereby reducing the repetitive designing of controls. This makes Visual Inheritance a powerful weapon in this era of Rapid Application Development. We can use visual inheritance in cases where we need to use the same set of controls again and again. Visual Studio.NET has incorporated visual inheritance as a part of .NET framework. Visual inheritance is so called because it gives the visual expression of the inherited control objects. Using Visual inheritance is a two step process: - Creating Base Form - Creating Derived Form These steps are explained below.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Creating Base Form Carry out the following steps to create a Base Form. 1. Create a Windows Application named 'baseform'. 2. Add a button having label as "Click" and Name as b. Also add a text box having Name as t. By default, these variables get added as private data members. Change the access modifiers to public through the Modifiers property. If we change the Modifiers property of a control to protected or public we would be able to change its properties in the derived form. The controls marked as private in the base form will be visible on derived form but will not be accessible through its Name. This seems relevant because in OOP inheritance also only protected and public members of a base class are visible to its derived classes. In any case, we would not be able to delete the derived controls from the form. 3. Add the Click event handler for the button and add following statement in it. MessageBox.Show ( t.Text ) ; 4. Now since our form stands ready we can build it into a class library so that we can export the form. Note that we cannot import a form from an exe file. To build the project in a class library, right click the solution name in Solution Explorer and select Properties. The 'baseform Property Pages' would get displayed. Select the Output Type as Class Library. Now build the project to create 'baseform.dll'. This assembly contains the baseform.Form1 class that we can inherit. Creating Derived Form 1. Create another Windows Application named 'derivedform'. 2. Right click the solution name in Solution Explorer and select 'Add | Add Inherited Form' menu option. The 'Add New Item' dialog box gets displayed. 3. Select the 'Inherited Form' from the 'Templates' list and provide a name of your choice in the 'Name' text box. We have kept the default name 'Form2.cs'. 4. The 'Inheritance Picker' dialog would get displayed. This dialog allows us to select an assembly that contains the form we want to inherit. For this, click the 'Browse' button. A dialog would appear from where we can select the 'baseform.dll' file and click the 'Open' button. 5. Clicking the 'Open' button dismisses the dialog and displays the forms exported by the assembly (an assembly can export any number of forms) in 'Specify the component to inherit from' list control. 6. Select the form name from the 'Specify the component to inherit from' list control and click the 'OK' button. As soon as we click the 'OK' button, a new form derived from the 'baseform' gets displayed in the design editor. The file 'Form2.cs' also gets displayed in the Solution Explorer as shown in Figure 1.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Figure 1 Figure 1 also displays reference of 'baseform.dll' being added in the 'References' tree in the Solution Explorer. The derived form displays the derived controls being added to the base form. These controls are accompanied by a small icon at the top left corner to distinguish between the derived controls and the new controls. 7. Open the 'Form1.cs' file. Change form name in Application.Run( ) method to Form2 as shown below. Application.Run ( new Form2( ) ) ; This ensures that when we would execute the application, the new form, i.e. Form2, would get displayed. If we enter the text in the textbox and click the button the text would get displayed in a message box. Let us now see how the whole thing works. To begin with the statement Application.Run ( new Form2( ) ) gets executed. Here we are creating an object of the Form2 class which is derived from the baseform.Form1 class. When we create an object of derived class, base class's constructor gets called. So, in our case constructor of the baseform.Form1 class would get called. This class is accessible to us since a reference to the 'baseform.dll' assembly is already being added to our project. The compiler adds a call to the InitializeComponent( ) method in the constructor of every form class. The InitializeComponent( ) method contains the code for creating and customizing the controls. Once this method gets executed and controls get created, the control returns to the constructor of the Form2 class. This constructor again calls the InitializeComponent( ) method. This time the InitializeComponent( ) method of the Form2 class gets called. This is the reason why derived form contains the derived controls (initialized by InitializeComponent( ) method of the baseform.Form1 class) and the new controls (initialized by InitializeComponent( ) method of the Form2 class). We have already added the Click event handler for the 'Click' button. We can override this handler in the Form2 class and add our code in it. Now if we click the button, firstly, event handler of the base class gets executed and then the overridden handler gets executed. This is because, the InitializeComponent( ) method of the baseform.Form1 class gets executed first, wherein, an address of the Click event handler defined in the baseform.Form1 class gets stored in the Click delegate. Next the InitializeComponent( ) method of the Form2 class gets executed. In it,

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


the address of the Click event handler defined in the Form2 class gets added to the Click delegate.

Article: C# - Structures And Enums - I


We have seen how to use classes in our programs. Whenever we needed to group dissimilar data along with some functionality we used classes. Structures are similar to classes because they too contain dissimilar data along with methods. A structure is defined using a struct keyword. Consider the following example: using System ; namespace sample { struct employee { string name ; int age ; float sal ; public employee ( string n, int a, float s ) { name = n ; age = a ; sal = s ; } public void showdata( ) { Console.WriteLine ( "Name: " + name ) ; Console.WriteLine ( "Age: " + age ) ; Console.WriteLine ( "Salary: " + sal ) ; } } class Class1 { static void Main ( string[ ] args ) { employee e1 = new employee ( "Amit", 35, 25000 ) ; e1.showdata( ) ; } } } In this program we have declared a structure called employee. This structure holds one string, and two ints. It also consists of a three-argument constructor and a showdata( ) method. In Main( ) we have declared a variable called e1 of the type employee. Here unlike C, we must not write the struct keyword while defining structure variables. Note that even though we have used new, space for employee gets allocated on the stack. Structures vs Classes In the previous example we could have replaced the struct keyword with class. This may give a

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


feeling that both structures and classes are alike. But in reality there are a lot of differences between the two. They are listed below. (a) We cannot add our own zero-argument constructor to the structure. (b) The structures are implicitly sealed. Hence structures cannot be inherited. (c) Being sealed, structures cannot be marked with an abstract modifier. (d) Since structures cannot be inherited, its members cannot have protected access modifier. Also there cannot be virtual functions in structures. (e) Structure members cannot be initialized at the point of declaration. For example, struct mypoint { int i = 10 ; int j = 20 ; } This results in an error. However if the data member is static we are permitted to initialize it. (f) Structures are value types, whereas, classes are reference types. The type of variable (value or reference) decides the storage and behavior of variables in the .NET environment. This has a direct bearing on the programming efficiency. Value Types and Reference Types In C# variables are either value types or of reference types. The difference between the value type and reference type is that the data of value type gets stored on the stack and that of the reference type gets stored on the heap. The variables of the value types directly contain the data, whereas, reference types contain references (or addresses) of the data. This is shown in following figure. Figure 1 To demonstrate the working of value type and reference type we would write two programs. The following program shows a value type at work: using System ; namespace sample { struct mystruct { public int i ; } class Class1 { static void Main ( string[ ] args ) { mystruct x = new mystruct( ) ; x.i = 9 ; mystruct y ; y=x; y.i = 5 ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Console.WriteLine ( x.i ) ; Console.WriteLine ( y.i ) ; } } } The output of this program would be 9 5. Let us now understand how this program works. The statement, mystruct x = new mystruct( ) ; creates a new structure variable x, which refers directly to the data. We have stored 9 in x. The statement mystruct y ; too creates a structure variable y, which refers directly to the data. The statement y = x assigns the value of x to y. Hence y would now hold 9 in it. Then the statement y.i = 5 assigns the value 5 to y. Now y would hold 5 and x would continue to hold 9 in it. Thus whenever we assign a structure variable to another structure variable the full contents of righthand side structure variable get copied in the left-hand side variable. The difference between mystruct x = new mystruct( ) ; and mystruct y ; is that for x a default zero-argument constructor would get called, whereas, for y no constructor would be called. The default zero-argument constructor sets the data members to their default values. Since no constructor gets called for y its members do not get initialized. In such a case we must take care to initialize the variables before their usage. In both the cases discussed above memory is allocated on the stack. Now let us see a reference type at work. using System ; namespace sample { class myclass { public int i ; } class Class1 { static void Main ( string[ ] args ) { myclass x = new myclass( ) ; x.i = 9 ; myclass y ; y=x; y.i = 5 ; Console.WriteLine ( x.i ) ; Console.WriteLine ( y.i ) ; } } }

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


The output of this program would be 5 5. The statement, myclass x = new myclass( ) ; creates a variable x on the stack and creates an object on the heap. This object would be used to hold the data. Here x is called a reference which refers (or points) to the object. In other words x holds an address of the object. Through the statement x.i = 9 we have assigned the value 9 to the object referred to by x. Then we have created a reference y through the statement myclass y ;. Since y is not assigned a value it would hold null in it. The statement y = x assigns the reference stored in x to y. Hence y would now start referring to the same object referred by x. The statement y.i = 5 ; would replace 9 from the object. Hence the output would be 5 5.

Article: C# - Structures And Enums - II


Continued from last week... When To Use What So when do we use structures and when do we use classes? This depends on the situation. For example, if we wish to group together a few dissimilar data types, we must use structures because being a value type it gets allocated on the stack. Memory allocation on a stack is always faster than allocation on the heap. On the other hand, if the structure is big then whenever we pass the structure variable as a parameter or assign it to another structure variable, the full contents of the structure variable gets copied. As against this for a class only the reference is copied. It is more efficient to copy a 4-byte reference than copying the whole structure. Data Types Revisited C# data types are divided into value types and reference types. Value types contain structures, and enumerations, whereas, references types are complex types such as classes, interfaces, delegates and arrays. Then where do the primitive data types (int, float, char etc.) stand? Actually primitive data types are structures. This is because C# compiler maps primitive data types to a set of predefined structures defined by .NET base class library. For example, the keywords int, float, etc. are simply aliases of the predefined struct types present in the System namespace, as shown in following table. Keyword sbyte byte short ushort int uint long ulong char float Aliased type System.Sbyte System.Byte System.Int16 System.Uint16 System.Int32 System.UInt32 System.Int64 System.UInt64 System.Char System.Single

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


double bool decimal System.Double System.Boolean System.Decimal

The primitive data types being structures, they can call functions defined in those structures. For example to convert an integer to a string we can write the following code: int n = 10 ; string s = n.ToString( ) ; C# supports two more primitive data types: object and string. They are of reference types and are mapped to the System.Object class and System.String class respectively. User-defined structures and classes by default get derived from the System.Object class. Even all .NET classes and structures are derived from the System.Object class. Enumerated data types and arrays too get mapped to the .NET base classes in some way or the other. Even though the structures cannot have virtual functions they can have override methods. This is because structures are derived from the System.Object class. Using the override methods we can override the virtual methods of the System.Object class. Boxing And Unboxing C# provides the flexibility to use value types as reference types (objects) as and when required. Whenever a value type is converted into a reference type it is known as boxing. On the other hand when a reference type is converted into a value type it is known as unboxing. For example, int i = 10 ; object o = i ; // boxing i = ( int ) o ; // unboxing This is a simple example where we have first "boxed" an int into an object (reference type) and then extracted the value back into an int variable. Note that boxing will always be implicit, whereas, unboxing is explicit. This is because while unboxing we extract the value from an object type and hence we are never aware of its actual type i.e. whether it is an int, float, char, etc. So we explicitly have to determine the type we want back. On the other hand while boxing, we need not bother about the type and just box it into the object. This is because all value types are inherited from the object class. Where do we need to use boxing? Boxing generally occurs while passing arguments to a method. If we pass a value type to a method that was expecting a reference type, the compiler boxes the value type into an object or System.Object. Consider the following example: int i = 12 ; myclass c1 = new myclass ( 10 ) ; Console.WriteLine ( "The value is {0} {1}", i, c1 ) ; Here we have passed three arguments to the WriteLine( ) method. This includes a string, an int and a class type. The WriteLine( ) method has been written to accept a string followed by a params array of object class. The declaration of WriteLine( ) is as follows: WriteLine ( string s, params object[ ] o ) ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


The notations {0} and {1} represent the positions of the arguments in the list being printed. All the arguments except the first are collected in the params array of object class. Hence there is no restriction on number of parameters being printed in the list. In the WriteLine( ) method we have passed an int variable when the method is expecting an object. Hence the compiler converts the int variable (value type) into an object (reference type) using boxing and collects it as the first element of the params array of objects. Then we have passed an object of the class myclass which would be collected as the second element of the array. This object being a reference type it would not get boxed. Recall that every reference and a value type is derived from the object or System.Object class. So whatever is passed to WriteLine( ) method can be collected as an object. Hence the Console class does not have overloads of the WriteLine( ) method for an int, float, char, and so on. Enumerations An enumeration (enum) is a special form of value type, which inherits from the System.Enum class. An enum consists of some underlying data types. The underlying type must be one of the built-in signed or unsigned integer types (such as short, int, or long). These data types are static and have constant values. Each field is assigned a specific value of the underlying type by the programmer or the compiler. We can access the enum members using the enum name followed by a dot. All members in an enum are public members. Following example illustrates its usage. using System ; namespace sample { enum color { red, blue, green } class Class1 { static void Main ( string[ ] args ) { Console.WriteLine ( " {0} ", color.red ) ; } } } The output of the program would be red. If we want to see the value we must write the following statement: Console.WriteLine ( ( int ) color.red ) ; Here the output would be 0. We can also change the underlying data type (which is int by default) as in the following program. We have also provided an initial value to one of the members of the enum. using System ; namespace sample { enum color : byte { red, blue = 8, green

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


} class Class1 { static void Main ( string[ ] args ) { Console.WriteLine ( color.green ) ; } } } The output of the program would be green. But here we have to be careful that we should not use a value, which is out of range, for example assigning a value like 500 to red in this program will result in error since we have declared that the enum is of type byte. Using, Console.WriteLine ( ( byte ) color.green ) instead of Console.WriteLine ( color.green ) in Main( ) would give the output as 9. All members towards the right of blue will be initialized to a value equivalent to blue's value plus the number of places it is far from blue. green is one place right from blue, its value will be 8 + 1 i.e. 9. This is not true for members on the left hand side. So in this case red will be initialized to 0 by the compiler. However we can initialize all the members with different values. Any uninitialized member will be initialized to a value according to its position from the last initialized one. This would be evident from the following program. using System ; namespace sample { enum color { red = 8, blue, green = 7, yellow, brown } class Class1 { static void Main ( string[ ] args ) { Console.WriteLine ( ( int ) color.red + " " + ( int ) color.yellow ) ; } } } The output of this program would be 8 8. There are a few more important points to note regarding enums: 1. We can give same values to two enum members. 2. An enum cannot have a circular definition. For example, enum color { red = yellow, blue, green, yellow, brown } The compiler will first try to give red yellow's value. But yellow's value depends on red's value. Hence yellow has no value yet and will be assigned a value later. This is circular dependency and is not allowed.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


3. The value of enum members cannot be changed. 4. An enum cannot have two members with the same name. 5. We cannot inherit from enums.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Article: C# - Creating Collection Classes


Creating efficient data structures has always been a nightmare of programmers. But while writing a C# program the last thing on our mind is how to build a data structure. .NET Foundation Class Library contains a namespace called System.Collections that provides classes to manage data structures like arrays, lists and maps. It also provides interfaces to enumerate and compare the elements of collections. Let us first discuss in brief the classes available for maintaining the above-mentioned data structures. The ArrayList class is similar to the Array class except that its size can grow dynamically. Like the Array class, the ArrayList class contains various methods to perform functions like adding, inserting, removing, copying, etc. The Queue and Stack classes provide the 'First In First Out' and 'Last In First Out' type of collection respectively. The base class library provides a class called BitArray that allows us to create an unusual array-array of bits. If we provide an int array, the bits array gets created with the bit values of every element of the array. The Hashtable and SortedList classes manage a collection of key-value pairs. The difference between the Hashtable and SortedList class is that in the SortedList class, the values are sorted by keys and are accessible by key as well as by index. Using these classes is straightforward and is dealt with in enough details in several popular C# books. We simple have to instantiate an object of the relevant collection class and call its methods. The difficult programming is involved when we have to provide collection support to our class. Let us see what 'collection support' means. A collection is a set of same type of objects that are grouped together and that is able to supply a reference to an enumerator. An enumerator is an object that iterates through its associated collection. It can be thought of as a movable pointer pointing to any element in the collection. In order to provide an enumerator, a class must implement the IEnumerable interface. If a class implements IEnumerable interface, we can use an object of the class in foreach statement. We would now see an example that shows how to provide enumeration support to our class. We would write a class sample having an int array named arr as a data member. The sample class would implement the IEnumerable interface so that we can enumerate through the array arr using the foreach statement. Here is the code. using System ; using System.Collections ; class sample : IEnumerable { int[ ] arr = { 10, 11, 12, 13, 14 } ; class myenumerator : IEnumerator { int c ; sample s ; public myenumerator ( sample ss ) { c = -1 ; s = ss ; }

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


public object Current { get { return s.arr [ c ] ; } } public bool MoveNext( ) { if ( c < s.arr.Length - 1 ) { c++ ; return true ; } else return false ; } public void Reset( ) { c = -1 ; } } public IEnumerator GetEnumerator( ) { return new myenumerator ( this ) ; } } The IEnumerable interface declares only one method GetEnumerator( ). The GetEnumerator( ) method returns reference to the enumerator object. We have to write our own enumerator so that it would enumerate our collection. To create an enumerator we have to write a class that implements the IEnumerator interface. Here our enumerator class is myenumerator. In the GetEnumerator( ) method we have created an object of myenumerator class and passed to its constructor the this reference. This is necessary because, we have to access arr in the methods of myenumerator class. We have implemented the methods of IEnumerator interfaceMoveNext( ) and Reset( ) and a property called Current. Let us now understand how an enumerator works. When an enumerator object is initialised, it does not point to any element of the collection. We must call the MoveNext( ) method that moves the enumerator to the first element of the collection. We can retrieve this element by calling the Current property. We can do whatever we want with this element. Then we must move to the next element by calling the MoveNext( ) method again. If we want to enumerate the collection again we can call the Reset( ) method that returns before the beginning of collection. Our implementation of MoveNext( ), Reset( ) and Current does the same. Now, we can use the foreach statement on an object of the class sample as shown below. sample s = new sample( ) ; foreach ( int i in s ) Console.WriteLine ( i ) ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


The foreach statement works like this. IEnumerator e = s.GetEnumerator( ) ; while ( e.MoveNext( ) ) Console.WriteLine ( e.Current ) ; The foreach statement would terminate when the MoveNext( ) method would return false. Note that it is necessary to design a separate class implementing the IEnumerator interface rather than implementing it in the collection class itself. If we implement the IEnumerator interface in the collection class, we would face problem when enumerating same object again.

Article: C# - Event Driven Programming With WinForm


Windows applications that we create fall under two major categories-managed and unmanaged. Unmanaged Windows applications can be created using Microsoft Foundation Classes (MFC). Managed application run under Common Language Runtime (CLR) and are created using .NET Framework Class Library. These applications are called WinForm applications. WinForms (Windows Forms) create graphical user interface (GUI) for Windows applications. A form is a toplevel window of an application. It can be a window, a dialog or a multiple document interface (MDI) window. Creating WinForms has many advantages over creating applications using MFC. In unmanaged Windows-based programs, we need to apply certain styles to the window only when it is created. WinForms eliminate this quirk. If we apply styles that are meant to be applied at creation time, .NET destroys the previous window and creates a new one with new styles. .NET Framework Class Library is richer than MFC. At the same time, the classes remain same for all the .NET compliant languages. All the classes that are used to create and design a WinForm are encapsulated in System.Windows.Forms namespace. For example, the System.Windows.Forms.Form class is used to create the form, System.Windows.Forms.Button class is used to create a button and so on. To create a GUI, we place components and controls on the form and so, a form acts as a container of components and controls. To create the GUI we drag and drop the controls from Toolbox and change their properties to suit our requirements. When we drag the control on form and change properties, Visual Studio.NET generates suitable code for us. However, only adding controls to create a user interface is not enough. Our application must also respond when the user interacts with the application. User can interact with the application by moving the mouse, clicking the mouse button, pressing a key, clicking on a button, etc. Whenever user interacts with the GUI, events are generated. Events are notifications sent to the container, which can then respond to it. For example, when we click a button, an event is generated notifying that user has clicked the button. In response, we can display a message box or do something else. This job is done in methods called 'event handlers'. When a particular event is generated, corresponding event handler gets called to process the event. For calling the event handlers .NET takes help of events and delegates. An event in C# is a multicast delegate having a predefined prototype. The prototype is such that every event returns a void and always accepts two parameters. The first parameter is always a reference to an object of System.Object class and the second parameter is always a reference to an object of the System.EventArgs class or a class derived from it. The EventArgs object contains information about the event. The object that raises an event is called an 'event raiser' and the object that receives an event is called an 'event receiver'. The event raiser class always declares the event and the receiver class must have an event handler to handle that event. The first parameter collected by the event handler is always a reference to an event raiser object. The

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


addresses of event handlers are stored inside the events (remember that events are actually delegates) and hence they also must have the same signature as the event. Such kind of a delegate is declared using the keyword event. To understand events, consider the following program. using System ; namespace Sample { public class mouseeventargs { public int x, y ; public mouseeventargs ( int x1, int y1 ) { x = x1 ; y = y1 ; } } public delegate void click ( object m, mouseeventargs e ) ; public class MyForm { public event click c1 ; public void mouseclick( ) { mouseeventargs m = new mouseeventargs ( 10, 20 ) ; c1 ( this, m ) ; } } class MyForm1 : MyForm { public MyForm1( ) { c1 += new click ( button_click ) ; mouseclick( ) ; } public void button_click ( object m, mouseeventargs e ) { Console.WriteLine ( "Mouse Coordinates: " + e.x + " " + e.y ) ; Console.WriteLine ( "Type is: " + m.GetType( ).ToString( ) ) ; } static void Main ( string[ ] args ) { MyForm1 f = new MyForm1( ) ; } } } In this program we have declared 3 classes-mouseeventargs, MyForm and MyForm1 derived from MyForm. The mouseeventargs class corresponds to the EventArgs class. This class contains two int variables x and y and a constructor to initialize them. We have declared a multicast delegate click whose signature is same as the event handler button_click( ). The MyForm class here is an event raiser class and hence contains an event as a data member called c1 of the type click. It also contains a method called mouseclick( ). In this method we have created an object of the mouseeventargs class. In the statement,

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


c1 ( this, m ) ; c1 encapsulates the button_click( ) method. this contains the reference of MyForm object (event raiser) and m is a reference of the mouseeventargs object. In the MyForm1 class, we have defined the method button_click( ) (i.e. event handler). When the compiler encounters the statement c1 += new click (button_click), it creates an event object (delegate object) that wraps up button_click( ) method. So whenever the c1 event is raised (or called, as in this program), the method button _click( ) would get executed. We could call a method even using a delegate. Then what are events for? Take a look at the following statement. c1 = new click ( button_click ) ; where, c1 is a delegate reference. This statement has a bug. Here, we are assigning a new delegate object to c1 and so, all the delegates previously added are now lost. Instead of = operator we should have used += operator to add a new delegate object to the delegate list. This would never happen in case of events. This is because we can perform only two operations on events, namely, += and -=. We cannot use = operator with events. As such events provide a protection layer on delegates. When we use the += and -= operators with delegates, they get converted into a call to Delegate.Combine( ) and Delegate.Remove( ) methods. If we use += and -= operators with events they get converted into a call to add_c1( ) and remove_c1( ) methods. These methods in turn call the Delegate.Combine( ) and Delegate.Remove( ) methods. WinForms also follow the same mechanism. Only thing is, we don't need to invoke the event handlers ourselves. They get called automatically when events occur. The compiler adds suitable code such that when an event occurs our event handler would get called. Let us now see what code gets generated when we create a WinForm application and add an event handler. The minimal code that is required to create a WinForm application is given below: using System ; using System.Windows.Forms ; namespace WinFormDemo { public class Form1 : Form { static void Main( ) { Application.Run ( new Form1( ) ) ; } } } Here, we have derived a class Form1 from the Form class and passed a reference to its object to the Application.Run( ) method. This method creates the form, displays it on screen and starts a message loop for it. Of course, we don't need to write this code, Wizard generates it for us. If we add a control to the form, a reference to the class representing the control gets added to the class as a private member. If we add a button the reference to the Button class would get added as shown below. private System.Windows.Forms.Button button1 ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


The reference button1 would get initialized in the InitializeComponent( ) method as given below. this.button1 = new System.Windows.Forms.Button( ) ; On adding a handler for the Click event, the code generated for it looks as given below. this.button1.Click += new System.EventHandler ( this.button1_Click ) ; The EventHandler is a delegate defined in the System namespace. This statement wraps the EventHandler around the button1_Click( ) method so that when the Click event is fired, button1_Click( ) method would get called. The definition of button1_Click( ) method is shown below. private void button1_Click ( object sender, System.EventArgs e ) { } The first parameter passed to button1_Click( ) method identifies the object that fired the event (button1 in this case). The second parameter contains additional information about the event. The objects of every control class fire events and now you can appreciate how easy it is to handle these events under .NET.

Article: C# - GDI+ - An Extension To GDI - I


If you have programmed under Windows you are familiar with the term GDI (Graphical Device Interface). GDI simplifies drawing by providing an interface to the hardware devices like screen or printer such that the programmers don't need to bother about hardware details and their differences. The same program can work on different display adapters, printers, keyboards, etc. without modifying it. .NET uses GDI+, an extension to GDI, which further simplifies drawing. GDI+ has added several new features like graphics paths, support to image file formats, image transformation, etc. GDI+ has also modified the programming model by introducing fundamental changes in the programming model used by GDI. Changes In Programming Model GDI uses an idea of Device Context (DC). Device Context is a structure that stores all the drawing related information viz. features of display device and attributes that decide the appearance of the drawing. Every device context is associated with a window. To draw on a window, one must first obtain a device context of that window. If we want to change any attribute, say, pen color we first select it in the device context by calling the SelectObject( ) method. Once selected all the drawing is done using this pen unless and until we select another pen in device context. GDI+ works with 'graphics context' that plays similar role as device context. The graphics context is also associated with a particular window and contains information specifying how drawing would be displayed. However, unlike device context it does not contain information about pen, brush, font, etc. If we want to draw with new pen we simply have to pass an object of Pen class to the DrawLine( ) method (this method draws line on window). We can pass different Pen objects in each call to DrawLine( ) method to draw the lines in different colors. Thus GDI uses a stateful model, whereas, GDI+ uses a stateless model. The Graphics class encapsulates the graphics context. Not surprisingly, most of the drawing is done by calling methods of the Graphics class.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Working With GDI+ We would see how to draw text and graphics using GDI+ by writing a small program. Create a Windows Application. Windows programmers know that a window receives WM_PAINT message when it is to be painted. We need to handle this message if we want to do any painting in the window. In .NET to do this we can either override the virtual method OnPaint( ) of the Form class or write a handler for the Paint event. The base class implementation of OnPaint( ) invokes the Paint event handler through delegate. Hence we should write our code in the Paint event handler. Add the Paint handler to the form. The Form1_Paint( ) handler would look like this. private void Form1_Paint ( object sender, PaintEventArgs e ) { } The first parameter passed to the Form1_Paint( ) handler contains the reference to the object of a control that sends the event. The second parameter contains more information about the Paint event. We would first see how to display a string on the form. To display the string we would use DrawString( ) method of the Graphics class. private void Form1_Paint ( object sender, PaintEventArgs e ) { Graphics g = e.Graphics ; Font myfont = new Font ( "Times New Roman", 60 ) ; StringFormat f = new StringFormat( ) ; f.Alignment = StringAlignment.Center ; f.LineAlignment = StringAlignment.Center ; g.DrawString ( "Hello!", myfont, Brushes.Blue, ClientRectangle, f ) ; } The Graphics property of the PaintEventArgs class contains reference to the Graphics object. We can use this reference for drawing. In a handler other than Paint event handler we can obtain the Graphics reference using the CreateGraphics( ) method of the Form class. The DrawString( ) method has several overloaded versions. We used one that allows us to display centrally aligned text in desired font and color. The first parameter passed to the DrawString( ) method is the string we wish to display. The second parameter is the font in which text would get displayed. We have created a font by passing the font name and font size to the constructor of the Font class. The text gets filled with the brush color specified as the third parameter. The fourth parameter specifies the surrounding rectangle. We have passed ClientRectangle property of Form class that contains a rectangle representing the client area of the form. To centrally align the text we have used the StringFormat class. The Alignment and LineAlignment properties of this class contain horizontal and vertical alignment of text respectively. The Graphics class contains various methods to draw different shapes. This includes drawing rectangle, line, arc, bezier, curve, pie, etc. We would add the code in Form1_Paint( ) handler that draws rectangles in different pens and brushes. You would be able to draw other shapes on similar lines. The following code draws a rectangle using green colored pen having line thickness of 3. Pen p = new Pen ( Color.Green, 3 ) ; g.DrawRectangle ( p, 20, 20, 150, 100 ) ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


The Pen class encapsulates various styles of pens like solid, dash, dash-dot, etc. We can change the style of pen using the DashStyle property of the Pen class. This is shown in the following statement. p.DashStyle = DashStyle.Dash ; If we want, we can specify custom pen style by using the DashPattern property. There are several other properties of the Pen class that allow us to specify the pen type (hatch fill, gradient fill, solid color, etc), cap style, join style, etc. Unlike GDI, GDI+ provides separate methods for rectangle and filled rectangle. To fill the rectangle we need to pass a Brush object. This is shown below. HatchBrush hb = new HatchBrush ( HatchStyle.BackwardDiagonal, Color.Red, Color.Black ) ; g.FillRectangle ( hb, 200, 20, 150, 100 ) ; We have used hatch brush to fill the rectangle. The hatch brush is created using the HatchBrush class. We have mentioned the hatch style as BackwardDiagonal. The rectangle will get filled with the hatch brush in red and black color combination. Like the HatchBrush class there are several other classes used to fill the shapes with viz. SolidBrush, TextureBrush, and LinearGradientBrush. Gradient brush is something that was not available in GDI. Let us see how to use it. LinearGradientBrush gb = new LinearGradientBrush ( ClientRectangle, Color.BlanchedAlmond, Color.Aquamarine, 90 ) ; g.FillRectangle ( gb, ClientRectangle ) ; Here, we have created an object of the LinearGradientBrush class and passed to its constructor the rectangle to be filled, and two colors that form the gradient pattern. The last parameter specifies the angle from which we wish to draw. Specifying 90 would fill the window vertically.

Article: C# - GDI+ - An Extension To GDI - II


...Continued from last week Coordinates And Transformations In the Graphics methods we specify coordinates in two-dimensional coordinate system. The system has origin at left-top corner and x and y axes point to right and down respectively. All the methods take coordinates in pixels. The coordinates passed to Graphics methods are world coordinates. When we pass world coordinates to a method, they firstly get translated into page coordinates (logical coordinates) and then into device coordinates (physical coordinates). Ultimately, the shape gets drawn in device coordinates. In both the page and device coordinate system the measure of unit is same i.e pixels. We can customize the coordinate system by shifting the origin to some other place in client area and by setting a different measure of unit. Let us see how this can be achieved. We would first draw a horizontal line having 1 inch of width. Here is the code to do this.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


private void Form1_Paint ( object sender, PaintEventArgs e ) { Graphics g = e.Graphics ; g.PageUnit = GraphicsUnit.Inch ; Pen p = new Pen ( Color.Green, 1 / g.DpiX ) ; g.DrawLine ( p, 0, 0, 1, 0 ) ; } Here firstly we have set the PageUnit property to GraphicsUnit.Inch specifying that the unit of measure is an inch. We have created a Pen object and set its width to 1 / g.Dpix. The Dpix property of the Graphics class indicates a value, in dots per inch, for the horizontal resolution supported by this Graphics object. Note that this is necessary because now Pen object also assumes 1 unit = 1 inch. So, if we don't set the pen width like this, a line with 1 inch pen width would get drawn. Next we have drawn a line having one unit measure, which happens to be an inch. Let us now shift the origin to the center of the client area and draw the line again. private void Form1_Paint ( object sender, PaintEventArgs e ) { Graphics g = e.Graphics ; g.PageUnit = GraphicsUnit.Inch ; g.TranslateTransform ( ( ClientRectangle.Width / g.DpiX ) / 2, ( ClientRectangle.Height / g.DpiY ) / 2 ) ; Pen p = new Pen ( Color.Green, 1 / g.DpiX ) ; g.DrawLine ( p, 0, 0, 1, 0 ) ; } Here, after setting the unit to inches using the PageUnit property, we have called the TranslateTransform( ) method to shift the origin to the center of the client area. This method maps the world coordinates to page coordinates and so the transformation is called world transformation. The x and y values we have passed to the TranslateTransform( ) method get added to every x and y values we pass to the Graphics methods. Finally, we have created a pen having proper width and drawn the line. GDI+ also allows us to orient the x and y axes's direction to the specified angle. For this, it provides the RotateTransform( ) method. For example, if we call the RotateTransform( ) method before drawing the line as shown below, g.RotateTransform ( 30 ) ; then line would get displayed slanting downwards, 30 degrees below the base line. We can use this functionality of the RotateTransform( ) method to create an application like analog clock. Disposing Graphics Objects Whenever we open a file, we close it after we have finished working with the file. This is because a handle is associated with the file that remains open if we don't close it explicitly. Similarly, GDI+ resources like pens, brushes, fonts need to be disposed of because they encapsulate GDI+ handles in them. To release the GDI+ resources, we can call the Dispose( ) method on every object that is to be released. For example, following statement would release the pen object represented by penobject using the Dispose( ) method. penobject.Dispose( ) ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


We must also release the Graphics object obtained by calling the CreateGraphics( ) method.

Article: C# - Reading Metadata Using Reflection


Every managed application in .NET is deployed as an assembly and every assembly defines certain types. These types are revealed in the form of metadata. Metadata is the data written in binary form in Portable Executable (PE) file. Metadata gives a detailed description of types and external assemblies that are used by the types. For example, metadata of a class would completely define the class including its methods, parameters of methods, calling convention, class's data members and visibility of class members. We can read this information from metadata using reflection. .NET base class library has provided namespaces and classes for this encapsulated in System.Reflection namespace. Using reflection we can read types from assembly, create instances of types dynamically, invoke methods, etc. Before we discuss how to use reflection technology, we would see how types are arranged in metadata and what purpose does metadata serve. One of the biggest benefits of .NET is that code written for it can be used by different languages. A function defined in VC++ can be called from VB. But as both the languages use different syntax there must be some common format to enable interoperability. This common format is metadata. Another benefit of using metadata is that it eliminates need of specifying the import library in the linker options. This is possible because metadata is written in the same EXE or DLL file as the code itself. The information in metadata is arranged in the following hierarchy.

Reflection allows us to either read data from assembly or write data to assemblies. The System.Reflection namespace contains classes to read an assembly, whereas, System.Reflection.Emit namespace contains classes to write to the assembly. In this article, we would firstly create an application that lists all the types of selected assembly. Then, on selecting a type its members get displayed. Create a Windows Application and design a form as shown in the following figure.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

The variables and events of different controls in the form are given in the following table. Control TextBox Load Button Types ListBox Methods and Constructors ListBox Properties ListBox Events ListBox Variable aname load list listmethods listprop listeve Click SelectedValueChanged Event

Also add the OpenFileDialog control to the form. On clicking the 'Load' button the standard 'Open' dialog box gets displayed. If user selects an assembly and clicks the OK button, its path gets displayed in the text box, the assembly gets loaded in memory and its types get displayed in the list box. To do this, we have added the Click event handler as shown below. private void load_Click ( object sender, System.EventArgs e ) { openFileDialog1.InitialDirectory = @"C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705" ; openFileDialog1.Filter = "Assemblies (*.dll)|*.dll" ; if ( openFileDialog1.ShowDialog( ) == DialogResult.OK ) { list.Items.Clear( ) ; aname.Text = openFileDialog1.FileName ; Assembly a ; try { a = Assembly.LoadFrom ( aname.Text ) ; tarray = a.GetExportedTypes( ) ; } catch ( Exception ex ) {

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


MessageBox.Show ( "Error in loading assembly" ) ; return ; } foreach ( Type type in tarray ) list.Items.Add ( type.FullName ) ; list.SetSelected ( 0, true ) ; } } Here, firstly we have set the default folder where all .NET framework assemblies are stored. We have also set the Filter property to '.dll' so that only assemblies would be listed in the dialog. To load the selected assembly, we have read the assembly path from the text box and called the LoadFrom( ) static method of the Assembly class. This method returns a reference to the Assembly object. Using this reference, we have called the GetExportedTypes( ) method that returns an array of types available in the assembly. tarray is an array of Type objects. Add this array as a private data member. The types returned by the GetExportedTypes( ) method are added to the list box in the foreach loop using the Add( ) method. Now let us write the code to display type members in respective list boxes, if any type is selected. The SelectedValueChanged event handler is given below. private void selchange ( object sender, System.EventArgs e ) { int index = list.SelectedIndex ; Type t = tarray [ index ] ; listmethods.Items.Clear( ) ; listprop.Items.Clear( ) ; listeve.Items.Clear( ) ; ConstructorInfo [ ] ci = t.GetConstructors( ) ; foreach ( ConstructorInfo c in ci ) listmethods.Items.Add ( c ) ; PropertyInfo [ ] pi = t.GetProperties( ) ; foreach ( PropertyInfo p in pi ) listprop.Items.Add ( p ) ; EventInfo [ ] ei = t.GetEvents( ) ; foreach ( EventInfo ev in ei ) listeve.Items.Add ( ev ) ; MethodInfo [ ] mi = t.GetMethods ( BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic ) ; String str = "" ; foreach ( MethodInfo m in mi ) { if ( t == m.DeclaringType ) { str = m.Name ; str += " ( " ; ParameterInfo [ ] pif = m.GetParameters( ) ; foreach ( ParameterInfo p in pif ) {

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


str += p.ParameterType ; str += " " ; str += p.Name ; str += ", " ; } int c = str.LastIndexOf ( ',' ) ; if ( c != -1 ) str = str.Remove ( c, 1 ) ; str += " )" ; listmethods.Items.Add ( str ) ; } } } To display members we must first obtain the item selected from the list box. We have done so by using the SelectedIndex property of the ListBox class. We have retrieved the selected type from the tarray array. The Type class contains various methods to access members of a type. We have used the same to read constructors, methods, properties and events of the selected type. These methods return a reference to an array containing respective members. We have listed the members in the respective list boxes. To the GetMethods( ) method we have passed certain flags. These flags indicate that we intend to read the instance methods, methods that are not inherited from base type and methods that are public as well as non-public. We can mention this flag in all the other methods also. Since method name and its parameters need to be read separately, we have used string concatenation to form a string that looks like a prototype declaration of method. Again, we have listed only those methods that directly belong to this type. We have used the DeclaringType property of the MethodInfo class. We would now see a small example that loads a user-created assembly, obtains a class type, creates its instance and invokes a method defined in the assembly. Here is the code Assembly a = Assembly.LoadFrom ( "c:\\mymath.dll" ) ; Type t = a.GetType ( "mymath" ) ; MethodInfo m = t.GetMethod ( "add" ) ; Object obj = Activator.CreateInstance ( t ) ; Object[ ] arg = new Object [ 2 ] ; arg [ 0 ] = 10 ; arg [ 1 ] = 20 ; m.Invoke ( obj, arg ) ; mymath is the name of class written in 'mymath.dll'. To the GetMethod( ) method we have passed the name of the method we want to invoke. Next, by calling the CreateInstance( ) method we have created an object of type stored in t and collected its reference in obj. The add( ) method takes two integers. So, we have created an array of objects arg. Lastly, we have called the add( ) method by using the Invoke( ) method. The add( ) method adds the two integers passed to it and displays the result.

Article: C# - Working With Attributes - I


Attributes are used to specify more information about an entity. This information gets written in metadata at compile time. An entity to which an attribute can be applied is called 'attribute target'. The target can be an assembly, interface, structure, class and all possible class members. An attribute is applied to the target by specifying the attribute name in brackets as shown below.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


[Serializable] This attribute is applied to a class stating that objects of this class can be serialized. When compiler encounters this attribute, it adds suitable instructions in the metadata. There are thousands of pre-defined attributes in FCL. In addition to them .NET allows us to define our own attributes, called 'custom attributes'. In this article we would examine the process of defining and using the custom attributes and reading them using reflection. We would create a custom attribute that can be applied to create a documentation of a class and its members. Documentation of a class includes for what the class was designed and how many methods it has. Documentation of methods includes what does they do and so on. We could write comments to know this information. However, comments remain in the source code and we may not have access to it. If we add documentation through attributes it remains in the assembly and can be accessed using reflection. Declaring an Attribute As everything in C# is declared in a class, an attribute is also embodied in a class. To create a custom attribute we have to derive a class from the System.Attribute class. We have named our derived class as DocumentAttribute. The class DocumentAttribute has three data members as shown below. class DocumentAttribute : System.Attribute { string info ; int cnt ; } The string variable info keeps description of the entity and the integer variable cnt keeps count of the methods. We can declare attributes either with parameters or without parameters. The parameters can be positional parameters or named parameters. The positional parameters are initialized in constructor, whereas, named parameters are initialized by defining a property. Another difference between the two is that positional parameters must be passed in the same sequence as given in the constructor. The named parameters are optional and can be passed in any sequence. We have declared the Document attribute to take two parameters. We want that one of them viz. info should be positional parameter and cnt should be named parameter. This is because cnt would be used only if attribute is applied to class. For class members we can drop it. So, we must define a constructor and a property as shown below. public DocumentAttribute ( string i ) { info = i ; } public int Count { get { return cnt ; } set { cnt = value ; } }

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


As we know, custom attributes are written in metadata and can be read through reflection. Generally speaking reading an attribute means reading values of data members of the attribute class. If we try to read the Document attribute it won't be able to access the info data member as it is declared private. So, in order to expose it through metadata, we would write a read-only property. Here it is. public string Info { get { return info ; } } We must also mention the attribute targets. This can be done by using nothing else than an attribute called AttributeUsage. The AttributeUsage attribute targets classes. So, it has to be declared just above the DocumentAttribute class as shown below. [ AttributeUsage ( AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Field, AllowMultiple = false ) ] class DocumentAttribute : System.Attribute { } The AttributeUsage attribute takes two parameters. Using the first parameter we can specify attribute targets. By setting the second parameter to true we can specify that one member can have multiple Document attributes. When attribute targets are assembly or module, the attributes should be placed immediately after all using statements and before any code.

Article: C# - Working With Attributes - II


Continued from last week... In the last article we saw how to create an attribute, let us now see how to use it. Using an Attribute We would use the Document attribute to create documentation of the class test1. Here is the declaration of test1 class. [ Document ( "Class test1: created for testing custom attributes", Count = 2 ) ] class test1 { [ Document ( "i: Counter variable" ) ] int i = 0 ; [ Document ( "Ctor test1: zero-argument ctor" ) ] public test1( ) { } [ Document ( "increment( ): Increments counter" ) ]

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


public void increment( ) { i++ ; } [ Document ( "decrement( ): Decrements counter" ) ] public void decrement( ) { i-- ; } } We have applied the Document attribute to the class through the statement [ Document ( "Class test1: created for testing custom attributes", Count = 2 ) ] Note that although name of our class is DocumentAttribute we have omitted the word Attribute from here. This is because, if we don't write Attribute, compiler adds it for us. When compiler encounters this statement, it searches for a class derived from the System.Attribute class in all the namespaces mentioned in using statements. The positional parameters are passed as the normal parameters. But named parameters are passed by mentioning the name of the parameter like Count = 2 No need to say that this would invoke the set block of Count property. On similar grounds, we have applied our attribute to other class members. Reading Attributes Following code snippet shows how to read the Document attribute applied to a class. Type t = typeof ( test1 ) ; object[ ] a = t.GetCustomAttributes ( typeof ( DocumentAttribute ), false ) ; foreach ( object att in a ) { DocumentAttribute d = ( DocumentAttribute ) att ; Console.WriteLine ( "{0} {1}", d.Info, d.Count ) ; } To begin with we have created a reference t to the Type object. We have used the typeof operator on test1 class, which returns reference to an object of Type. The GetCustomAttributes( ) method takes the type of the attribute we want to search and returns an array of references to objects, each of type DocumentAttribute. Next, we have run a foreach loop to read and display each attribute in the array. In our case only one attribute would get displayed. To read the attributes for methods, we would first obtain all the methods and then read attributes of each of them. This is done through the following statements. MethodInfo[ ] mi = t.GetMethods( ) ; foreach ( MethodInfo m in mi ) {

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


object[ ] o = m.GetCustomAttributes ( false ) ; foreach ( object ma in o ) { DocumentAttribute d = ( DocumentAttribute ) ma ; Console.WriteLine ( "{0}", d.Info ) ; } } We have used the reference t to obtain the methods and collected them in an array of type MethodInfo. We have called the GetCustomAttributes( ) method of the MethodInfo class to read the attributes of each method. Similarly we can use the GetCustomAttributes( ) method of the ConstructorInfo and FieldInfo classes to read the attributes given to constructors and fields.

Article: C# - Accessing Registry


Registry has a lion's share in running the system smoothly. It stores all the configuration information relating to Windows setup, user preferences, softwares installed and devices. The registry is arranged in a hierarchical tree like structure. Each node in this tree is called a key. Each key can contain additional keys or sub-keys (which allow further branching) as well as values that are used to store the actual data. Each registry key may have several values. For example a registry key 'Desktop' may have values like 'Wallpaper', 'TileWallpaper', etc. Each value in a key contains the actual data. This data may take several forms ranging from a simple integer value to a user-defined binary object. Each type is represented by a special registry specific type. For example an integer is represented by REG_DWORD and a string is represented by REG_SZ. Many applications store their status viz. last file opened in the application, options selected by the user, etc. in registry. We would also create such an application that would store the background image, foreground color, size of the window and its position in the registry so that next time when the application is run these selections could be restored. For accessing the registry we will use the Registry and RegistryKey classes available in the Microsoft.Win32 namespace. Naturally, we will have to add a using statement for this namespace. Create a Windows Application and design a form as shown in the following screen shot.

Also add the OpenFileDialog and ColorDialog controls to the form. Name them as file and color respectively. The 'Choose Bitmap' button allows user to select an image file through the 'Open' file dialog. The 'Choose Color' button lets the user to select a foreground color through the standard 'Color' dialog.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


To store the information of our application we would create a tree structure of two sub-keysTheme and Settings under the 'HKEY_LOCAL_MACHINE/SOFTWARE' key. The Settings subkey would contain all the values and data. Each key we want to access is represented by an object of the RegistryKey object. So, create the objects that would represent the SOFTWARE key and two user-defined keys as shown below. RegistryKey skey, tkey, rootkey ; To write anything in registry keys, we must open them. If keys are not created, we must first create them. We would do this in constructor after a call to the InitializeComponent( ) method. Add the following statements to the constructor. rootkey = Registry.LocalMachine.OpenSubKey ( "SOFTWARE", true ) ; tkey = rootkey.CreateSubKey ( "Theme" ) ; skey = tkey.CreateSubKey ( "Settings" ) ; In a file system, root drives like C:\ or D:\ are the root directories. In registry, there are root keys called 'registry hives' or 'base keys'. There are seven such registry hives. The Registry class provides seven fields of type RegistryKey representing the seven registry hives. The LocalMachine field represents the HKEY_LOCAL_MACHINE base key. The OpenSubKey( ) method opens the key. Since we have called the method using LocalMachine field, it would open the SOFTWARE key of Local Machine hive. By passing true as the second parameter we have specified that the key is to be opened for writing. Next, we have created the 'Theme' sub-key in the SOFTWARE key and 'Settings' in the 'Theme' sub-key. We have called the CreateSubKey( ) method for this. Now let us add handlers for the buttons. The b_bitmap_Click( ) handler gets called when 'Choose Bitmap' button is clicked. private void b_bitmap_Click ( object sender, System.EventArgs e ) { file.Filter = "Image Files (*.bmp,*.gif,*.jpg)|*.bmp;*.gif;*.jpg||" ; if ( file.ShowDialog( ) == DialogResult.OK ) { BackgroundImage = Image.FromFile ( file.FileName ) ; skey.SetValue ( "Image", ( string ) file.FileName ) ; } } Here, we have displayed the 'open' dialog. We have applied filter so that only image files would get displayed. If the user selects file we have changed the background image of the form and also written the file path as data of the 'Image' value in the 'Settings' sub-key. We have called the SetValue( ) method for writing the data. The SetValue( ) method takes the value name and data as parameters. The data needs to be type-casted in suitable type as the method takes parameter of type object. The b_color_Click( ) method gets called when clicked on the 'Choose Color' button. The handler is given below. private void b_color_Click (object sender, System.EventArgs e ) { if ( color.ShowDialog( ) == DialogResult.OK ) {

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


ForeColor = color.Color ; skey.SetValue ( "Red", ( int ) color.Color.R ) ; skey.SetValue ( "Green", ( int ) color.Color.G ) ; skey.SetValue ( "Blue", ( int ) color.Color.B ) ; } } Finally add the code to write size and position to the registry. This code should get executed when the window is closed. So, we would add this code in the Dispose( ) method. The Dispose( ) method is given below. protected override void Dispose ( bool disposing ) { skey.SetValue ( "Height", ( int ) Height ) ; skey.SetValue ( "Width", ( int ) Width ) ; skey.SetValue ( "X", ( int ) DesktopLocation.X ) ; skey.SetValue ( "Y", ( int ) DesktopLocation.Y ) ; skey.Close( ) ; tkey.Close( ) ; rootkey.Close( ) ; // AppWizard generated code } After writing the values we have closed the keys by calling the Close( ) method. Our writing part is now over. We want that when application is executed the next time, the form should get displayed the same way as it was before closing. To read the information from registry, we have written a user-defined method readsettings( ). public void readsettings( ) { rootkey = Registry.LocalMachine.OpenSubKey ( "SOFTWARE", false ) ; tkey = rootkey.OpenSubKey ( "Theme" ) ; if ( tkey == null ) return ; skey = tkey.OpenSubKey ( "Settings" ) ; string f = ( string ) skey.GetValue ( "Image" ) ; if ( f != null ) BackgroundImage = Image.FromFile ( f ) ; try { int r = ( int ) skey.GetValue ( "Red" ) ; int g = ( int ) skey.GetValue ( "Green" ) ; int b = ( int ) skey.GetValue ( "Blue" ) ; ForeColor = Color.FromArgb ( r, g, b ) ; Height = ( int ) skey.GetValue ( "Height" ) ; Width = ( int ) skey.GetValue ( "Width" ) ; int x = ( int ) skey.GetValue ( "X" ) ; int y = ( int ) skey.GetValue ( "Y" ) ; DesktopLocation = new Point ( x, y ) ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


} catch ( Exception e ) { return ; } } Here, firstly we have opened the keys. When the application is run for the first time, keys are not created. So, we have checked for the null reference in the RegistryKey object. The statements written thereafter read the data from registry and use it. Call this method from the InitializeComponent( ) method after the initialization code.

Article: C# - Creating Multithreaded Applications - I


In a broad sense Multithreading can be thought of as the ability to perform several jobs simultaneously. For example, while working in Windows we can simultaneously carry out different jobs like printing a document on the printer, receiving e-mails, downloading files and compiling programs. All these operations are carried out through different programs, which execute concurrently in memory. Even though it may appear that several tasks are being performed by the processor simultaneously, in actuality it is not so. This is because in a single-processor environment, the processor divides the execution time equally among all the running threads. Thus each thread gets the processor's attention in a round robin manner. Once the time-slice allocated for a thread expires, its state and values are recorded, the operation that it is currently performing is put on hold and the processor directs its attention to the next thread. Thus at any given moment if we take the snapshot of memory we will find that only one thread is being executed by the processor. Thread switching happens so fast that we get a false impression that the processor is executing several threads simultaneously. Multithreading has several advantages to offer. These are listed below: Responsiveness: Take an example of MS-Word. Here had the spell checker and the grammar checker not run as different threads, we would have been required to write documents and submit it to the checkers from time to time. This would have resulted in low responsiveness. Since the checkers run in different threads, our document gets checked as we type, thereby increasing the responsiveness of the application. Organization: Threading simplifies program organization. In the 'File Copy' example if both the operations-playing the animation and the actual copying-are run in the same thread, then after copying a few thousand bytes we would be required to play the next frame of animation. If we run the copying code and animation code in separate threads we can avoid cluttering the copying code with animation code and vice versa. Performance: Many a times it happens that a program needs to wait for user input or has to give some output. The I/O devices are generally slower than the processor. So the application waits for the I/O operation to finish first. If instead we use another thread for the I/O operation, the processor time can be allotted to other important tasks independent of the I/O operation, thereby increasing the performance. Launching threads Now that we know what threads are, let us now see how they can be created. Starting a thread is very simple. The following statements launch a new thread.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


TheradStart ts = new ThreadStart ( func ) ; Thread t1 = new Thread( ) ; t1.Start( ) ; While creating a thread, we must specify which method should get executed when the thread starts execution. If we wish that a static method func( ) should get executed in the thread, we would have to wrap its address in a delegate and pass it to the constructor of the Thread class. For this, we have to use a predefined .NET delegate class called ThreadStart. The signature of this delegate is such that it returns a void and does not accept any arguments. Hence func( ) also needs to have the same signature. To start the thread we must call the Start( ) method of the Thread class. Both the Thread class and the ThreadStart delegate belong to the System.Threading namespace hence we need to write using System.Threading at the beginning of any program. Let us now see an example where multithreading is actually needed. Here we plan to make a simple game. The UI of the game is given in the following screen shot:

This application consists of two buttons named Start and Hit, and three textboxes named num1, num2 and num3. The user needs to click on the Start button to start the game. As soon as this button is clicked, random numbers would get displayed on the three textboxes. Now at any instance if the user clicks on the Hit button, the display of numbers stops. If the numbers turn out to be the same the user hits the jackpot. It is impossible to generate and display the random numbers in the three textboxes simultaneously in the main thread. If we attempt to do so, numbers in the second textbox would get generated only after generating and displaying numbers in the first textbox. So here if we want concurrent functionality, we need to generate and display the numbers for the textboxes in three different threads. On clicking the Start button, the three threads get launched as shown in the following code snippet: private void start_Click ( object sender, System.EventArgs e ) { t1 = new Thread ( new ThreadStart ( this.display1 ) ) ; t1.Start( ) ; t2 = new Thread ( new ThreadStart ( this.display2 ) ) ; t2.Start( ) ; t3 = new Thread ( new ThreadStart ( this.display3 ) ) ; t3.Start( ) ; } We have added the references t1, t2 and t3 of the Thread class as data members of the Form1 class. The display1( ) method is given below.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


public void display1( ) { int j = r.Next ( 0, 50 ) ; int k = r.Next ( 50, 100 ) ; for ( int i = j ; i <= k ; i++ ) { num1.Text = i.ToString( ) ; Thread.Sleep ( 200 ) ; } } Here we have used an object of the Random class referred to by r that we also added as a data member of the Form1 class. Using this object we have created two random numbers and displayed all numbers lying between the two in the textbox. The display2( ) and display3( ) methods are on the same lines. Hence random numbers keep on getting displayed simultaneously on the three textboxes. Now the user needs to click the Hit button. The handler for the Hit button is given below: private void hit_Click ( object sender, System.EventArgs e ) { t1.Abort( ) ; t2.Abort( ) ; t3.Abort( ) ; if ( int.Parse ( num1.Text ) == int.Parse ( num2.Text ) && int.Parse ( num2.Text ) == int.Parse ( num3.Text ) ) MessageBox.Show ( "Jackpot" ) ; } Here we have aborted the threads using the Abort( ) method, compared the numbers and displayed a message if they are same.

Article: C# - Creating Multithreaded Applications - II


...Continued from last week Thread States From the time a thread is started until it gets terminated the thread undergoes many transitions and is said to be in at least one of the several 'thread states'. A thread can be in one or more of the following states at any given time: Unstarted, Running, Suspended, WaitSleepJoin, SuspendRequested, Aborted, AbortRequested, Stopped and StopRequested. All these states are members of the ThreadState enumeration declared in System.Threading namespace. Let us now discuss these states. Unstarted: A thread is said to be in the Unstarted state when it is first created. It remains in this state until the program calls the Start( ) method of the Thread class. Running: As soon as the Start( ) method is called, the thread starts executing and is said to be in the Running state. This means that the thread will now start getting CPU time slots Suspended: When a running thread's Suspend( ) method is called, the thread goes into the

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Suspended state and would stop receiving CPU time-slots. WaitSleepJoin: At times we may want to prevent our thread from getting CPU cycles till passage of some time or make our thread wait till some other thread completes some operation or wait till some other thread terminates. We can achieve these three scenarios by calling the methods Thread.Sleep( ), Monitor.Wait( ) and Thread.Join( ) methods respectively on our thread. Upon calling one of these three methods, our thread enters the WaitSleepJoin state. Once in this state we can transition out of it in the following three ways: (a) The sleeping time specified by the Sleep( ) method expires. (b) Another thread calls the Thread.Interrupt( ) method before the sleeping time expires. (c) Another thread calls the Monitor.Pulse( ) method or Monitor.PulseAll( ) method. Monitor.Pulse( ) moves the waiting thread into the Running state. Monitor.PulseAll( ) method moves the thread along with all the other waiting threads into the Running state. All the above three ways move the thread from the WaitSleepJoin state to the Running state. Stopped: When a thread completes its execution, it goes into the Stopped state. Aborted: Whenever an exception is thrown and the thread stops executing abruptly it goes into the Aborted state. AbortRequested: The AbortRequested state is reached when a thread is in another state but is being requested to abort. As soon as it comes out of the present state, it gets aborted. SuspendRequested: The SuspendRequested state is reached when a thread is in another state but is being requested to suspend using the Suspend( ) method. As soon as it comes out of the present state, it gets suspended. StopRequested: The StopRequested state is reached when a thread is being requested to stop. There is no method available that we can invoke to manually force our thread in this state. The following figure depicts the life cycle of a thread.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Article: C# - Synchronizing Threads


Synchronization plays an important role in multithreaded applications where the threads are not independent of each other and share common resources. This is because if two threads share common resources and try to manipulate the resources simultaneously, the resources become inconsistent. To tackle such situations synchronization provides a lock on the resource that is shared among threads and makes a thread wait until the other thread finishes the job with the resource. Thus synchronization 'locks' the shared resource and prevents another thread from using it. C# provides a lock keyword to lock the shared object or resource. Whatever is written inside the parenthesis following the lock keyword gets locked for the current thread and no other thread is permitted to obtain the lock on that resource or object. We can write an expression that evaluates to an object, or just the object on which we wish to have a lock, inside the parenthesis. Whatever the expression may be, the result should be a reference type. The code that uses the object to be synchronized should be written inside the block of the lock statement. To give you a more concrete example, consider two threads working on a file. If both the threads try to open the file and write to it simultaneously, an exception is thrown. Here what we need to do is synchronize both the threads in such a way that only one thread opens the file and writes in it at any given moment. We have illustrated the same scenario in the example that follows. The user interface of the application is shown in the following screen shot.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Here we have added a textbox named quantity, a button called purchase and a label called msg. In this application we have simply asked the user number of goods he wants to purchase, i.e. the demand. We have maintained number of goods in stock in a file called log.bin. Whenever the user purchases certain amount of goods, the number in the file is updated. In this application we have also launched another thread which keeps on checking continuously whether the goods are out of stock or not. If the thread finds that the number of goods in the store is zero, it fills the store with hundred goods and hence updates the number in log.bin file. We need to synchronize the two threads so that only one thread works on log.bin at one time. We added the following as data members of the Form1 class. FileInfo f ; FileStream fs ; byte total = 100 ; total denotes the total number of goods in store. We have used a value like 100 that can be represented in one byte. This is because FileStream is used to write an array of bytes in the file and if we take a larger number, we would have to first create an array of bytes representing the large number. For the sake of simplicity here we have used a number that can be represented in one byte. We initialized the reference f, and launched the thread that would keep on checking the stock from time to time after the call to the InitializeComponent( ) method in the constructor as shown below: f = new FileInfo ( "C:\\log.bin" ) ; Thread t = new Thread ( new ThreadStart ( checker ) ) ; t.IsBackground = true ; t.Start( ) ; We have made this thread a background thread because we wish that as soon as the application terminates, the thread should also get terminated. The checker( ) method is given below: public void checker( ) { while ( true ) { lock ( f ) {

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


try { fs = f.OpenWrite( ) ; if ( total <= 0 ) { total = ( byte ) ( total + 100 ) ; fs.WriteByte ( total ) ; msg.Text = "Stock sold out!!!! Goods incremented" ; } else msg.Text = "Items in stock: " + total ; Thread.Sleep ( 1000 ) ; fs.Close( ) ; } catch { MessageBox.Show ( "Can not Open file" ) ; } } } } We have put the checker logic in a while loop so that the store is checked continuously after every 1000 milliseconds (Thread.Sleep(1000) ensures this). Next we have obtained a lock on the file object referred to by f using the lock statement. After acquiring the lock we have checked whether total is zero or less than zero. If yes, we have incremented total by 100 and wrote the value back in the file. If it is not zero or less than zero, we have simply displayed the number of goods in the label named msg. We have put the whole logic in a try-catch block, the reason for which would be clarified later. Now if the user supplies some number in the textbox and clicks on the purchase button, the following handler gets called: private void purchase_Click ( object sender, System.EventArgs e ) { lock ( f ) { try { fs = f.OpenWrite( ) ; byte b = byte.Parse ( quantity.Text ) ; total = ( byte ) ( total - b ) ; fs.WriteByte ( total ) ; MessageBox.Show ( "Transaction Complete" + "\n" + "Item remaining: " + total ) ; fs.Close( ) ; } catch { MessageBox.Show ( "Cannot Open file" ) ; } } }

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Here also we have first acquired a lock on the file object. Next we have collected the quantity demanded by the user in a byte called b. Then we have subtracted that amount from total and wrote back the new value of total in the file. We have put this logic also in a try-catch block. This method gets executed in the main thread, whereas checker( ) gets executed in a thread referred to by t. Now if you execute the program, you would see that the number of goods in the store is displayed continuously on the msg label. As soon as the user purchases some goods, the number is updated and when the number goes below zero, the goods are incremented. This works fine, but if you really want to understand the need of synchronization, remove or comment the lock statement and see the effect. As soon as the user clicks on purchase an exception gets thrown indicating that the file is already in use. To catch this exception we have used the try-catch blocks. The exception gets thrown because both the threads try to open and write to the file simultaneously. Besides the lock statement synchronization can also be achieved in C# using the Interlocked class, the Monitor class, Mutexes and Events. The Interlocked class: provides four methods to perform operations like incrementing, decrementing or exchanging variables in a thread-safe manner. The four static methods areIncrement( ), Decrement( ), Exchange( ), and CompareExchange( ). Monitors: in .NET are similar to the lock statement and are used to synchronize concurrent thread accesses so that any resource can be manipulated only by one thread at a time. Thus they support mutually exclusive access to a shared resource. Monitors are similar to Critical Sections in Windows. The Framework Class library provides a Monitor class to represent the Monitor. The above program will also work if we use Monitor.Enter( f ) and Monitor.Exit( f ) methods, belonging to the Monitor class, instead of the lock statement. All we need to do is to write the code present in the lock block between the calls to Monitor.Enter( f ) and Monitor.Exit( f ) methods. In fact when we use the lock statement it gets resolved into calls to Monitor.Enter( ) and Monitor.Exit( ) methods in the IL code. Mutexes: The word mutex comes from two words-"mutually' and "exclusive". Mutexes are similar to monitors except that they permit the object or resource to be shared across processes. Mutexes can thus synchronize threads belonging to different applications. The System.Threading.Mutex class represents a mutex object. Events: are used to synchronize threads in some order. For example if two threads are executing and we want that not only should the threads work synchronously, but they should also get executed alternately, we should use events. If we use events we will get the following order of execution: Thread1 executing Thread2 executing Thread1 executing Thread2 executing And so on But instead if we use only monitors, we will achieve synchronization but threads are likely to get executed in the following manner: Thread1 executing Thread1 executing Thread2 executing Thread1 executing

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


The .NET Framework class library wraps two of the Windows' kernel objects-auto-reset events and manual-reset events-into two classes called AutoResetEvent and ManualResetEvent.

Article: C# - File Transfer Using Network I/O - I


Though on the face of it the Internet and Web appear fairly simple, if you scratch the surface you would appreciate that it is built upon complex protocols, networking technologies and programs. .NET attempts to reduce this complexity for the programmer and therefore is able to impact the web and network programming in a major way. Network Programming Network programming under .NET is quite similar to reading and writing files on local disk. Network applications are written using the Client-Server model. In this model the communication is carried out using entities called "sockets". Sockets are nothing but software abstractions that are used to represent the end points of a connection between two machines. For any given connection there is one socket on the client and one socket on the server. A program can read from a socket or write to a socket in a manner that is similar to File-IO. The socket-based communication can be of two types, namely, Connection-Oriented and Connectionless. Of these the Connection-Oriented service uses the popular Transmission Control Protocol (TCP), whereas the Connectionless service uses the User Datagram Protocol (UDP). In this article we will concentrate on TCP protocol. To be able to communicate between any two machines in a network, there must be a unique way to identify them. This is achieved using the IP (Internet Protocol) Address of the machine. If we mention a machine name it ultimately gets converted into an IP Address. However, it is possible for more than one application to be using network connection at the same time. Therefore each application must have a unique ID so that the client can indicate which application it is looking for. This unique ID is called port number. Thus the IPAddress and port number represent respectively the first and second level of addressing. .NET provides several classes and interfaces organized under the namespace System.Net.Sockets to help us write Connectionless and Connection-Oriented networking applications. Typically in a Connection-Oriented service, a server waits for a connection request from the client. This waiting is generally done in a loop. Once the server gets a request a connection is setup between the server and the client. The end points of this connection are sockets. The functionality of these sockets has been wrapped inside the TcpListener and TcpClient classes present in the System.Net.Sockets namespace. Hence to carry out Connection-Oriented communication between two applications running on same/different machines we need to create objects of these classes. The TcpListener object is used to listen to the requests from the client. The TcpClient object is used to establish a connection between the client and the server. Let us now see how to use the classes in this namespace to build an application. We have designed this application to transfer a file requested by the client from server to client. The same application acts as a client as well as a server. The interface of this application is shown below.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

The following table shows the controls and their Names. Control Server Text Box Port Text Box Listen As Server Button Connect As Client Button File Name Text Box Open Button Text Box Name Tserver tport bserver bclient fname bopen text

Both the users have to start the same application. Out of the two, one should listen as server and another should connect as client. It is necessary to listen as server before connecting as a client, otherwise the client would get an exception. To be able to listen as server, the user has to enter the port number (any integer value) and click the 'Listen As Server' button. The client must enter both the server name (name of machine on which server application is running) and the same port number and then click the 'Connect As Client' button. The client now can enter the file name with entire path in the 'Enter File Name' text box and click the 'Open' button. As soon as the client clicks the 'Open' button a request to send the specified file is sent to the server and the file contents are received back from the server. Let us now add the handlers and write code in them. First of all we would add the Click event handler for the 'Listen As Server' button. The code of the handler is given below. private void bserver_Click ( object sender, System.EventArgs e ) {

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


int portno = Convert.ToInt16 ( port.Text ) ; TcpListener l = new TcpListener ( portno ) ; l.Start( ) ; tc = l.AcceptTcpClient( ) ; st = tc.GetStream( ) ; bserver.Enabled = false ; recvthread r = new recvthread ( st ) ; Thread t = new Thread ( new ThreadStart ( r.sendfile ) ) ; t.IsBackground = true ; t.Start( ) ; } Here, we have first obtained the port number. We have then created an object of the TcpListener class and stored the port number in it. We have then called the Start( ) method of the TcpListener class. This method would wait in a loop (listening) for a connection request from the client. The method would listen on the port number assigned to the TcpListener object. Here we're effectively blocking on the Start( ) method until a request comes in from the client. We have then called the AcceptTcpClient( ) method to accept the connection request and obtain an object of the TcpClient class. Hence we need to create a reference tc of the type TcpClient as the data member of the Form1 class. We have then called the GetStream( ) method using the tc reference to obtain a reference to the object of the NetworkStream class. This object would be used to write into the socket. To collect the reference we need to create a reference st of the type NetworkStream as the data member of the Form1 class. We have disabled the 'Listen As Server' button so that user should not click it again. The server and client can exchange messages as soon as the connection is established. The messages sent by both the server and client would get written to the stream. We do not receive any notification when the data is written to the stream. Hence we need to continuously check whether the data has been written to the stream or not so that we can read it. If we don't start another thread and wait for the messages in the current thread that has displayed the form, we would not be able to interact with the form. Hence it is necessary to start a thread in which we can read the data from stream. We also need to make the thread a background thread because as soon as the application closes, we also want the thread to stop. The thread would need the NetworkStream reference to read the messages from the stream. We cannot pass these parameters directly to the sendfile( ) method that is used for reading and sending file contents in the thread as the ThreadStart delegate doesn't permit it. Hence we have wrapped the sendfile( ) method in the recvthread class and used its constructor to initialize the parameter needed by the sendfile( ) method. To the one-argument constructor of the recvthread class, we have passed the reference to the NetworkStream object (obtained using the GetStream( ) function). Next, we have started the thread to read the data received from the socket.

Article: C# - File Transfer Using Network I/O - II


... Continued from last week Let us now write the code that should get executed when client clicks the 'Connect As Client' button. The bclient_Click( ) handler is given below. private void bclient_Click ( object sender, System.EventArgs e ) { String servername = tserver.Text ; int portno = Convert.ToInt16 ( port.Text ) ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


tc = new TcpClient( ) ; try { tc.Connect ( servername, portno ) ; } catch ( Exception ex ) { MessageBox.Show ( "Cannot connect to server" ) ; return ; } bclient.Enabled = false ; } Here, we have firstly obtained the server name and port number. In the next statement we have created an object of the TcpClient class. Using this object we have called the Connect( ) method and passed to it the server name and port number. The Connect( ) method would send the connection request to the server specified by the server name at the port specified by the port number. The Connect( ) method would wait until the server accepts the connection. Lastly, we have disabled the 'Connect As Client' button. The client can now enter and send the file name to the server. The handler for the 'Open' button is given below. private void bopen_Click ( object sender, System.EventArgs e ) { string s = fname.Text ; s += "*" ; byte[ ] buf = new byte [ s.Length ] ; buf = Encoding.ASCII.GetBytes ( s ) ; st = tc.GetStream( ) ; st.Write ( buf, 0, s.Length ) ; recvthread r = new recvthread ( st, text ) ; Thread t = new Thread ( new ThreadStart ( r.getfile ) ) ; t.IsBackground = true ; t.Start( ) ; } In this handler we have obtained the file name and attached a character to the string object to mark the end of the file name. Why we need this would be clear in a short while. To write the file name on stream we have first created an array of bytes and copied the contents of string object into the array. We have then obtained the stream object by calling the GetStream( ) method and written the filename to the stream by calling the Write( ) method of the NetworkStream class. The Write( ) method writes to the stream and advances the current position within this stream by the number of bytes written. Next, we have started a thread as we did for server. This time we have passed the reference to the NetworkStream object as well as reference to the TextBox object. Note that this time we have passed two arguments to the constructor of the recvthread class. The getfile( ) method would receive the file contents sent by the server and display them in the text box. Let us now see how the recvthread class is declared. class recvthread { NetworkStream ns ; TextBox tb ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


public recvthread ( NetworkStream s, TextBox t ) { ns = s ; tb = t ; } public recvthread ( NetworkStream s ) { ns = s ; } public void sendfile( ) { byte[ ] buffer = new byte[ 255 ] ; ns.Read ( buffer, 0, buffer.Length ) ; string str = Encoding.ASCII.GetString ( buffer ) ; int i = str.IndexOf ( '*' ) ; str = str.Substring ( 0, i ) ; string filestr = "" ; try { FileInfo f = new FileInfo ( str ) ; StreamReader sr = f.OpenText( ) ; string temp ; do { temp = sr.ReadLine( ) ; filestr += temp ; filestr += "\r\n" ; } while ( temp != null ) ; byte[ ] buf = new byte [ filestr.Length ] ; buf = Encoding.ASCII.GetBytes ( filestr ) ; ns.Write ( buf, 0, filestr.Length ) ; } catch( Exception e ) { MessageBox.Show ( e.ToString( ) ) ; } } public void getfile( ) { byte[ ] buffer = new byte[ 512 ] ; ns.Read ( buffer, 0, buffer.Length ) ; string str = Encoding.ASCII.GetString ( buffer ) ; tb.Text = str ; } } The class contains two data members that are initialized in the constructor. The class has two constructor of which one-argument constructor is called from the bserver_Click( ) handler, whereas, the two-argument constructor is called from the bclient_Click( ) handler. In the sendfile( ) method, which would get called when the server thread starts, we have called the Read( ) method of the NetworkStream class. The Read( ) method reads a sequence of bytes

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


from the stream referred to by s and advances the current position within the stream by the number of bytes read. In our case, the Read( ) method would read the file name written to the stream by the client. The bytes read would get stored in the buffer array. We have encoded the bytes read in the buffer array into a string using the Encoding.ASCII.GetString( ) method. This method would copy all the 255 characters to the string object. We must take only that part of the string where file name is stored. For this we would use the end mark '*' that we have concatenated to the file name in the bopen_Click( ) method. In the next few statements, we have opened the file and read its contents. Now the only job remaining is to write the contents back to the client. We have done so by calling the Write( ) method. The client also stands ready to read the file contents in the getfile( ) method. In the getfile( ) method we have merely called the Read( ) method, converted the byte stream into a string and displayed it in the text box. Lastly, add the following using statements at the beginning of the program. using System.Net.Sockets ; using System.Text ; using System.IO ; using System.Threading ;

Article: C# - Implementing UDP


Unlike the TCP protocol, the UDP protocol is connectionless. Here there is no setting up of connection needed, instead the data is sent in packets. The .NET framework provides the UdpClient class for connectionless transmission. Like TcpListener and TcpClient, UdpClient also wraps the Socket class. The UdpClient's Send( ) and Receive( ) methods invoke the SendTo( ) and ReceiveFrom( ) methods of the Socket( ) class respectively. To demonstrate the usage of the connectionless service we have created two applicationsQuizmaster and Player. The idea is basically to conduct an online quiz, where the Quizmaster would ask questions to two players on two different machines. The player who responds with a correct answer first wins. Create a Windows application named Quizmaster and design the form as shown below.

The Quizmaster asks a question by typing it in the 'Post a Question' text box named que. He is also supposed to provide an answer to cross check the answers supplied by the players in the

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


'Correct Answer' text box named ans. Then he should specify the names of the computers on which the 'Player' application is executing. We have allowed two players to play at one time. These names should be supplied in the 'Computer 1' and 'Computer 2' text boxes named pcname1 and pcname2. On receiving the answers, they would get displayed in the messages list box. Let us first take a look at the Quizmaster application. After typing the question-answer along with the computer names, the Quizmaster clicks the 'Send' button. This invokes the following handler: private void sendbut_Click ( object sender, System.EventArgs e ) { string question ; byte[ ] senddata ; question = que.Text + "@" + Dns.GetHostName( ) ; answer = ans.Text ; senddata = Encoding.ASCII.GetBytes ( question) ; try { client.Send ( senddata, senddata.Length, pcname1.Text, 201 ) ; } catch { MessageBox.Show ( "Cannot send to " + pcname1.Text ) ; } try { client.Send ( senddata, senddata.Length, pcname2.Text, 201 ) ; } catch { MessageBox.Show ( "Cannot send to " + pcname2.Text ) ; } } In this handler we have first collected the question as well as the answer in the strings question and answer respectively. We have made answer a data member of the class because we will need it in another method to crosscheck the answers provided by the players. Next we have appended the question with the computer name separating them with an '@'. The GetHostName( ) method of the Dns class returns a string containing the host name of the machine. Then we have encoded the data in an array of bytes called senddata. The data is sent using the Send( ) method of the UdpClient class. For this we have added a data member called client of the type UdpClient to the Form1 class. The Send( ) method takes four parameters-an array of bytes to be sent, the length of the array of bytes, the computer name where we wish to send the data and the port number to which the data would be sent. We chose the port number to be 201 (you can choose any other). Now the Quizmaster application should be ready to accept answers from the players. The player who first sends the correct answer wins. This calls for waiting for a packet to arrive at the specified port. For this we have started a different thread from the constructor of the Form1 class. This thread would start waiting for a packet as soon as the application starts. The following code written inside the constructor launches a separate thread Thread svthread = new Thread ( new ThreadStart ( startserver ) ) ; svthread.IsBackground = true ; svthread.Start( ) ; The startserver( ) method is given below

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


public void startserver( ) { // 1-Create an IPEndPoint to receive messages IPEndPoint recvpt = new IPEndPoint ( IPAddress.Any, 0 ) ; byte[ ] data ; string str, from ; int index ; while ( true ) { // 2-Receive data data = server.Receive ( ref recvpt ) ; str = Encoding.ASCII.GetString ( data ) ; index = str.LastIndexOf ( "@" ) ; from = str.Substring ( index + 1 ) ; messages.Items.Add ( str ) ; str = str.Remove ( index, str.Length - index ) ; // 3-Check the answer string result ; if ( str.CompareTo ( answer ) == 0 ) { result = "Correct! your rank is " + rank + "@" + HostName( ) ; rank += 1 ; } else result = "Your answer is wrong!" + "@" + Dns.GetHostName( ) ; if ( rank == 3 ) rank = 1 ; // 4-Send the result byte[ ] senddata ; senddata = Encoding.ASCII.GetBytes ( result ) ; try { client.Send ( senddata, senddata.Length, from, 201 ) ; } catch { MessageBox.Show ( "Cannot send result" ) ; } } } Here, we have firstly created an object of the IPEndPoint class. We need it to receive messages from the client. To the constructor of the IPEndPoint class we have passed a default IPAddress using the Any Filed of the IPAddress class. The Any field specifies that the server should listen for client activity on all network interfaces. We have also passed a port number 0 to indicate that it should pick any available port. The player sends his answer to the Quizmaster in packets. To receive the packet we have called the Receive( ) method of the UdpClient class. We have added server as a data member of the Form1 class as shown below. UdpClient server = new UdpClient ( 200 ) ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


The Receive( ) method returns an array of bytes containing the answer which we have after converting into string displayed in the list box. The player would send his answer along with the computer name separated with '@'. To check whether the answer is correct or not we must first separate the answer and computer name. The correctness of answer is checked using the CompareTo( ) method of the String class. If the answer is correct we have constructed a string result containing a rank. We have added rank as an integer data member of the Form1 class and initialized it to 1. If the answer does not match then we have stored a string saying that the answer is wrong. If the answer is right the rank is also incremented by 1 so that whoever replies next will be ranked 2nd. If the rank exceeds 2 we have reset it to 1 because there are only two players. Next we have sent the result string using the Send( ) method of the UdpClient class. Separating the string, checking the answer and sending the result should be carried out every time a packet is received. So, we have done them in a while loop. Now let us take a look at the 'Player' application. The 'Player' is a very simple application. Its form contains a label named question. We have changed the font size of the text that would get displayed in the label to 11 and changed its style to bold. All the player needs to do is type in the answer and click the 'Send' button. We chose 201 as the port number where the player would receive packets and 200 as the port number for sending the packets. In the player application too we have started a new thread in the constructor of the Form1 class that waits for a packet to arrive, as shown below. Thread svthread = new Thread ( new ThreadStart ( startplayer ) ) ; svthread.IsBackground = true ; svthread.Start( ) ; The startplayer( ) method is given below public void startplayer( ) { IPEndPoint recvpt = new IPEndPoint ( IPAddress.Any, 201 ) ; byte[ ] data ; string str ; int index ; while ( true ) { data = server.Receive ( ref recvpt ) ; str = Encoding.ASCII.GetString ( data ) ; index = str.LastIndexOf ( "@" ) ; from = str.Substring ( index + 1 ) ; str = str.Remove ( index, str.Length - index ) ; question.Text = str ; } } Here also we have created an object of the IPEndPoint class and collected its reference in recvpt. After receiving the question we have separated the question and the computer name in str and from respectively. server (a reference of UdpClient instance) and from (a reference to a string) have been added to the Form1 class as data members. Then we have displayed the question on the label named question. As soon as the player receives a question he has to type in the correct answer and click the 'Send' button. This would invoke the following handler.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


private void sendbut_Click ( object sender, System.EventArgs e ) { byte[ ] senddata ; string answer ; answer = ans.Text + "@" + Dns.GetHostName( ) ; senddata = Encoding.ASCII.GetBytes ( answer ) ; try { client.Send ( senddata, senddata.Length, from, 200 ) ; } catch { MessageBox.Show ( "Error sending data" ) ; } } Here we have collected the answer provided by the player in a string called answer and appended it with an '@' followed by the host name of the player machine. After encoding it in a byte array we have again used the Send( ) method of the UdpClient class to send the data. client has been added as the data member of the Form1 class. Now since both the applications are ready, we can enjoy quizzing.

Article: C# - Introduction To Assemblies


Assembly is an important element of .NET programming. In .NET platform, an assembly is a unit of reuse, versioning, security and deployment. In order to package and deploy our types, they must be placed into modules that are part of an assembly. Every managed application in .NET is deployed as an assembly. It means that entire .NET code on compilation gets converted into an IL code and gets stored as an assembly. In addition to the IL code, an assembly also contains Assembly Metadata (Manifest), Type metadata and Resources. Assemblies are hence selfdescribing. Let us peep into the structure of an assembly. Structure Of Assembly If an assembly is to be made up of several programs, the programs can be stored in separate modules. Suppose there are two source files 'a.cs' and 'b.cs' of which, 'a.cs' is stored in a module, whereas, 'b.cs' is stored in the assembly itself. Both comprise an assembly named 'mydll.dll'. The structure of the assembly 'mydll.dll' would look as shown in the following figure.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

The PE file 'a.dll' is said to be stored in a module of the 'mydll.dll' assembly. Had 'mydll.dll' contained resources, they would also get added in the structure with the type metadata and manifest. The 'assembly description' shown in manifest contains the identity of the assembly, consisting of its name, version and culture. An assembly has a four part version number e.g. 1.0.1.1. The parts are <Major> . <Minor> . <Build> . <Revision>. Other contents are the names of all the files in the assembly, information regarding whether all the types defined in the assembly are visible to other assemblies or private to one, a hash of all files in the assembly and details of any security permissions that clients need to have in order to be able to run the assembly. Private and Shared Assemblies We can create two types of assemblies-private assemblies and shared assemblies. A private assembly is used by only one application while a shared assembly is shared amongst different applications. By default when we compile a C# program, the assembly produced will be a private assembly. This assembly (DLL/EXE) should be placed in the same folder as the calling application. With a private assembly it's not necessary to think about naming conflicts with other classes or versioning problems because each application has its own copy of the assembly. In shared assemblies we have to ensure that the assembly is unique, and therefore, have a unique name (called strong name). In this article we would see how to build and use a shared assembly. We plan to write a class library consisting of a function called display( ). We will call this function from a client program, which we will create later. Here is code of the display( ) method which is defined in the mytext class. public class mytext { public void display ( Form fr, string s, Color c, string fname, int size, Point pt ) { Graphics g = fr.CreateGraphics( ) ; Font myfont = new Font ( fname, size) ; SolidBrush mybrush = new SolidBrush ( c ) ; g.DrawString ( s, myfont, mybrush, pt ) ; } }

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


The display( ) method simply draws text with the specified Font and Brush. On building the project a 'fontassembly.dll' file would get created in the 'fontassembly\bin\Debug' subfolder. A shared assembly is always unique. To be uniquely identified, a shared assembly has a strong name. The combination of a file name, a public key, a version number and culture (locale details) gives an assembly a strong name, which is guaranteed to be unique. Now let's first see what are public and private keys and then see how to build them. Public, Private Keys And Encryption Encryption is the act of encoding files/programs so that others not privy to the decryption mechanism cannot understand the content's of the text. Thus encryption is the process of hiding our data from anyone and everyone we feel should not know it. Under .NET platform this has special significance since here we distribute our IL (Intermediate Language) code embedded in assemblies, instead of the executable machine code, which is not too much difficult to decipher. .NET has a strong inbuilt mechanism to maintain the privacy of code. If this had not been the case, any one with the ILDASM.EXE utility would have an access to your code. Not only that he or she would also have the opportunity to distribute it under his name. .NET achieves this security by public key encryption. Public Key and Private Keys are complimentary entities; one is meaningless without the other. The creation of Public and Private Keys is carried out by complicated mathematical algorithms. A document encrypted with one key can be decrypted only using the other key. Not even the key with which we encrypted the data can be used to decrypt it back. The public key can be distributed freely without any fear of it being misused. Building the Keys To build public and private keys we have to use the sn (standing for strong name) utility. This utility generates a public/private key pair. The public key created using this utility will be used to define a strong name. To create the key pair we must type the following at command prompt: C:\CSharp\fontassembly>sn -k mykey.snk On executing the utility a file called mykey.snk gets created. This file contains the public and private keys To create a strong name the compiler uses the public key from the mykey.snk file, hence we must provide this file to the compiler. To do so we would have to open the AssemblyInfo.cs file of the project. In this file we would have to set the AssemblyKeyFile attribute to the '.snk' file path. The attribute must be either set to an absolute path to the key file or if the file is copied to the local directory of the project, only the file name must be mentioned. We need to add the following to the 'AssemblyInfo.cs' file. [ assembly: AssemblyKeyFile ( "mykey.snk" ) ] We should also change the version number of our assembly as shown below. [ assembly: AssemblyVersion ( "1.0.1.1" ) ] On rebuilding the program, the assembly would now use the public key from the mykey.snk file along with the name of the assembly, the version number and the culture to build a strong name. Culture is a combination of a two letter word indicating the language and a two letter word indicating the country code. The strong name never contains the private key. This ensures that the private key is not written in the manifest and hence is not made available to everybody. This strong name is written in the manifest of the assembly.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Along with the strong name, the compiler also generates a cryptographic hash from the names and contents of the files in the assembly. The compiler then encrypts the cryptographic hash for the assembly using the private key (available in mykey.snk). It places the encrypted hash in the manifest of the assembly. This hash would be used by the client to check the authenticity of the assembly. So, in all, two things are written inside the manifest, the strong name and the encrypted hash of the names and contents of the files. The process of writing the encrypted hash value in the manifest is called 'Signing of an assembly'. Now our shared assembly is ready. To make it available to all the clients we would have to install it in the Global Assembly Cache. All the shared assemblies available on a system are stored in the Global Assembly Cache. This store is located in the <drive>:\Windows\Assembly folder. Installing The Shared Assembly To install a shared assembly in the global cache we would have to use the Global Assembly Cache utility tool called gacutil along with the /i option. Here /i stands for install. This is what we must type at the command prompt to install the assembly. C:\CSharp\fontassembly\bin\Debug>gacutil /i fontassembly.dll If the assembly is successfully installed, the following message would appear: Assembly successfully added to the cache Building The Client Let us now build a client that would use the assembly that we created above. To create the client select a 'Windows Application' project and name it as fontclient When we click on the form, some text should be displayed at the position where we click. This can be achieved by calling the display( ) method from 'fontassembly.dll' in the Form1_MouseDown( ) handler. To have access to this method we have added a reference of the mytext class as a data member of the Form1 class. The Form1_MouseDown( ) handler is shown below. private void myform_MouseDown ( object sender, System.Windows.Forms.MouseEventArgs e ) { if ( e.Button == MouseButtons.Left ) { Point pt = new Point ( e.X, e.Y ) ; t.display ( this, "Hello", Color.Red, "Comic Sans MS", 30, pt ) ; } } Here we have first checked whether the left mouse button has been clicked. If so then we have called the display( ) method of the mytext class from the fontassembly assembly. For the mytext class to become available we have added the statement using fontassembly ;. However this is not enough. We also need to add a reference to the library. To do this we should right click on 'References' in the Solution Explorer window and select 'Add References'. On doing so the 'Add References' window would appear. Execute the program and click on the form, a string "Hello" would appear at the point where mouse is clicked.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com Article: C# - Emitting Metadata


Reflection is generally used for three purposes: viewing metadata, type discovery and invoking methods. However, the most powerful use of Reflection is emitting metadata to assembly. Reflection emit supports creation of types at run-time. For emitting metadata, .NET has provided Reflection.Emit namespace. Reflection emit enable creation of dynamic module defined in a dynamic assembly. A dynamic module created in a dynamic assembly can be transient or persistable. When I first read about Reflection emit the first question came to my mind is that where on earth would I need to write metadata to an assembly when the compiler does it for us? I found few application scenarios where the applications use Reflection emit. Some of them are executing a script in a web browser, executing a script in an ASP.NET Page, compiling a Regular Expression, etc. Let us discuss these scenarios in brief. When a web browser requests for an HTML page containing a script program the web browser first launches the script engine. Then it extracts the script from the HTML page and passes it to the script engine. The script engine creates a dynamic assembly by writing metadata on the fly. The script engine uses the Reflection emit functions to emit the code into the dynamic assembly. In the second scenario, a browser opens an ASP.NET page containing a script program. The program is compiled on the server and executed. For this, ASP.NET launches the script engine to compile and execute the program. The script engine creates a persistable dynamic assembly and a dynamic module in it. It compiles the program using the reflection emit functions and emits the code into the persistable dynamic module. The compiled code is then executed. If any expression is encountered the script engine creates a transient dynamic module in the dynamic assembly to contain the code for the expression. The script engine evaluates the expression by executing the transient dynamic module. ASP.NET requests the script engine to save the dynamic assembly and the persistable dynamic module in the cache so that the script does not need to be recompiled when the page is visited again. In the third scenario, a compiler uses Reflection emit to compile regular expressions in source code. The compiler processes the first use of a regular expression in a users source code. The compiler compiles the regular expression into a custom scanner class using reflection emit. The regular expression is first translated to the compilers regular expression bytecodes. For example, one instruction might say, try to match zero or more as. The regular expression bytecodes are then translated to Microsoft intermediate language (MSIL). For example, the compiler might generate a loop that iterates over all the occurrences of the letter 'a' that it found. The compiler saves the compiled scanner class for future use. Whenever a subsequent expression is encountered, the compiler instantiates the compiled scanner class and executes the code. In this article we would create a type called sample at run-time and store it in an assembly. The class has a method fun( ) that outputs a string Hello on console. Here is the source code. static void Main ( string[ ] args ) { AssemblyName an = new AssemblyName( ) ; an.Name = "emitassembly" ; AppDomain ad = Thread.GetDomain( ) ; AssemblyBuilder ab = ad.DefineDynamicAssembly ( an, AssemblyBuilderAccess.Save ) ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


ModuleBuilder mb ; mb = ab.DefineDynamicModule ( "emitmodule", "emitmodule.mod" ) ; TypeBuilder t = mb.DefineType ( "sample", TypeAttributes.Public ) ; MethodBuilder m = t.DefineMethod ( "fun", MethodAttributes.Public, typeof ( void ), null ) ; ILGenerator mil = m.GetILGenerator( ) ; Type[ ] tp = new Type [ 1 ] ; tp [ 0 ] = typeof ( String ) ; MethodInfo wm = typeof ( Console ).GetMethod ( "WriteLine", tp ) ; mil.Emit ( OpCodes.Ldstr, "Hello" ) ; mil.Emit ( OpCodes.Call, wm ) ; mil.Emit ( OpCodes.Ret ) ; t.CreateType( ) ; AssemblyBuilder asb = ( AssemblyBuilder ) t.Assembly ; asb.Save ( "emitassembly.dll" ) ; } The first step in creating a type is to create an assembly. We have created an assembly named emitassembly using the Reflection.AssemblyName class. An object of AssemblyName class fully describes an assemblys unique identity. Using this object we have obtained an object of the Reflection.Emit.AssemblyBuilder class. To obtain the assembly builder object we have called the DefineDynamicAssembly( ) method on current domain. The current domain is obtained by calling the GetDomain( ) method of the current thread. The parameters passed to the DefineDynamicAssembly( ) are the assembly name and an assembly access mode. The 'Save' mode specifies that the assembly we are creating will be persistable i.e will be saved on disk. If we specify the access mode as Run instead of Save the assembly would be transient. It can be executed but would not be saved on disk. The third mode is RunAndSave which means the dynamic assembly can be executed and saved on disk. The type we would create will be written in a module built dynamically. We have created this module using the Reflection.Emit.ModuleBuilder object. The method DefineDynamicModule( ) creates a module named emitmodule and saves it on disk in a file emitmodule.mod. We can now emit the type sample in the module emitmodule. The DefineType( ) method of the ModuleBuilder class defines the specified type and returns an object of Reflection.Emit.TypeBuilder object. The TypeBuilder class provides methods using which we can define classes, methods and fields. In the next statement we have defined the method fun( ). The second parameter specifies the access specifier, whereas, third and fourth parameters specify the return type and an array containing types of parameters respectively. Now since our type stands created, only thing remaining is to emit the body of the fun( ) method. The Reflection.Emit. ILGenerator class is used to generate IL instructions. The class contains a method called Emit( ) that is used to write the IL into the assembly. We are supposed to call the WriteLine( ) method from the fun( ) method. So, we have firstly obtained the MethodInfo object representing the WriteLine( ) method. The GetMethod( ) method would match the WriteLine( ) method receiving a string. mil.Emit ( OpCodes.Ldstr, "Hello" ) ; mil.Emit ( OpCodes.Call, wm ) ; mil.Emit ( OpCodes.Ret ) ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


The first call to Emit( ) method would push the reference to the string Hello to the metadata. The second call would call the method as described by the second parameter. The third call to the Emit( ) method would return from the method. The OpCodes is the class that contains number of static fields representing the IL instructions. Next, we have cooked the type by calling the CreateType( ) method of the TypeBuilder class. The Assembly property of the TypeBuilder class returns the dynamic assembly that contains calling type. We have stored this assembly object in the AssemblyBuilder class. This is possible because the Assembly class is the base class of the AssemblyBuilder class. Finally we have saved the dynamic assembly to the disk using the Save( ) method of the AssemblyBuilder class. Add the using statements as given below. using System.Threading ; using System.Reflection ; using System.Reflection.Emit ; Let us use this assembly in a test program. Create another console application and write the following statements in Main( ). sample s = new sample( ) ; s.fun( ) ; Add reference to the emitassembly.dll through Solution Explorer. Run the program. The string Hello would get displayed on the console. Another way to invoke the fun( ) method is to use Reflection as shown below. Assembly a = Assembly.LoadFrom ( "emitassembly.dll" ) ; Type t = a.GetType ( "sample" ) ; Object o = Activator.CreateInstance( t ) ; t.InvokeMember ( "fun", BindingFlags.InvokeMethod, null, o, null ) ;

Article: C# - Adding Resources To Assembly


An assembly can contain resource files. An assembly containing resources is called 'satellite assembly'. A resource file can contain any resource such as text, string tables, pictures, etc. The resource file can be embedded inside the assembly. In this article we plan to create a resource file called 'quotes.resources' in an application called res and embed this file in another assembly called resclient. The 'quotes.resources' file would contain 5 images and 5 quotes as resources. The assembly in which we would embed this file will simply pick out a random image and a quote and display them on a form. Let us first see how to build a resource file. Create a Console Application. Add the following code in the Main( ) method. using System ; using System.Resources ; using System.Drawing ; static void Main ( string[ ] args ) { ResourceWriter rw = new ResourceWriter ( "quotes.resources" ) ; Image img0 = Image.FromFile ( "heart.jpg" ) ; Image img1 = Image.FromFile ( "fire.jpg" ) ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Image img2 = Image.FromFile ( "face02.jpg" ) ; Image img3 = Image.FromFile ( "face03.jpg" ) ; Image img4 = Image.FromFile ( "face05.jpg" ) ; rw.AddResource ( "img0", img0 ) ; rw.AddResource ( "img1", img1 ) ; rw.AddResource ( "img2", img2 ) ; rw.AddResource ( "img3", img3 ) ; rw.AddResource ( "img4", img4 ) ; rw.AddResource ( "quo0", "Health is wealth" ) ; rw.AddResource ( "quo1", "A long journey starts with the single step" ) ; rw.AddResource ( "quo2", "Better late than never but better never late" ) ; rw.AddResource ( "quo3", "Opportunity knocks for those who listen" ) ; rw.AddResource ( "quo4", "The best time to make a friend is before you need one" ) ; rw.Close( ) ; } After creating a ResourceWriter reference we have created 5 Image references img0 through img4 and initialized them with images from 5 different files. Next we added these resources in the file using the AddResource( ) method of the ResourceWriter class. The first argument of the method specifies the key and the second argument specifies the image object to be added. The key that we have added is in the form imgnumber. Note that the image files must either be in the 'bin/debug' folder or their path must be specified.. Next we have added 5 quotes to the same file with the key format quonumber. Then we have closed the ResourceWriter by calling the Close( ) method. On executing this application a file called 'quotes.resources' gets created. Now let us see how to embed this file in another assembly. For this we have created a simple windows forms application called resclient and added a PictureBox named pic and a Label named quote to it. We have changed the font size and color of the text that would get displayed in the label using the 'Properties' window. To embed the resource file we need to select the 'Add | Add Existing Item' from the context menu that pops up on right clicking the Solution Explorer. Select the 'quotes.resource' file. The file gets displayed in the Solution Explorer. In the Properties window of this resource file change the BuildAction from None to Embedded Resource so that the resource gets embedded into the output assembly. The 'Properties' window is shown in the following figure.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

After this much is done, we have added code to the constructor of the form class to display a quote and a picture in the form. The constructor is given below: public Form1( ) { InitializeComponent( ) ; Assembly asm = Assembly.GetExecutingAssembly ( ) ; ResourceManager rm = new ResourceManager ( "resclient.quotes", asm ) ; Random r = new Random( ) ; string str ; int i = r.Next ( 4 ) ; str = string.Format ( "img{0}", i ) ; pic.Image = ( Image ) rm.GetObject ( str ) ; i = r.Next ( 4 ) ; str = string.Format ( "quo{0}", i ) ; tip.Text = ( string ) rm.GetObject ( str ) ; } To use the embedded resource, we have used the ResourceManager class defined in the System.Resources namespace. We need to pass the reference of the Assembly class where the resources are embedded to the constructor of the ResourceManager class. In this case the file is embedded in the executing assembly, so we have passed the result of Assembly.GetExecutingAssembly( ) as the second argument. The first argument is the root name of the resource file. The root name is made of the namespace followed by the name of the resource file without extension. We have collected the reference of this ResourceManager object in rm. To extract a resource from the file we have used the GetObject( ) method. We have passed a key to this method. This method returns us the object associated with the key specified. To create the key we have used the Random class's Next( ) method that would return any number between 0 and 4 (0 & 4 inclusive). Next we have set the Image property of pic and Text property of quote to the Image and string objects respectively returned by the GetObject( ) method. The output of this application is shown in the following figure.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Every time we execute this application we get a different picture and quote on the form.

Article: C# - XML And ADO.NET


A powerful feature of ADO.NET is its ability to convert the data stored in a data source in XML and vice versa. In this article we would read records from a data source and display them in a 'DataGrid' control. At the same time we would write the records in an XML file. The contents of the XML file would get displayed in a text box where we can modify it. The modified contents would get added to the data set and would get displayed in the 'DataGrid' control. We are going to use OLEDB for accessing the database. Let us first understand few basic issues in the ADO.NET technology. The System.Data namespace is the root namespace of ADO.NET API. The primary namespaces of ADO.NET, System.Data.OleDb and System.Data.SqlClient contain classes that enable programs to connect with and modify the datasources. A datasource can be any file containing records such as a '.mdb' file. The namespace OleDb can be used to work with any datasource. On the other hand SqlClient namespace is used for working with MS SQL Server 2000 datasources. ADO.NET has two major components-DataSet and .NET Data Providers. A .NET Data Provider is used for connecting to a database, executing commands, and retrieving results. DataSet is used to cache the data read from the datasource in local memory. The data stored in the memory can be modified and written back to the datasource. The System.Data.DataSet class is provided to take care of the DataSets. Let us move on and write a program using ADO.NET. Create a Windows application and design the form as shown in the following figure.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

The dark gray colored control is the 'DataGrid' control. The controls, their Names and handlers are given in the following table. Control Name DataGrid dg Write Button wb Clear Button cb Read Button rb TextBox xmltext Handler Click Click Click -

First of all we would look at the Click event handler for the 'Write' button. private void wb_Click ( object sender, System.EventArgs e ) { String constr = @"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=c:\book.mdb" ; OleDbConnection con = new OleDbConnection ( constr ) ; con.Open( ) ; String comstr = "SELECT Name, Email, Phone FROM addressbook" ; OleDbCommand com = new OleDbCommand ( comstr, con ) ; OleDbDataAdapter adapt = new OleDbDataAdapter ( com ) ; adapt.Fill ( dset, "addressbook" ) ; dg.SetDataBinding ( dset, "addressbook" ) ; dset.WriteXml ( "addressbook.xml" ) ; xmltext.Text = dset.GetXml( ) ; con.Close( ) ; }

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Interacting with a database using ADO.NET involves connection and command objects. Since we have used OLEDB to access the database, the connection must be established between the database and OLEDB .NET Provider. The class OleDbConnection is used for this job. So, in this method we have firstly created an object of this class passing to it the connection string. The connection string contains the name of the OLEDB .NET Provider and that of the datasource. Our datasource is 'book.mdb' that maintains an address book. This file is already created using Microsoft Access. It contains details like names, e-mail IDs and phone numbers. Only creating object of connection class does not physically open a connection to the database. Calling Open( ) method does. So we have called the Open( ) method in the next statement. The Command object allows us to execute an SQL statement or a stored procedure in a data source. We have created the command object using the OleDbCommand class and passing to it the command string. The command string contains the SQL statement to select all the records from the datasource. The command object is used to connect the connection object to a DataAdapter object. A DataAdapter is used to fill data from the database into the DataSet object. To read the records into the DataSet we have used the OleDbDataAdapter.Fill( ) method. To this method we have passed the DataSet object dset and the table name. Add the data member dset of type DataSet to the form class. Initialize the data set object in the constructor as dset = new DataSet( ) ; Next, we have called the DataGrid.SetDataBinding( ) method to bind the grid control with the datasource. We have passed the DataSet object as the first parameter to specify whose data the grid control should display. Second parameter is the name of table within the datasource we want to bind to the control. When this function call is executed, the data grid is filled with the records in the DataSet. Next comes the main part of the program i.e writing records to an XML file. The DataSet.WriteXml( ) method generates the XML representation of the data contained in the DataSet object and writes it to the specified file. We have displayed the same XML data that we have just written to the file in the text box. For this, we have called the DataSet.GetXml( ) method. The OleDbConnection.Close( ) method closes the connection with the datasource. A part of the XML file is given below. <NewDataSet> <addressbook> <Name>Meghana</Name> <Email>Meg2003@hotmail.com</Email> <Phone>2242567</Phone> </addressbook> . </NewDataSet> On clicking the 'Clear' button the grid control should get cleared so that we can display modified contents in it. The code to clear the control is given in the cb_CLick( ) event handler. The handler is given below. private void cb_Click ( object sender, System.EventArgs e ) { dset.Clear( ) ; dg.Update( ) ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


} Since the grid control is attached to the datasource represented by dset, clearing dset and updating the grid control clears the contents from it. Now add the following node to the XML data displayed in the text box. <addressbook> <Name>Sanjay</Name> <Email>sanju@hotmail.com</Email> <Phone>227257</Phone> </addressbook> Click the 'Read' button. Following handler would get called. private void rb_Click ( object sender, System.EventArgs e ) { StreamWriter sw = new StreamWriter ( "addressbook.xml", false ) ; sw.Write ( xmltext.Text ) ; sw.Close( ) ; dset.ReadXml ( "addressbook.xml" ) ; dg.SetDataBinding ( dset, "addressbook" ) ; } Here, we have used the StreamWriter class to write the contents from textbox to the XML file. To read new contents of the file and fill the DataSet with it we have used the ReadXml( ) method. Again to fill the grid control we have called the SetDataBinding( ) method. The result is shown in the following figure.

Note that we must add the following declarations at the beginning of the program. using System.Data.OleDb ; using System.IO ;

Article: C# - Using MS Agents - I Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


The characters provided by Microsoft Agent technology are something we often use in MS-Word, Excel and PowerPoint applications. These are cute animated characters that appear to help us finding answers to questions. The MS Agent characters can be added to Windows applications as well as to Web applications. The MS Agent control provides access to four animated charactersGenie (genie), Merlin (genius), Peedy (parrot) and Robby (robot). Out of these we are going to use Peedy and Merlin in this article. The synopsis of the application is like this. We would first create a timer user control that would show current time on a label. The control would expose two properties through which client can set the alarm time and a message string. It would also throw an event when the time set by the client and the current time equals. The client would handle this event and communicate the message through either Peedy or Merlin. Selection of animation character can be made through radio buttons. Every character supports number of animations. Our application would allow user to select the animation using a combobox. The characters would also speak the text that the user would enter in a text box. Let us see in brief how to create a user control. Create a Windows Control Library project named ClockControl. As soon as we do this, a class called UserControl1 gets created. Add two labels and a timer control (named mytimer) to the form. Set the Interval property of the Timer control to 1000 milliseconds (1 second). Add two methodsstart( ) and stop( )to the UserControl1 class. These methods are given below. public void start( ) { DateTime d = DateTime.Now ; sec = d.Second ; min = d.Minute ; hrs = d.Hour ; mytimer.Start( ) ; } public void stop( ) { mytimer.Stop( ) ; } Add the three integerssec, min and hrs as data members of the class that represent the seconds, minutes and hours respectively. In the start( ) method we have set these data members to the present time using DateTime class. We have then started the timer by invoking the Start( ) method of the Timer control. In the stop( ) method we have stopped the Timer using the Stop( ) method. Add the Tick event handler. In this event handler we have simply displayed the current time in the label control named time. The mytimer_Tick( ) handler is given below. private void mytimer_Tick ( object sender, System.EventArgs e ) { sec += 1 ; if ( sec == 60 ) { min += 1 ; sec = 0 ; if ( min == 60 ) { hrs += 1 ; min = 0 ; } }

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


String str = hrs + ":" + min + ":" + sec ; time.Text = str ; } Add the data members altime and almessage of type string. Add the AlarmTime and Message properties for these data members. Now our approach is that whenever the alarm time becomes equal to the current time, the event must be raised. To do so, we need to keep on checking the current time in the mytimer_Tick( ) event handler and once the condition is satisfied we need to throw an event to the client. Declare the delegate and an event in the UserControl1 class as shown below: public delegate void del ( object sender, TimeEventArgs e ) ; public event del d ; The TimeEventArgs is a user-defined class that needs to be necessarily derived from the EventArgs class. This class simply contains a public data member msg of type String and a constructor to initialize msg. The TimeEventArgs is given below. public class TimeEventArgs : EventArgs { public String msg ; public TimeEventArgs ( String s ) { msg = s ; } } Add the code as shown below to check the time and raise the event. int i = str.LastIndexOf ( ":" ) ; str = str.Substring ( 0, i ) ; if ( ( str == altime ) && ( sec == 0 ) ) { TimeEventArgs t = new TimeEventArgs ( almessage ) ; d ( this, t ) ; } Here, when the current time equals the alarm time, we have created an object of the TimeEventArgs class by passing the message to it and raised the event d. Build the application. The ClockControl.dll file would get created.

Article: C#- Using MS Agents - II

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

We would now create the client. Create a Windows application and design the form as shown in the following figure.

Note that in order to run the application we must first download and install Microsoft Agent software from the website www.microsoft.com/products/msagent/downloads.htm. Next we need to add them to the toolbox by right clicking on the Toolbox and selecting Customize Toolbox. From the dialog box that would appear we need to select Microsoft Agent Control 2.0 and then click on OK. On doing so the Microsoft Agent control would get added to the toolbox. Next we need to drag the control on the form. On dragging the Microsoft Agent control an object of the type AxAgent class that belongs to the AxAgentObjects namespace gets added as data member of our Form1 class. Following table shows the controls and their properties.

Control TextBox Speak button Peedy Radiobutton Merlin Radiobutton ComboBox Change button Agent Add the following code to the constructor.

Name speechtext speak ped mer mood change agent

String loc = @"C:\WINNT\msagent\chars\" ; agent.Characters.Load ( "Merlin", loc + "merlin.acs" ) ; agent.Characters.Load ( "Peedy", loc + "peedy.acs" ) ; speaker = agent.Characters [ "Peedy" ] ; loadmoods( ) ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


speaker.Show ( 0 ) ; Here we have first created a string, loc, specifying the location of the character on the disk. Next we have used the Load( ) method of IAgentCtlCharacter, whose reference can be obtained by accessing the Characters property of AxAgent class, to load both the characters. We have passed the character name, location and file name to the Load( ) method, which creates an object of the specified character. In this application we have planned to keep Peedy as the default character and so set the Checked property of Peedy radio button to true. Add a reference to the IAgentCtlCharacter interface as the data member of the form as AgentObjects.IAgentCtlCharacter speaker ; Next, we collected the reference of Peedy in speaker. Then we have called the loadmoods( ) method. This is a user-defined method that populates the combo-box with names of animations. We have then called the Show( ) method to display the character. Lastly, we have started the timer by calling UserControl1.start( ) method. The loadmoods( ) method is defined as given below. public void loadmoods( ) { IEnumerator arr ; arr = agent.Characters [ speaker.Name ].AnimationNames. GetEnumerator( ) ; mood.Items.Clear( ) ; while ( arr.MoveNext( ) ) mood.Items.Add ( arr.Current ) ; } Here, we have created a reference arr of the type IEnumerator. Then using the GetEnumerator( ) method we have obtained a list of all the animations of the current speaker and added the animations to the combo-box. User can select the character of his choice using the radio buttons and clicking the Change button. The change_Click( ) method is given below. private void change_Click ( object sender, System.EventArgs e ) { String character ; if ( ped.Checked == true ) character = ped.Text ; else character = mer.Text ; speaker.Hide ( 0 ) ; speaker = agent.Characters [ character ] ; loadmoods( ) ; speaker.Show ( 0 ) ; } Here, we have first checked which of the two radio buttons is selected using the Checked property of the ped radio button. Then using the Hide( ) method we have removed the current character from view and loaded the newly selected character. We have again called the loadmoods( ) method to populate all the moods of the newly selected character in the combo box. Finally using the Show( ) method we have displayed the character.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

As soon as the user selects some mood from the combo box, the mood_SelectedIndexChanged( ) event handler gets invoked. This handler is given below. void mood_SelectedIndexChanged ( object sender, System.EventArgs e ) { speaker.StopAll ( "Play" ) ; speaker.Play ( mood.Text ) ; speaker.Play ( "RestPose" ) ; } In this handler we have first stopped all the animations presently playing using the StopAll( ) method. Next we have played the selected mood from the combo box using the Play( ) method. To this method we have passed the name of animation to play. After this we have played the Rest Pose animation, which indicates an idle position of the character. If we type something in the textbox and click on the Speak button the speak_Click( ) event handler gets called. Here we have first played the animation selected by the user and then played the text written by the user using the Speak( ) method. Here is the handler. void speak_Click ( object sender, System.EventArgs e ) { speaker.Play ( mood.Text ) ; speaker.Speak ( speechtext.Text, "" ) ; } The jobs that are remaining are adding the user control and writing an event handler for it. Add the user control by right clicking on the Toolbox and selecting Customize Toolbox. From the dialog box that would appear select the .NET Framework Components tab. Click the Browse button. From the Browse dialog select the ClockControl.dll and click Open. The user control would get added to the list of controls. Dismiss the dialog by clicking on OK. It would appear on the Toolbox. Drag and drop it on the form. Name it as c. Set the Alarmtime and Message property of the control through the Properties window. First of all we need to start the timer in the constructor of the Form1 class by calling the start( ) method of the control. Do so as given below. c.start( ) ; We also need to add an event handler to handle the d event of the control. Do so through Properties window. The code in this handler is shown below. void c_d ( object sender, ClockControl.TimeEventArgs e ) { int i ; for ( i = 0 ; i < 5 ; i++ ) speaker.Speak ( e.msg, "" ) ; } The TimeEventArgs object would contain the message to be displayed in the msg data member. In the event handler we have simply made the character speak out the message five times.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Article: C#- Solutions, Projects, Items, Etc. - I

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Article: C#- Going International With Locale - I


As the number of Internet users grew worldwide, need to create software supporting multiple languages was felt intensely because only ten percent of people use English as primary language. People wanted an application that could communicate with them in their native language. This became simple with the release of .NET framework. Locale and .NET Culture Geographically speaking, a locale is a place. In software terms, a locale is a set of information associated with a place. Locale information includes the name and identifier of the spoken language, cultural conventions, etc. A Locale Identifier (LCID) is used to retrieve information about the locale. LCID is a 32-bit unsigned integer value that is divided into four parts. The first two parts identify the language and sub-language (sub-language corresponds to country/region) and the last two parts specify the sorting order for text strings. The culture in .NET refers to users language and region. A culture is identified by language coderegion/country code. For example, French language spoken in France is identified by frFR. Here, fr is the short form for French and FR is abbreviation of France. Similarly, fr-CA is the culture identifier for French in Canada. There are cultures that are identified by language only. These cultures are called neutral cultures. The cultures having language-region combination are called specific cultures. For example, fr is a neutral culture, whereas, fr-FR is a specific culture. .NET encapsulates the culture related information in the System.Globalization and System.Resources namespaces. The object of the Globalization.CultureInfo class represents a specific culture. Using the methods of this class, we can obtain the information of the culture that is set for the current thread. Following code snippet shows how to set the culture for the current thread and obtain its name, number format and currency format. foreach ( CultureInfo c in CultureInfo.GetCultures( CultureTypes.AllCultures ) ) { Thread.CurrentThread.CurrentCulture = new CultureInfo ( c.Name ) ; Console.WriteLine ( "{0}:{1},Num:{2},Dt:{3},Curr:{4}",c.Name, c.EnglishName, (12345).ToString ( "n" ), ( 12345.50 ).ToString ( "c" ), ( DateTime.Now ).ToShortDateString( ) ) ; } The CultureInfo.GetCultures( ) method returns the list of all the supported cultures. CultureTypes is an enum that contains the types of culture viz. specific, neutral, all cultures and only those cultures that are installed on the system. To set the culture for a thread, firstly we must obtain the reference to that thread. Here, we have obtained the same by using the CurrentThread property of the Thread class. The two culture values of an application determine what resources are loaded for an application and how information like currency, numbers, and dates is formatted. The resources loaded are determined by the UI culture setting, and the formatting options are determined by the culture setting. The Thread class provides two propertiesCurrentCulture and CurrentUICulture to change the respective culture settings. We have used the CurrentCulture property since we needed to set the culture specific formatting options. The Name and EnglishName are properties of the CultureInfo class that give the culture name and its corresponding Language (Country/Region) combination respectively. Of course, we need to use the Globalization and Threading namespaces to run this code. We would now see how to localize resources. We would create a localized WinForm application that would allow user to select a language. On clicking a button another form would get displayed in the selected language. This form would contain a textbox where you can type your name. On

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


clicking a button you would be greeted in the selected language. Our form would look as shown below.

Name the radio buttons as reng, rger, rita, and rfre respectively. Name the Display button as bdisplay. Add the Click event handler for the Display button. Here is the handler. void bdisplay_Click (object sender, System.EventArgs e ) { Thread t = Thread.CurrentThread ; if ( rfre.Checked ) t.CurrentUICulture = new CultureInfo ( "fr-FR" ) ; if ( rger.Checked ) t.CurrentUICulture = new CultureInfo ( "de-DE" ) ; if ( rita.Checked ) t.CurrentUICulture = new CultureInfo ( "it-IT" ) ; if ( reng.Checked ) t.CurrentUICulture = new CultureInfo ( "en-US" ) ; greetform g = new greetform( ) ; g.ShowDialog( ) ; } Here, we have only checked which radio button the user has selected and set the UI culture accordingly. After this we have displayed another form. We need to add this form to the project. Add controls to this form as shown below.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

The controls and their names are given in the following table. Control Name text box Greet button Label Close button Name tname bgreet lgreet bclose

Add the Click event handlers for the Greet and Close buttons. The bgreet_Click( ) handler is given below. void bgreet_Click ( object sender, System.EventArgs e ) { String s ; DateTime t = DateTime.Now ; }

Article: C#- Going International With Locale - II


Last time we had designed the greeting form and added code to change the culture. Let us now add localization support to it. After we are done with developing the form, select the Localized property of the greetform to True. This property specifies whether localized code is to be generated for this form. We must now specify the languages that our application would support. For this, select the Language property. Click the down arrow. It would display list of cultures. Select French (France) then select Italian (Italy) and German (Germany) one after other. As soon as we select a language, say, French (France) two resource files greetform.fr.resx and greetform.fr-FR.resx get added to our project. In these files we need to add French equivalents for the resources. Add the data as shown in the following table in the greetform.fr-FR.resx file. We will see the purpose of greetform.fr.resx file later. Name Lname.Text bgreet.Text bclose.Text Value Nom: Saluer Fermer

Following table shows the data to be added to German and Italian resource files.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Name German lname.Text bgreet.Text bclose.Text Italian lname.Text bgreet.Text Bclose.Text Value Name: Begren Enden Nome: Saluare Argomentare

Now you can run the program. Select a language and display the greetform. The greetform in Italian is shown in the following figure.

But there is a problem in this output. Although resources are appearing in Italian, the greeting message is still in English. This is because, when we localize resources, an entry is made in their properties to extract proper resource from appropriate resource file. Since welcome messages are string literals their properties are not changed. We have to do this job ourselves. We also need to make few changes in the program. Add the following translations in the resource files for German, French and Italian. Name French GoodMorning GoodAfternoon GoodEvening German GoodMorning GoodAfternoon GoodEvening Italian GoodMorning GoodAfternoon GoodEvening Value Bonjour Bonsoir Bonaprsmidi Guten Morgen Guten Tag Guten Abend Boungiorno Bounpomeriggio Buonasera

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


We must also provide default culture settings for English. For this, we can modify the main resource file i.e. greetform.resx. In this file we must add three resource strings and their English equivalents that happen to be same. Change the bgreet_Click( ) handler as given below.

private void bgreet_Click ( object sender, System.EventArgs e ) { ResourceManager r = new ResourceManager ( "locale_greet.greetform", Assembly.GetExecutingAssembly( ) ) ; String s ; DateTime t = DateTime.Now ; if ( t.Hour <= 12 ) s = r.GetString ( "GoodMorning" ) ; else { if ( t.Hour <= 19 ) s = r.GetString ( "GoodAfternoon" ) ; else s = r.GetString ( "GoodEvening" ) ; } s += " " + tname.Text ; lgreet.Text = s ; } The ResourceManager class provides methods to work with culture specific resources at runtime. The locale_greet.greetform is the root name of the resources (If resource file name is MyResource.en-US.resources then root name is MyResource) that we want to access from the current assembly. We have specified fully qualified name of the resource file. We have used the ResourceManager.GetString( ) method to extract the value of the resource passed to it as parameter. Use the System.Resources and System.Reflection namespace for the ResourceManager and Assembly classes respectively. Now run the program again and confirm that the greetings are displayed in the chosen language. Behind The Scene Let us see what happens behind the scene when we localize the form, select the language and compile the program. When we set the Localizable property to true, information about all the resource strings, properties, embedded pictures, etc. gets stored in the root resource file i.e greetform.resx. The following statement gets added to the InitializeComponent( ) method. ResourceManager resources = new ResourceManager( typeof ( greetform ) ) ; The type greetform provided to the constructor is used to gather all information like assembly name, root name of resource, etc. for finding the resources. Instead of assigning values directly to the properties, methods like GetString( ), GetObject( ) are used to retrieve the strings and pictures from the resource file. Before retrieving the values, the CurrentUICulture property is checked for the current culture. On compilation, for every localized resource separate assembly called satellite assembly gets

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


created in the folder named after the culture name. We can find this folder in bin\Debug folder. The satellite assembly contains manifest describing the localized resource. Since resources are shipped as separate assemblies and not as part of main assembly we can easily replace or update resources corresponding to a specific culture without replacing the application's main assembly. We know that on selecting the language two resource files get created. One is for specific culture (greetform.fr-FR.resx) and another for neutral culture (greetform.fr.resx). To understand the purpose of creating two files, we must first understand the path in which localized resources are searched. The localized resources are searched for in a hierarchical manner. At the top of hierarchy is the resources for default culture i.e English (en). Below that are the resources for any neutral culture. Below those are the resources for any specific cultures. Suppose a user requests for the resources localized in French (France). The CLR would first search in the global assembly cache for the assembly matching requested culture (fr-FR). If not found, it searches in the folder of currently executing assembly for the fr-FR folder. If not found it searches the GAC again for the fallback culture contained in the parent assembly (fr). If the parent assembly is not found runtime searches all potential levels of parent assemblies. On failing that then it uses the resources for default culture. If we dont provide the neutral cultures problem may arise in some cases. For example, it may so happen that a machine contains culture of fr-CA and our program loads the culture fr-FR. If fr-FR is not found then run-time would directly load the English culture instead of French culture that we could provide in neutral fr assembly.

Article: C#- Security Under .NET


Security in the field of computers is similar to that in the real life. We install security systems in our homes, banks and work places. These systems include gatekeepers, ID cards, Closed circuit cameras, etc. Parallels to these are found even in the digital world. Gatekeepers are comparable to FireWalls. FireWalls are programs that will continuously keep a watch on the files that are coming into our computer. Files that are known to be malicious are denied an entry. Similarly ID cards are comparable to user names and passwords. Cameras are comparable to network monitors or file-system monitors. Network monitors listen to and keep a record of all the communication happening on the network. Similarly, File System monitors keep track of any changes made to the files on the hard disk. In the computer world it is important to know who is allowed to use something and to what extent. That Who could be a person sitting at a computer or a program that is being executed. This divides security implementation in two distinct branches. - Protection from malicious code - Protection from malicious users The implementation of security in either type involves two stages, identification and deciding the scope of activity. In security terminology this is known as authentication and authorization respectively. Authentication is responsible for identification and authentication for deciding scope of activity. We would discuss authentication and authorization in detail later. After a program/user is positively identified, it needs to be decided as to what are the activities that he is allowed to do. A list is constructed containing all the things that the program/user is allowed to do. Each entry in this list is known as permission. The list is known as the permission set. Windows Security Model Windows like many other operating systems decides permissions on the basis of the type of user who has logged in. The security features were almost negligible under Windows 9x operating

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


systems. Two users could look at each others personal data without ever being asked why. All software installed were available to all the users. Windows NT had a better design. There was now a distinction between different users using a machine. Moreover, every user had to log on to the computer before using it and then log off. There was no such thing as a default user. The operating system interacted differently with different users. Windows implemented a concept called group. A group is a set of users having same permissions. And for the user the group to which he belongs becomes his role. For example if XYZ belongs to the Administrator group, then role of XYZ is Administrator and had permissions to almost do anything on the machine. Then there were users, which could use the computer but could not do tasks such as installing new software or changing system variables such as page memory size, etc. There were Replicators, Printers, Power Users and so on. An administrator had the right to add new users to the machine. He could decide the permissions to be given to these users. An Administrator could also create custom groups with custom permissions. A user belonging to a certain group could do only those things that were permitted to him and nothing else. For example a user allowed to use only a printer could do only that besides logging on and off. Under Windows if we intend to get some work done, we pass a request stating that to the operating system. The operating system in turn performs the task for us. In a network, the origin of a request could be the local machine or the remote machine. Requests could be anything like accessing data, authenticating a user against a list of valid users maintained on the server or using a resource like printer. The server operating systems are fine-tuned to prioritize network requests (requests from remote computer) rather than local requests. Again keeping in tune with the concept of security we can configure the server to respond only to certain requests and turn down others. Another thing is, to grant permissions for requests on the basis of the computer that is requesting or grant them on the basis of the current login on that computer. This scenario is very flexible and highly configurable. Lets see how the operating system manages this. With Windows NT 3.1 and onwards, Microsoft introduced a new way of managing files on the hard disk called the NT File System (NTFS). This file system was better than the FAT32 file system. NTFS had provisions to allow or deny access to files on the basis of the user requesting to access it. For every file NTFS maintains a list of users allowed to access it. This functionality is not implemented in the FAT32 file system. Instead in FAT32, the operating system keeps a list of files and who is allowed to access them. Such an arrangement works but at the cost of performance. The protection mechanisms discussed above were about granting of permissions to the user who is logged on. But if the user runs the malicious code, there is nothing that can be done to stop the code from causing havoc. This concern has been addressed by .NET through a concept called Code Access Security that we would discuss later. Authentication and Authorization As stated earlier, authentication is identification of user and authorization is granting permissions to the identified user. In any security related scenario, Authentication and Authorization are indispensable. Windows NT at the time of Login, performs authentication and authorization. Windows maintains a list of all users allowed to use that computer. This list is known as the Access Control List (ACL). Whenever a person tries to login using one of these registered users, Windows internally looks at ACL, and grants permissions to the user according to his or her role. Permissions are access permissions to files, ability to install programs, modify system parameters and so on. After authenticating a user, the next step is to determine whether that user has permission to access the resources it is requesting. This process is known as authorization. Authorization can be controlled using any of the following methods.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


a. Windows Access Control List (ACL) - This allows us to create permissions specific to the file system. Users can be allowed or denied access to resources right at the file system level. The NTFS file system discussed earlier is best suited for this. Using ACL to grant/deny permissions works best where our application is authenticated using Windows account. b. Web Server Permissions - Web Server Permissions are configured on the IIS (Internet Information Server). This configuration specifies permissions such as read, right, access and denial to anyone accessing the website. There is a difference between NTFS permissions and Web Server permissions. Web Server Permissions apply to all those who access the web and FTP sites, NTFS permissions apply only to specific users and groups with registered Windows accounts. c. URL Authorization - The URL maps specific users and roles to the contents of the URL. It is possible to specifically allow or deny users and roles, access to contents of the URL. Entries made to the web.config file will implement this authorization. d. Principal Objects - Under Security terminology users or entities that have been authenticated are known as Principals. Identification of the principal could be through any of the above-discussed procedures or could also be custom defined. The .NET platform provides a GenericPrincipal Class that can be extended as per requirements. We can then map our custom table to the Windows accounts. Security Under .NET .NET security mechanisms work in close interaction with Windows security. It divides security into two distinct models. - Role Based Security - Code Access Security Role based security decides permissions on the basis of the role (or type) of the user, whereas code access security grants permission on the basis of identity of the code. Identifying code is identifying the location from where the code is running.

Article: C#- Role Based Security Model - I


Role based security is an elegant way to provide user authorization and user access checks for our application. We must first understand what role means in security vocabulary. A role is a set of users sharing same security privileges. A user belonging to particular role can access the code/softwares/resources for which permissions are granted for the role. Granting permissions to access resources/code using roles rather than using a particular user is easier to manage. For example, suppose an application grants permission to access a particular feature to four users. Now if the number of features grow to ten the application would need to decide which user to grant permission to access which feature and add the permissions accordingly. If the application uses role-based security it needs to only declare that the users belonging to a particular role can access a feature. Another important thing is, role based model works without walking the stack. Before we learn more about role-based security let us first see what is stack walk.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Stack Walk Stack walks are an essential part of the security system. A stack walk operates in the following manner. Every time a method is called a new activation record will be put on the stack. This record contains the parameters passed to the method, if any, the address to return to when this function completes and any local variables. At certain stages during execution, the thread might need to access a system resource, such as the file system. Before allowing this access the protected resource may demand a stack walk to verify that all functions in the call chain have permission to access the system resource. At this stage a stack walk will occur and each activation record is checked to see that callers do indeed have the required permission. Principal In case of role-based security, the code can perform actions based on the data it collects about the user. It is best when used in conjunction with Windows 2000 accounts. The heart of Role based security lies the Principal (identity and role of the user). Role based security is most useful in situations where access to resources is an issue. Consider a bank, where everyone needs to log into a software in order to use it. Access to records will depend on the role of the user trying to access it. A clerk will login with a different role than the manager, hence he will not be allowed access to personal data of various customers whereas the manager might have the powers to modify them if necessary. These situations are very common and hence .NET provides easy ways to implement security on the basis of roles. .NET allows developers to use role based security as attributes freeing the business logic from the responsibility of performing security checks. Let us now put the role-based security model to work in an application. This application retrieves personal information about employees that is stored in a database. User will be allowed to view the database only if he has an administrative login on that computer. Create a Windows application and design the form as shown in following figure

Change the names of the controls as shown in the following table Control Employee ID First Name Last Name City Lookup button Exit button Name empid fname lname city lookup exit

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com Article: C#- Role Based Security Model - II
Now, add the Click event handler for the Lookup button. Add the code given below in this handler. private void lookup_Click ( object sender, System.EventArgs e ) { SqlDataReader dr = null ; SqlConnection con = new SqlConnection ((@"server=(local)\NetSDK;Trusted_Connection=yes;database=backup" )); SqlCommand com = new SqlCommand ( "Select * from Employees",con ) ; con.Open( ) ; dr = com.ExecuteReader( ) ; while ( dr.Read( ) ) { if ( empid.Text == dr [ "EmployeeID" ].ToString( ) ) { fname.Text = dr [ "FirstName" ].ToString( ) ; lname.Text = dr [ "LastName" ].ToString( ) ; city.Text = dr [ "City" ].ToString( ) ; } } con.Close( ) ; }

Here, we have created three basic objects required to deal with databasedr, com and con of type SqlDataReader, SqlCommand and SqlConnection respectively. We have then used the ExecuteReader( ) method of the command object to execute the command and collected the result in dr. Then we have iterated through the record set till we find the record whose Employee ID matches with the one user has asked for. Once the record is found we have displayed it in the text boxes. Add an event handler for the Load event and write code in it as given below.

private void Form1_Load ( object sender, System.EventArgs e ) { AppDomain.CurrentDomain.SetPrincipalPolicy ( PrincipalPolicy.WindowsPrincipal ) ; WindowsPrincipal p = ( WindowsPrincipal ) Thread.CurrentPrincipal ; lookup.Enabled = p.IsInRole ( WindowsBuiltInRole.Administrator ) ; } In this handler to begin with we have set the principal of the current application domain. The method SetPrincipalPolicy( ) is used for this purpose. To access the current domain we have used the CurrentDomain property of the AppDomain class. It returns a reference to the application domain in which our application is running. We have passed the PrincipalPolicy.WindowsPrincipal to this method. PrincipalPolicy is an enumeration in the System.Security.Principal namespace. PrincipalPolicy enumeration holds three types NoPrincipal, UnauthenticatedPrincipal and WindowsPrincipal. Of these three, the WindowsPrincipal holds the identity of the current user logged on to Windows. In the next statement we have created a reference to an object of type WindowsPrincipal. The

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


WindowsPrincipal class is capable of holding all information about a Windows account holder. The reference is made to point to the identity of the current user. In the previous statement we have setup the principal policy of the current application domain to the current user. Since our application thread is executed inside the current application domain, CurrentPrincipal property of the thread will hold the same value that we setup for the whole application domain in the previous statement. This much just to access the Windows identity of the current user. Now we must check whether or not the role of the current user is that of the Administrator. The WindowsPrincipal object we have referenced above has a method IsInRole( ) which compares the role of information it holds with the one that has been passed to it. We have passed the WindowsBuiltInRole.Administrator role to this method to check whether the user belongs to the Administrator group. If IsInRole( ) returns true it means that the user is actually a member of the Administrator group and hence the Enabled property of the Lookup button is set to true to allow user to look up the employees information. Otherwise the button is disabled. If the role of the user using this program is not Administrator, then the interface will look as shown in the following snap shot

Lastly add the Click event handler for the Exit button and call Dispose( ) method from it to close the form. Note that we must use System.Threading, System.SqlClient and System.Principal namespaces to run the program.

Article: C#- Creating Web Application - I


ASP.NET is a technology used to create web applications and dynamic web sites. ASP.NET is compatible and is integrated with the .NET environment. It is very much different from ASP. First lets see how it differs. ASP (Active Server Pages) is a technology that helps us create web pages dynamically. An ASP page is an HTML file with server-side script written in VBScript or JScript. When a client requests an ASP page, the web server delivers the static HTML portions of the page as it is, and processes the server side script, which further generates HTML. The problems faced with ASP are: (a) The scripting is interpreted, leading to slow rendering of pages. (b) The entire HTML portion (content) and scripting portion (code) is jumbled up in one .asp file. (c) We have to write code in ASP for everything including simple jobs like validating form fields.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


ASP.NET solves all these problems faced with ASP. First of all ASP.NET pages are compiled and not interpreted. Secondly ASP.NET pages are structured, meaning server-side scripts and plain HTML are not jumbled up; scripts and HTML can be separated. ASP.NET provides a feature called code-behind. This feature allows us to separate the server-side code of a page, and place it into another file. A .aspx file contains the HTML portion of the application and a .cs file contains the code. This allows one team of team members to concentrate on HTML design, as others work on the code. Web Forms .NET Web Applications or Web Forms like WinForms brings RAD to development of web applications. Web forms are created by dropping controls onto a form and then double-clicking those controls and writing event handlers for them in code behind pages. The controls to be used in Web Forms are present in the .NET Framework class library. Some controls are mere wrappers around simple HTML tags, but others represent complex UI objects that generate HTML. Let us first build a Web Form and then understand the working of an ASP.NET Web Form application. In this article we would see how to create a registration form that would allow students to register for an online course. Let us now set to build the application. Create an ASP.NET application names Registration by selecting ASP.NET Web Application from the template list. On doing so a virtual directory named Registration would get created in the IIS and its local location will be C:\Inetpub\wwwroot\Registration. As soon as we create a project the following files would get generated in the Registration directory: - A Global.asax file containing application-level program directives, handlers for application and session-level events, and declarations of objects that are globally accessible to all parts of the application. - A Web.config file containing XML that stores the application configuration information. - A WebForm1.aspx file containing HTML for rendering Web Forms. - A WebForm1.aspx.cs file containing the code behind page written in C#.NET. - An AssemblyInfo.cs file containing standard code for assembly description. - A WebForm1.disco file describing any web services in the project. We will only be concentrating on the WebForm1.aspx file (content) and the WebForm1.aspx.cs (code) file for our application. On creating the application an empty web form would get displayed in the design view of the WebForm1.aspx file. We intend to add a table to this form. To add a table we need to select Table menu and then Insert | Table option and we would be presented with the Insert Table Dialog box. Select the rows (11) and columns (3) that we wish to add to the table. A grid would get displayed on the form. Insert the controlslabels, text boxes, validation controls and button to the form as shown in the following figure.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

The details of the controls are given in the following table. Control TextBox TextBox TextBox TestBox TextBox TextBox TextBox TextBox TextBox RadioButtonList Button Name uid pass cpass sname address state zip country mail course submit

The controls appearing in red color are called validation controls. Whenever we enter something on the form and submit it to the server it is called a postback. Validation controls provide a method of validating user input without writing any code. Whenever postback is initiated (i.e. we click the Submit Form button) each control checks the control it is validating and changes its IsValid property accordingly. If the property is set to false it means that the user input is wrong. In

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


such a case an error message is flashed. If the property is set to true the postback occurs. Some of the validation controls that we have used in this program are given in the following table. Control RequiredFieldValidator CompareValidator RegularExpressionValidator Name reqid compass checkmail

The pass textbox would accept a password. Generally a password is something that should not be visible hence we need to change the TextMode property of this textbox to Password. Now whatever the student types in this textbox is substituted by *s. We must now change the properties of validation controls. How to do this would be discussed next week.

Article: C#- Creating Web Application - II


To accomplish this we must set the ErrorMessage property of this validator to some string and most importantly associate this validator with the uid textbox. We can do so by setting the ControlToValidate property of this control to the uid textbox. The name compass is given to the CompareValidator control. This control is used to check whether the value in the Password textbox matches the Confirm Password textbox. To be able to do so we need to set the ControlToValidate property of the validator to cpass and ControlToCompare to pass. If the password does not match, an error message should be displayed. The name checkmail is given to the RegularExpressionValidator. Here too we need to set the ErrorMessage property to a string and the ControlToValidate property to the mail textbox. This is because we want that the e-mail should be in a proper format. To be able to do so we can set the RegularExpression property of this control to Internet e-mail Format. This can be done by clicking a small button that appears beside the property name in the Properties window. On doing so a Regular Expression Editor would get open. We can now choose Internet E-mail address from the editor. What we plan to do in this application is to store the information of the student in the database. So whenever the student enters his or her information and clicks the Submit Form button a handler should get called that will write the details to the database. Add the Click event handler for the Submit Form button and write the code in it as shown below. private void submit_Click ( object sender, System.EventArgs e ) { String constr = @"Provider=Microsoft.Jet.OLEDB.4.0 ; Data Source=c:\online.mdb" ; String cmdstr = "SELECT * from registration" ; OleDbDataAdapter da ; da = new OleDbDataAdapter ( cmdstr, constr ) ; DataSet ds = new DataSet( ) ; DataTable dt = ds.Tables [ "registration" ] ; da.Fill ( ds, "registration" ) ; DataRow row = dt.NewRow( ) ; row [ 0 ] = uid.Text ; row [ 1 ] = pass.Text ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


row [ 2 ] = sname.Text ; row [ 3 ] = address.Text ; row [ 4 ] = state.Text ; row [ 5 ] = zip.Text ; row [ 6 ] = country.Text ; row [ 7 ] = mail.Text ; row [ 8 ] = course.SelectedItem.Text ; dt.Rows.Add ( row ) ; OleDbCommandBuilder mybuilder ; mybuilder = new OleDbCommandBuilder ( da ) ; da.Update ( ds, "registration" ) ; Response.Redirect ( "Confirm.aspx" ) ; }

We have used the OLEDB .NET Data provider in this case with a disconnected approach and the data source is the online.mdb file stored in the local drive. In this handler we have created the connection string, the command string, the OleDbDataAdapter object and the DataSet object. Next we have filled the DataSet with the table from the database and extracted the Table in a DataTable object referred to by dt. Then we have created a new DataRow object. We have initialized the row fields with the text entered in the corresponding textboxes containing the students information. Next we have added the row to the DataTable object referred to by dt. Then we have created an OleDbCommandBuilder object and updated the database using the Update( ) method. After doing this we have used the static method called Redirect( ) of the Response class to browse to a different page called Confirm.aspx. We can create the Confirm.aspx file by simply adding another Webform (.aspx file) to the project (through Solution Explorer), naming it Confirm.aspx and adding the text to it. Compilation We are now all set to compile the program. We need to do so using Build | Compile menu option. On compiling the HTML tags present in the WebForm1.aspx file and the code in the WebForm1.aspx.cs file called the code-behind file, a new intermediate file would get created. This file contains a class written in C# and is derived from the WebForm1 class that contains code to emit HTML from ASP.NET tags. This class gets compiled to a Registration.dll file. Here we have chosen to deploy our files on the local machine. But if we plan to deploy it on the Web Server, we need to copy the .aspx and .aspx.cs files into the virtual directory. We can also copy the Registration.dll file but this is optional because if the file is not deployed, it gets created and cached in the web server as soon as the first request is made. The process of compilation is shown in the following figure.

Let us now see the WebForm1.aspx file in HTML view. This file contains the ASP.NET tags for our application. The first line of this file is known as the @Page directive. This directive is given below.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

<%@ Page Language = "c#" Codebehind = "WebForm1.aspx.cs" Inherits = "Registration.WebForm1"%> This directive defines general attributes and compilation settings for ASPX files (for example, C# or VB). It also specifies the code behind file and the base class from which the intermediate class was derived. Sending A Request Now, if a client wants to send a request for executing the program that we developed, he can do so by starting the browser and mentioning the following URL http://localhost/Registration/WebForm1.aspx This sends a request to the server. On the server, an object of the class present in Registration.dll would get created and an event handler called Page_Load( ) would get called. This handler outputs HTML, which is then rendered on the client browser. Now whenever a student enters information into the registration form and clicks on the Submit Form button, he is presented with the page shown in the following figure.

Article: C#- Code Access Security


Code access Security is a new concept brought in by the .NET framework. Code access security essentially involves granting permissions to an assembly. Code access security uses the location of assembly and other information about the identity of code as a primary factor in determining permissions to be granted to the assembly. This information about the identity of an assembly is called evidence. Once loaded in runtime, the code starts executing in the restricted environment depending upon permissions granted to it. If the code is not trusted enough to run or runs but performs an action for which it has no permissions, then a security exception is thrown. The code access security system means we can stop running of malicious code and also restrict the code to run in a restricted environment where we are sure that it wont do any damage to the resources. Let us now see few cases where code access security becomes crucial.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Suppose an organization is working with some extremely important data, we would use code access security system to state which code is allowed to access the database and which is not. Similarly if we run an application from a network drive and it tries to access the file on a local drive an exception must be thrown. This can be done using code access security system. It is important to know that code access security protects resources like local disk, network, user interface from malicious code. It is not a tool for protecting software from users. Code access security works on the basis of Code Groups and Permissions. Code Group Code groups are a grouping of assemblies with same privileges. For example, code groups include Internet and Intranet. The group Internet includes code downloaded from Internet and the group Intranet includes code sourced from LAN. The information based on which the assemblies are grouped is called evidence. The assembly loader is responsible for collecting the evidence at load time based on where the code is loaded from. The CLR ships with seven types of evidence. - Zone: Region from which the code originated - Site: Web site from which the code was downloaded - URL: Specific location of the code - Application Directory: Location of the assembly - Strong name: The unique name for the code - Publisher: Publisher of the code - Hash value: Hash value for the assembly Collectively these seven types of evidence are called host evidence as they are implemented by the host environment. Permission Permission means authorization to perform actions. These actions often involve accessing certain resources. These permissions are exposed programmatically through the System.Security.PermissionSet namespace. Whenever a code is running, the CLR has to decide which permissions to grant that code and which ones to deny. The CLR decides which permissions to grant and which to deny by doing a simple trick, it checks whether the caller of our code has the permission perm1 or not. CLR repeats this process for the callers of our assembly till there are no more callers are left. If all the callers have that permission, our code is granted the requested permission. This can be better explained by the following example. Consider an assembly A. which calls Assembly B, B in turn calls C. C finally calls our assembly D. If our assembly demands a certain permission say perm1, the CLR will first check whether our assembly's caller (C in this case) has that permission. If it has, the CLR further looks whether B has it or not. If B has that permission, the CLR finally checks to see whether the root assembly A has the demanded permission. If all of the preceding assemblies C, B and A have that permission, our assembly is also granted the permission. Even if any one intermediate assembly does not have the demanded permission, our assembly is denied perm1. This process of checking permissions of all the parent assemblies is known as Stack Walking. Stack Walking is a costly activity, but considering the gains it has to offer in terms of security implementation, Microsoft decided to implement it in the CLR. Assemblies demand permissions when it is clear that without those permissions the assembly will not execute. Demanding permissions is done programmatically. The following program shows us

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


how. Our program will read a file from the local disk and display the first line. In our program we will demand complete access to the C:\ drive. If the access demand is denied, an exception will be raised which we will catch. Create a Windows based application and design the form as shown below.

Name the text box as t, Read button as bread and Exit button as bexit. Add the following code in the constructor of the Form1 class just below the call to InitializeComponent( ) method. FileIOPermission fp ; try { fp = new FileIOPermission( FileIOPermissionAccess.AllAccess, @"C:\" ); fp.Demand( ) ; } catch ( Exception e1 ) { MessageBox.Show ( e1.Message ) ; } Here we create a reference of type FileIOPermission. We have inisialised the reference in the try block. In the constructor we have passed the AllAccess enumerated type to specify that our code needs complete access permissions to the C:\ drive of the machine where our application is to execute. The constructor is followed by a demand for the above permission. It is necessary to place the demand part in a try-catch block because if the permission is denied, the Demand( ) method would raise an exception and our program would be terminated abruptly. Now add a handler for the Read button. Write the code as shown below to it. private void bread_Click ( object sender, EventArgs e ) { StreamReader sr = new StreamReader ( "c:\\hi.txt" ) ; t.Text = sr.ReadLine( ) ; sr.Close( ) ; } We have created a stream reader object to read the c:\hi.txt file. Next we have read a line from that file and displayed it in the text box t. Now add a handler for the Exit button and call Dispose( ) method from it. Calling Dispose( ) would terminate the application if the Exit button is clicked. Finally add the following declarations at the beginning of the program.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


using System.IO ; using System.Security ; using System.Security.Permissions ; Run this application in various scenarios, like on the local machine with security on, local machine with security off, copy it to another machine and run it from the remote computer. Configure security policy to give full trust for code from the remote machine and run the program. Also try out running the program from the remote computer with security switched off. To switch the security on/off we can use the caspol utility that is shipped with Visual Studio.NET. This exercise will give you a better insight into the working of code access security.

Article: C#- ASP.NET security


ASP.NET security is mostly concerned with building secured sites that serve up pages only to authorized users. There are certain sites on the net that require login before displaying certain pages. These sites must implement some application level security to identify authorized users. This application-level security is provided using ASP.NET. It works in conjunction with IIS, the .NET platform and the underlying operating system security services. Whenever a client tries to connect to a website, it has to make a request to the Web Server for a particular page. This request is known as a webrequest. To implement the security at application level, the application needs to take two actionsidentify the person who has made the request to the web server and specify who can access which pages. This action of identifying the caller of web page is known as authentication. Once authentication is done, it is decided which pages the caller can view. This is known as authorization. ASP.NET supports four types of authentication and authorization mechanisms. - Windows authentication - Passport authentication - Forms authentication Let us discuss them one by one. Windows Authentication This type of authorization is best suited for intranet applications. A user will be able to access a requested resource only if he has a valid and active account on Windows. Moreover that account needs to have permissions to access the specific resource. This type of authentication is very secured since it uses hash algorithms to encode and decode clients credentials. However there are a few problems, this type of authentication does not work through most proxy servers, firewalls, and some routers. Hence this technique is not very suitable for Internet applications. Setting up Windows authentication is simple. Just make the following settings in the web.config file of your project. <configuration> <system.web> <authentication mode="Windows" /> <identity impersonate="true" /> <system.web /> <configuration />

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


These entries ask ASP.NET to use Windows authentication with Identity impersonation for the authentication. Simply doing this will not work if IIS is configured to accept anonymous requests to this website (by default IIS accepts anonymous requests to any Website). To turn off anonymous access to this site, follow the instructions given below. (a) Start Internet Services Manager from Administrative tools in the Control Panel. (b) In the IIS, explore the branch with name same as your local machine name. (c) Explore Default WebSites. (d) Locate the Website we want to authenticate using Windows authentication. (e) Right click on it and select Properties. Property pages would get displayed. (f) Select the tab named Directory Security (g) Click on the edit button inside the group box named Anonymous access and authentication control (h) In the following dialog, uncheck Anonymous access check box. Make sure Integrated Windows Authentication check box is checked. (i) Click OK to dismiss the dialogs. This process will force IIS to pop up Windows authentication dialog before displaying the web page requested.

This can be done programmatically by modifying the <authorization> section of the web.config file. Make the following changes to the authentication section <configuration> <system.web> ::: <authorization> <deny users="?" /> </authorization> ::: </system.web> </configuration>

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


We instruct IIS to not to allow any users without proper authentication. The tag deny users=? will stop all unauthenticated users from accessing the website. Passport Authentication Passport authentication is a service provided by Microsoft. This service allows us to implement single SignIn for multiple applications or Websites that want to authenticate users. The user is expected to use only one user name and password to access all the sites more over, the user need not re-SignIn whenever he switches from one site to another (provided both sites support Passport authentication). For example, if site1.com and site2.com both support passport authentication, then if a user visits site1.com, sign in the site and then decide to visit site2.com, you will be automatically authenticated on the basis of the credentials you presented at site1.com. This is possible because whenever you sign into a Passport service supporting site, the service creates a secure cookie into our machine. Later when we visit another Passport supporting site, our browser presents this cookie. This cookie indicates that we have already been authenticated and no new authentication is required. To setup Passport authentication, following configuration needs to be added to the web.config file. <configuration> <system.web> <authentication mode="Passport" > <Passport redirectUrl="internal|url" /> <authentication /> <system.web /> <configuration /> But Passport service is not free. If we want to support Passport authentication on our website, we will have to subscribe to it. Forms Authentication Form based Authentication is best suited where very high degree of security is not required. We can use our own login form, replacing the default login provided by Windows. In almost all situations we will allow anonymous access to our website, since authentication is done by ASP.NET instead of IIS. ASP.NET first checks whether there is any authentication cookie present in the request header. If cookie is present, we know that the user is already authenticated and his identity is present in the cookie. Otherwise the user is automatically redirected to our custom login page. The user then presents his login credentials. If the user is authenticated, we place a cookie in the request header and pass it on to ASP.NET other wise access is denied. Form based authentication is configured in the web.config file. The <authentication> section carries information regarding cookies, password formats, list of registered users, etc.

Article: C#- The Regular Expressions


Almost every application has search facility, where we type a string in a dialog box and search it in the given text. We can replace the string with specified string too. We can provide this kind of facility in our program using methods of the System.String class. But if we wish to search how many times a string is repeated or the strings starting and ending with a given character or the

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


strings representing dates in a given range or strings having repeated characters in it, etc. then searching becomes difficult. For this kind of situation regular expression language is of great use. In regular expressions language we can write search expressions. Using these search expressions we can extract, delete or replace a substring. We can also split a string into substrings. One of the most common usages of regular expressions is to validate the user input such as email address, credit card number, ZIP code, etc. Another common use of regular expression is screen scraping. Suppose a web site extracts real time information from a database and displays it on an HTML page. Information can be a weather report, stock exchange prices, air ticket reservation and so on. If we want to use this information in our application we would access the HTML page. What we would get is the HTML script. We would need to parse the script to obtain the required information. Regular expressions can be effectively used in this task. The regular expressions language consists of literals and metacharacters (sometimes called escape sequences). A metacharacter acts as a command to the regular expression parser. A parser is the engine responsible to understand and interpret the regular expression. The System.Text.RegularExpressions namespace provides classes to create and use the regular expressions. Let us take an example. The metacharacter '\b' is used as a word boundary indicating either beginning or end of a word. If we wish to search a word that starts with character a then the search expression will be @\ba. To search for a word that ends with characters ing the expression will be @ing\b. If we have to write an expression that searches strings starting with @\ba and ending with @ing\b, what about the characters in the middle? For this, we must use the '\S' escape sequence. '\S' stands for any character except a whitespace. So, our expression would be @\ba\S*ing\b. * here means zero or more number of characters. So the expression \S* means zero or more number of characters except the whitespace Let us use this search expression in a program. using System ; using System.Text.RegularExpressions ; static void Main ( string [ ] args ) { String instr = @It's amazing that the amount of news that happens in the world everyday always just exactly fits the newspaper." ; String pattern = @"\ba\S*ing\b" ; Match m = Regex.Match ( instr, pattern, RegexOptions.IgnoreCase ) ; while ( m.Success ) { Console.WriteLine ( m.Value ) ; m = m.NextMatch( ) ; } } This program would output amazing. The Regex class contains several methods that we can use to perform operations using the specified regular expression. Here, the string pattern contains our regular expression. The static method Regex.Match( ) finds the string matching to the specified pattern in the input string instr. Matching is done case-insensitively since we have mentioned the enumerated value RegexOptions.IgnoreCase. The Match( ) method returns a reference to an object of the Match class that we have collected in m (dont get confused

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


between the Match( ) method and Match class). If the Match( ) method succeeds, the Value property of the Match class contains the resultant substring and the Success property contains true. Another property of Match class called Index contains the index of the first character of the resultant substring. To locate and display all the matching substrings, we have called the NextMatch( ) method of the Match class. The NextMatch( ) method returns the Match reference with the next matching substring. If the NextMatch( ) method is called after the last match is found, it would fail and the Success property would contain false. Instead of m.Value we can directly pass m to WriteLine( ) method because it calls the ToString( ) method overridden in Match class. The ToString( ) method of Match class returns the same substring that the Value property holds. The following table displays the metacharacters we can use in regular expression. Expression . [character] [^characters] [charX-charY] \w \W \s \S \d \D ^ $ \b \B * + ? {n} {n,} {n,m} () (?<name>) | Meaning Matches any character except \n Matches a single character in the list Matches a single character not in the list Matches a single character in the specified range Matches a word character (word character is any alphanumeric character and underscore) Matches a non-word character Matches a whitespace character Matches a non-whitespace character Matches a decimal digit Matches a non-digit character Beginning of the line End of the line On a word boundary Not on a word boundary Zero or more matches One or more matches Zero or one matches Exactly n matches At least n matches At least n but no more than m matches Capture matched substring Capture matched substring into group name Logical OR

We would now write a program that splits a given input string using the specified delimiter. Suppose we have collected e-mail addresses separated by semicolon ( ; ). Then we can split the string into single address as shown in the following code. String instr = "rucha_200@hotmail.com;malviya@yahoo.com;rdeshpande@hotmail.com" ; Regex ex = new Regex ( ";" ) ; string [ ] str = ex.Split ( instr ) ; foreach ( string s in str ) Console.WriteLine ( s ) ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


We have created an object of the Regex class passing to its constructor the delimiter string i.e ;. The Split( ) method of the Regex class splits the string passed to it. It uses the pattern passed to the Regexs constructor. The Split( ) method splits the string into substrings and returns an array of the substrings. We have collected the same and displayed. We can use multiple delimiters to split a string. The multiple delimiters must be separated by a pipe ( | ) character. We saw how to find a pattern in a string using the Match( ) and Matches( ) methods. We can use these methods to find multiple patterns in a string too. For example, String instr = @"The brain is a wonderful organ, it does not stop until you get into the office." ; Regex ex = new Regex ( "(is)|(in)|(it)" ) ; MatchCollection mc = ex.Matches ( instr ) ; foreach ( Match m in mc ) Console.WriteLine ( "{0} found at position {1}", m, m.Index ) ; We have specified the multiple patterns is, in and it separated by |. This will display multiple instances of the given patterns along with their positions. The character i is common in all the patterns, so alternatively, we can use a regular expression as "i(s|n|t)". Regular expressions language can be effectively used for creating applications like HTML processing, HTTP header parsing, etc. Here is an example that checks the HTML script for the href tag used for specifying links. String instr = @"<HTML> <A href = ""freevb.htm"">Free VB.NET source code</A> <A href = ""freec.htm"">Free VC++ source code</A> </HTML>" ; string pattern = @"href\s*=\s*(?:""(?<1>[^""]*)""|(?<1>\S+))" ; MatchCollection mc = Regex.Matches ( instr, pattern,RegexOptions.IgnoreCase ) ; foreach ( Match m in mc ) Console.WriteLine ( m ) ; Interpreting the expression used to find hrefs is now your job. We can use the brackets [ ] to find a set or range of characters in a string. For example, the expression [aeiou] can be used to match any vowel in the string. On the other hand, if we use ^ as the first character in [ ] then it finds characters other than those specified. For example, [^aeiou] will find all the consonants. To find characters that fall in a range, we can use dash () to separate the two characters. For example, the expression \d[0-25-9] will find any digit (\d is used to match a digit) in the string that is in the range 0 to 2 or 5 to 9. Groups And Captures One of the features of regular expressions is that we can group characters together. For example, suppose a training institute has maintained a list of machine names and their IP addresses in a string. We can create two different groups. One group will contain machine names from all the strings and second will contain IP addresses. Following program illustrates how to create and use groups. using System ; using System.Text.RegularExpressions ; static void Main ( string [ ] args ) {

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


string instr = "User1 192.168.90.45\n" + "User2 192.168.90.46\n" + "User3 192.168.90.47" ; Regex ex = new Regex ( @"(?<name>\S+)\s"+@"(?<ip>(\d|\.)+)" ) ; MatchCollection mc = ex.Matches ( instr ) ; foreach ( Match m in mc ) { Console.WriteLine ( "\nEntire string: {0}", m ) ; Console.WriteLine ( "Name: {0}", m.Groups [ "name" ] ) ; Console.WriteLine ( "IP: {0,5}", m.Groups [ "ip" ] ) ; } } The groups are always created in pair of parenthesis. Our two groups namely name and ip are noticeable by the two pairs of parenthesis.

Article C# - Printing Through .NET


Any sophisticated application would definitely have support for printing. .NET facilitates printing with the help of a PrintDocument component. Along with this we can make use of the various dialog boxes that are commonly used for printing. The PrintDocument Component .NET supports printing through methods and properties of the PrintDocument component. The PrintDocument component is available in the Toolbox and when added to a form, it appears in the component tray at the bottom of the Windows Forms Designer. This is because the PrintDocument component is not visible at runtime. The PrintDocument class represents the PrintDocument component and falls under the System.Drawing.Printing namespace. Typically in a printing application we call the Print( ) method of the PrintDocument class. It also contains properties such as DefaultPageSettings, which gets or sets page settings that are used as defaults for all pages to be printed, PrinterSettings, which gets or sets the printer that prints the document. The class contains events like BeginPrint, EndPrint and PageEvent. BeginPrint is raised when the Print( ) method is called and before the first page of the document is printed. Here we can do any initializations if needed. EndPrint event is raised when the last page of the document has been printed. We can do cleaning up jobs here. The PrintPage event is raised when its time to print the current page. We can write code in the handler of this event to do the desired printing. Hence the order of events raised when Print( ) method is called is BeginPrint, PrintPage and then EndPrint. In the following sections, we have programmed simple examples that illustrate how to use the PrintDocument component to achieve printing. Printing A Salary Slip Let us see an example where we wish to print salary slip of an employee. Here we have created a Windows Form Application named Salaryslip. We have added 5 textboxes to the form to gather information about the employeea Name textbox named name, a Month textbox named month, a Gross Salary textbox named sal, a Tax textbox named tax and a Total textbox named total. We have added these textboxes to collect information about an employee like his name, his salary, the tax he needs to pay, etc. Next we have calculated his salary according to the tax. We have also added two buttons to the forma Print button named print and a Calculate button named cal. As soon as the user clicks on the Calculate button the salary gets calculated and if he clicks on the Print button the salary slip gets printed. Next we have added the PrintDocument component to our form. It gets added in the component tray. We have changed the name of the component from PrintDocument1 to mypdoc.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


We have added an event handler called cal_Click( ) to handle the Click event of the Calculate button. This handler is shown below: private void cal_Click ( object sender, System.EventArgs e ) { int t = int.Parse ( sal.Text ) - int.Parse ( tax.Text ) ; total.Text = t.ToString( ) ; } Here we have subtracted the tax from the gross salary and stored it in an integer variable called t. Then we have set the Text property of the textbox named total to t (we converted t from an integer to a string). On clicking the Print button the event handler called print_Click( ) would get called. This handler is shown below: private void print_Click ( object sender, System.EventArgs e ) { mypdoc.Print( ) ; } In this handler we have simply called the Print( ) method of the PrintDocument class. Whenever the Print( ) method is called the events are raised. We have not added handlers for the BeginPrint and EndPrint handlers. We have added a handler for the PrintPage event. If we double click on mypdoc in the component tray of the Windows Form Designer, the mypdoc_PrintPage( ) event handler gets added automatically to the code. This handler is shown below: private void mypdoc_PrintPage ( object sender, System.Drawing.Printing.PrintPageEventArgs e ) { Graphics g = e.Graphics ; SolidBrush b = new SolidBrush ( Color.Black ) ; Pen p = new Pen ( Color.Black, 3 ) ; Font f = new Font ( "Arial", 10 ) ; g.DrawString ( "Name", f, b, 30, 50 ) ; g.DrawString ( empname.Text, f, b, 130, 50 ) ; g.DrawString ( "Month", f, b, 30, 70 ) ; g.DrawString ( month.Text, f, b, 130, 70 ) ; g.DrawString ( "Gross Salary", f, b, 30, 100 ) ; g.DrawString ( sal.Text, f, b, 130, 100 ) ; g.DrawString ( "Tax", f, b, 30, 120 ) ; g.DrawString ( tax.Text, f, b, 130, 120 ) ; g.DrawString ( "Total", f, b, 30, 140 ) ; g.DrawString ( total.Text, f, b, 130, 140 ) ; Font f1 = new Font ( "Arial", 15, FontStyle.Bold ) ; g.DrawString ( "KNK Pvt Ltd", f1, b, 50, 10 ) ; g.DrawRectangle ( p, 14, 4, 180, 175 ) ; p.Width = 2 ; g.DrawRectangle ( p, 22, 95, 165, 75 ) ; }

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


PrintPageEventsArgs provides data for the PrintPage event. Using this class we have retrieved the Graphics object using which we will do the painting. Next we have created Pen, Brush and Font objects. Then using these objects we have printed the strings. Run the program. Enter the salary and tax and click the Calculate button. The result would get displayed in the Total text box. Figure 1 shows the form with salary details.

Figure 1 As soon as we click the Print button, the Printing dialog indicating the number of page that is getting printed gets displayed. The salary slip that gets printed is shown in Figure 2.

Figure 2

Article C# - Form Authentication


ASP.NET has come with a new feature called Form authentication. Form authentication involves asking the user his credentials and authenticate him to access the web pages if his credentials are ok. Form authentication has greatly reduced the quantum of code that checks whether the user has logged in or not, if he has not then redirects the user to the login page and if the login is successful, redirects the user to the page he has requested. All this is managed by making entries in Web.config file where we can specify the login page and the pages that are protected.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


The first time the user tries to access the protected pages ASP.NET asks him to login. If the login is successful, ASP.NET grants him an authentication ticket in the form of a cookie and then allows the user to the access the protected page. If the user requests the page again and again this cookie allows him to access the pages without having to log in. Let us now implement the form authentication in a program. Our program will have a default page, a login page and a protected page that is displayed only if the login succeeds. First of all to create the forms, create an ASP.NET Web application. Rename the web form to public.aspx. Also change the CodeBehind tag to public.aspx.cs. We would keep the public page simple. It would contain only a button View Page on clicking which it would open the protected page. But before opening the page, it would ask username and password to the client. Add two more web forms to the application namely protected.aspx and login.aspx. Add a label on the protected page that would display a message on it. Add two text boxes and a Login button to the login page. The text boxes would take user name and password from user. On clicking the Login button the credentials of the client would be checked and the client would be redirected to the protected page. Add the Click event handler for the View Page button in the public.aspx file. Add the following statement to the handler. Response.Redirect ( "Secured/Protected.aspx" ) ; The Redirect( ) method redirects the client to the new URL specified in it. Open the Web.config file that gets created in the application folder. Add the statements to the <authentication> section so that the <authentication> section would look like this: <configuration> ... <system.web> <authentication mode="Forms" > <forms loginUrl = "login.aspx"> <credentials passwordFormat="Clear"> <user name="ypk" password="kicit" /> </credentials> </forms> </authentication> <system.web /> <configuration /> The <authentication mode="Forms"> indicates that the authentication mode for this website is Forms. This means that if there is no authentication cookie in the request header, the request has to be redirected to the login page. If the cookie is found, access to the requested page is granted. The <forms> section contains the login URL from where an identification cookie has been placed. Next statement indicates configuration for password. The following list specifies the correct username and password. We can specify more than one username-password entries. Now add the Click event handler for the Login button. Add the following code to it. if ( FormsAuthentication.Authenticate ( uid.Text, pwd.Text ) ) FormsAuthentication.RedirectFromLoginPage ( uid.Text, false ) ; The Authenticate( ) method would return true if the username and password match to one specified in the Web.config file. If it does then the client would be directed to the protected.aspx

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


page. The FormsAuthentication class is a member of the System.Web.Security namespace. So we must declare it at the beginning of the program. Create a virtual directory Secured inside the application folder. Copy protected.aspx and Web.config files to this folder. Open the Secured/Web.config file and add the <authorization> section to it. The contents of the Web.config file are given below: <configuration> <system.web> <authorization> <deny users="?" /> </authorization> </system.web> </configuration> In the authorization section we have indicated that every anonymous user has to be denied access to the page. Run the application. The default page would get displayed as shown in the following snap shot.

Click the View Page button. It will take you to the login page as shown below.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Enter the username as ypk and password as kicit. Click the Login button. The protected page would get displayed. Now request the default page again and click the View Page button. This time the protected page would get displayed directly without asking the username and password.

Article C# - ASP .NET Services - I


A Web service is an application stored on a machine that can be accessible through another machine over Internet or LAN. Even before introduction of Web services we were able to access applications or business logics across the net. Therefore, before starting with Web Services we must know the need that gave rise to Web services. To begin with we would discuss the four Ps that are important in doing business using computers. Partners: Every business needs partners and that is how they make enormous amount of profit. Profit: No business can run without making profits. Profit must increase every year to make the business successful. Productivity: Computer as its very nature can be used to improve productivity of a business and hence the profit. Programming should be cheap: If computer is to improve productivity of the business programming and maintenance cost should decrease.

Let us now understand the current business scenario. We would take an example of an airlines company. The customers of the airlines company may access the company through personal computers, PDAs or simple phones. The airlines company may communicate with partners such as a food company or the bank. Partners and clients would still be there but the way they would interact would be different. The airlines company would have a web server to which clients would send requests for ASP or HTML pages. The request would be in form of HTTP request. The Web Server would communicate with the business logic in the application server and use the data bases to store the data. The Web Server would respond by sending HTML back to the clients. The food company and bank organization would have application servers running business logic in the form of components. They would also have data base servers for secured and efficient data storage. If airlines company is to access the business logic exposed by application servers of food company and bank it would do so through Remote Procedure Calls. Also the food company and bank may also be interacting with each other.
Different client organizations would use various software and programming model. Even the Operating Systems installed on the client devices would be different. The client would like to interact with the Web Server using these devices. The Web Server of the Airline company may either have IIS, JWS or Apache server running appropriate sever side scripts. The food company may have COM+ model on their Application servers with business logic implemented as COM components and MS-SQL database. The bank organization may have J2EE model with business logic implemented as EJB components running on their Application Servers and data base in Oracle. In a distributed computing architecture the clients form the Presentation layer and the DCOM components, EJB components, CORBA components and DCOM components form the Business layer. The clients has to cross the firewalls to access components. Firewalls ensure that communication is done through a specified port and data format. The external applications,

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


databases and legacy system form the Data layer. In our Airline example, the main reason of conflict is that all the three interacting companies (airlines company, food company and bank) have different standards. The airlines company has CORBA components installed. The food company has DCOM components and Bank has EJB components. The problems faced in developing these components are as follows: Language: DCOM components could be written only in VC++ or VB, whereas, EJB components could be written only in Java. Infrastructure: CORBA components need ORB libraries and services. DCOM components need COM libraries and services, and EJB components need J2EE Services. Layout of Objects: Layout of CORBA components differ from DCOM components which in turn differs from EJB components. Description: CORBA components are defined using CORBA Interface Description Language, DCOM components are defined using Microsoft Interface definition languages and EJB components are exposed as interfaces. Discovery Standards: CORBA components are discovered using the CORBA registry, DCOM using the Registry and EJB using the Java Native Directory Interface.

The conflict between these models occur mainly due to the Wire Protocol and Data Standard. This was different for each of the infrastructure. CORBA uses IIOP (Inter Internet Object Protocol), DCOM uses RPC (Remote Procedure Calls) and EJB uses RMI (Remote Method Invocation) / IIOP. All these protocols are non-standard protocols and hence are not followed by all companies. These existing Distributed Computing solutions suffer from various problems. For example, DCOM is a proprietary protocol. It does not support interoperability and it has firewall problems because DCOM transfers data in binary format and it uses many ports to call remote functions. CORBA uses IIOP protocol, which is non-internet friendly. EJB requires very costly infrastructure. Moreover all these object models require their client to use the same libraries as that used on server. This makes a very tight coupling between client and the component. If component is changed and written using new object model the client will also have to change. To address these needs, XML Web services came into existence and were introduced as part of ASP.NET, which is part of the .NET Framework. Web services are based on open Industry standards, such as HTTP, XML, and SOAP. Using these open standards, Web services deliver application functionality across the Web to any type of client, on any platform. XML Web services are based on open Web standards that are broadly supported and are used for communication and data formats. XML Web services provide the ability to expose application logic as URI-addressable resources, available to any client in a platform-independent way. Web services are self-describing. Any clients incorporating open Web standards for communication and data formatting (HTTP and XML) can query dynamically for Web service information and retrieve an XML document describing the location and interfaces supported by a particular XML Web service. These open standards make Web services indifferent to the operating system, object model, and programming language used. Web services are accessible to disparate systems, supporting application interoperability to an unprecedented level thanks to the ubiquity of HTTP and XML. Instead of communicating in binary formats between applications, Web services use XMLencoded messages. Because XML-based messaging is used for the data interchange, a high level of abstraction exists between a Web service implementation and the client. This frees the client from needing to know anything about a Web service except for its location, method

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


signatures, and return values. Additionally, most Web services are exposed and accessed via HTTP, virtually eliminating firewall issues. We would see more about Web services, the protocols they use and the way they are discovered in the next article.

Article C# - ASP .NET Services - II


In the last article we saw the distributed computing architecture, the different solutions for it along with their pros and cons and the reasons why Web services came into existence. In this article we would see more issues regarding Web services. Here we go SOAP The only requirement of Web services is that both the communicating parties should have SOAP (Simple Object Access Protocol) servers. SOAP is built upon HTTP and uses XML. It describes function calls and their parameters using XML. The .NET Web services use this protocol for transfer of data. A Web service is a piece of code that resides on the net server. This code can accept request from the clients using HTTP and XML. Once a Web service is put on the Internet it can be consumed or used by any client across the Internet that uses HTTP and XML. We can use a Web service already available on net in our web site. For example, a book store can have a Web service that takes an ISBN number of book and returns all the details of the book to the user. This Web service can be used by many sites, which provide information related to books. Apart from being generalized, the main advantage of using SOAP protocol is that SOAP can support a rich set of data types including the primitive data types, enums, classes, structs, ADO.NET data sets and arrays of these types. I must note here that the Web services can be built in any .NET compliant language like VB.NET, C# or Managed C++. XML Web services are based on open Web standards that are broadly supported and are used for communication and data formats. XML Web services provide the ability to expose application logic as URI-addressable resources, available to any client in a platform-independent way. Web services are self-describing. Any clients incorporating open Web standards for communication and data formatting (HTTP and XML) can query dynamically for Web service information and retrieve an XML document describing the location and interfaces supported by a particular XML Web service. These open standards make Web services indifferent to the operating system, object model, and programming language used. Web services are accessible to disparate systems, supporting application interoperability to an unprecedented level thanks to the ubiquity of HTTP and XML. Because XML-based messaging is used for the data interchange, a high level of abstraction exists between a Web service implementation and the client. This frees the client from needing to know anything about a Web service except for its location, method signatures, and return values. Additionally, most Web services are exposed and accessed via HTTP, virtually eliminating firewall issues. UDDI & WSDL Web services are discovered using the UDDI (Universal Description Discovery and Integration). We would look at UDDI in more detail later in the article. Any client can use a Web service. Hence, when we create Web services we must provide the information programmers need to know. For example, we must provide information about the methods available, types of parameters and return values of methods, ways of calling these methods, how the web service should be used, etc. This information is available through a WSDL file standing for Web service Definition Language. This file contains XML schema that describes the web service.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Benefits of Web Services One of the benefits of using Web services is that we have a broader reach. No matter what the infrastructure is, if the object is exposed as Web service the communication becomes easier. Another benefit is that even within enterprise the objects can be exposed as Web services. Web services hence facilitate Business to Business (B2B) communication and Enterprise Application Integration. How to Use Web Service Web services are deployed on Web Servers. Once a Web service is put on the Web any client that understands HTTP and XML can use it. Here we have taken an example of the IIS Web Server. The IIS has a built-in Soap Server. IIS listens for client requests on port 80. The WSDL file can also be kept on the same web server. The client who wants to use the web service adds the link to WSDL file in VS.NET IDE. VS.NET then creates a proxy, which contains the methods with same name as those were exposed by the Web service. These methods contain logic to convert the data passed by the client to SOAP request. The client calls method in the proxy class. The proxy creates a SOAP envelope and sends it to IIS. When IIS detects that it is a SOAP message IIS passes the message to the SOAP server, which in turn invokes methods in the Web service. The return values trace the path back from the server, get converted into SOAP and are sent to the proxy and finally to the client. Like any other resources on the Internet, it would be virtually impossible to find a particular Web service without some means to search for it. Web service directories provide central locations where Web service providers can publish information about their Web services. Such directories can be accessed directly or programmatically, which provide search results in response to queries from potential Web service clients. The UDDI is such a location that defines a standard way to publish and discover information about Web services. Using the browser we make a request to search for the Web service. The UDDI responds with listing of the services. The list of services contains URIs of either discovery documents or WSDL documents. If we get this we can get the WSDL file and then the client creates a proxy object based on the details provided by the WSDL. Once we have the proxy object we can call the methods of the Web service. Creating A Web Service After understanding the need of web services, how they evolved and how they make communication possible between heterogeneous systems, let us now see how to build and consume a Web service. We would build a simple Web service that exposes two methods. One method would convert temperature in Celsius to Fahrenheit. Another method would convert temperature in Fahrenheit to Celsius. The steps to create the Web Service are given below: (a) Open Visual Studio.NET IDE. Select 'File | New | Project | Visual C# Projects'. Select 'ASP.NET Web Service' as project template. Provide the project name as 'webservice' and click OK. The location of this project would be 'C:\Inetpub\wwwroot' folder. The 'Inetpub' folder is present on the local drive if IIS is installed. (b) A form would get displayed. Right click on it and select 'View Code'. You would see a commented HelloWorld( ) method as shown below: //[WebMethod] //public string HelloWorld( ) //{ // return "Hello World" ; //} Uncomment the code and execute the program by pressing Ctrl + F5. You would see the output in IE as shown in the following screen shot.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Here, HelloWorld is a Web service. The attribute [WebMethod] enables the method from being called by the clients through network.We would add our web methods and create a Winform client next time.

Article C# - Creating And Consuming Web Services


When we create a Web service project named 'webservice' a namespace having name webservice and a class having name Service1 would get created. Change the class name to temperature. Add the public methods ctof( ) and ftoc( ) to the class temperature. These methods are given below. [ WebMethod ] public double ctof ( double c ) { double f = ( c * 9.0 / 5.0 ) + 32 ; return f ; } [ WebMethod ] public double ftoc ( double f ) { double c = 5.0 / 9.0 * ( f - 32 ) ; return c ; } A web service class can contain methods that can be called by client or the methods that are used internally within the class. To expose a method as a web service so that they can be called by the clients we have to add an attribute [ WebMethod ] to it. Note that the methods to be exposed as Web service must be declared public. Now compile and execute the program by pressing Ctrl + F5. You will see a window as shown in the following figure.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Note that the 'Address' bar contains the URL 'http://localhost/webservice/Service1.asmx'. The '.asmx' file acts as an entry point to the Web service. The statement written in the 'Service1.asmx' file is given below: <%@ WebService Language="c#" Codebehind="Service1.asmx.cs" Class="webservice.temperature" %> Here, WebService is an ASP.NET tag, which states that the code written in the specified class is to be exposed as a web Service. The Codebehind tag specifies the name of source file in which Web service is defined. We can omit this tag and write the Web service code in '.asmx' file itself. In fact, defining the Web service in '.asmx' file itself facilitates the deployment of the service. The 'Service1.asmx' file contains fully qualified name of class (webservice.temperature) in which our methods ctof( ) and ftoc( ) are defined. When the '.asmx' file is executed all those methods which are exposed as Web service using the [ WebMethod ] attribute get displayed in the output window. If we click the ctof link a page as shown in the following figure gets displayed.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Enter a number representing the temperature in centigrade and click the 'Invoke' button. The ctof( ) method would get called and the output would get generated in XML. You would appreciate how testing a Web service is being made easy. When we build the project the 'bin' folder gets created in the 'Debug' folder and 'webservice.dll' gets created in it. We would now create a Winform application that would use this Web service. Create the application and design the form as shown in the following figure.

Name the text box as ttemp, label as ltemp and buttons as cb and fb respectively. We must add a reference to the 'webservice.dll' we are going to use in this application. For this, right click on the project name in the 'Solution Explorer' and select 'Add Web References' from the pop-up menu. The window given below would appear.

Enter the address as 'http:\\localhost\webservice\Service1.asmx'. To use a Web service, which is available in different machine, say User1, add its web reference by specifying the URL as http://User1/webservice/Service1.asmx. Click the arrow present on the right side of the 'Address' text box. A dialog box displaying a page with links to the web methods gets displayed. Click the 'Add Reference' button on the dialog box. On doing this, a folder 'WebReferences\localhost' gets created in the project directory. In the 'Localhost' folder four files namely, 'Reference.cs', 'Reference.map', 'Service1.wsdl' and

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


'Service1.disco' get generated. The 'Reference.cs' file contains the proxy class discussed in the last article. The 'Reference.map' file contains the reference in the form of URLs of the '.asmx' and the discovery files. The files 'Service1.wsdl' and 'Service1.vsdisco' are the WSDL and discovery files respectively. By default the proxy class gets defined in the WSclient.localhost namespace. Instead of the localhost name we can give some meaningful name to the namespace. We can rename the localhost namespace from 'Solution Explorer'. For this, right click the localhost name and select 'Rename' from the pop-up menu. We would give the namespace name as tempservice. Let us now add Click event handlers for both the buttons on the form. These handlers are given below. private void cb_Click ( object sender, System.EventArgs e ) { temperature t = new temperature( ) ; double f = Double.Parse ( ttemp.Text ) ; double d = t.ftoc ( f ) ; ltemp.Text = d.ToString( ) ; } private void bf_Click ( object sender, System.EventArgs e ) { temperature t = new temperature( ) ; double c = Double.Parse ( ttemp.Text ) ; double d = t.ctof ( c ) ; ltemp.Text = d.ToString( ) ; } In these handlers we have used the methods exposed by our Web service. We have simply created a reference to the temperature class's object and called the methods using it. Thus, using a Web service is as simple as using a class. As said earlier, the proxy class is defined in the tempservice namespace, so we must add its declaration at the beginning of the program as, using WSclient.tempservice ; Run the program. Enter temperature in Celsius in the text box and click the 'Get Fahrenheit' button. You would see the temperature in Fahrenheit displayed on the label.

Article C# - Creating ASP.NET Client for WebService


In the last article we had created a temperature web service with two methods ctof( ) and ftoc( ). The ctof( ) method converts the temperature in Fahrenheit to Celsius. and a WinForm based client for it. Now let us take a look at how to create an ASP.NET Web Form client for our Web Service. Create an ASP.NET Web Application called 'temperatureclient'. Design the web form as shown in the following figure using the controls from the Toolbox.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

We have changed the background color of the table, font and font size 'Build Style' option. Select this option from the pop-up menu that appears after right clicking on the form. We have also changed the background colors of the label and button control by changing their respective properties. Change the names of controls as shown in the following table. Control Text box Celsius button Farehnheight button Label Name ttemp cb fb ltemp

The form stands created. Now we would add the reference of the Web Service assembly in our project. For this, right click in the 'Solution Explorer' and select 'Add Web Reference' option from the pop-up menu. On selecting this option, the 'Add Web Reference' window gets displayed. Enter the address as 'http:\\localhost\webservice\Service1.asmx' (Name of the temperature Web Service project is 'webservice'). Click the 'Add Reference' button on the dialog box. On adding the reference a folder 'Web References\localhost' gets created in the project directory containing the four files namely, 'Reference.cs', 'Reference.map', 'Service1.wsdl' and 'Service1.disco'. Rename the namespace 'localhost' to 'currencyservice'. For this, right click the 'Web References\Localhost' in the Solution Explorer and select 'Rename' from the pop-up menu. Also add the reference to the currencyservice namespace at the beginning of the program: using temperatureclient.currencyservice ; Add the Click event handlers for both the buttons. These button handlers are given below: private void cb_Click ( object sender, EventArgs e ) { temperature t = new temperature( ) ; double f = Double.Parse ( ttemp.Text ) ; double d = t.ftoc ( f ) ; ltemp.Text = d.ToString( ) ; } private void fb_Click ( object sender, EventArgs e ) { temperature t = new temperature( ) ; double c = Double.Parse ( ttemp.Text ) ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


double d = t.ctof ( c ) ; ltemp.Text = d.ToString( ) ; } In these handlers we have created a reference to the temperature class's object and called the methods using it. Run the program. Our web form would get displayed. Following figure displays the screen shot taken after the Web Service method ftoc( ) is invoked.

Synchronous & Asynchronous Communication Web Services support both synchronous and asynchronous communication between the client and the server that hosts the Web Service. Under synchronous communication, the client sends a request to the server and waits for the response. This prevents the client from performing other operations while waiting for the results. On the other hand, in the asynchronous communication, the client continues processing other tasks as it waits for a response. The client responds to the result of the service request when it becomes available. When a proxy class is created by .NET using the wsdl tool, it generates the synchronous and asynchronous versions of the methods in the class. The asynchronous versions consist of two methods having names as Beginmethodname and Endmethodname. The Begin method is used to initiate the Web Service, while the End method is used to retrieve the results. The handler cb_Click( ) is given below that shows how to make asynchronous call to the ftoc( ) method. private void cb_Click ( object sender, EventArgs e ) { AsyncCallback cb = new AsyncCallback ( ftoccallback ) ; float f = float.Parse ( ttemp.Text ) ; t.Beginftoc ( f, cb, t ) ; // Do some work }

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Here, we have firstly created a reference to the AsyncCallback delegate class. The delegate object cb represents the method ftoccallback( ). Next, we have retrieved the value entered in the text box and called the Beginftoc( ) method. To the Beginftoc( ) method, we have passed the temperature in Farehnheit, reference to the callback object, and reference to the temperature class's object. Add ftoccallback( ) as method of the WebForm1 class. This method is given below. public void ftoccallback ( IAsyncResult ar ) { temperature t = ( temperature ) ar.AsyncState ; double d = t.Endftoc ( ar ) ; ltemp.Text = d.ToString( ) ; } Here, we have obtained the reference to the temperature class's object. Using this reference, we have called the Endftoc( ) method to collect the return value, which is then displayed in the label.

Article C# - A Tryst With Printer


Even in our increasingly digital age, there remains great power in the printed word. And though most of us are not overly fond of the idea, we typically do end up printing reports as part of our applications. .NET facilitates printing with the help of a PrintDocument component. Along with this we can make use of the various dialog boxes that are commonly used for printing. We would first get familiar with the PrintDocument component The PrintDocument Component .NET supports printing through methods and properties of the PrintDocument component. The PrintDocument component is available in the Toolbox and when added to a form, it appears in the component tray at the bottom of the Windows Forms Designer. The PrintDocument component is not visible at runtime. The PrintDocument class represents the PrintDocument component and falls under the System.Drawing.Printing namespace. Typically in a printing application we call the Print( ) method of the PrintDocument class. It also contains properties such as DefaultPageSettings, which gets or sets page settings that are used as defaults for all pages to be printed, PrinterSettings, which gets or sets the printer that prints the document. The class contains events like BeginPrint, EndPrint and PageEvent. BeginPrint is raised when the Print( ) method is called and before the first page of the document is printed. Here we can do any initializations if needed. EndPrint event is raised when the last page of the document has been printed. We can do cleaning up jobs here. The PrintPage event is raised when it's time to print the current page. We can write code in the handler of this event to do the desired printing. Hence the order of events raised when Print( ) method is called is BeginPrint, PrintPage and then EndPrint. In this article we would use the PrintDocument components and its events to print the contents of a file. For this, we have created a WinForm application named TextPrint and created a simple GUI as shown in the following figure.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

We have added a textbox called filename to the form and a 'Print' button named print. We have also added the PrintDocument component to our form and renamed it to mypdoc. Add the Click event handler for the 'Print' button. Add the code in it as shown below: private void print_Click ( object sender, System.EventArgs e ) { mypdoc.Print( ) ; } In this handler we have simply called the Print( ) method of the PrintDocument class. Whenever the Print( ) method is called the events are raised. We have not added handlers for the BeginPrint and EndPrint handlers. We have added a handler only for the PrintPage event. If we double click on mypdoc in the component tray of the Windows Form Designer, the mypdoc_PrintPage( ) event handler gets added automatically to the code. This handler is shown below: private void mypdoc_PrintPage ( object sender, System.Drawing.Printing.PrintPageEventArgs e ) { StreamReader reader = new StreamReader ( filename.Text ) ; string str = reader.ReadToEnd( ) ; reader.Close( ) ; Font f = new Font ( "Arial", 10 ) ; e.Graphics.DrawString ( str, f, Brushes.Black, 10, 10 ) ; } PrintPageEventsArgs provides data for the PrintPage event. This data include the Graphics for the printer, the PageSettings for that page, the bounds of the page, and the size of the margins. We have used the Graphics object for printing the text. Here we have created an object referred to by reader of the StreamReader class by passing the file specified in the filename textbox to the constructor of the StreamReader class. To create an object of the StreamReader class we must add using System.IO to our code. Then using this object we have called the ReadToEnd( ) method which reads the stream till the end and returns a string which we collected in str. Next we have created a font object. Then using the DrawString( ) method we printed the string. Printing Graphics From A File Now let us see how to print graphics from a file. To demonstrate this we have created a WinForm application called GraphicsPrint. The UI of this application is same as TextPrint and the print_Click( ) handler is also same. We have made changes only in the mypdoc_PrintPage( ) shown below: private void mypdoc_PrintPage ( object sender, System.Drawing.Printing.PrintPageEventArgs e ) {

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


e.Graphics.DrawImage ( Image.FromFile ( filename.Text ), 0, 0 ) ; } Here we have passed the file name supplied in the textbox to the FromFile( ) method of the Image class. We have then passed the Image object returned by the FromFile( ) method to the DrawImage( ) method. On doing so the contents of the specified file gets printed. Printing A Multi-page Document The application that we saw in the previous section which prints text suffer from two limitations-it does not print words of a line that go beyond the margins and it does not print more than one page. This is because the PrintDocument class does not allow automatic wrapping of words that go beyond the margin. It also crops up words that don't fit into one page. In this section we have demonstrated how to print a line that goes beyond one line and how to print a multi-page document. To do so we have created a Windows Form Application called Multipage. As usual, we have added a PrintDocument component and named it mypdoc. The UI of the application is shown in the following figure.

In addition to the filename text box and the print button here we have added a multi-line textbox named mytext and a button named open. The idea is that whichever file is displayed in the mytext textbox gets printed even if the words go beyond the margin and pages are more than one. In the open_Click( ) event handler we have used an object of the StreamReader class to read from the specified file. Whatever the StreamReader reads is displayed in the mytext textbox. The handler is shown below: private void open_Click ( object sender, System.EventArgs e ) { StreamReader reader = new StreamReader ( filename.Text ) ; mytext.Text = reader.ReadToEnd( ) ; reader.Close( ) ; } Add the Click event handler for the 'Print' button and add the code in it as shown below:

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


private void print_Click ( object sender, System.EventArgs e ) { str = mytext.Text ; mypdoc.Print( ) ; } Here before calling the Print( ) method we have stored the entire text from the text box into a String called str that we have added as a data member of the form. Here we intend to print multiple pages. Hence we have created the Font, SolidBrush and StringFormat objects in the handler for the BeginPrint event. Note that we could have done this in the handler of the PrintPage event as well but then these objects would have been created for each page. The mypdoc_BeginPrint( ) event handler is shown below: private void mypdoc_BeginPrint ( object sender, System.Drawing.Printing.PrintEventArgs e ) { f = new Font ( "Arial", 12, FontStyle.Regular ) ; b = new SolidBrush ( Color.Black ) ; strformat.Trimming = StringTrimming.Word ; } We have added references f (Font), b (SolidBrush) and strformat (StringFormat) as data members of the form class. Instantiate strformat in place as StringFormat strformat = new StringFormat( ) ; We have set the Trimming property of the StringFormat class to StringTrimming.Word, which ensures word wrapping. StringTrimming is an enumeration that specifies how to trim characters from a string that does not completely fit into the specified page layout. Word specifies that text should be trimmed to the nearest word. Next PrintPage event is raised which invokes the following handler: private void mypdoc_PrintPage ( object sender, System.Drawing.Printing.PrintPageEventArgs e ) { RectangleF myrect = new RectangleF ( e.MarginBounds.Left, e.MarginBounds.Top, e.MarginBounds.Width, e.MarginBounds.Height ) ; SizeF sz = new SizeF ( e.MarginBounds.Width, e.MarginBounds.Height); e.Graphics.MeasureString ( str, f, sz, strformat, out chars, out lines ) ; printstr = str.Substring ( 0, chars ) ; e.Graphics.DrawString ( printstr, f, b, myrect, strformat ) ; if ( str.Length > chars ) { str = str.Substring ( chars ) ; e.HasMorePages = true ; } else e.HasMorePages = false ; } Here we have created two objects of the RectangleF and SizeF classes according to the MarginBounds property of the PaintEventArgs class. This property returns an object of the Rectangle class that represents the portion of the page between the margins. Then we have

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


passed the Top, Left, Width and Height properties of this rectangle to the constructor of the RectangleF and SizeF structure. Next we have called the MeasureString( ) method of the Graphics class which actually does the job of making multi-page printing easy. The first four parameters passed to this method are passed by value and the last two parameters are passed by reference. The first parameter we have passed is the string to be measured (str). Then we have passed f, the SizeF object that we created and strformat that determines the formatting. The next parameters that we have passed are two integers called chars and lines that we added as data members of the form. This method measures the string and stores the number of characters in the string in chars and number of lines in the string in lines that would fit in the current page according to the specified font, format, and size. Then using the Substring( ) method we retrieved a string that would fit in one page in another string called printstr that we added as a data member of the form. Next we printed printstr using the DrawString( ) method. After printing the string we have checked whether the length of the string printed is greater than the number of characters that can fit in one page. If yes, it means that there are more pages to be printed. So, we have collected the remaining string and set the HasMorePages property of the PrintPageEventArgs to true. This raises the PrintPage event again and the remaining string also gets measured using the MeasureString( ) method and then printed using the DrawString( ) method. If this string exceeds one page then again the cycle is repeated. This keeps on happening till the length of string becomes such that it can fit in one page, i.e. the length becomes less than chars.

Article C# - Common Dialog Boxes For Printing


In this article we would see how to print a multi-page document using common dialog boxes of printing such as PrintPreview, Print and PageSetup. For these dialog boxes .NET has provided the PrintPreviewDialog control, the PrintDialog control and the PageSetupDialog control. To illustrate the use of these dialog boxes let us create a Windows Form application called prntdlgs. We also added a vastly used OpenFileDialog control to the form along with two textboxesfilename and mytext-and five buttons-a 'Browse' button named browse, an 'Open' button named open, a 'PageSetup' button named pgsetup, a 'Print Preview' button named preview, and a 'Print' button named print. Next we added five components to the component tray and changed their names as shown below: Component PrintDocument PageSetupDialog PrintPreviewDialog PrintDialog OpenFileDilaog Name mypdoc mypgsdlg mypreviewdlg myprintdlg myopendlg

The UI of the prntdlg application is shown in the following figure.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Next we have added Click event handlers for all the five buttons. The handler for the browse button is given below. private void browse_Click ( object sender, System.EventArgs e ) { myopendlg.Filter = "Text Files ( *.txt ) | *.txt" ; myopendlg.ShowDialog( ) ; if (myopendlg.FileName != "" ) filename.Text = myopendlg.FileName ; } The 'Browse' button would let the user to select a file for printing. The user would select the file from standard Open File dialog box. We have displayed the dialog box in this handler. The selected file name is displayed in the text box. As soon as the user clicks the 'Open' button the following handler gets called. private void open_Click ( object sender, System.EventArgs e ) { StreamReader reader = new StreamReader ( filename.Text ) ; mytext.Text = reader.ReadToEnd( ) ; reader.Close( ) ; } Here we have read the file contents with the help of an object of the StreamReader class and displayed them on the mytext textbox. Now if the user wants to change the page settings he needs to click the 'Page Settings' button. On doing so the following handler would get called. private void pgsetup_Click ( object sender, System.EventArgs e ) { try { mypgsdlg.PageSettings = ps ; mypgsdlg.ShowDialog( ) ; } catch ( Exception ex ) {

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


MessageBox.Show ( ex.Message ) ; } } We have added an object referred to by ps of the PageSettings class as a data member of the form class as follows: PageSettings ps = new PageSettings( ) ; The zero-argument constructor of this class creates an object of the PageSetting class for the default printer. The default constructor initializes all fields to their default values. Next we have set the PageSettings property of the PageSetupDialog class to ps. Then we have displayed the Page Setup Dialog box using the ShowDialog( ) method. The user can also preview the page to be printed by clicking on the 'Print Preview' button. On doing so the following handler would get called. private void preview_Click ( object sender, System.EventArgs e ) { try { str = mytext.Text ; mypdoc.DefaultPageSettings = ps ; mypreviewdlg.Document = mypdoc ; mypreviewdlg.ShowDialog( ) ; } catch ( Exception ex ) { MessageBox.Show ( ex.Message ) ; } } Here first we have collected the string in mytext textbox in str. We have added str of type string as a data member of the form class. Next we set the DefaultPageSettings property of the PrintDocument class to ps. Then we set the Document property of the PrintPreviewDialog class to mypdoc, which specifies the document to be previewed. Next we have displayed the dialog using the ShowDialog( ) method. The PrintPreviewDialog is shown in the following figure.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

On clicking the 'Print' button the following handler gets called. private void print_Click ( object sender, System.EventArgs e ) { try { mypdoc.DefaultPageSettings = ps ; str = mytext.Text ; myprintdlg.Document = mypdoc ; if ( myprintdlg.ShowDialog( ) == DialogResult.OK ) mypdoc.Print( ) ; } catch ( Exception ex ) { MessageBox.Show ( ex.Message ) ; } } Here first we have set the DefaultPageSettings property of the PrintDocument class to ps. Next we have collected the text of mytext textbox, which is to be printed in str. The document to be printed is then set to the Document property of the PrintDialog class. Next we displayed the PrintDialog box using the ShowDialog( ) method and if the result happens to be DialogResult.OK, i.e if the user clicks OK, we have called the Print( ) method of the PrintDocument class. On calling the Print( ) method the following handlers get invoked. private void mypdoc_BeginPrint ( object sender, System.Drawing.Printing.PrintEventArgs e ) { f = new Font ( "Arial", 12 ) ; b = new SolidBrush ( Color.Black ) ; strformat.Trimming = StringTrimming.Word ; } private void mypdoc_PrintPage ( object sender, System.Drawing.Printing.PrintPageEventArgs e ) {

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


RectangleF myrect = new RectangleF( e.MarginBounds.Left, e.MarginBounds.Top, e.MarginBounds.Width, e.MarginBounds.Height ) ; SizeF sz = new SizeF ( e.MarginBounds.Width, e.MarginBounds.Height f.GetHeight(e.Graphics ) ) ; e.Graphics.MeasureString ( str, f, sz, strformat, out chars, out lines ) ; printstr = str.Substring ( 0, chars ) ; e.Graphics.DrawString ( printstr, f, b, myrect, strformat ) ; if ( str.Length > chars ) { str = str.Substring ( chars ) ; e.HasMorePages = true ; } else e.HasMorePages = false ; } The code written in this handler takes care of multiple pages being printed as well as word wrapping.

Article C# - Custom Controls - I


Prior to .NET the controls that were popularly used as language independent reusable userdefined controls were ActiveX controls. These included controls like multimedia controls, spreadsheet controls, mailing controls, etc. But they had their own disadvantages. ActiveX controls were COM-based controls and COM had a steep learning curve. In addition to this there were overheads of maintaining the registry, maintaining CLSIDs, handling interfaces and working through complex threading models. .NET has solved all these problems by facilitating creation of user-defined controls in a simple manner. In this article we plan to see how to create such userdefined controls. Custom Controls V/s User Controls Normally when we develop a .NET Windows application, we use controls from the System.Windows.Forms namespace. We have a wide variety of controls available, from simple controls such as Label and TextBox, to controls that are richer and more complex, such as MonthCalendar and ColorDialog. While these controls are good enough for most Windows applications we need to build, sometimes we need to create a different control that we cannot find in the Framework class library. We can create two types of controls-Custom Controls and User or Composite Controls. Custom controls display UI by making calls to a Graphics object. Custom controls are typically derived from the Control class. The Control class implements very basic functionality required by classes that display information to the user. It handles user inputs through the keyboard. It handles message routing and security. There is limited design-time support for creating custom controls. User or Composite controls are composed of other existing controls. User controls are derived from the UserControl class. The UserControl class is also derived from the Control class There is full design-time support for creating user controls with the Visual Studio .NET Windows Forms Designer. Creating A Custom Control

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Let us create a Custom Control and use it in a Windows Form project. The idea is to make an analog clock. Here we plan to display time in a dial using the hour, minute and second hands. The control (after dragging and dropping it in a form) is shown in the following figure.

To create a custom control, select 'Windows Control Library' template. Name the project as ClockCtrl. By default a class called UserControl1 gets created, derived from the UserControl class. Change the base class of the control class from UserControl to Control. Also change the name of the control class from UserControl1 to Clock. Next, set the Size property of the control to 120, 120 and BackColor property to Light Blue. To keep track of the time we must add a Timer control. Do so and name it as mytimer. Set the interval time of the timer to 1000 milliseconds (equivalent to one second) and add a handler mytimer_Tick( ) to handle the Tick event that would get generated every second. We would draw the hands and background of control in mytimer_Tick( ) event handler because we need to redraw the control every second. This is the reason why we did not do the painting in the Paint event handler. Let us now see what we have done for drawing the control. On occurrence of every tick we have drawn the clock UI on a bitmap and displayed the bitmap on the control. To draw on the bitmap we first need to obtain the graphics context of the bitmap. We have done this in the constructor of the Clock class. To collect the graphics context we have added a reference g of type Graphics as a data member of the control. We have also added a reference mybmp of type Bitmap to this class. Let us now take a look at the constructor. public Clock( ) { InitializeComponent( ) ; Size sz = this.Size ; mybmp = new Bitmap ( sz.Width, sz.Height ) ; g = Graphics.FromImage ( mybmp ) ; Color bkclr = this.BackColor ; g.Clear ( bkclr ) ; p = new Pen ( Color.Black ) ; b = new SolidBrush ( Color.Purple ) ; }

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


In the constructor, after a call to InitializeComponent( ), we have created a Bitmap object having the same size as that of the control and collected its reference in mybmp. Then we obtained a graphics context of the bitmap using the FromImage( ) shared method of the Graphics class and collected the reference of the context in g. Next using the Clear( ) method we have painted background of the bitmap with background of the control. We have then initialized a black pen and purple brush. As you guessed, b and p are added as data members of type SolidBrush and Pen respectively. Let us now see how the painting is done in the Tick event handler. Private Sub mytimer_Tick ( ByVal sender As Object, ByVal e As System.EventArgs ) Handles mytimer.Tick { g.TranslateTransform ( 60, 60 ) ; for ( int i = 0 ; i<=12; i++ ) { g.FillRectangle ( b, -2, -45, 4, 5 ) ; g.RotateTransform ( 30 ) ; } g.ResetTransform( ) ; //seconds p.Width = 1 ; p.EndCap = LineCap.Flat ; p.Color = Color.Red ; g.TranslateTransform ( 60, 60 ) ; g.RotateTransform ( s ) ; g.DrawLine ( p, 0, 0, 0, -40 ) ; g.ResetTransform( ) ; //minutes p.Width = 3 ; p.EndCap = LineCap.Triangle ; p.Color = Color.Blue ; g.TranslateTransform ( 60, 60 ) ; g.RotateTransform ( m ) ; g.DrawLine ( p, 0, 0, 0, -30 ) ; g.ResetTransform( ) ; //hours p.Width = 4 ; g.TranslateTransform ( 60, 60 ) ; g.RotateTransform ( h ) ; g.DrawLine ( p, 0, 0, 0, -20 ) ; g.ResetTransform( ) ; s += 6 ; if ( s == 360 ) s=0; sec = sec + 1 ; if ( sec == 60 ) { sec = 0 ; m += 6 ; if ( m == 360 )

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


m=0; min = min + 1 ; h += 0.5f ; if ( h == 360 ) h=0; if ( min == 60 ) { min = 0 ; hr += 1 ; } } Size sz = this.Size ; Rectangle rect = new Rectangle ( 0, 0, sz.Width, sz.Height ) ; Bitmap bm = mybmp.Clone ( rect, mybmp.PixelFormat ) ; this.BackgroundImage = bm ; Color bkclr = this.BackColor ; g.Clear ( bkclr ) ; } We would understand this handler next time. In the next article we would also create a client of this custom control.

Article C# - Custom Controls - II


In the last article we had added the Tick event handler for the mytimer control. Let us see what we have done in this handler. Consider the following code of the mytimer_Tick( ) handler. g.TranslateTransform ( 60, 60 ) ; for ( int i = 0 ; i<=12; i++ ) { g.FillRectangle ( b, -2, -45, 4, 5 ) ; g.RotateTransform ( 30 ) ; } g.ResetTransform( ) ; Here we have drawn the rectangles that represent the hours. We have used the TranslateTransform( ) method of the Graphics class to shift the origin to (60, 60). Using the FillRectangle( ) method we drew 12 rectangles and rotated the graphics world every time by 30. After drawing the rectangles we used the ResetTransform( ) method to reset the transform world to default settings. Next we have drawn the seconds, minutes and hour hands. To display the current time we need to calculate the angles of the hands first. For every second, the second hand should be rotated by 6 (360 / 60). For every minute, the minute hand should be rotated by 6 (360 / 60) again and for every hour the hour hand should be rotated by 30 (360 / 12). Moreover, the hour hand should also be rotated by 0.5 for every minute. This is because in every 60 minutes the hour hand rotates by 30, hence in every minute it would rotate by 0.5. So while displaying the current time we need to multiply the seconds, minutes and hours values by the angles and rotate the hands by the multiplication results. These calculations need to be done before starting the timer and hence we have written this logic in a method called start( ). We would see this method later. To draw the hands we have used appropriate Color, Width and EndCap style of the Pen object. Next we have translated the graphics world by 60, 60 and rotated it by s. Then we have drawn

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


the hand using the DrawLine( ) method at appropriate co-ordinates. We have again used the ResetTransform( ) method to reset the transform. For drawing the minute hand we have used the same logic but rotated the hand by m and made the hand shorter, thicker and of blue color. We have also changed the EndCap style to LineCap.Triangle. After resetting the transform we have drawn the hour hand rotated at an angle of h and made it more short and thick than the minute hand. We have used the same EndCap style as of the minute hand for the hour hand. With every second we have incremented s by 6. As soon as the angle becomes 360, we have reset it to 0. With every second we have also incremented the value of sec by 1. As soon as sec becomes 60 (i.e. after 1 minute) we have done three things-reset sec to 0, incremented angle m by 6 and incremented the value of min by 1. As soon as the angle m becomes 360, we have reset it to 0. With every minute we have incremented the value of angle h by 0.5. Similarly, after completion of 360, we have reset the angle to 0. After min becomes 60 (i.e. after 1 hour) we have reset the value of min to 0 and incremented the value of hr. All these would get drawn on the bitmap because the graphics context is of the bitmap. Now we need to display the bitmap on the control. To do so we created another bitmap object bm using the Clone( ) method. We created bm with the same size as that of the control and having the same PixelFormat as of mybmp. PixelFormat represents number of bits associated with one pixel of data. Next we have displayed the bitmap on the control by setting the BackGroundImage property of the control to bm. Lastly, we have cleared mybmp with the BackColor of the control making it ready for painting. Let us now see the start( ) method that was mentioned above. public void start( ) { now = DateTime.Now ; sec = now.Second ; min = now.Minute ; hr = now.Hour ; s = sec * 6 ; m = min * 6 ; h = ( ( hr % 12f ) * 30f ) + ( min * 0.5f ) ; mytimer.Start( ) ; } The start( ) method would be called by the client when he wants to start the clock. We must start the clock and place the second, minute and hour hands according to the present time. To do this we have first collected the current system time in now of type DateTime. We have added now as a data member of the class. To collect the seconds, minutes and hours values we have also added 3 integers named sec, min and hr as data members of the Clock class. According to the current time we have displayed the hands at different angles. We have used two integer variables s and m to specify the angles for the second and minute hands respectively and we have used a single variable h to specify the angle for the hour hand. We have also added s, m and h as data members of the Clock class. % (modulus operator) is used to avoid the AM/PM conflict. As soon as we start the timer using the Start( ) method the Tick event is fired every second. And every second we have painted the control with the new bitmap and changed the angles. To stop the timer we have added a method called Halt( ) to the control shown below:

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


public void Halt( ) { mytimer.Stop( ) ; } Using the Custom Control To use the control we have created 'Windows Form' client called ClockClient. To be able to add the control to our form, we need to add it first to the Toolbox. For this we need to right click on the Toolbox and select Customize Toolbox. On doing so the Customize Toolbox window would get opened. Here we need to select the .NET Framework Components Tab. Our control would not get displayed in the list of existing controls; we need to browse for its dll. After selecting the dll we need to click the OK button. This would add our control to the Toolbox as shown in the following figure.

To add the control to our form we need to drag it on the form. After adding it to the form, we have changed its name to myclock and set its Locked property to True to lock its size. To start the ticking, we have called the start( ) method of the control in the constructor of the form as shown below: public Form1( ) { InitializeComponent( ) ; myclock.start( ) ; } This starts the timer and the control starts displaying the time.

Article C# - Adding Events To Custom Controls


We can also add properties and events to a custom control. In last two articles we saw how to create and use a clock control. In this article we would add properties and an event to it.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

The idea is to modify the clock control to an alarm clock control. We plan to add two properties AlarmTime and Message to the control. These properties can be set or retrieved programmatically as well as through the Properties Window. The user can set the AlarmTime property to some specific time and as soon as the specified time is reached a message gets displayed. The user can specify the message to be displayed through the Message property. The form data members-altime (of type DateTime) and almessage (of type string)-are controlled by these properties. We have added an event called alarm that would be fired as soon as specified AlarmTime is reached. The AlarmTime and Message properties are given below: [ Category ( "User Defined" ) , Description ( "Controls the Alarm Time" ) ] public DateTime AlarmTime { get { return altime ; } set { altime = value ; } } [ Category ( "User Defined" ), Description ( "Controls the Alarm Message" ) ] public string message { get { return almessage ; } set { almessage = value ; } } Notice the two attributes that we applied to the properties. The Category attribute specifies the category under which the property would get displayed in the Properties window. This would be visible whenever we drag the control on the form and open the Properties window. The Description attribute accepts a String that would get displayed in a small part of the window present at the end of the Properties window. This string describes the property. The Properties window of the control is shown in the following figure.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

To add the event we have first added a delegate called NotifyAlarm to the control that accepts two parameters-an object and a TimeEventArgs object. public delegate void NotifyAlarm ( object sender, TimeEventArgs e ) ; TimeEventArgs is a user-defined class. In this class we have added a data member named msg of type String and a one-argument constructor accepting a string that would be stored in msg. The class is shown below: public class TimeEventArgs : EventArgs { public string msg ; public TimeEventArgs ( string s ) { msg = s ; } } Next we added the event as data member of the class as shown below: public event NotifyAlarm alarm ; For the alarm to ring at the specified time, with every minute we must check whether the specified alarm time is equal to the time displayed in our control. We have done the checking in the Tick event handler. The modified Tick event handler is given below. private void mytimer_Tick ( object sender, System.EventArgs e ) { g.TranslateTransform ( 60, 60 ) ; for ( int i = 0 ; i <= 12 ; i++ ) { g.FillRectangle ( b, -2, -45, 4, 5 ) ; g.RotateTransform ( 30 ) ; } g.ResetTransform( ) ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

//seconds p.Width = 1 ; p.EndCap = LineCap.Flat ; p.Color = Color.Red ; g.TranslateTransform ( 60, 60 ) ; g.RotateTransform ( s ) ; g.DrawLine ( p, 0, 0, 0, -40 ) ; g.ResetTransform( ) ; //minutes p.Width = 3 ; p.EndCap = LineCap.Triangle ; p.Color = Color.Blue ; g.TranslateTransform ( 60, 60 ) ; g.RotateTransform ( m ) ; g.DrawLine ( p, 0, 0, 0, -30 ) ; g.ResetTransform( ) ; //hours p.Width = 4 ; g.TranslateTransform ( 60, 60 ) ; g.RotateTransform ( h ) ; g.DrawLine ( p, 0, 0, 0, -20 ) ; g.ResetTransform( ) ; s += 6 ; if (s == 360 ) s=0; sec = sec + 1 ; if (sec == 60) { sec = 0 ; m += 6 ; if (m == 360) m=0; min = min + 1 ; if ( altime.Hour == hr && altime.Minute == min ) { TimeEventArgs t = new TimeEventArgs ( almessage ) ; alarm ( this, t ) ; } h += 0.5f ; if ( h == 360 ) h=0; if ( min == 60 ) { min = 0 ; hr += 1 ; } }

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Size sz = this.Size ; Rectangle rect = new Rectangle ( 0, 0, sz.Width, sz.Height ) ; Bitmap bm = mybmp.Clone ( rect, mybmp.PixelFormat ) ; this.BackgroundImage = bm ; Color bkclr = this.BackColor ; g.Clear ( bkclr ) ; } As soon as altime.Hour becomes equal to hr and altime.Minute becomes equal to min, we created an object referred to by t of the TimeEventArgs class by passing almessage to it. Next we raised the event using RaiseEvent and passed the reference of the control to it. We have also added an attribute called DefaultEvent to the Clock class as shown below: [ DefaultProperty ( "Message" ) , DefaultEvent ( "alarm" ) ] As a result, whenever we drag our control on the form and double click on the control in the Client's Windows Designer, of all the event handlers available the alarm event handler would get added in the code. Now let us see what we need to do to handle the event in the client. As soon as we double click on the control after dragging it on the form the myclock_alarm( ) event handler gets added to the form class. To display the alarm message we have simply popped a messagebox displaying the alarm message. The handler is shown below. private void myclock_alarm ( object sender, ClockCtrl.TimeEventArgs e ) { MessageBox.Show ( e.msg ) ; } In the client on selecting AlarmTime in the Properties window we would get a calendar control. We have set the values for AlarmTime and Message properties. When the clock would reach the alarm time it would display the message as shown in the following figure.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com Article C# - COM Interoperability


COM components and .NET components are not compatible since they have different internal architectures. However, there are tools available in the .NET SDK for generating COM proxies for .NET components and .NET proxies for COM components. Using these proxies we can use COM components in .NET projects and .NET components in non-.NET projects. Let's now discuss these two situations. Using COM Components in .NET Application Here we would be using a COM component called 'AtlServer' that exposes an interface 'IMath' containing two methods Add( ) and Sub( ). The component is stored in the file 'AtlServer.dll'. Note that 'AtlServer.dll' must be registered in you machine. If it is not registered simply build the 'AtlServer' project so that the .NET will make the registration or use the 'regsvr32' utility. We now plan to use this COM component in a .NET project. For this we have created a console application and named it as 'AtlClient'. To use the COM component in our project we would have to create a wrapper class for the COM component. A wrapper class surrounds a class that follows a different architecture than .NET. This class provides a familiar interface to the .NET architecture. We can create a wrapper class in two ways. First is to use the 'TlbImp.exe' tool provided in the .NET SDK. TlbImp stands for 'Type Library Importer'. This EXE is invoked from the command prompt as shown below: c:\com_interop\AtlServer\Debug>tlbimp AtlServer.dll /out:NetAtlServer.dll The /out option will store the newly created wrapper class in the 'NetAtlServer.dll' file. We would have to copy 'NetAtlServer.dll' in the 'Debug' sub-directory of our .NET project. The second way to create a wrapper class is to right click in the 'Solution Explorer' and choose the 'Add Reference' option. Next we must choose the 'COM' tab. On doing so the window shown below would appear.

To select the file click on the 'Browse' button, locate the file and select it. On clicking 'OK', a file with the same name i.e. 'AtlServer.dll' would get created in the 'Debug' sub-directory of our project and would contain the wrapper class called CMath. We can now call the methods of the class as shown in the following code.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


using System ; using AtlServer ; namespace AtlClient { class Class1 { [ STAThread ] static void Main ( string [ ] args ) { CMathClass m = new CMathClass( ) ; Console.WriteLine ( m.Add ( 10, 20 ) ) ; Console.WriteLine ( m.Sub ( 20, 30 ) ) ; } } } Using .NET Components In Non-.NET Projects To use a .NET component in a non-.NET project we have to use a tool called RegAsm, standing for 'Registry Assembly'. This tool registers a .NET component into the system registry so that standard Windows client can bind to the classes in the component. The .NET component that we have created is just a simple class library called 'NetServer' that contains the following code. using System ; namespace NetServer { public interface IMath { int Add ( int n1, int n2 ) ; int Sub ( int n1, int n2 ) ; } public class CMath : IMath { public int Add ( int n1, int n2 ) { return n1 + n2 ; } public int Sub ( int n1, int n2 ) { return n1 - n2 ; } } } Here we have declared an interface called IMath and implemented this interface in the CMath class. On building this project we get the 'NetServer.dll' file. Now we need to register this component in the registry using the RegAsm tool as well as create a corresponding COM type library file ( .tlb file). To create a COM type library file we need to use the TlbExp tool. TlbExp stands for 'Type Library Exporter'. This tool interrogates the assembly's manifest and outputs a corresponding COM type library. We have used both the tools as shown in the following figure.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Now let us create a non-.NET project that would use this component. We have created our project in VC++. To create this project, click on 'Visual C++ Projects' and select 'Win32 Project'. Name the project as NetClient. On clicking 'OK' the window shown in the following figure would appear. In the 'Application Settings' tab select the 'Console Application' option and click on the 'Finish' button.

We need to add the following code to our project. # include "stdafx.h" # include "iostream.h" # import "C:\dotnet\c#\com-interop\NetServer\bin\Debug\NetServer.tlb" using namespace NetServer ; int _tmain ( int argc, _TCHAR* argv [ ] ) { CoInitialize ( NULL ) ; IMathPtr p ; HRESULT hr = p.CreateInstance ( "NetServer.Math" ) ; if ( FAILED ( hr ) ) { cout << "CreateInstance Failed" << endl ; return 0 ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


} cout << p -> Add ( 10, 20 ) << endl ; cout << p -> Sub ( 20, 10 ) << endl ; return 0 ; } Here we have imported the Type Library using the #import directive. Then we have created a pointer called IMathPtr. Using the CreateInstance( ) method we have stored the component object's address in the interface pointer and then used it to call the Add( ) and Sub( ) methods. On executing this program we would get the output on the console.

Article C# - Storing Images


"How to store an image in a database and how to read it back?" is a frequently asked question. This article gives the answer. In this article we would see how ADO.NET is used to store BLOBs (images) in a database and read them back. We would create two applications. One that would store information of books into a database and another that would retrieve this information and display it. The information consists of the book name, the author name and an image representing the cover pages of the book. For this we have maintained a database called books, having a table called bookinfo and having entries such as bookname (char), author (char) and logo (image). Logo represents the cover page of the book. Create a WinForm application and design the form as shown in following figure.

The controls and their names are shown in the following table Book Name Textbox Author Textbox Image Textbox Browse button Insert Button book author file browse insert

Using the Browse button the user would select the image file of the book cover. On clicking the Insert button the book information would get stored in the database. First of all to add entries in the table we need to open the connection to the data source. For this

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


we must declare a connection string and a connection object. We have done it in the Form1 class as shown below: string constr ; SqlConnection con ; Declare the System.Data.SqlClient namespace at the beginning of the program to make available the SqlConnection class. In the constructor of the Form1 class add the following statement to initialize the connection string and connection object and also to open the connection. constr = "server=kicitsqlserver;database=books;uid=sa;pwd=kicit" ; con = new SqlConnection ( constr ) ; con.Open( ) ; Once the connection is established, user is free to input the book information. The user would enter the book name and author name and then select the image file by clicking the Browse button. So, next we would add the Click event handler for the Browse' button. The handler is given below: private void browse_Click ( object sender, EventArgs e ) { OpenFileDialog ofd = new OpenFileDialog( ) ; ofd.Filter = "Image files |*.jpg" ; if ( ofd.ShowDialog( ) == DialogResult.OK ) file.Text = ofd.FileName ; } Here, we have first created an object of the OpenFileDialog class and collected its reference in ofd. Next we have used the Filter property to specify the file type we wish to browse. Here we have specified that we wish to browse for all the jpg files. We have then displayed the Open File Dialog by calling the ShowDialog( ) method and checked whether the user clicked on the OK button of this dialog or not. If he does then we have initialized the Text property of the file text box with the file name returned by the FileName property. After filling in all the information, we need to click on the Insert button. As soon as we click on this button the insert_Click( ) handler would get called. This handler is given below: private void insert_Click ( object sender, EventArgs e ) { FileStream f = new FileStream ( file.Text, FileMode.Open ) ; byte[ ] buff = new byte [ f.Length ] ; f.Read ( buff, 0, ( int ) f.Length ) ; string cmdstr = "Insert into bookinfo values ( @b, @a, @l )" ; SqlCommand com = new SqlCommand ( cmdstr, con ) ; com.Parameters.Add ( "@b", book.Text ) ; com.Parameters.Add ( "@a", author.Text ) ; com.Parameters.Add ( "@l", buff ) ; com.ExecuteNonQuery( ) ; con.Close( ) ; } Here we have first created a FileStream object by passing the file name and FileMode to it. We have read the file name from the file textbox. Next we have created an array of bytes called buff having length equal to the length of the data that is in the file stream. Then we have read the file into the byte array using the Read( ) method. Next, we have created a command string that would

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


insert the information into the database. We have used the parameterized command to add the values to the fields in the data source. So, in the command string we have specified the parameters as @b, @a and @l for the book name, author name and cover page logo respectively. The advantage of using parameterized commands is that we can change the values of some or all the fields again and again without having to create the command string again and again. The Parameters property of the SqlCommand class returns the collection of parameters in the form of a reference to SqlParameterCollection class object. We have added the parameter to this collection by calling the Add( ) method of the SqlParameterCollection class. Next we have called the ExecuteNonQuery( ) method that would actually fill the database. Lastly we have closed the connection with the Close( ) method. To be able to use the FileStream class we need to use the System.IO namespace in our application. Let us now create an application for accessing and retrieving BLOBs stored in the bookinfo table. Create a Winform application. Add two Labels and one PictureBox to display the book name, author name and the cover page respectively. The UI is shown in following figure

. Change the names of controls as shown in the following table. Book Name Label Author Label Picture Box Next Button bookl authorl img next

On clicking on the Next button the information of the next book stored in the database would get displayed. Add the following data members to the Form1 class. string constr ; SqlConnection con ; string cmdstr ; SqlCommand com ; SqlDataReader r ; Initialize them in constructor after the call to the InitializeComponent( ) method as shown below: constr = "server=kicitsqlserver;database=books;uid=sa;pwd = kicit" ; con = new SqlConnection ( constr ) ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


cmdstr = "Select * from bookinfo" ; com = new SqlCommand ( cmdstr, con ) ; Also add the code to open the connection and display the details of first book as shown below: con.Open( ) ; r = con.ExecuteReader( ) ; if ( r.Read( ) ) { bookl.Text = r [ 0 ].ToString( ) ; authorl.Text = r [ 1 ].ToString( ) ; byte[ ] b = ( byte[ ] ) r [ 2 ] ; MemoryStream st = new MemoryStream( ) ; st.Write ( b, 0, b.Length ) ; Image i = Image.FromStream ( st ) ; img.Image = i ; } After opening connection to database we have retrieved the reference of the SqlDataReader object in r by making a call to the ExecuteReader( ) method. Then we have checked whether the Read( ) method returns a true or false depending on the existence of a row. If it returns a true, we have extracted the book name and the author name and displayed them in the corresponding textboxes. Now we need to retrieve the BLOB. We have collected the BLOB in a byte array b. Realize that we cannot directly display the contents of b in the PictureBox because it is in not in a bitmap format. Hence we must first convert the byte array into a bitmap. To do so we have created an object of the MemoryStream class and collected its reference in st. MemoryStream class is used when the backing store is memory. Recall how we had created a FileStream object in the previous example where we had read from a file. Next, using the Write( ) method of the MemoryStream class we have written the contents of the byte array into the stream. Then we have created a bitmap by passing the reference of the MemoryStream object to the constructor of the Image class. Next we have displayed the image on the PictureBox. As soon as the user clicks the Next button the next_Click( ) handler gets called. This handler is shown below: private void next_Click ( object sender, EventArgs e ) { if ( r.Read( ) ) { bookl.Text = r [ 0 ].ToString( ) ; authorl.Text = r [ 1 ] .ToString( ) ; byte[ ] b = ( byte[ ] ) r [ 2 ] ; MemoryStream st = new MemoryStream( ) ; st.Write ( b, 0, b.Length ) ; Image i = Image.FromStream ( st ) ; img.Image = i ; } } In this handler we have used the same logic. Every time the user would click this button information of the next book stored in the database would get displayed.

Article C# - Miscellaneous .NET Features...


Language Interoperability

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Language Interoperability is a key feature of the .NET environment. Language Interoperability means that we can use an assembly written in any .NET compliant language in a program written in another .NET compliant language. This is all possible because all .NET compliant languages compile into IL (Intermediate Language). Language Interoperability supports code-reuse, which is the most sought after feature in today's programming world. To illustrate language Interoperability we would created an assembly in Managed C++ and then see how to use it through C#. Let's first take a look at the assembly written in Managed C++. To create this select "Visual C++ Projects" and choose the "Managed C++ Class Library" template. Name the class library as 'McppServer'. The code to be written in it is given below. #include "stdafx.h" namespace McppServer { public __gc class fact { public: int factorial ( int n ) { int j = n ; for ( int i = 1 ; i < n ; i++ ) j=j*i; return j ; } }; } In the fact class we have written a method called factorial( ) that accepts a number and returns the factorial value of that number. The __gc stands for garbage collected. It specifies that the underlying type would be treated as a managed type. It is necessary to mention this because in Managed C++ by default a type is unmanaged. On building this program an assembly called "McppServer.dll' would get created. Now let's look at the C# program. We have created a console application called 'CSharpClient'. To be able to use 'McppServer.dll' in this project, we have to add its reference through the 'Solution Explorer' window. using System ; using McppServer ; namespace CSharpClient { class Class1 { [ STAThread ] static void Main ( string [ ] args ) { fact f = new fact( ) ; Console.WriteLine ( f.factorial ( 5 ) ) ; } } } We have added the statement using McppServer at the beginning of the program. This gives us access to the classes defined in this namespace. Here we have created an object of the fact

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


class and used it to call the methods of this class. On executing this program we get the output as 120. Using Pointers in .NET Pointers can be used in C# only in the blocks of code that we have specifically marked for pointer use. The keyword to do so is unsafe. 'Unsafe' because there are potential risks associated with pointers such as memory leaks, overwriting of important information, stack overflow, etc. Code that uses pointers is difficult to debug and will fail the memory type safety checks imposed by the Common Language Runtime. We can mark individual methods, classes, structures, blocks of code or even local variables as unsafe. For example we can write: unsafe float myfunction( ) { // can use pointers } unsafe class myclass { unsafe int *x ; } unsafe { // unsafe block } Declaring pointers is different in C# than in C/C++. For example, if we want to declare two pointers to ints, we write: int *x, y ; in C# as, against

int *x, *y ; in C/C++. Once we've declared the pointers, we can use them as normal pointer variables using the 'address of' (&) and the 'value at address' (*) operators. For the most part, C# relies on references of instances of classes, and the language has been designed in such a way that pointers are not required as often as they are in C/C++. The checked and unchecked operators The checked and unchecked operators can be used to control overflow checking for arithmetic operations and conversions of integer types. If a statement is marked as checked, the CLR enforces overflow checking and throws an exception if an overflow occurs. On the other hand if it is marked unchecked, and overflow occurs, the overflowing bits (higher) are discarded and exception is not thrown. For example, consider the following snippet:

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


byte b = 255 ; checked { b++ ; } Here an exception would be thrown. But the following would not throw an exception: byte b = 255 ; unchecked { b++ ; } Here the overflowing bits would be lost and b would contain 0. By default, all the operations are unchecked.

Article C# - Serialization
Serialization is the process of writing objects on a persistent storage media such as a file on the disk. Complementary to serialization is Deserialization using which we can restore objects. Let us see an example where we have used serialization and deserialization to store and retrieve objects of a class to/from a file. Let us discuss the application first. We would create a WindowsApplication and add two menus File and Generate to the form. The File menu would have two menu items. Open and Save. On clicking Generate ten shapes would get generated randomly. We can save them in a file. To save the shapes drawn we would use serialization. While saving the shapes, we should not save the images of the shapes. Instead we should save the relevant information of the shapes using which we should be able to regenerate them again when the file is loaded. This means that we must write the object containing the information about the shape (coordinates of the shape and the color) in the file while saving it and load it back while opening the file. This is done using serialization and deserialization. To be able to represent the shapes we would create three classes-line, rectangle and ellipse. To generate the shapes we would call the draw( ) method of these classes. To be able to call the draw( ) methods of the line, rectangle and ellipse classes using the same call, we would use virtual mechanism. We would declare a class called shapes having an abstract method draw( ). The above mentioned three classes would be derived from the shapes class. These classes would override the draw( ) method. To save the objects on a disk we would create an ArrayList and store the objects of the shapes class in it in the order in which they are drawn. We can then write this array list to the disk. The names of menu items are given in the following table. Menu Open Save Generate Name open save generate

Also add the following data members to the Form1 class.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


ArrayList s = new ArrayList( ) ; BinaryFormatter b = new BinaryFormatter( ) ; We would now write the shapes class and derive three classesline, rectangle and ellipse from it. Here are the classes. [ Serializable( ) ] abstract class shapes { protected int r, g, b ; public shapes( ) { Random rd = new Random( ) ; r = rd.Next ( 256 ) ; g = rd.Next ( 256 ) ; b = rd.Next ( 256 ) ; Thread.Sleep ( 5 ) ; } abstract public void draw ( Graphics g ) ; } In this class we have declared three data members r, g, and b representing red, green and blue components to store the color of the shapes. We have also declared an abstract method in this class called draw( ). The classes derived from shapes class would have to implement the draw( ) method to be able to create their objects. In the constructor of the shapes class we have generated random numbers using an object of the Random class. The Next( ) method of the Random class generates a positive random number less than the number passed to it. Using this method we have initialized the r, g and b data members. The statement [Serializable( )] written before the class declaration is known as an attribute. Attributes are attached to classes, methods, data member or any such entities. Any class that is attached with this attribute indicates that all the data members of the class can be serialized i.e. can be written in a file, except for the data members that are marked with <NonSerialized( )> attribute. We have not marked any data members as <NonSerialized( )> hence all data members of the class would get written in a file. The derived classes are given below: [ Serializable( ) ] class line : shapes { int x1, y1, x2, y2 ; public line ( int i, int j, int k, int l ) { x1 = i ; y1 = j ; x2 = k ; y2 = l ; } override public void draw ( Graphics gr ) {

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Color c = Color.FromArgb ( r, g, b ) ; Pen p = new Pen ( c, 4 ) ; gr.DrawLine ( p, x1, y1, x2, y2 ) ; } } [ Serializable( ) ] class rectangle : shapes { int x1, y1, x2, y2 ; public rectangle ( int i, int j, int k, int l ) { x1 = i ; y1 = j ; x2 = k ; y2 = l ; } override public void draw ( Graphics gr ) { Color c = Color.FromArgb ( r, g, b ) ; Pen p = new Pen ( c, 4 ) ; gr.DrawRectangle ( p, x1, y1, x2, y2 ) ; } } [ Serializable( ) ] class ellipse : shapes { int x1, y1, x2, y2 ; public ellipse ( int i, int j, int k, int l ) { x1 = i ; y1 = j ; x2 = k ; y2 = l ; } override public void draw ( Graphics gr ) { Color c = Color.FromArgb ( r, g, b ) ; Pen p = new Pen ( c, 4 ) ; gr.DrawEllipse ( p, x1, y1, x2, y2 ) ; } } In these classes we have declared four integers that are used to store the coordinates of the shapes. It also consists of a constructor used to initialize these data members. We have implemented the draw( ) method in these classes that contains the logic to draw the line. We have attached the [Serializable( ) ] attribute to all the classes also indicating that objects of this class can be serialized. Add the Click event handlers for all the menu items. We would first see the Generate menu handler. It is given below: private void generate_Click ( object sender, EventArgs e ) {

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Graphics g = CreateGraphics( ) ; g.Clear ( BackColor ) ; Size sz = ClientSize ; Random rd = new Random( ) ; int i ; int shapeno, x1, y1, x2, y2 ; for ( i = 0 ; i <= 9 ; i++ ) { shapeno = rd.Next ( 3 ) ; x1 = rd.Next ( sz.Width ) ; y1 = rd.Next ( sz.Height ) ; x2 = rd.Next ( sz.Height - y1 ) ; y2 = rd.Next ( sz.Width - x1 ) ; switch ( shapeno ) { case 0 : s.Add ( new line ( x1, y1, x2, y2 ) ) ; break ; case 1 : s.Add ( new rectangle ( x1, y1, x2, y2 ) ) ; break ; case 2 : s.Add ( new ellipse ( x1, y1, x2, y2 ) ) ; break ; } } Invalidate( ) ; } When we click the Generate menu item this handler gets called. In this handler an object of the Random class is created. We have used the Next( ) method of this class to not only decide which shape should be generated but also the coordinates of this shape. The coordinates of the shapes to be generated should not be greater than the coordinates of the form. Hence the coordinates are generated using the size of the form, which is available in the ClientSize property of the form. Using these coordinates we have created ten random objects of rectangle, ellipse or line class. While creating these objects the constructors of the respective classes get called. Since all these classes are derived from the shapes class, firstly the base class constructor gets called. This constructor selects a random color. The references of objects of line, rectangle and ellipse are stored in the ArrayList using the Add( ) method. Lastly, we have called the Invalidate( ) method, which results in the Form1_Paint( ) event handler getting called. This handler id given below. private void Form1_Paint ( object sender, PaintEventArgs e ) { Graphics g = e.Graphics ; foreach ( shapes ss in s ) ss.draw ( g ) ; } As the line, rectangle and ellipse classes are derived from shapes, it is perfectly legitimate for a reference variable of shapes such as ss to hold a reference of the derived class. Using this reference we have called the draw( ) method. To this method we have also passed an object of the Graphics class. Depending upon which reference is present in ss, the draw( ) method of the appropriate class gets called and the corresponding shape gets drawn. This was the reason

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


behind deriving all the three classes from a common class shapes. The handler for Save menu item is given below. private void save_Click ( object sender, EventArgs e ) { SaveFileDialog sd = new SaveFileDialog( ) ; sd.Filter = "dat files | *.dat" ; if ( sd.ShowDialog( ) == DialogResult.OK ) { FileInfo f = new FileInfo ( sd.FileName ) ; Stream st ; st = f.Open ( FileMode.Create, FileAccess.ReadWrite ) ; foreach ( shapes ss in s ) b.Serialize ( st, ss ) ; st.Close( ) ; } } Here, we have created an object of the SaveFileDialog class and used a '*.dat' filter for it. When we type in a file name and click OK, a FileInfo object gets created with the selected filename. The Open( ) method returns a Stream object associated with the file. We have collected it in a Stream reference. Then we have used a BinaryFormatter object to serialize the objects. This binary formatter is added as a data member of the form class. The BinaryFormatter serializes and deserializes an object, in binary format. To be able to use this class we need to use the System.Runtime.Serialization.Formatters.Binary namespace in our program. The Serialize( ) method of this class serializes the object to the given stream. After serializing all the elements of the array, we have closed the stream using the Close( ) method. Lastly, here is the handler for Open menu item. private void open_Click ( object sender, EventArgs e ) { OpenFileDialog od = new OpenFileDialog( ) ; od.Filter = "dat files | *.dat" ; if ( od.ShowDialog( ) == DialogResult.OK ) { s.Clear( ) ; Graphics g = CreateGraphics( ) ; g.Clear ( BackColor ) ; FileInfo f = new FileInfo ( od.FileName ) ; Stream st = f.Open ( FileMode.Open ) ; while ( st.Position != st.Length ) s.Add ( b.Deserialize ( st ) ) ; st.Close( ) ; Invalidate( ) ; } } Here we have first created an object of the OpenFileDialog class. This class represents the common Open File dialog. Next, we have set the Filter property of this class to .dat files. This means that this dialog will display only the .dat files. The ShowDialog( ) method displays the open file dialog. If we select the OK button, then this method returns the DialogResult.Ok

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


member of the DialogResult enumeration. If the user selects a file and clicks on the OK button, we have firstly cleared the shapes, if any, drawn in the client area. The statement s.Clear( ) clears the array list in which shapes objects are stored. Next, we have created a FileInfo object and collected the corresponding Stream object of the specified file. Next we have used a while loop to deserialize the objects until the end of stream is reached. The Deserialize( ) method deserializes the specified stream into an object. We have collected these objects into our array by using the Add( ) method, closed the stream and called Invalidate( ) function for painting these shapes. Add the following declarations at the beginning of the program. using System.Threading ; using System.Runtime.Serialization ; using System.Runtime.Serialization.Formatters.Binary ; using System.IO ; Execute the program and click the Generate menu item. You would see ten shapes in different colors. Try saving and opening the shapes.

Article C# - Visual Inheritance


In Visual Studio 6.0, to display a dialog box, we derive a class from a pre-defined MFC class. The event handlers and variables associated with controls get added to this user-defined class. All the information about controls get stored in a separate '.rc' file. The compiler creates and displays controls using information stored in the '.rc' file. Visual Studio 6.0 IDE provides facilities for adding controls, variables for controls and handlers. So far so good. Now, consider a situation where an extensive user interface on a dialog comprising of several controls exists and we want to reuse this user interface in other application. What we would try is to inherit the dialog class creating the user interface to create a new class. Major problem with this is that although we get access to the base dialog class members, we don't get controls placed on the new dialog. This is because IDE of Visual Studio 6.0 has no means to access the '.rc' file and render the controls according to the information stored in it. So, our next step would be to copy all the controls from existing dialog template and to paste them on the new dialog. Now we get the controls and the variables and event handlers. But the problem here is that the code that associates controls with their variables and handlers remains missing. So, reusing an existing user interface is far more different and difficult than reusing an existing class. Through 'Inheritance' we create a new class by using an existing class. Through 'Visual Inheritance' we create a new form by using an existing form. When we inherit a form from an existing form we also inherit controls, their properties, events and methods. So, the user interface that is already created can be reused in a new application thereby reducing the repetitive designing of controls. This makes Visual Inheritance a powerful weapon in this era of Rapid Application Development. We can use visual inheritance in cases where we need to use the same set of controls again and again. Visual Studio.NET has incorporated visual inheritance as a part of .NET framework. Visual inheritance is so called because it gives the visual expression of the inherited control objects. Using Visual inheritance is a two-step process: 1. Creating Base Form 2. Creating Derived Form These steps are explained below.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Creating Base Form Carry out the following steps to create a Base Form. (a) Create a Windows Application named 'baseform'. (b) Add a button having label as "Click" and Name as b. Also add a text box having Name as t. By default, these variables get added as private data members. Change the access modifiers to public through the Modifiers property. If we change the Modifiers property of a control to protected or public we would be able to change its properties in the derived form. The controls marked as private in the base form will be visible on derived form but will not be accessible through its Name. This seems relevant because in OOP inheritance also only protected and public members of a base class are visible to its derived classes. In any case, we would not be able to delete the derived controls from the form. (c) Add the Click event handler for the button and add following statement in it.

MessageBox.Show ( t.Text ) ; (d) Now since our form stands ready we can build it into a class library so that we can export the form. Note that we cannot import a form from an exe file. To build the project in a class library, right click the solution name in Solution Explorer and select Properties. The 'baseform Property Pages' would get displayed. Select the Output Type as Class Library as shown in the following figure.

Now build the project to create 'baseform.dll'. This assembly contains the baseform.Form1 class that we can inherit. Creating Derived Form

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


(a) Create another Windows Application named 'derivedform'. (b) Right click the solution name in Solution Explorer and select 'Add | Add Inherited Form' menu option. The 'Add New Item' dialog box gets displayed. (c) Select the 'Inherited Form' from the 'Templates' list and provide a name of your choice in the 'Name' text box. We have kept the default name 'Form2.cs'. This is shown in the following figure.

(d) The 'Inheritance Picker' dialog would get displayed. This dialog allows us to select an assembly that contains the form we want to inherit. For this, click the 'Browse' button. A dialog would appear from where we can select the 'baseform.dll' file and click the 'Open' button. (e) Clicking the 'Open' button dismisses the dialog and displays the forms exported by the assembly (an assembly can export any number of forms) in 'Specify the component to inherit from' list control. (f) Select the form name from the 'Specify the component to inherit from' list control and click the 'OK' button. As soon as we click the 'OK' button, a new form derived from the 'baseform' gets displayed in the design editor. The file 'Form2.cs' also gets displayed in the Solution Explorer as shown in the following figure.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

The figure also displays reference of 'baseform.dll' being added in the 'References' tree in the Solution Explorer. The derived form displays the derived controls being added to the base form. These controls are accompanied by a small icon at the top left corner to distinguish between the derived controls and the new controls. (g) Open the 'Form1.cs' file. Change form name in Application.Run( ) method to Form2 as shown below.

Application.Run ( new Form2( ) ) ; This ensures that when we would execute the application, the new form, i.e. Form2, would get displayed. If we enter the text in the textbox and click the button the text would get displayed in a message box. Let us now see how the whole thing works. To begin with the statement Application.Run ( new Form2( ) ) gets executed. Here we are creating an object of the Form2 class which is derived from the baseform.Form1 class. When we create an object of derived class, base class's constructor gets called. So, in our case constructor of the baseform.Form1 class would get called. This class is accessible to us since a reference to the 'baseform.dll' assembly is already being added to our project. The compiler adds a call to the InitializeComponent( ) method in the constructor of every form class. The InitializeComponent( ) method contains the code for creating and customizing the controls. Once this method gets executed and controls get created, the control returns to the constructor of the Form2 class. This constructor again calls the InitializeComponent( ) method. This time the InitializeComponent( ) method of the Form2 class gets called. This is the reason why derived form contains the derived controls (initialized by InitializeComponent( ) method of the baseform.Form1 class) and the new controls (initialized by InitializeComponent( ) method of the Form2 class). We have already added the Click event handler for the 'Click' button. We can override this handler in the Form2 class and add our code in it. Now if we click the button, firstly, event handler of the base class gets executed and then the overridden handler gets executed. This is because, the InitializeComponent( ) method of the baseform.Form1 class gets executed first, wherein, an address of the Click event handler defined in the baseform.Form1 class gets stored in the Click delegate. Next the InitializeComponent( ) method of the Form2 class gets executed. In it, the address of the Click event handler defined in the Form2 class gets added to the Click delegate.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com Article C# - Getting Management Information using WMI
As the enterprise systems, applications, and networks became larger and more complex, the challenge in front of the managers to manage them also increased. In order to solve these problems, Microsoft developed WMI, a scalable management infrastructure and shipped it with Windows 2000. When we implement WMI on Windows platforms, the technology enables the Common Information Model (CIM) designed by the Distributed Management Task Force (DMTF) to represent systems, applications, networks, and other managed components. The CIM Specification describes the modeling language, naming, and mapping techniques used to collect and transfer information from data source and other management models. The CIM schema provides the actual model descriptions and information framework. It defines a set of classes with properties and associations, making it possible to organize information about the managed environment. The key features of WMI are discussed below: (a) Uniform Scripting API: WMI uses the CIM object model to create the managed objects. So, scripts only need to use a single API of WMI to access information for numerous disparate sources. (b) Remote Accessibility: Objects managed within WMI can be used by the applications and scripts running on the local machine as well as on the remote machine. (c) Discovery: Applications and scripts are able to discover what information is available about a system by enumerating the classes that are available. (d) WMI Queries: WMI allows SQL queries to be executed on its objects. (e) Powerful Event Publication: Events can be requested for any change in the managed objects in the system, regardless of whether they support an internal event capability. If you have used WMI in the past, you might be daunted by its complexities as it exposes COM interfaces. You would be happier to know that .NET provided easy to use namespaces and classes that encapsulate the WMI API. We would start with a simple program that displays information of the drive entered by the user. Create a Windows Forms application and design the form as shown below:

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

We have added few labels and read only text boxes to the form. Give suitable Names to the text boxes. The user would enter the drive name, for example, C: in the text box names as 'Enter Drive Name'. To get the information of the specified drive the user would click the 'GetInfo' button. Add the Click event handler for the button. This handler is given below:

private void binfo_Click ( object sender, System.EventArgs e ) { ManagementClass mc = new ManagementClass ( "Win32_LogicalDisk" ) ; ManagementObjectCollection disks = mc.GetInstances( ) ; foreach ( ManagementObject disk in disks ) { if ( disk [ "Name" ].ToString( ) == tdrive.Text ) { text1.Text = disk [ "DeviceID" ].ToString( ) ; text2.Text = disk [ "DriveType" ].ToString( ) ; text3.Text = disk [ "FileSystem" ].ToString( ) ; text4.Text = disk [ "FreeSpace" ].ToString( ) ; text5.Text = disk [ "MediaType" ].ToString( ) ; text6.Text = disk [ "Size" ].ToString( ) ; text7.Text = disk [ "VolumeName" ].ToString( ) ; text8.Text = disk [ "VolumeSerialNumber" ].ToString( ) ; } } }

Here, we have firstly declared a reference mc to the ManagementClass object. To the constructor of this class we have passed the name of the management class

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Win32_LogicalDisk. The Win32_LogicalDisk WMI class represents a data source that resolves to an actual local storage device on a Windows system. The idea is to obtain the objects of the logical disk class at run time and use its properties to obtain the management information. Then we have used the GetInstances( ) method to retrieve all the instances of the logical disk class. It returns the reference to the collection of the class instances. We have then applied the foreach loop to enumerate all the instances. The object of the ManagementObject class represents a management data object. Using the Name property of the logical disk class we have retrieved the name of the drive. If this name matches the name of the drive entered by the user, then we have obtained the information of the drive using various properties of the Win32_LogicalDisk class. We have displayed this information in the text boxes. Declare the System.Management namespace at the beginning of the program. Also add the reference to 'System.Management.dll' through the Solution Explorer window. Run the program. Enter the drive name as C: and click the 'GetInfo' button the drive information would get displayed as shown in the following snap shot.

What we saw in this article is only a tip of the iceberg. In the coming few article we would study the WMI architecture and use more WMI classes to explore the management information.

Article C# - Viewing Processes Using WMI


Microsoft had invented Web-Based Enterprise Management (WBEM), to develop a standardized technology for accessing management information. Management information includes details about the state of system memory, inventories of currently installed client applications, and other information about client status. WMI can handle many tasks, ranging from simple workstation configuration to full-scale enterprise management across multiple platforms. WMI uses Common Information Model (CIM) designed by the Distributed Management Task Force (DMTF) to represent systems, applications, networks, and other managed components. CIM can model anything in the managed environment regardless of data source location. In addition to data modeling, WMI allows query-based information retrieval and event notification.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Let's first study the architecture of WMI. Following figure describes the three-layer model of WMI comprising of providers, the CIM Object Manager (CIMOM), and consumers of WMI information (applications).

The first tier in the WMI architecture is the provider. A provider is a mediator between the system to be managed (for example, operating system, service, application, device driver, and so on) and the CIM object manager. The job of a provider is to extract management information from the underlying data source using whatever interfaces that software presents for management. The management information and interfaces are then mapped by the provider into the object classes that WMI presents to WMI consumers. Moving forward, new and updated managed systems will use providers as a direct way to expose management APIs without significant intermediate conversions. Next is CIMOM, the CIM Object Manager has its own storage repository. It acts as a broker for object requests. CIMOM and its repository are represented on the system by the system service called WinMgmt. Providers plug into CIMOM via a published set of COM interfaces. CIMOM keeps track of what classes are available and what provider is responsible for supplying instances of those classes. When an application requests for management information to CIMOM, it evaluates the request, identifies which provider has the information, and upon getting it returns the data to the consumer. Finally, there are consumers of WMI data. These are the applications requesting for the management information. These consumers, as previously noted, only need to know about the classes of the objects about which they wish to get information. Thus an application or script can call one WMI API function and get a wealth of information about the computer, operating system, applications, devices and even information available via other management protocols like SNMP and DMI. A WMI class exposes properties, methods, events and associations. An application can make use of them for obtaining the management information. Properties supply descriptive information about a particular object of a class. For example, the object of Win32_Process class has a property called Caption that contains the name of the process. The WMI classes provide methods, that an application can call using the object of that class. The WMI object can throw

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


events that are the notifications a consumer can request to receive for occurrences or failures in the system. We would now see a program that uses the Win32_Process WMI class for enumerating the processes currently running on system. Create a WinForm application. Place a list box and a button on the form. Name the button as m_browse and list box as m_list. Add the Click event handler for the button and write code in it as shown below.

ManagementClass mc = new ManagementClass ( @"root\cimv2:Win32_Process" ) ; ManagementObjectCollection mobjects = mc.GetInstances( ) ; foreach ( ManagementObject mo in mobjects ) m_list.Items.Add ( mo [ "Caption" ].ToString( ) ) ; Here, firstly we have created a reference to the ManagementClass object passing to it the WMI class name. 'root\cimv2' is the default namespace for System.Management API. Most of the system instrumentation classes reside here. We have retrieved the managed objects by calling the GetInstances( ) method of the ManagementClass class. This method would return the instances of the Win32_Process class, which is the class that represents a Windows process. The instances are returned in a collection, each instance would represent one process. We have then run a foreach loop to access the objects in the collection. We have obtained the name of the process by using the Caption property of the Win32_Process class. Note that we can access the property of this class because an object of ManagementObject class represents the instance of the Win32_Process class. Declare the System.Management namespace at the beginning of the program and add the reference to the 'System.Management.dll' to the project. Now run the program and click the 'Browse' button. All the processes would get listed as shown in the following snap shot.

Article C# - Tapping the Processes Using WMI - I


In the last article we saw how to list the processes currently running on the local machine. In this article we would see a similar application that displays the processes currently running on the machine but with additional functionality. We would display more information of each process and also extend the program to view the processes running on a remote machine. The application would also allow us to terminate the running process. Create a WinForm application and place controls on it as shown below:

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Change the names of controls as shown in the following table. Control ListView Machine Name TextBox Username TextBox Password TextBox Refresh Button Terminate Process Button Name m_plist m_mname m_uname m_password m_brefresh m_bterminate

When the application is executed, it would display the list of processes and their information of local machine. To view the processes of remote machine, the user should enter the machine name, username and password and click the Refresh button. To terminate the process, the user should select the process from list view control and click the Terminate Process button. Let us first add code to the constructor of the Form1 class after the call to InitializeComponent( ) method to display processes of the current machine.

ManagementClass mc = new ManagementClass ( @"root\cimv2:Win32_Process" ) ; ManagementObjectCollection mobjects = mc.GetInstances( ) ; addprocesses ( mobjects ) ; The object collection returned by the GetInstances( ) method is passed to a user-defined function addprocesses( ). We have separated code to add the processes in a function, because we need to execute the same code again when user clicks the Refresh button. The addprocesses( ) function is given below:

public void addprocesses ( ManagementObjectCollection moc ) { m_plist.Items.Clear( ) ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


string[ ] items = new string [ 5 ] ; foreach ( ManagementObject mo in moc ) { items [ 0 ] = mo [ "Caption" ].ToString( ) ; items [ 1 ] = mo [ "ProcessId" ].ToString( ) ; int vs = Int32.Parse ( mo [ "WorkingSetSize" ].ToString( ) ) ; vs = vs / 1024 ; items [ 2 ] = vs.ToString( ) + " Kb" ; if ( mo [ "ExecutablePath" ] == null ) items [ 3 ] = "NA" ; else items [ 3 ] = mo [ "ExecutablePath" ].ToString( ) ; items [ 4 ] = mo [ "Priority" ].ToString( ) ; ListViewItem lvitems = new ListViewItem ( items ) ; m_plist.Items.Add ( lvitems ) ; } } In this function, at first, we have removed all the previously added list items from the control by calling the Clear( ) method. Next, we have enumerated the objects from the collection passed to this function in a foreach loop. Each object in the collection represents a process. We would display the process name, process ID, memory the process is using, path of the EXE and priority of process in the list control. To obtain this information of the process, we have used various properties of the Win32_Process class. They are given below: Caption: It returns the name of the process. ProcessId: It returns the ID of the process. WorkingSetSize: It returns the amount of memory (in bytes) the process is required to run efficiently. ExecutablePath: It returns the path of the process. Priority: It returns the priority of the process. To display the values returned by these properties, firstly we have created an array of five strings. Since the properties return value of type object we have converted them to strings. The WorkingSetSize property returns memory size in bytes. We have converted bytes into kilobytes before converting them to string. After populating the string array, we have created an object of the ListViewItem and passed the array to its constructor. The 0th element in the array will be treated as new list item, and rest of the elements as its sub-items. Then we have called the Add( ) method to add the new list item to the list control. So, when we execute the application, it would look as shown in the following figure.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

We can now enter the machine name, user name and password and click the Refresh button to view the processes of that machine. We would see the Refresh button handler next time.

Article C# - Creating Owner Drawn Menus


Most of the times menu items are strings, but sometimes picture make more sense than text strings. For example, a color menu should show colors rather than text strings containing names of various colors. It would make more sense for the user if the colors like magenta and cyan are shown as they are going to look like rather than as strings saying Cyan and Magenta. If the colors were shown, their meaning would be crystal clear. Unfortunately, the MenuItem class does not provide a standard way to display pictures/icons. For example, there is no Icon property you set to display an icon automatically. However, the MenuItem class provides the capability for nonstandard drawing, often called owner-drawing. Every menu item has a property called OwnerDraw. When the OwnerDraw property is set to true, it indicates that the user, not Windows, will handle all drawing of the menu item. .NET IDE gives full support for creating the owner drawn menus. In this article we would create a WinForm application with owner drawn menu. The menu titled Color will display three menu items having icons plus text. The icons will represent colors Red, Green and Magenta. On clicking the menu items background of the form will get filled with the selected color. Create a WinForm application and add a Menu control to the form. Name the control as m. Add the menu item Color to the menu m. Add three menu items to the Color menu item. Name them as m1, m2 and m3 respectively. Set the OwnerDraw property of these menu items to True. When a menu is pulled down, the Framework first calls the MeasureItem event handler for each owner-drawn menu item to determine how big the menu needs to be. Then it calls the DrawItem event handler for each owner-drawn menu item to actually do the drawing. Thats why we need to add event handlers for both these events. We must add the event handlers for all the three menu items. This will add total of six functions to the Form1 class. Lets now add code to these handlers. Look at the MeasureItem event handler for the m1 menu item.

private void m1_MeasureItem ( object sender, MeasureItemEventArgs e ) { e.ItemHeight = 20 ; e.ItemWidth = 80 ; }

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


The MeasureItemEventArgs class provides data for the MeasureItem event. The properties we need to set are ItemHeight and ItemWidth. We will need the height of the menu item, which is the greater than the icon height or the font height plus a few pixels, and the width of the menu. We will do the actual drawing in the DrawItem event handler. The handler is given below.

private void m1_DrawItem ( object sender, DrawItemEventArgs e ) { e.Graphics.FillRectangle ( SystemBrushes.Control, e.Bounds ) ; e.Graphics.DrawIcon ( new Icon ( "C:\\icon1.ico" ), e.Bounds.Left + 3, e.Bounds.Top + 3 ) ; Brush br = new SolidBrush ( Color.Blue ) ; e.Graphics.DrawString ( "Red", new Font ( "Courier New", 9 ), br, ( float )( e.Bounds.Left + 35 ), ( float ) ( e.Bounds.Top + 2 ) ) ; } The DrawItemEventArgs class contains all the information needed for the user to paint the specified item, including the item index, the Rectangle and the Graphics on which the drawing should be done. In this handler, firstly, we have filled the bounds of the menu item with the standard control color. This is necessary to display the bounding rectangle around the icon. Otherwise the icons will get mixed up. Next, we have drawn the icon on the menu item using the DrawIcon( ) method. We have left the suitable number of pixels from left and top of the icon. Next to the icon we have displayed the string mentioning the color name. While drawing the string, we must leave the space where icon has been drawn. We must also keep suitable distance from icon. Thats why we have left 35 pixels from left side of the menu item bounds. The MeasureItem and DrawItem event handlers for the other two menu items are same. Only the icon files are different. Add the Click event handlers for the menu items and set the BackColor property of the form to respective color. Creating one menu item having three owner drawn menu items is quite manageable, although it is resulting into repetition of code. We can avoid this by inheriting a class from the MenuItem class and handling the event handlers in it. Create our own iconmenuitem class derived from the MenuItem class. This class is given below.

class iconmenuitem : MenuItem { Icon m_icon ; string mtext ; public iconmenuitem( ) { } public iconmenuitem ( string menutext, EventHandler eh, Shortcut sh, Icon ico ) : base ( menutext, eh, sh ) { this.OwnerDraw = true ; this.DrawItem += new DrawItemEventHandler ( drawitem ) ; this.MeasureItem += new MeasureItemEventHandler ( measureitem ) ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


m_icon = ico ; mtext = menutext ; } private void drawitem ( object sender, DrawItemEventArgs e ) { e.Graphics.FillRectangle ( SystemBrushes.Control, e.Bounds ) ; e.Graphics.DrawIcon ( m_icon, e.Bounds.Left + 3, e.Bounds.Top + 3 ) ; Brush br = new SolidBrush ( Color.Blue ) ; e.Graphics.DrawString ( mtext, new Font ( "Courier New", 10 ), br, ( float )( e.Bounds.Left + this.m_icon.Width + 5 ), ( float ) ( e.Bounds.Top + 2 ) ) ; } private void measureitem ( object sender, MeasureItemEventArgs e ) { e.ItemHeight = 20 ; e.ItemWidth = 80 ; } } In this class we have provided the default constructor and a four-argument constructor. To this constructor we have passed the menu text and the icon to be displayed. We have set the OwnerDraw property to true and added the DrawItem and MeasureItem event handlers. We have stored the icon and menu text passed to the constructor to some data members of iconmenuitem class. The event handlers drawitem( ) and measureitem( ) contains the same code we saw above. We would have a Menu control named m. The menu m will have one menu item m1 titled Color and Color menu item will have menu items m2 and m3. The m1 menu item is created by calling default constructor as shown below.

m1 = new ownerdrawn.iconmenuitem( ) ; Now create the menu items m2 and m3 using the iconmenuitem class as shown below. Add this code to the constructor of the Form1 class after the call to the InitializeComponent( ) method.

Icon i1 = new Icon ( "C:\\icon1.ico" ) ; m2 = new iconmenuitem ( "Red", new EventHandler ( m2_click ), new Shortcut( ), i1 ) ; Icon i2 = new Icon ( "C:\\icon2.ico" ) ; m3 = new iconmenuitem ( "Green", new EventHandler ( m3_click ), new Shortcut( ), i2 ) ; m1.MenuItems.AddRange ( new System.Windows.Forms.MenuItem[ ] { m2, m3 } ) ; Add m1, m2 and m3 as data members of type iconmenuitem to the Form1 class. The Click event handler for the m2 menu item is given below. In the same way add the event handler for the m3 menu item.

private void m2_click ( object sender, System.EventArgs e ) {

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


BackColor = Color.Red ; } The output of the program is shown below.

Article C# - Creating UI for an XML Document


There are two purposes of this article. First, to show how to work with a tree control in .NET and second, to create a user interface for an XML document. To fulfill these purposes, we have created a WinForm application that displays the elements and nodes of an XML document in a tree view control. Firstly we would understand the structure of a tree view control. The TreeView control displays tree items, called nodes, in a hierarchical manner. A parent node contains child nodes. The child nodes can be parent nodes for other nodes. Two child nodes having same parent node are called sibling nodes. The first parent node of a tree is called the root node. There can be multiple root nodes in a tree, just like a system has multiple root drives. The nodes displayed in a tree are instances of the TreeNode class. Each TreeNode has a Nodes collection stored in the TreeNodeCollection. This collection stores the list of other TreeNodes, its children. The Parent property returns the reference to the parent node. Now, place a TextBox, Button, TreeView, Label and an ImageList control on the form. Name the control as shown in the following table. Control TextBox Button TreeView ImageList Label Name txtfile bload xmltree imglist lblpath

We would display different images for XML elements and nodes in the tree control. For this, create four bitmap files. Add these files to the Images collection of the ImageList control. The first two images would be used for elements and nodes, whereas, next two images would be used as selected images for elements and nodes The user should enter an XML file name in the text box and click the Load button. This would

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


display the XML document in the tree control. Add the Click event handler for the Load button. This handler is given below.

private void bload_Click ( object sender, System.EventArgs e ) { try { XmlDocument doc = new XmlDocument( ) ; doc.Load ( txtfile.Text ) ; xmltree.Nodes.Clear( ) ; additem ( doc.DocumentElement, null ) ; } catch ( Exception e1 ) { MessageBox.Show ( e1.Message ) ; } } Here, we have loaded the document in memory by calling the Load( ) method of the XmlDocument class. It may happen that the user would first load one document and then another. In such case, we must delete the nodes of first document before adding new nodes to it. We have done so by calling the Clear( ) method of the TreeNodeCollection class. We have accessed the collection using the Nodes property of the TreeView class. To add the new item, we have called the user-defined additem( ) method. We have passed two parameters to itthe node of the XML document loaded in memory as first parameter and node of the tree control as second parameter. The root node in the document is represented by the DocumentElement property. We have passed null as the tree controls node because there are no nodes in the tree control yet. We have written the code in try-catch block because the Load( ) method throws an exception if it fails instead of returning an error value. Lets write the additem( ) method.

public void additem ( XmlNode xnode, TreeNode tnode ) { TreeNode child = addnode ( xnode, tnode ) ; if ( xnode.Attributes != null ) { string text ; foreach ( XmlAttribute attr in xnode.Attributes ) { text = attr.Name + " = " + attr.Value ; child.Nodes.Add ( new TreeNode ( text ) ) ; } } if ( xnode.HasChildNodes ) { foreach ( XmlNode node in xnode.ChildNodes ) additem ( node, child ) ; } }

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


The additem( ) method is used to traverse the document structure loaded in memory. It would start traversing from the node that is passed to it in xnode. For the first time, xnode would contain the root document node. From this method we have called another user-defined method called addnode( ). The addnode( ) method actually adds the XML node to the tree control at appropriate place and returns its reference. We have collected this reference in child. If the XML node that has been added to the tree has attributes, we must add them to the newly added tree node. To retrieve the attributes we have used the Attributes property. It returns all the attributes of the node in a collection. We have retrieved an attribute from collection in a foreach loop and added its name and value to the tree node. For this, we have used the Add( ) method. If the XML node has child nodes then this procedure should repeat for each child node. We have checked whether the XML node has children or not using the HasChildNodes property. Then for each node we have called the additem( ) method recursively. This time we are passing reference to the child node as first parameter and reference to the newly added tree node as the second parameter to the additem( ) method. The addnode( ) method is given below.

public TreeNode addnode ( XmlNode xnode, TreeNode tnode ) { string txt ; TreeNode child = new TreeNode( ) ; TreeNodeCollection tnodes ; if ( tnode == null ) tnodes = xmltree.Nodes ; else tnodes = tnode.Nodes ; switch ( xnode.NodeType ) { case XmlNodeType.Element: child = new TreeNode ( xnode.Name ) ; child.ImageIndex = 0 ; child.SelectedImageIndex = 2 ; tnodes.Add ( child ) ; break ; case XmlNodeType.Text: txt = xnode.Value ; if ( txt.Length > 128 ) txt = txt.Substring ( 0, 128 ) + "..." ; child = new TreeNode ( txt ) ; child.ImageIndex = 1 ; child.SelectedImageIndex = 3 ; tnodes.Add ( child ) ; break ; } return child ; } Let us now see the addnode( ) method. Here, firstly we have declared child as a reference of type TreeNode and tnodes of type TreeNodeCollection. The TreeNodeCollection object represents a collection of tree node objects. If the tree control is empty we must add the XML node as the root node of the control. Otherwise we must add the XML node as a child of tnode. We have achieved this by applying if condition on tnode.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


We have checked the type of XML node in the switch-case block. If the node type is element we have added its name to the tree node. Before adding, we have created the new node and collected its reference in child. This node is then added to the tree control. We have provided proper images using the ImageIndex and SelectedImageIndex properties. If the node type is text content we must add its value to the tree node. Before adding text content, we have checked whether its length exceeds 128. If it does, we have extracted first 128 characters and added ellipses () to it indicating the incomplete string. We have then created a new node child and added it to the tree control. Lastly, we have returned the reference to the newly created node. We have added a handler for the AfterSelect event of the TreeView control. This event is thrown when tree item selection is changed. In this handler we have obtained the path of the tree node and displayed it in the label.

private void xmltree_AfterSelect ( object sender, TreeViewEventArgs e) { lblpath.Text = xmltree.SelectedNode.FullPath ; } We have obtained currently selected tree node using the SelectedNode property. The FullPath property of the TreeNode class returns the path of the node with respect to the root node.

Article C# - Deploying .NET Applications - I


Though distributing libraries in the form of DLLs was a major step forward, it suffered from the now in-famous DLL hell. COM could avoid this but it had no versioning mechanism. Moreover a COM component had foot-prints at so many places that if one of them got modified/corrupted, the

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


application used to break down. .NET has come up with more sophisticated approaches for deployment and versioning. Deployment Issues Deployment is a process by which you distribute a finished application or component to be installed on other computers. In Visual Studio .NET, deployment is based on Microsoft Windows Installer technology. Microsoft Windows Installer is a service shipped with Windows Me, Windows 2000, and Windows XP. It is used for installation and configuration of applications to be installed. Every .NET application is deployed in the form of one or more assemblies. Assemblies may be deployed as regular standalone files (DLL or EXE files), or they may be deployed using CAB, MSI, or MSM files. The simplest way of deploying a private assembly is to use an XCOPY, i.e. copying the assembly in the desired folder. On the other hand we can deploy shared assemblies by installing them in the Global Assembly Cache of the target machine by using the Gacutil.exe. To help programmers develop setup and deployment solutions, Visual Studio .NET provides several templates and wizards. We can create a setup or deployment project by selecting Setup and Deployment Projects in the New Project dialog box shown in the following figure.

Let us first discuss the types of projects shown in the dialog box and see the usage of each. Later we have illustrated how to deploy different types of applications using these projects. Setup Project A setup project builds a Windows Installer file or an MSI file with the .msi extension. This file is used to install the specified files and resources on the target machine automatically. The .msi file contains the application, any dependent files, information about the application such as registry entries, and instructions for installation. When the .msi file is distributed and run on another computer, you can be assured that everything necessary for installation is included; if for any reason the installation fails (for example, the target computer does not have the required operating system version), the installation will be rolled back and the computer returned to its preinstallation state. CAB Project A CAB project creates a cabinet file with the .cab extension. It is much like a Zip file, compressing

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


a number of specified files into an easy to use and easy to deploy package. The resulting cabinet (.cab) file can then be deployed or downloaded. The files present in the .cab file can be extracted by double-clicking the .cab file. Merge Module Project A Merge Module project produces a merge module file having a .msm extension. A Merge Module is a single package that contains all files, resources, registry entries, and setup logic necessary to install a component. Merge Modules are used to install components that are shared by multiple applications. The basic distinction between a Merge Module (.msm) and a Windows Installer (.msi) is based on the user using these components. Whatever we wish to deploy directly to the end user of the application (executable files, documents, HTML pages) should be packaged in a Windows Installer, whereas, whatever we wish to deploy to the developer (DLLs, controls, resources) should be packaged in a Merge Module. The developer can then repack it in a Windows Installer for distribution to the end user. It is possible to put multiple components into a single Merge Module but it's best to create a Merge Module for each component in order to handle versioning problems. Once you have distributed a Merge Module it should never be modified; instead you should create a new Merge Module for each successive version of your component. Web Setup Project Web Setup Project helps us to deploy web-based applications. In addition to this any Windows application or its installer can be deployed to a web server so that users can later download and run them from a web site. In order to deploy web-based application we will have to build a Web Setup Project, copy it to the web server and run the installer to install it on the server. Setup Wizard The Setup Wizard is used to help us start creating any of the above-discussed projects in a fast and simple manner. We just have to follow some simple steps the wizard leads us through and the wizard does the initial job for us. Next we may extend the project further as per our requirements. Now let us understand the projects discussed above in detail. Setup Projects We know that a Setup Project creates an .msi file, which actually installs the application on the target computer. To demonstrate this we plan to deploy a simple Windows application using the Setup Project. Here we have assumed that the Windows application stands created and the .EXE named windowsapp1.exe is ready. To deploy this Windows application we need to select New | Project and select Setup and Deployment project from the available options. Next we must select Setup Project as the project template and specify the name (say winsetup) and the location of the setup project and click OK. Then we are taken to the File System Editor. The File System Editor is shown in the following figure.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

The File System Editor has three foldersthe Application Folder, the Users Desktop folder and the Users Programs Menu folder. These folders actually represent the folders on the target machine. For example, whatever you put in Users Desktop will be deployed on the desktop of the target machine. From the three folders in the file system editor, files from Application Folder would be deployed in the Program Files folder; typically it is C:\Program Files\Company Name\Application Name of the target machine. Users Desktop folder contains files and folders that would appear on the desktop of the target machine on a per-user basis. Typically the path is C:\Documents and Settings \username\Desktop. Users Programs Menu folder contains users program groups that would usually get deployed in C:\Documents and Settings \username\Start Menu\Programs. Now we need to add the Windows application EXE file into this project. For this we must right click on the Application Folder. A menu is popped. We must select Add | File and on doing so an Add Files dialog is popped. Now we need to browse for windowsapp1.exe file so that it gets added to the Application Folder. We can add the EXE to Users Desktop and Users Programs Menu as well but while doing so we must keep in mind that these two folders are on per-user basis. This means that only the user who installs the application would be able to access the file on his desktop and not the other users. This completes the basic steps needed to build an installer. We can now build this project and an installer called winsetup.msi would get created in the debug folder. Now all we need to do is to distribute this installer and on running the installer on the target machine the application would get installed there. On running the installer we get a series of screens depicting different stages of installation. Note that if our application needs more files than just the windowsapp1.exe then we can copy them to any of the above-mentioned folders. There is much more to a Setup Project than what we discussed above. We saw the simplest form and there are several more features that we need to explore. All the deployment capabilities discussed below are not mandatory and we can customize our installation process according to the needs of our application. Adding Shortcuts We can add shortcuts to our application in any of the 3 folders. For this we need to right click on

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


the application file (windowsapp1.exe) that we added to the project and select Create shortcut to windowsapp1.exe. On doing so a shortcut for our application would get created. Now we must drag this shortcut in the Users Desktop Folder. If we wish to add a shortcut in Users Programs Menu also, we need to create another shortcut in the same manner discussed above and drag it in the folder. On building and installing the application, the shortcuts get added in the specified folders of the target machine. Adding Registry Entries We can make a provision that some registry entries would be added for a particular application during installation of the application. We can then access these entries later through our applications code at run-time. To add the registry entries we must right click on winsetup in the Solution Explorer and select View | Registry. On doing so we will be presented with the Registry Editor shown in the following figure.

Article C# - Deploying .NET Applications - II


Suppose we wish to add a key-value pair to HKEY_CURRENT_USER | Software | [Manufacturer]. For this we must right click on it and select New | Key. We can rename the key as per our wish. To add a value we need to right click on the newly formed key and select the type of value we wish to add, i.e. whether it should be a String value, a DWORD value, a Binary value, etc. We can set it to some value using the Properties Window. Now if we build winsetup and install the application, the entry would be made in the registry. We can verify this by executing the Registry Editor RegEdit through the Start | Run dialog box. Adding Custom Installation Dialog Boxes Once the MSI file is built and we double click on it, the installation starts. The user is presented with five dialog boxes during installation. These dialog boxes are predefined dialog boxes that get added to our project by default. We can customize these dialogs or new dialog boxes to our project using the User Interface Editor. This editor can be opened by right clicking on the project in Solution Explorer and selecting View | User Interface. The User Interface Editor shows a tree control containing two sectionsInstall and Administrative Install. The Install section contains dialog boxes that will be displayed when any end user runs

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


the installer. Administrative installation is a feature of Microsoft Windows Installer that allows us to install a source image of an application on a network share. Users in a workgroup who have access to the network share can then install the application from the source image. The User Interface Editor allows us to specify a different set of installation dialog boxes that will be displayed when an administrator installs the application to a network share via the command line as shown below:

Msiexec.exe /a Setup1.msi This will start the installer of our application and dialog boxes specified for the Administrative Install will be displayed. The default set of predefined dialog boxes is displayed in the User Interface Editor; we can rearrange or delete these if we wish. The default set of dialog boxes varies according to the type of deployment project. Predefined dialog boxes are divided into three categories: Start Dialog Boxes Start dialog boxes are displayed before the installation begins. Commonly they are used to gather customer information or to allow the user to change the installation directory. Progress Dialog Boxes A progress dialog box is displayed to provide feedback on the progress of an installation. End Dialog Boxes End dialog boxes are displayed once the installation has finished successfully. Common uses are notifying the user that the installation is complete or to allow the user to launch the application. We can remove dialog boxes from the default set as per our wish or reposition them using the right click | Move Up/Move Down options. Note that all combinations are not possible here. For example, we cannot remove the Progress dialog box and place it in the Start dialog boxes category after the Welcome dialog box. Now in addition to these dialog boxes we can add and configure our own custom dialog boxes that would get displayed during the installation. To do so we need to right click on the desired category and select Add Dialog. On doing so the Add Dialog Box gets displayed. Here we are presented with several ready-made dialog boxes that we may want to get displayed during installation. Following table indicates the use of these dialog boxes. Dialog Box RadioButtons (2 buttons) RadioButtons (3 buttons) RadioButtons (4 buttons) Checkboxes A, B, or C Purpose Gives the user a choice between two options through two radio buttons. Gives the user a choice between three options through three radio buttons. Gives the user a choice between four options through four radio buttons. Gives the user a choice to add 1, 2, 3 or 4 checkboxes in the same dialog.

Customer Information Used to retrieve information including name, company, and

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


serial number. Textboxes A, B, or C License Agreement Read Me Register User Splash Used to retrieve custom information using 1, 2 or 3 text boxes. Displays a license agreement for the user to read and acknowledge. Allows the user to view any Read me file in .rtf format. Allows the user to submit registration information. Displays a Splash Screen in .bmp format during installation.

Out of the several dialog boxes listed in this table we would discuss only the ones that are likely to be used more commonly. These include the Checkbox dialog box, Read Me Dialog box and the Splash dialog box. The Checkbox Dialog Box Suppose during installation we plan to ask the user whether he wants to add the Disclaimer.txt file along with windowsapp1.exe or not. To control this we plan to add the Checkbox dialog box. If the user checks the Checkbox, the text file gets installed. To add this custom dialog box we have followed the same steps discussed above and added the Checkboxes (A) Dialog. This dialog box would get added as the last dialog box of the Start dialog boxes category. So we can move it up by two positions. Next we have changed some properties of the Checkboxes (A) dialog box. These are shown in the following table. Property BannerText BodyText Checkbox1Label Checkbox1Value Checkbox1Visible Checkbox2Visible Checkbox3Visible Checkbox4Visible Changed to... Disclaimer Do you want to install the Disclaimer text file? Install Disclaimer Unchecked True False False False

Note that we have changed the visible property of the remaining checkboxes to false because we need just one checkbox. Now we need to add a folder in the Application Folder named Disclaimer. For this we must right click on the Application Folder and select Add | Folder. This would add a new folder we have renamed it to Disclaimer. Next we added a text file called Disclaimer.txt to this folder. Hence the Application Folder would contain the windowsapp1.exe along with the Disclaimer folder holding the Disclaimer.txt file. Then comes the most important step of setting the Condition property of the Disclaimer.txt file so that it would only get installed when the checkbox is checked. To do this we need to open the Properties Window of the Disclaimer.txt and set its Condition property to CHECKBOXA1=1. On building the winsetup.msi project, and double clicking it we are presented with this dialog box in the second step of the installation process. The Disclaimer dialog box is shown in the following figure.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

The Read Me Dialog box This dialog box displays the Read Me file during installation procedure and installs it along with the application. To demonstrate this we must add the Read Me dialog box in the Start dialog boxes category. Next we need to associate a Rich Text File (rtf) with this dialog box. For this we have to create a ReadMe.rtf file and add it to the Applications Folder. Next we have to set the ReadmeFile attribute of the Read Me Dialog box to this file. We can browse for this file and since we had added it to the Applications Folder we will find it there. Note that we cannot browse beyond the three folders (Application Folder, Users Program and Users Programs Menu), hence if we wish to make any file available in the project we have to first get it copied in one of these. Now after re-building the project and installing it we are presented with this Read Me dialog box as the 5th step of installation and this file gets copied along with the folder. The Splash Dialog Box We added the Splash dialog box just after the Welcome dialog box. The User Interface Editor after addition of all the dialog boxes is shown in the following figure.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

To display a splash screen in the Splash dialog box, all we need to do is to set the SplashBitmap property of the dialog to a .bmp file. To make the file available we must first add it to the Application Folder. On re-building this project and running the installer we are presented with the Splash dialog box. In the next part we would see how to add launch conditions to the setup project.

Article C# - Using the FileSystemWatcher Component


In this article we would walk through the process of using the FileSystemWatcher component and watching the changes made to a subfolder/files of a selected folder. The FileSystemWatcher component can keep track of creation, deletion, changing and renaming of a file/folder. It conveys the application about changes done to the file system by throwing events. It throws the Created, Deleted, Changed and Renamed events respectively. The name and path of the file/folder being changed is also made available in the event handlers. The FileSystemWatcher component can watch files on a local computer, a network drive, or a remote computer. We can specify which files to watch by setting the appropriate value in the Filter property. If we wish to watch all the files we must set the Filter property to an empty string (). To watch a specific file, we must assign that file name to the Filter property. We can also use wildcards to specify certain type of file. For example, to watch for changes in EXE files, we can set the Filter property to *.exe. The component has a property called NotifyFilter that can be used to specify the types of changes viz. changes in attribute, last write date and time, size, etc. Having this much of knowledge about FileSystemWatcher component in hand, we can now use the component in our application. We would create an application that uses the FileSystemWatcher control to keep watch on the folder selected by the user. We would watch whether a file/folder is created, changed or deleted.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Create a WinForm application and put the controls on the form as shown in Figure 1.

Figure 1 We have added three list boxes to list the files/folders being created, changed or deleted. The Watch Folder button allows user to select a folder to watch. The path of the selected folder gets displayed on the label placed next to the Watch Folder button. The Clear button allows to delete the items listed in the list box having input focus. In addition to these controls, add the FolderBrowserDialog control from the Windows Forms tab and FileSystemWatcher component from the Components tab of the ToolBox. The controls, their names and event handlers are given in the following table. Controls Created list box Changed list box Deleted list box Clear button FileSystemWatcher Name listcreate listdelete butclear watcher Handler butwatch_Click butclear_Click -

listchange -

Watch Folder button butwatch

FolderBrowserDialog browser

Add handlers for the Created, Deleted and Changed events. Also Set the IncludeSubdirectories property of the FileSystemWatcher component to true.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

When the application is run, the user has to first select a folder to watch. He can do so by clicking the Watch Folder button. We have displayed the Browse For Folder standard dialog box in which user can select the folder. The dialog is displayed by calling the ShowDialog( ) method as shown below.

private void butwatch_Click ( object sender, System.EventArgs e ) { if ( browser.ShowDialog( ) == DialogResult.OK ) { watcher.Path = browser.SelectedPath ; label1.Text = browser.SelectedPath ; } } We have specified the folder to watch by setting the Path property of the FileSystemWatcher class to the path of selected folder. The path of selected folder is retrieved from the SelectedPath property of the FolderBrowserDialog class. We have displayed the path on the label. The handlers added for the FileSystemWatcher events are given below.

private void watcher_Changed ( object sender, System.IO.FileSystemEventArgs e ) { listchange.Items.Add ( e.FullPath ) ; } private void watcher_Created ( object sender, System.IO.FileSystemEventArgs e ) { listcreate.Items.Add ( e.FullPath ) ; } private void watcher_Deleted ( object sender, System.IO.FileSystemEventArgs e ) { listdelete.Items.Add ( e.FullPath ) ; } In these handlers we have only added the full path of the file/folder being changed, created or deleted in the respective list boxes. To clear a list box, the user has to select an item in that list box and click the Clear button. The handler for the Clear button is given below.

private void butclear_Click ( object sender, System.EventArgs e ) { if ( listcreate.SelectedIndex != -1 ) listcreate.Items.Clear( ) ; else { if ( listchange.SelectedIndex != -1 ) listchange.Items.Clear( ) ; else if ( listdelete.SelectedIndex != -1 )

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


listdelete.Items.Clear( ) ; } } The SelectedIndex property returns 1 if no item is currently selected. If any item is selected, the condition becomes true and the list box gets cleared. Figure 2 shows our application at work. The list boxes seem to have trapped few files being changed.

Article C# - Deploying .NET Applications - III


In the last article we saw how to add custom dialog boxes to the setup project. We would now add the launch conditions to it. Sometimes our application may require some pre-requisites before installation. For example, our application may demand that Internet Explorer 5.0 or higher must be installed on the target machine. This calls for a check that must be satisfied for successful installation of the application. We can apply Launch Conditions in such cases. If the condition specified during this step (here, Internet Explorer installed) is not fulfilled then the installation halts. Note that here this step is intended to demonstrate the concept of launch conditions and windowsapp1.exe has no actual dependency on Internet Explorer. To add launch conditions we need to right click on the project in the solution explorer and select View | Launch Conditions. On doing so a Launch Condition Editor will get opened. Next we need to right click on the Requirements on Target Machine node and we would be presented with 5 options to choose fromAdd File Launch Condition, Add Registry Launch Condition, Add

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Windows Installer Launch Condition, Add .NET Framework Launch Condition, and Add Internet Information Services Launch Condition. As the names suggest we can check for the specified entities on the target machine and if these entities are present on the target machine, the installation proceeds otherwise it halts. Here we have added the Add File Launch Condition. On doing so two nodes called Search For File1 and Condition1 would get added in the Search Target Machine and Launch Conditions nodes respectively falling under the Requirements on Target Machine node. We changed the properties shown in the following table for the Search For File1 entity. Property Name FileName Folder Depth MinVersion Changed to... Search For Internet Explorer Iexplore.exe [ProgramFilesFolder] 3 5.00 Used Specifies the name used in Launch Condition Editor. Specifies the name of a file to search for. Specifies the folder where a file search will start. Specifies the number of levels of subfolders to search for a file. Specifies the minimum version number for a file in the file search.

Now we need to specify the launch condition. To do so we must set the Condition property of the Condition1 entity to FILEEXISTS1. Note that in the Properties window of Search For File1 the Property property is set to FILEEXISTS1. We can also specify a message through the Properties window that would be displayed if the condition evaluates to false (i.e. if file is not found) at installation time. Changing Icons We can change icons for our application using the Properties window. To change the icon for the shortcuts we must select the shortcut file and set the Icon property of the file to any .ico file. Note that we need to first copy this file to the Application Folder to make it available. On the same lines we can change the icon of the setup file that would be displayed in the Add/Remove Programs Window. To do so, we must right click on winsetup in Solution Explorer and select Properties. This would display the Properties window of the whole solution. Here we need to set the AddRemoveProgramsIcon to any desired file. Adding File Associations Suppose our application creates files having the userdefined extension (for example, we can serialize data in a file having the .mine extension) and now we wish that on double clicking such a file it should automatically get opened in our application. To achieve this we must use file associations. File Associations allows the developer to associate user-defined file types with his or her application. Assume that we need to deploy a file called myfile.mine with our application. To deploy it along with the application we first need to copy it in the Applications Folder. After installation whenever the user double clicks on this file it should get opened with windowsapp1.exe. Note that here too we have made an assumption for demonstration purpose that our application is creating files having .mine extension. Actually windowsapp1.exe is too simple and does not do any serialization or file I/O. Now to associate this file with our application we must right click on the project name in the Solution Explorer and select View | File Types. On doing so we are presented with the File Types Editor. Next we need to right click on the node and select Add File type. Now we need to give any

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


file name (here we have used file1) along with the extension (.mine) in the Properties window. This ensures that any file with the .mine extension would get opened with our application. Note that we need not specify the dot ( . ) while mentioning the extension. After this we have to set the Command property of the file to windowsapp1.exe. The File Types Editor along with the Properties window is shown in the following figure. Now on re-building the project and running the installer, myfile.mine would get deployed along with the application. And moreover whenever the user double clicks on this file it gets opened with our application. Adding Custom Actions Custom actions allow us to run code at the end of an installation to perform actions that cannot be handled during installation. For example, if we wish to create a database after installation and before running the deployed application, we need to add the DLL or EXE, which would create a database, as a custom action. We can add custom actions through the Custom Actions Editor. The Custom Actions Editor can be opened by right clicking on the project name and selecting View | Custom Actions. The Custom Actions Editor is shown in the following figure.

This editor contains four folders, each corresponding with a phase of installationInstall, Commit, Rollback, and Uninstall. Custom actions are run in the same order that they are displayed in the editor. They can be reordered by dragging with the mouse or through the Cut and Paste commands on the Edit menu. All the Custom Actions run at the end of installation. In addition to the custom actions we add, there are 5 pre-defined custom actions included in Visual Studio .NETEvent Log, Message Queue, Performance Counter, Service, and Service Process components. We can also add these predefined Custom Actions in our project. Deploying to Special Folders In addition to the folders mentioned in the previous sectionApplication Folder, Users Desktop, and Users Programs Menuwe can add more folders to the File System Editor through the Add Special Folders menu. If we right click on the left pane of the File System Editor we get a popup menu offering fourteen folders from which we can select the ones that we can add.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


On selecting a folder from this menu it gets added to the File System on Target Machine tree. This provision is made so that we can deploy our files to these specific folders on the target machine. For example, if we have a signed assembly and we wish to deploy it in the Global Assembly Cache of the target machine, all we need to do is add the Global Assembly Cache folder in the File System Editor and copy our signed assembly to it. On installing the application on the target machine one can find the assembly installed in the Global Assembly Cache. That brings us to the end of discussion on how we can customize our MSI project according to the requirement of the application we want to deploy. If we wish to deploy the application on the development computer while building it, we have to right click on the project name in the Solution Explorer and select Install. And if we wish to deploy it on another computer then, as it might be very obvious to you by now, we need to distribute the winsetup.msi file.

Article C# - Deploying .NET Applications - IV


Merge Modules are a feature of Windows Installer that provides a standard method for delivering components, ensuring that the correct version of a component is installed. Merge Modules is something that we would give to a developer and not the end user. For example, if we want to distribute our DLL to another developer, well create a Merge Module for it and distribute our DLL in a Merge Module. While deploying a finished product the developer will include this Merge Module in his MSI project and give it to the end user. Merge Modules are used to install components that are shared by multiple applications. Now let us proceed with creation of a Merge Module. Here we have assumed that a Class Library stands created and the .DLL named mylib.dll is ready. To create a merge module we need to select Merge Module from the project templates available and name it, say mergesetup. On doing so we are taken to the File System Editor. The File System Editor is shown in the following figure.

The File System Editor has two foldersCommon Files Folder and Module Retargetable Folder falling under File System on Target machine. Files present in a Merge Module are generally sharable files hence Common Files Folder is a good option to deploy the files. Whichever file we copy in this folder gets deployed to the Common Files folder of the target machine. Here too we have an option of adding special folders to the File System Editor by right clicking on the left pane and selecting the desired folder. Files deployed in these folders would get deployed to corresponding folders on the target machine.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


The other folder, i.e. the Module Retargetable Folder, offers a lot of flexibility in deciding where files should be installed. Let us see how. Now suppose the author of the merge module is not sure where the developer wants the file to get deployed on the end users machine. In such a case the author of the Merge Module must copy this undecided file into the Module Retargetable Folder and set a default location for this file using the Properties window. This gives the developer a chance to change or retarget the location of the file later while deploying the whole application to the end user. Let us see how it is done. For this we need to copy mylib.dll in the Module Retargetable Folder and set the DefaultLocation property of the Module Retargetable Folder to [GAC]. Next we must build the Merge Module. On doing so a mergesetup.msm file would get created in the debug folder. We can now give this .msm file to the developer. Now assume that the developer creates a Setup project called msimerge.msi. To add the Merge Module to the project he needs to right click on the project name in the Solution Explorer and select Add | Merge Module. He can then browse for mergesetup.msm and add it to his project. Now to retarget the file all he needs to do is open the Properties window of the mergesetup.msm and set the Module Retargetable Folder property to any desired location. For example, if he wants the file to get installed in Common Files Folder and not GAC as specified by the author of the Merge Module then he might change the property. The Module Retargetable Folder property falls under the MergeModuleProperties in the Properties window. Now whenever the end user installs the msimerge.msi, mylib.dll gets installed in the Common Files Folder. Note that the developer can (and surely will) add his own application and associated files in msimerge.msi along with mergesetup.msm for deployment. CAB Projects Unlike the other deployment project types, there are no editors provided for working with CAB projects. Files and project outputs can be added to a CAB project through Solution Explorer, and properties can be set in the Properties window or in the Project Property pages. For .NET deployment, a CAB file can contain only one assembly, and the CAB file must be assigned the same name as the contained assembly, but with the .cab extension. For example, if we create a cabinet file for mylib.dll, we need to name the cabinet file as mylib.cab. Creating a cab file is very simple. Let us see how to create it. To create a Cabinet or CAB project we select the Cabinet Project template from the New Project dialog and name it, say mylib. To add files to this project, we need to right click on the project name and select Add | Files. This would add the specified files in the project and on building the project the mylib.cab file would get created which can be deployed to target machines. Double clicking on the cab file extracts the files compressed in it. Deploying Windows Applications On Web We have discussed two cases here. First we have explained the method by which a Windows application (.exe) can be executed directly on the web and second by which an installer (.msi) of the Windows Application can be downloaded from the web. For both the scenarios we have assumed that windowsapp1.exe stands created. And for both we first need to create a Web Setup project. To create a Web Setup project we selected the Web Setup Project from the project templates and named it websetup. On doing so, the File System Editor of websetup would get opened. Now we need to add windowsapp1.exe to the Web Application Folder as shown in the following figure.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Next we need to change two of the properties of the Web Application Folder. First we have to set the AllowDirectoryBrowsing property to True. This property determines whether users can see a hypertext listing of files and subdirectories in a virtual directory. If it is set to True, users can browse for it. Next we have to set the VirtualDirectory property to myweb. Now we need to build websetup and copy the websetup.msi file to the web server. On double clicking the MSI file the project would get installed. To test the project we need to start Internet Explorer and type the http:\\computername\myweb URL. You will see the name of the windowsapp1.exe file in the browser window. On clicking filename the EXE would get executed. For the second scenario we need to follow the same steps as given above, but instead of copying the EXE to the Web Application Folder, we need to copy an MSI (winsetup.msi) project, which includes the EXE to the folder. Then on deploying and installing websetup.msi we would get the window displaying the name of the websetup.msi file. On clicking it we would be presented with a dialog box that gives us options to install or download the MSI. On installing or downloading the MSI we would be able to execute the Windows application. Setup Wizard As told to you earlier the Setup Wizard helps us to start the deployment projects. The wizard guides us through the steps of creating setup program that contains all information required for installation. The steps in the Setup Wizard are self-explanatory. As soon as we select Setup Wizard, give the project a name (say wizsetup) and press OK, we are presented with a Welcome dialog. On clicking Next we are presented with the Step 2 window of the wizard. It asks us type of project we intend to make. Suppose we select the first option and click Next, we get the third dialog box. Here the Wizard asks us to add the files we wish to deploy. We can add the files by clicking on the Add button and browsing for the desired files. On clicking the Next button the Wizard presents us with the summary of the project. We had selected the first option and hence on clicking the Finish button the Wizard takes us to the File System Editor of the project. We can now build the project as we would build any deployment project.

Article C# - Binding Data With WinForm Controls

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Gone are the days when we required to read records from a data source, separate the values of a record in a set of variables and display the values in controls by writing page full of code. .NET provides an ability that binds a control with a field in the data source. ADO.NET provides a common set of classes for data binding for WebForm and WinForm controls. In this article we will see data binding with the WinForm controls. Create a WinForm application and design the form as shown below.

We will bind the controls to the data source of a hospital management system. The list box will display patient IDs. On selecting the ID, patients name, his address and doctors name will get displayed in text boxes. The patients photograph will get displayed in the picture box. The controls, their names and handlers are given in the following table. Control ListBox Name TextBox Address TextBox Picture Box Name list name address photo

Add the following data members to the Form1 class.

private SqlDataAdapter m_da ; private DataSet m_ds ; private BindingManagerBase m_bman ; We will first fill the dataset with the data we wish to bind with the control. For this, add the following statements to the constructor of the Form1 class.

m_da = new SqlDataAdapter ( "SELECT * FROM PatientInfo", "SERVER=localhost;database=hospital;uid=sa;" ) ; m_ds = new DataSet( ) ; m_da.Fill ( m_ds, "PatientInfo" ) ; We have read the hospital database and filled the dataset with the PatientInfo table. Fill the list box with patient IDs using the following statements.

DataTable dt = m_ds.Tables [ "PatientInfo" ] ; for ( int i = 0 ; i < dt.Rows.Count ; i++ )

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


list.Items.Add ( dt.Rows [ i ][ 0 ].ToString( ) ) ; Lets now see how data binding works. Binding data with control actually means binding a property of a control with a column of a data source. When the form is loaded the data bound property gets evaluated and the value returned is displayed in the control. For example, the Text property of TextBox control can be bound to a column of a data source. A WinForm control maintains a collection of its data bindings in the ControlBindingsCollection class. The data bindings in the collection are maintained using the DataBindings property. The DataBindings list is set once, stays up forever. The list is defined in a position-agnostic fashion. In fact, the control does not know about the current row to which it is bound. We will see how to select the row to be displayed later. Firstly, we would see how to bind the control property with data source. Consider the following statements.

Binding bname = new Binding ( "Text", m_ds, "PatientInfo.PatientName" ) ; name.DataBindings.Add ( bname ) ; Here, we have created a new data binding using the Binding class. We have passed three parameters to its constructor. The first parameter is the binding property. Second parameter is the data source and third specifies the table.column in the data source. So, we are binding the Text property with the PatientName column of PatientInfo table. We have added this data binding to the collection of data bindings of the Name text box using the Add( ) method. The property does not always evaluate to the required data type. The Binding class enables us to format the values for display through the Format event. We will see how to use this event while binding data to the Image property of the Picture Box control. Also bind the rest of the controls as shown below.

Binding baddress = new Binding("Text", m_ds, "PatientInfo.PatientAddress") ; address.DataBindings.Add ( baddress ) ; Binding bdname = new Binding ( "Text", m_ds, "PatientInfo.DoctorName" ) ; dname.DataBindings.Add ( bdname ) ; Binding bphoto = new Binding ( "Image", m_ds, "PatientInfo.Photograph" ) ; bphoto.Format += new ConvertEventHandler ( convertpicture ) ; photo.DataBindings.Add ( bphoto ) ; Add these statements in the constructor after the call to the InitializeComponent( ) method. Note that we have added a handler to the Format event. We need to add this handler because the required type is Image, whereas, the contents of the Photograph field resolve to Byte[ ]. The Format event is raised when the data is transferred from data source to control and when the data is transferred from control to data source. The event handler convertpicture transforms an array of bytes into a Bitmap object that can be safely assigned to the Image property of a PictureBox control. The handler is given below.

void convertpicture ( Object sender, ConvertEventArgs e ) { Byte[] b = ( Byte[] ) e.Value ; MemoryStream ms = new MemoryStream( ) ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


ms.Write ( b, 0, b.Length ) ; Bitmap bmp = new Bitmap ( ms ) ; ms.Close () ; e.Value = bmp ; } The Value property contains the data, the image in our case, read from the data source. We have first written the chunk of bytes containing the image into a memory stream. This is necessary because we cannot create a bitmap using the Bitmap class directly from a byte array. The memory stream object is then passed to the constructor of the Bitmap class and the bitmap object is assigned as the new contents of the Value property. The BindingContext property of the Form class returns bindings involved for a particular data source. However, it does not return an object of the Binding class. Instead it returns a supervisory object of the BindingManagerBase class. The BindingManagerBase class handles a specific data source and provides a property called Position that maintains the row index. We are going to use this property to select the data to be displayed in the controls. We would first collect the object of the BindingManagerBase class. Write the following statement in the constructor.

m_bman = BindingContext [ m_ds, "PatientInfo" ] ; This line selects all the bindings that involve the m_ds data source and PatientInfo data member from the forms binding context. As said earlier, we would select the patients ID from the list box. The record containing this ID will be displayed in the controls. For this purpose, we need to change the position in the binding context using the Position property. Add the handler for the SelectedIndexChanged event and change the position as shown below.

private void list_SelectedIndexChanged ( object sender, EventArgs e ) { m_bman.Position = list.SelectedIndex ; } When the application is executed, the data at zeroeth position would get displayed in the controls. For this, set the selected index to 0 in the constructor after collection the binding manager base object.

list.SelectedIndex = 0 ;

Article C# - Application Domains


Under Windows it is not possible to access data of one application from another application. This is because Windows creates process boundaries for each application. The code as well as the data of an application is stored in its process boundary. Windows provides security by not allowing one application to enter into the process boundary of another application. Hence data cannot be shared. In general, communication is not possible across process boundaries making the application more secured. Note that using sockets we can communicate between two separate applications/processes. But

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


this communication is purely text based, means we cannot pass integers, floats, etc. through sockets. Also, we cannot call methods across process boundaries. If we want to pass the data or call methods across process boundaries without affecting the security of applications, we need to use the DCOM protocol. This protocol uses a concept called marshalling to pass the data and unmarshalling to accept the data. But marshalling/unmarshalling is time consuming and hence is slow. There is a need for a way that would provide bothsecurity as well as performance. .NET uses a concept called Application Domain using which two separate applications can safely communicate with each other without affecting the performance. In .NET when an application is loaded in memory a process is created and within this process an application domain is created. The application is actually loaded in the application domain. If this application communicates with another application, .NET loads the other application in a different application domain. This application domain may belong either to the same process or to a different process. Thus one process can host multiple application domains. If loaded in the same process then the communication between the two applications is more efficient because the overheads involved in inter-application domain communication are less as compared to interprocess communication. In Remoting the communication happens between two application domains running in same or different processes on physically same or different machines connected to an intranet or internet. Following figure demonstrates two applications loaded in different application domains.

Communication between application domains is encapsulated in the AppDomain class. Lets create a simple application called firstdomain that uses the AppDomain class.

static void Main ( string[ ] args ) { AppDomain a = AppDomain.CurrentDomain ; Console.WriteLine ( a.FriendlyName ) ; } The AppDomain class is used to create and terminate application domains and load and unload assemblies. The CurrentDomain property holds reference to the current domain. The FriendlyName property gets the friendly name of this application domain. The friendly name of the default application domain is the name of the application loaded in the application domain. This program just extracts the name of the exe running in the current domain. Now write another program named seconddomain.

static void Main ( string[ ] args ) {

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


AppDomain sec = AppDomain.CurrentDomain ; Console.WriteLine ( sec.FriendlyName ) ; AppDomain first ; first = AppDomain.CreateDomain ( "mydomain" ) ; first.ExecuteAssembly ( "firstdomain.exe" ) ; } In the second program we have first extracted the name of the EXE running in the current domain. Then we have created a new domain, loaded and executed another EXE in that domain. The CreateDomain( ) method of the AppDomain class creates a new application domain called mydomain. The ExecuteAssembly( ) method executes the specified executable file. The firstdomain.exe runs in the newly created domain called mydomain. Before running the second application we must make sure that we copy the firstdomain.exe in the bin folder of the current project. Now lets look at a more complex program in which we share data between two applications running in the same process but different application domains. Suppose we have a class Stack containing methods to push and pop elements. A program in the same project uses this class. When compiled, the program gets converted to an EXE. If the developer of this program wants to make the Stack class residing in an EXE reusable, the developer needs to expose the class implementation through an interface. To do this the developer needs to declare an IStack interface containing push( ) and pop( ) methods in a library project and compile it to a DLL. Then adding the reference of this DLL in the project having the Stack class the developer needs to implement the IStack interface in the Stack class.

Here is the IStack interface declared in StackLib library.

public interface IStack { void push ( int item ) ; int pop( ) ; } Design the Stack class and use it in the StackDemo project as shown below.

public class Stack : MarshalByRefObject, IStack { int [ ] arr = new int [ 10 ] ; int top ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


public Stack( ) { top = -1 ; } public void push ( int item ) { if ( top >= 9 ) { Console.WriteLine ( "Stack is Full" ) ; return ; } top += 1 ; arr [ top ] = item ; } public int pop( ) { if ( top == -1 ) { Console.WriteLine ( "Stack is Empty" ) ; return -1 ; } int data = arr [ top ] ; top -= 1 ; return data ; } } static void Main ( string[ ] args ) { Stack s = new Stack( ) ; s.push ( 20 ) ; s.push ( 5 ) ; s.push ( 15 ) ; s.push ( 12 ) ; s.push ( 6 ) ; Console.WriteLine ( s.pop( ) ) ; Console.WriteLine ( s.pop( ) ) ; Console.WriteLine ( s.pop( ) ) ; Console.WriteLine ( s.pop( ) ) ; } Here the Stack class has been derived from MarshalByRefObject class that allows data marshalling. Hence, we can now send data from one application domain to another. This class also implements the IStack interface. Now we wish to use the Stack class in another EXE. Recall that we cannot create an object of the Stack class in another EXE because we cannot add a reference of an EXE in another project, and hence we have no access to this class. So, to use an object of the Stack class in an EXE we must execute the EXE containing the Stack class in another application domain and then gain access to the object of this class. Create another project named seconddemo and write the code as shown below.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

using stacklib ; using System.Runtime.Remoting ; static void Main ( string[ ] args ) { AppDomain a ; a = AppDomain.CreateDomain ( "mydomain" ) ; ObjectHandle o ; o = a.CreateInstance ( "stackdemo, "stackdemo.Stack" ) ; IStack s = ( IStack ) o.Unwrap( ) ; s.push ( 10 ) ; s.push ( 5 ) ; s.push ( 3 ) ; Console.WriteLine ( s.pop( ) ) ; Console.WriteLine ( s.pop( ) ) ; Console.WriteLine ( s.pop( ) ) ; AppDomain.Unload ( a ) ; } First of all we would have to copy the stackdemo.exe in the bin folder of the current project. Here we have first created a reference of AppDomain class called a and created a new application domain. Then we have used the CreateInstance( ) method to create an instance of a class that is passed as the second parameter to this method. The assembly in which the class is present is passed as the first parameter. The object of the specified class would get created in the domain mydomain. This method returns the object of type ObjectHandle. This returned object is nothing but a wrapper around the object of the class Stack. To extract the actual object, we must unwrap it using the Unwrap( ) method. Here the reference that we need to create to store the reference of the unwrapped object must be of type Stack. Realize that we cannot create a reference of the Stack class in this EXE. Hence we have created a reference s of its base class IStack and stored the reference of the Stack object in it. The IStack reference can be created here because we can easily add a reference of the DLL, containing the definition of IStack, in the EXE. This is the reason why we created another DLL for the IStack interface. Now using this reference we have called methods from the application domain. Next we have unloaded the application domain using the Unload( ) method.

Article C# - Grooming the DataGrid Control


Programmers are never satisfied with what is shipped with a development environment. They always require something else than what is available to create an application using that environment. For example, instead of normal menus, we may want menus to appear sliding. Instead of the blue colored menu selection bar, we may want to change it to suit the current skin of the application window. In short, developers try to customize the available controls to suit their requirements. If you are thinking of customizing the DataGrid control to give it a different look then this article will prove helpful to you. In this article we will change the background and foreground color of the currently selected row in the DataGrid control. We will also rearrange the sequence of the columns before displaying the data in the table. Create a WinForm application and place the DataGrid control on it. Open the Server Explorer window. Go to the table, which you want to provide as data source. Drag and drop the table on the DataGrid control. If it requires password to access the data source, a message box will be popped up to ask you whether you want the password to get displayed in source code or not. Say

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


yes to it otherwise connection string will lack the password and connection to the data source will not get established. The following references will get added as data members of the Form1 class.

private.SqlCommand sqlSelectCommand1; private SqlCommand sqlInsertCommand1; private SqlConnection sqlConnection1; private SqlDataAdapter sqlDataAdapter1; The command string for SELECT and INSERT statements as well as the connection string also get created. Now right-click on the SqlDataAdapter1 component and select Generate DataSet from the popup menu. The Generate DataSet dialog box appears. Change the DataSet name to ds1 and click OK. This adds a DataSet reference to the component tray. Add the Load event handler and write the following statement in it.

sqlDataAdapter1.Fill ( ds1 ) ; The InitializeComponent( ) method contains the code to connect to the data source. Check whether the connection string is constructed properly and then run the program. You will see the datagrid control filled with data as shown in the following figure.

The control in our form shows records of the bank database. For the field having datatype bit (or boolean) DataGrid control displays a checkbox. Records having value 1 (or true) in that field appear checked. Let us now start the customization work. Firstly, we would arrange the order in which columns should appear. By default DataGrid shows the columns in order specified in the SQL query. If we want to change this order we can change the query. However, what if the order of columns is dependent on an action taken by the user? This can be managed by using the DataGridTableStyle class. Dont confuse this class with the table (datasource) displayed in the DataGrid control. The DataGridTableStyle class represents the grid drawn in the control.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Therefore, to customize the appearance of the grid for a DataTable, we can use the DataGridTableStyle class. To associate the name of the table with a table style the MappingName property of the DataGridTableStyle class is initialized with the table name i.e. the name of the data source. Name of our table happens to be account. The DataGrid class has a property called TableStyles. It returns a reference to the object of the GridTableStylesCollection class. An object of the GridTableStylesCollection class holds a collection of the objects of DataGridTableStyle class. Each object can specify different table styles. The DataGridTableStyle class has a property called GridColumnStyles. It returns a reference to an object of the GridColumnStylesCollection class. This collection holds objects of the DataGridColumnStyle class. We can customize the appearance of a column through the DataGridColumnStyle class. To associate a column style with a column in the data table, we must initialize the MappingName property of the DataGridColumnStyle class with the column name. We cannot instantiate the DataGridColumnStyle class because it is an abstract class. Instead we use the derived classes DataGridTextBoxColumn or the DataGridBoolColumn. The DataGridBoolColumn makes the column look and behave like a check box. This class is useful when we have a field of type bool in the data source. We would now write the code to customize the columns, add the column styles in the columns style collection maintained in the table style object, and then add the table style to the datagrid control. This code is to be written in the Load event handler.

DataGridTableStyle ts = new DataGridTableStyle( ) ; ts.MappingName = "account" ; DataGridBoolColumn bcol = new DataGridBoolColumn( ) ; bcol.MappingName = "ATM" ; bcol.Width = 30 ; bcol.AllowNull = false ; ts.GridColumnStyles.Add ( bcol ) ; DataGridTextBoxColumn column = new DataGridTextBoxColumn( ) ; column.MappingName = "accno" ; column.HeaderText = "Account No." ; column.Width = 80 ; ts.GridColumnStyles.Add ( column ) ; column = new DataGridTextBoxColumn( ) ; column.MappingName = "name" ; column.HeaderText = "Name" ; column.Width = 110 ; ts.GridColumnStyles.Add ( column ) ; column = new DataGridTextBoxColumn( ) ; column.MappingName = "bal" ; column.HeaderText = "Balance" ; column.Width = 110 ; ts.GridColumnStyles.Add ( column ) ; dataGrid1.TableStyles.Add ( ts ) ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


We have changed the order of columns as ATM, accno, name and bal. Here, we have used the properties like HeaderText and Width to change the column heading and width of the columns respectively. The Add( ) method is used to add the column and table style to the respective collections. Now run the program. You will see the columns arranged in the order set in the table style. Next week we will customize the background and foreground color of the selected row.

Article C# - Grooming the DataGrid Control - II


Continued from last week... Last week we customized the DataGrid control by rearranging the order of columns and applying styles to them. We would now see how to change the background and foreground colors of the cells. The DataGridTextBoxColumn class is responsible for drawing every cell in the DataGrid control. The background and foreground brushes are passed to the Paint event handler in this class. So, to color the cells with desired brushes, we can change the brushes in the Paint event handler. For this, we must derive a class from the DataGridTextBoxColumn class. We would add an event to this class that would be fired when a cell is about to be painted. The handler of this event would receive the current row and current column. Here is the derived class, formatcolumn.

class formatcolumn : DataGridTextBoxColumn { public event formateventhandler format ; protected override void Paint ( Graphics g, Rectangle bounds, CurrencyManager source, int row, Brush backbrush, Brush forebrush, Boolean alignToRight ) { int col = DataGridTableStyle.GridColumnStyles.IndexOf ( this ) ; formateventargs e = new formateventargs ( row, col ) ; format ( this, e ) ; backbrush = e.Backbrush ; forebrush = e.Forebrush ; base.Paint ( g, bounds, source, row, backbrush, forebrush, alignToRight ) ; } } The class declares the event named format of type formateventhandler. Declare the formateventhandler delegate outside the classes as shown below:

public delegate void formateventhandler( object sender, formateventargs e ) ; This delegate specifies that the handler of the format event would accept two parameters, first the reference of type object and second reference of type formateventargs. We cannot pass a reference to the predefined EventArgs class because we have to pass the row and column to the format event handler. We would see the formateventargs class later.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

In the formatcolumn class we have overridden the Paint event handler. To this handler, the brushes along with the current row are passed. We have obtained the current column using the IndexOf( ) method. After this, we have fired the format event. The format event handler would initialize the brushes with the desired colors. We have obtained these colors from the formateventargs class by calling its properties Backbrush and Forebrush. We have then called the base classs Paint handler for doing the painting job. The formateventargs class contains the constructor and few properties. This class is given below.

public class formateventargs : EventArgs { private Brush backbrush, forebrush ; private int r, c ; public formateventargs ( int row, int col ) { Row = row ; Col = col ; } public int Row { get { return r ; } set { r = value ; } } public int Col { get { return c ; } set { c = value ; } } public Brush Backbrush { get { return backbrush ; } set { backbrush = value ; }

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


} public Brush Forebrush { get { return forebrush ; } set { forebrush = value ; } } } Only thing remaining is handling the event. Add the event handler in the Form1 class. The handler is given below.

private void column_formathandler ( object sender, formateventargs e ) { if ( e.Row == dataGrid1.CurrentRowIndex ) { e.Backbrush = Brushes.Aqua ; e.Forebrush = Brushes.Red ; } else { e.Backbrush = new SolidBrush ( dataGrid1.BackColor ) ; e.Forebrush = new SolidBrush ( dataGrid1.ForeColor ) ; } } This handler would get called for every cell of the grid. So, we have checked whether the cell that is getting painted belongs to the currently selected row. Now modify the Load event handler as shown below. Here, instead of DataGridTextBoxColumn, we have created reference of type formatcolumn class. We have also added the format event to each column added to the control.

private void Form1_Load ( object sender, System.EventArgs e ) { sqlDataAdapter1.Fill ( ds1 ) ; DataGridTableStyle ts = new DataGridTableStyle( ) ; ts.MappingName = "account" ; DataGridBoolColumn bcol = new DataGridBoolColumn( ) ; bcol.MappingName = "ATM" ; bcol.HeaderText = "" ; bcol.Width = 30 ; bcol.AllowNull = false ; ts.GridColumnStyles.Add ( bcol ) ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


formatcolumn column = new formatcolumn( ) ; column.MappingName = "accno" ; column.HeaderText = "Account No." ; column.Width = 80 ; column.format += new formateventhandler ( column_formathandler ) ; ts.GridColumnStyles.Add ( column ) ; column = new formatcolumn( ) ; column.MappingName = "name" ; column.HeaderText = "Name" ; column.Width = 110 ; column.format += new formateventhandler ( column_formathandler ) ; ts.GridColumnStyles.Add ( column ) ; column = new formatcolumn( ) ; column.MappingName = "bal" ; column.HeaderText = "Balance" ; column.Width = 110 ; column.format += new formateventhandler ( column_formathandler ) ; ts.GridColumnStyles.Add ( column ) ; dataGrid1.TableStyles.Add ( ts ) ; } Execute the program and select a row. The selected row would appear as shown in the following figure.

Article C# - Transformation in GDI+ - I


As compared to GDI, GDI+ provides greater support for graphics, images and transformation. GDI+ allows following operations to be performed. Translation: On translating an object the size of the object remains fixed but it moves along any one of the axes along which the translation takes place. Moving object 10 units in x direction is an example of translation transformation.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Rotation: On rotating an object, the object moves about one of the axes. Scaling: On scaling an object, its size gets increased or decreased but the shape does not change. Shearing: On shearing an object, it moves in some direction but its base remains fixed. Transformations are always applied using matrices. It is a two-step process. The steps involved are: (a) Creating a transformation matrix and coordinate matrix. (b) Multiplying the coordinate matrix with transformation matrix. Translation Transformation Let us understand this form of transformation with the help of an example.

We plan to translate a triangle shown in this figure by three units in x direction and two units in y direction. For doing this we need to change all the three coordinates of the triangle. The new coordinates can be obtained by multiplying the transformation matrix with the coordinate matrix. In the transformation matrix the elements 3 and 2 are the units by which we wish to translate the shape in the x and y directions respectively. The coordinate matrix has three elements. The first element consists of the x coordinate of the vertex, which is to be transformed. The second element consists of y coordinate of the vertex and the last element consists of the z coordinate of the vertex. Hence the first and the second elements of the coordinate matrix would be 2, 2 respectively and as a triangle does not have any z order, the last element of the coordinate matrix would contain 1. After the multiplication is performed the coordinates (2, 2) would get transformed into (5, 4) respectively. Rotation Transformation

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Suppose we want to rotate the triangle shown in the above figure by 90 degrees. To do so, we need to replace the transformation matrix angle A by 90 degrees. The coordinate matrix would contain the coordinates of the triangle to be transformed. The figure shows the transformation of only one of the coordinates of the triangle i.e. (2, 4). As the triangle does not have any z order the third element of the coordinate matrix would be 1. The resultant matrix shows that the coordinate (2, 4) has changed to (-4, 2). Similarly we need to transform other two coordinates of the triangle. Scaling Transformation Following figure shows the transformation matrix for scaling.

Suppose the triangle is to be scaled by two units in x direction and two units in y direction. Hence sx and sy in the transformation matrix would be two units each. The coordinate matrix would contain the particular coordinate of the triangle to be transformed, which in our case happens to be (4, 1). On multiplying the coordinate matrix with the transformation matrix we get the resultant matrix which shows that the coordinate (4, 1) has been transformed into (8, 2). The effect of

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


scaling is that the figure either enlarges or reduces in size. Shearing Transformation The following figure shows the shearing transformation

Suppose the triangle is to be sheared two units in x direction only. Hence sx in the transformation matrix would be 2 whereas sy would be 0. The coordinate matrix would contain the particular coordinate of the triangle to be transformed, which in our case happens to be (1, 4). On multiplying the coordinate matrix with the transformation matrix we get the resultant matrix, which shows that the coordinate (1, 4) has been transformed into (9, 4). On performing similar shearing operation on all other coordinates we would get the resultant triangle as shown in the figure. We would see how to perform all these transformations programmatically in the next article.

Article C# - Transformation In GDI+ - II


In the last article we discussed various forms of transformations. We would now see how to perform these transformations programmatically. Look at the following Paint event handler.

private void Form1_Paint ( object sender, PaintEventArgs e ) { Graphics g = e.Graphics ; Image myimg = Image.FromFile ( "C:\\palace.jpg" ) ; Matrix mymat = new Matrix( ) ; mymat.Scale ( -1, 1 ) ; mymat.Translate ( -350, 0 ) ; g.Transform = mymat ; g.DrawImage ( myimg, 50, 50 ) ; g.ResetTransform( ) ; } This code creates a mirror image. Here we have used a Static method FromFile( ) of the Image class, which returns a reference to the image, which we have collected in myimg. Next in order to create a transformation matrix we have first created an object of the Matrix class. Since the

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Matrix class is declared in the System.Drawing.Drawing2D namespace, we must declare this namespace in our program. We have scaled the matrix by passing a 1 as the first parameter to the Scale( ) method. Due to this all the x coordinates would be multiplied by 1. After multiplying this matrix with the coordinates of the image the resultant image would be the mirror image of the original. When we scale the coordinates of an image by multiplying them with 1 the resulting coordinates become negative. Hence they would not be visible as top left corner of the form is (0, 0). To bring the image back in the form we have to translate it by some x and y values. Next we have assigned this resultant transformation matrix to the Transform property of the Graphics object. There onwards everything that gets drawn would be multiplied with the transformation matrix. For drawing the image we have used the DrawImage( ) method. Next, we would create an application that would display the string KICIT and its shadow on a WinForm. In this program we shall draw the shadow of the text before drawing the text, so that the text overlaps the shadow making the shadow appear as if it is behind the text. We shall draw the shadow using the same font as the original text and shall use gray color for it. The shadow size would then be required to keep half the size of the original text and also to be sheared in the x direction.

private void Form1_Paint ( object sender, PaintEventArgs e ) { Graphics g = e.Graphics ; Matrix mymat = new Matrix( ) ; mymat.Shear ( -1.4f, 0f ) ; mymat.Scale ( 1, 0.5f ) ; mymat.Translate ( 236, 170 ) ; g.Transform = mymat ; Font myfont = new Font ( "Times New Roman", 100 ) ; SolidBrush mybrush = new SolidBrush ( Color.Gray ) ; g.DrawString ( "K", myfont, mybrush, 50, 50 ) ; g.DrawString ( "I", myfont, mybrush, 150, 50 ) ; g.DrawString ( "C", myfont, mybrush, 200, 50 ) ; g.DrawString ( "I", myfont, mybrush, 300, 50 ) ; g.DrawString ( "T", myfont, mybrush, 350, 50 ) ; g.ResetTransform( ) ; mybrush.Color = Color.DarkMagenta ; g.DrawString ( "K", myfont, mybrush, 50, 50 ) ; mybrush.Color = Color.FromArgb ( 150, 0, 255, 255 ) ; g.DrawString ( "I", myfont, mybrush, 150, 50 ) ; LinearGradientBrush lgb = new LinearGradientBrush ( new Point ( 200, 50 ), new Point ( 350, 200 ),Color.Brown, Color.Yellow ) ; g.DrawString ( "C", myfont, lgb, 200, 50 ) ; HatchBrush hb = new HatchBrush ( HatchStyle.DiagonalCross, Color.Blue, Color.Red ) ; g.DrawString ( "I", myfont, hb, 300, 50 ) ; Image myimg = Image.FromFile ( @"C:\test.bmp" ) ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


TextureBrush tb = new TextureBrush ( myimg ) ; g.DrawString ( "T", myfont, tb, 350, 50 ) ; }

To create a transformation matrix we have firstly created an object of the Matrix class. This object represents an identity matrix of size 3 x 3. We intend to perform shearing, scaling and translation transformations. For this we have called the methods Shear( ), Scale( ) and Translate( ) using the mymat object. These methods manipulate the object by doing matrix multiplication as discussed earlier. At the end of these calls, mymat object represents the transformation matrix. Next, we have set the Transform property of the Graphics class object g to mymat object. Now whenever a shape would be drawn, the corresponding shapes coordinate matrix would get multiplied with the transformation matrix stored in mymat. Next we have selected a SolidBrush of gray color and used the DrawString( ) method of the Graphics class to display the string. We have called ResetTransfrom( ) method that resets the world transformation matrix of this Graphics object to the identity matrix. The identity matrix represents a transformation with no scaling, rotation, or translation. To display K we have used a solid brush of dark magenta color. To display I we have used a transparent brush. A brush can be made transparent by using the FromArgb( ) method and passing an alpha component as its first parameter. The alpha component specifies how opaque or transparent a color should be. The alpha value ranges from 0 (fully transparent) to 255 (fully opaque). The default value is 255 and hence if we do not pass any value the color created is always opaque. In our program we have passed 150 as the first parameter to the FromArgb( ) method. This results in a semi-transparent color. The string I gets drawn with semi-transparent blue color. Next we have displayed C using a linear gradient brush. Here the y coordinate of the second point passed to the constructor of the LinearGradientBrush class does not match with the y coordinate of the first point and hence the gradient fill is not horizontal. The I is displayed using a hatch brush and lastly to display T, we have used a texture brush. To the constructor of the TextureBrush class a reference to an image, which is to be filled, is passed. We have used the Static method FromFile( ) of the Image class to load the image. If you run the program, you will see the string KICIT written as shown below.

Article C# - The Timezone Application - I

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


We have started the timezone application in the last article. Just to revise, we have drawn two lines, intersecting each other at the cursor position. Add the following data members to the Form1 class. Point hstart, hend, vstart, vend ; Image img ; Label l ; The hstart and hend objects would contain starting and ending coordinates of the horizontal line. The vstart and vend objects would contain starting and ending coordinates of the vertical line. The Image object would be used to load and draw the world map image. The label would be popped up to show the day of week, time and city name. Add the Load event handler. Add the initialization code as shown below. private void Form1_Load ( object sender, System.EventArgs e ) { img = Image.FromFile ( "World.gif" ) ; hstart = new Point ( 0, ClientSize.Height / 2 ) ; hend = new Point ( ClientSize.Width, ClientSize.Height / 2 ) ; vstart = new Point ( ClientSize.Width / 2, 0 ) ; vend = new Point ( ClientSize.Width / 2, ClientSize.Height ) ; }

Here, we have loaded the world.gif file containing the map image. The Point objects are initialized with the proper values. Add the Paint event handler wherein we would draw the image on the form. We would also draw the lines using the Point objects initialized just now. private void Form1_Paint ( object sender, PaintEventArgs e ) { Graphics g = e.Graphics ; g.DrawImage ( img, 0, 0, img.Width, img.Height ) ; Pen p = new Pen ( Brushes.Red ) ; g.DrawLine ( p, hstart, hend ) ; g.DrawLine ( p, vstart, vend ) ; }

Run the program, you would see the output as shown in the following figure.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


You must have noticed the grayed maximized box of the form. We have set the MaximizeBox property of the form to false so that the size of the form wont change. We have hidden the cursor by adding the following statement to the Load event handler Cursor.Dispose( ) ;

The lines should move as the mouse moves. We have already written the code to draw new lines and erase previous ones in the Form1_MouseMove( ) handler. Update that code as shown below. private void Form1_MouseMove ( object sender, MouseEventArgs e ) { Graphics g = CreateGraphics( ) ; hend.Y = hstart.Y = e.Y ; vend.X = vstart.X = e.X ; g.DrawImage ( img, 0, 0, img.Width, img.Height ) ; Pen p = new Pen ( Brushes.Red ) ; g.DrawLine ( p, hstart, hend ) ; g.DrawLine ( p, vstart, vend ) ; }

Here, we have updated the coordinates stored in the Point objects according to the mouse position and drawn lines at new position. We must keep checking the mouse position. If the mouse is placed over a city that is present in our city database, we must display the label carrying day, time and city. In our program the application data is the name of the city, its coordinates and the time at that place with respect to the Indian Standard Time. To keep things simple we have stored this data in an array of objects. The objects are of type location. location is a user-defined class. We would first declare this class. class location { public int hours, minutes ; public string city ; public int x, y ; public location ( int h, int m, String c, int xx, int yy ) { hours = h ; minutes = m ; city = c ; x = xx ; y = yy ; } }

The location class contains data members to hold hours, minutes, city name and x-y coordinates of the city on the map. The data members are initialized through constructor. Populate the array in the Form1 class as shown below. This is only a part of the array. location[ ] loc = {

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


new location ( 0, 0, "NewDelhi", 245, 90 ), new location ( 0, 0, "Calcutta", 254, 99 ), new location ( 0, 0, "Mumbai", 240, 107), new location ( 0, 0, "Nagpur", 245, 100), new location ( 0, 0,"Chennai", 245, 110), new location ( -5, -30, "Lisbon", 160, 79), new location ( -4, -30, "Madrid", 165, 74), new location ( -3, -30, "Athens", 192, 84), new location ( -3, -30, "Cairo", 202, 91), };

Article C# - The Timezone Application - I


Now comes the real part. private void Form1_MouseMove ( object sender, MouseEventArgs e ) { // Previous code int i = search ( new Point ( e.X, e.Y ) ) ; Rectangle m_rect = new Rectangle( ) ; if ( i != -1 ) { m_rect = this.ClientRectangle ; Point dpt = new Point ( 0, 0 ) ; if ( e.X + 150 < m_rect.Width ) dpt.X = e.X + 5 ; else dpt.X = e.X - 155 ; if ( e.Y + 20 < m_rect.Height ) dpt.Y = e.Y + 5 ; else dpt.Y = e.Y - 20 ; string str = calculate ( i ) ; l.Left = dpt.X ; l.Top = dpt.Y ; l.Size = new Size ( 150, 20 ) ; l.Text = str ; l.Visible = true ; } else l.Visible = false ; } We have called the search( ) method that returns the index of the array element whose coordinates match with the coordinates of the current mouse position. We have then calculated the suitable place where the label of size 150 x 20 can be displayed. The left-top position is stored in the dpt object. Next we have called the calculate( ) method. This method customizes the string containing information of the city and returns the same. Once we have the information, what remains is to display this information on the label. We must first create the label. For this, add the following code in the Load event handler.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


l = new Label( ) ; l.Visible = false ; Controls.Add ( l ) ; The following statements specify the position, size and text of the label. The label would be invisible initially. We have to make it visible using the Visible property.

l.Left = dpt.X ; l.Top = dpt.Y ; l.Size = new Size ( 150, 20 ) ; l.Text = str ; l.Visible = true ; If The mouse is positioned at some obscure place in the world whose entry is not present in the array the search( ) method returns a value -1. In such a case the label is hidden by setting the Visible property to false. Lets now look at the two helper functions search( ) and calculate( ). They are given below.

int search ( Point p ) { Rectangle r = new Rectangle ( p.X , p.Y , 5, 5 ) ; Point pt ; for ( int i = 0 ; i < loc.Length ; i++ ) { pt = new Point ( loc [ i ].x, loc [ i ].y ) ; if ( r.Contains ( pt ) ) return i ; } return -1 ; } To this method we have passed the current mouse position. We have run a for loop to see whether coordinates of any city fall within the specified area. If they do, we have returned the index of the element. This index is then passed to the calculate( ) method.

string calculate ( int i ) { int m_hour = loc [ i ].hours ; int m_minute = loc [ i ].minutes ; DateTime t = DateTime.Now ; t = t.AddHours ( m_hour ) ; t = t.AddMinutes ( m_minute ) ; string week_day = t.DayOfWeek.ToString( ) ; string str = week_day + " " + t.Hour + ":" + t.Minute + " " + loc [ i ].city ; return str ; }

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


In this method, we have read the hour and minutes of the specified array element. Remember that these hour and minute values specify the time with respect to the Indian Standard Time. We have added this time to the current time to get the exact time at the city. Lastly, we have obtained the day of week and constructed the string with all the information we have. This string is returned back to the MouseMove event handler. Run the program and move the mouse on the form. You will get the pop-ups as shown in the following snap shot.

Article C# - E-Mail Enabled Windows Application


Want to send e-mail from a .NET Framework application? You could do it the hard way by using sockets to establish a connection to a mail server and then transmit a mail message using Simple Mail Transfer Protocol (SMPT). Or you could do it the easy way and rely on classes in the System.Web.Mail namespace. System.Web.Mail provides a simple managed interface to SMTP. The core classes are MailMessage, which helps preparing an e-mail message; MailAttachment, which helps sending attachments; and SmtpMail, which places a friendly wrapper around the host systems SMTP mail service. These classes construct and send messages using the CDOSYS (Collaboration Data Objects for Windows 2000) message component. To send the mail either the SMTP mail service of Microsoft Windows 2000 or the specified SMTP server is used. In our application we would use localhost as the SMTP server. Although mail facility would be required mainly by Web applications, even the WinForm applications need to send mails. TODO We would create a WinForm application that is capable of sending mail and/or an attachment. Design the form as shown in the following screen capture.

We have placed several labels and text boxes along with two buttons. The textboxes are respectively given names as txtto, txtfrom, txtcc, txtbcc, txtsubject, txtattach and txtbody. The buttons are named as butsend and butattach respectively. Declare a reference msg to the MailMessage class as data member of the Form1 class and initialize it in the constructor as shown below. msg = new MailMessage( ) ; Add the Click event handler for both the buttons. These handlers are given below.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


private void butattach_Click(object sender, System.EventArgs e) { if ( filedlg.ShowDialog( ) == DialogResult.OK ) { MailAttachment ma = new MailAttachment ( filedlg.FileName ) ; txtattach.Text = filedlg.FileName ; msg.Attachments.Add ( ma ) ; } } To enable the user to select a file for attaching to the mail, we have displayed the OpenFile dialog with name filedlg. We have passed the selected file name and path to the constructor of the MailAttachment class. The attachment represented by an object of the MailAttachment class is then added to the Attachments collection of the MailMessage object. After attaching the file, click the Send button. In the Send button handler we have filled various properties of the MailMessage class with respective values. Here, mentioning To and From properties are mandatory. private void butsend_Click ( object sender, System.EventArgs e ) { if ( txtto.Text != null ) msg.To = txtto.Text ; else return ; if ( txtfrom.Text != null ) msg.From = txtfrom.Text ; else return ; msg.Cc = txtcc.Text ; msg.Bcc = txtbcc.Text ; msg.Subject = txtsubject.Text ; msg.Body = txtbody.Text ; try { SmtpMail.SmtpServer = "localhost" ; SmtpMail.Send ( msg ) ; } catch ( Exception ex ) { MessageBox.Show ( "Error in sending mail" ) ; } } The SmtpServer property specifies the SMTP server through which mail will be sent. If the SmtpServer Property is not set, mail is by default queued on a Windows 2000 system. We can check this mail in the C:\Inetpub\mailroot\Queue folder. Add reference to the System.Web.Mail namespace at the beginning of the program. Also add the reference to the System.Web.dll in the Solution Explorer. Run the program and enjoy mailing. If the application throws an exception when you click the Send Mail button, make sure your machines SMTP service is running. You can do that in the IIS configuration manager or in the Administrative Tools | Services Control Panel applet. Second, make sure the SMTP service is

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


configured to allow relaying from localhost. To do that, open the IIS configuration manager from the Administrative Tools, right-click Default SMTP Virtual Server, select Properties, click the Access tab, click the Relay button, select Only List Below, and use the Add button to add 127.0.0.1 to the list of computers allowed to relay

Article C# Using the FileSystemWatcher Component


In this article we would walk through the process of using the FileSystemWatcher component and watching the changes made to a subfolder/files of a selected folder. The FileSystemWatcher component can keep track of creation, deletion, changing and renaming of a file/folder. It conveys the application about changes done to the file system by throwing events. It throws the Created, Deleted, Changed and Renamed events respectively. The name and path of the file/folder being changed is also made available in the event handlers. The FileSystemWatcher component can watch files on a local computer, a network drive, or a remote computer. We can specify which files to watch by setting the appropriate value in the Filter property. If we wish to watch all the files we must set the Filter property to an empty string (). To watch a specific file, we must assign that file name to the Filter property. We can also use wildcards to specify certain type of file. For example, to watch for changes in EXE files, we can set the Filter property to *.exe. The component has a property called NotifyFilter that can be used to specify the types of changes viz. changes in attribute, last write date and time, size, etc. Having this much of knowledge about FileSystemWatcher component in hand, we can now use the component in our application. We would create an application that uses the FileSystemWatcher control to keep watch on the folder selected by the user. We would watch whether a file/folder is created, changed or deleted. Create a WinForm application and put the controls on the form as shown in following figure.

We have added three list boxes to list the files/folders being created, changed or deleted. The Watch Folder button allows user to select a folder to watch. The path of the selected folder gets displayed on the label placed next to the Watch Folder button. The Clear button allows to delete the items listed in the list box having input focus.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


In addition to these controls, add the FolderBrowserDialog control from the Windows Forms tab and FileSystemWatcher component from the Components tab of the ToolBox. The controls, their names and event handlers are given in the following table. Control Created list box Changed list box Deleted list Watch Folder button Clear button FileSystemWatcher FolderBrowserDialog Name listcreate listchange boxlistdelete butwatch butclear watcher browser Handler butwatch_Click butclear_Click -

Add handlers for the Created, Deleted and Changed events. Also Set the IncludeSubdirectories property of the FileSystemWatcher component to true. When the application is run, the user has to first select a folder to watch. He can do so by clicking the Watch Folder button. We have displayed the Browse For Folder standard dialog box in which user can select the folder. The dialog is displayed by calling the ShowDialog( ) method as shown below. private void butwatch_Click ( object sender, System.EventArgs e ) { if ( browser.ShowDialog( ) == DialogResult.OK ) { watcher.Path = browser.SelectedPath ; label1.Text = browser.SelectedPath ; } } We have specified the folder to watch by setting the Path property of the FileSystemWatcher class to the path of selected folder. The path of selected folder is retrieved from the SelectedPath property of the FolderBrowserDialog class. We have displayed the path on the label. The handlers added for the FileSystemWatcher events are given below. private void watcher_Changed ( object sender,System.IO.FileSystemEventArgs e ) { listchange.Items.Add ( e.FullPath ) ; } private void watcher_Created ( object sender,System.IO.FileSystemEventArgs e ) { listcreate.Items.Add ( e.FullPath ) ; } private void watcher_Deleted ( object sender, System.IO.FileSystemEventArgs e ) { listdelete.Items.Add ( e.FullPath ) ; }

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


In these handlers we have only added the full path of the file/folder being changed, created or deleted in the respective list boxes. To clear a list box, the user has to select an item in that list box and click the Clear button. The handler for the Clear button is given below. private void butclear_Click ( object sender, System.EventArgs e ) { if ( listcreate.SelectedIndex != -1 ) listcreate.Items.Clear( ) ; else { if ( listchange.SelectedIndex != -1 ) listchange.Items.Clear( ) ; else if ( listdelete.SelectedIndex != -1 ) listdelete.Items.Clear( ) ; } } The SelectedIndex property returns 1 if no item is currently selected. If any item is selected, the condition becomes true and the list box gets cleared. Following figure shows our application at work. The list boxes seem to have trapped few files being changed.

Article C# - Using The Splitter Control


In earlier version of Visual Studio, we used to create splitter windows by calling methods of an MFC class. The main application window actually used to get split in panes. Each pane represented a separate view window. .NETs concept of splitting windows is different. .NET provides a Splitter control, which is used to resize docked controls at run time. It does not actually splits a window. The control to be resized must be just before the splitter control in z-order. This article shows how to use the Splitter control in a WinForm application. We intend to display a form window as shown in the following snap shot.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

The blue horizontal bar is a label control. We have changed its BackColor, ForeColor and Font properties. The control placed at the left hand side is the ListBox control. The control placed on the right hand side is the ListView control. The program is to list the currently running processes in the list box. If a process is selected its information is displayed in the list view control. Here, our aim is to show how to use the Splitter control. Our stress is not on browsing and retrieving information of processes. When we place the Splitter control on a container, it divides the entire container in two partsleft and right (or top and bottom if placed horizontally). But, we dont want to show the vertical bar of the Splitter control on the label. We want that the effect of splitter should be felt only on the remaining part of the form. For this, we have placed a Panel on the form so as to cover the remaining part of the form. This is shown in the following snap shot.

Now, place the ListBox and change its Dock property to Left. Name the control as list. Drag the Splitter control on the form. It will get docked to the left side indicating that it has to resize the control placed on the left. Run the program and place the cursor on the splitter bar. When the cursor changes, drag it to left or right. You would see the list box resizing. We want to place a ListView control as well as button on the right side of the splitter. If user moves the splitter, both the controls should be relocated properly. For this, we have again placed a Panel covering the right side of the form and placed the ListView and Button controls on it. Name the Panel control as panel, ListView control as listview and Button control as kill. Clicking this button would kill the process selected from the list box. Again note that our aim is to show you how to relocate the multiple controls if Splitter control is moved, not to kill the process. Lastly, add the Process component from the Components tab on ToolBox and name it process. The designing part is over, lets move on to the coding part. Firstly, add the Load event handler. The handler is shown below. private void Form1_Load ( object sender, System.EventArgs e ) {

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Process[ ] parr = Process.GetProcesses( ) ; foreach ( Process p in parr ) list.Items.Add ( p.ProcessName ) ; } Here, we have browsed the processes and listed them in the list box . Now add the Click event handler for the button. In this handler we have checked whether any process is selected. If it is, then we have closed the process using the kill( ) method. private void kill_Click ( object sender, System.EventArgs e ) { if ( list.SelectedItem == null ) return ; Process[ ] p = Process.GetProcessesByName ( list.SelectedItem.ToString( ) ) ; p [ 0 ].Kill( ) ; list.Items.Remove ( list.SelectedItem ) ; list.SelectedIndex = -1 ; listview.Items.Clear( ) ; } After the process is closed, we have deleted the process name from the list box, set the selected index to 1 and cleared the list view control. When the user selects a process, its information is displayed in the ListView control. The code to fill the ListView control is written in the SelectedIndexChanged event handler. private void list_SelectedIndexChanged ( object sender, EventArgs e ) { if ( list.SelectedIndex != -1 ) { listview.Items.Clear( ) ; Process[ ] p = Process.GetProcessesByName ( list.SelectedItem.ToString( ) ) ; listview.Items.Add ( p [ 0 ].BasePriority.ToString( ) ) ; listview.Items [ 0 ].SubItems.Add ( p [ 0 ].Id.ToString( ) ) ; listview.Items [ 0 ].SubItems.Add ( p [ 0 ].StartTime.ToShortTimeString( ) ) ; listview.Items [ 0 ].SubItems.Add ( ( p [ 0 ].WorkingSet / 1024 ).ToString( ) ) ; } } Here, firstly we have checked whether the handler has got called because of the change in selected index in the kill_Click( ) event handler. Then we have used various properties of the Process class to obtain information of the process. Moving the splitter would resize the list control, but it would not change the width of the Panel control hosting the ListView and button. We have to do it ourselves. Add a handler for the SplitterMoved event for Splitter control and adjust the size and left coordinate of the Panel control as given below. private void splitter_SplitterMoved ( object sender, SplitterEventArgs e ) {

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


panel.Width = Width - e.X ; panel.Left = e.X ; } Run the program. The form after moving the splitter to the right would look as given below.

Article C# - DirectX 3-D Basics


DirectX is immensely powerful library that supports multimedia programming. The new version of this library, known as DirectX 9.0 provides multimedia functionality for managed applications. DirectX 9.0 supports managed languages like C#, Visual Basic.NET, VC++.NET and JScript.NET. Components DirectX 9.0 for Managed Code provides following components Direct3D Used for 3-D graphics programming. DirectDraw Enables direct access to video memory, specially used for high-speed rendering. DirectInput Used for programming with various input devices. DirectPlay Used for creating network enabled multiplayer games. DirectSound Used for capturing sounds from input devices and playing sound through playback devices. Audio Video Playback Used for working with audio-video files. Direct3D Concepts We will start our journey through DirectX 9.0 by understanding the terms and concepts involved in it. Direct3D uses a left-handed cartesion coordinate system. The values on the x-axis increase from left to right. The values on the y-axis increase from bottom to top and the values on the z-axis increase from back to front. This is shown in following Figure.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Consider your left hand with the palm up as shown in the above figure. Then the thumb would represent the z-direction, which is traveling away from the body. In the left handed coordinate system we can position 3D objects in one of the three different types of space coordinates. Model Space: Suppose we are drawing different 3D entities like a cube, a sphere, a pyramid etc. Each such object can be called a model. In the model space each such model has a different origin. World Space: In the world space there is a fixed origin. The world transformation matrix changes coordinates from model space, where vertices are defined relative to a model's local origin to world space where vertices are defined relative to an origin common to all the objects in a scene. In essence, the world transformation places a model into the world and hence its name.

Camera Space (View Space): This view of the world places the viewer (user) at the origin and faces him or her in the direction of the positive z-axis. The view matrix is used to transform vertices from the world space to the Camera space. Above figure and following two figures depicts these three spaces.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Let us now take an example and combine these three spaces together. If we want to spin two cubes the first thing that we need to do is create the tow cubes using the model coordinates. In the above figure for depicting the model space the two cubes have their own coordinate separate coordinate systems. We have placed both the cubes at origin in their respective coordinate systems. Then using the world transformation matrix we place the cubes into the world space. The origin of the model space and world space may be same or different. (In the above example the origin of the model space and the camera space are the same). Then we have translated the cube 2 in the world space using transformations because had we done that the two cubes would have got overlapped. Note that the camera is placed at (-200,100) in the world space. In the world space to rotate scale and translate the cube various transformation matrices are used. Next to look at the cube we have to indicate the position of the eye/camera in the world space. When we do so the origin of the world space is mapped to the eye position (Camera space origin). Due to this the camera or the eye is placed at the origin and the two cubes are reoriented with respect to the camera. Now if we display the cubes on the screen they would hardly appear like real cubes. To make the cubes appear more realistic we need to make some more effort. There are two facts involved when a human eye sees an object (a) A human eye sees what falls in the conical volume as shown in following figure.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

(b) That part of the object that is nearer to the eye appears bigger than the part that is farther away from it. This way of looking at an object is known as perspective projection. Let us now see how Direct3D uses these facts to generate realistic shapes. Instead of using a cone Direct3D uses a close approximation of it a pyramid to represent the viewing volume. In principle we can see an object which is present on any distance, even at infinity. But in reality we can see an object present only upto a particular distance. Hence instead of a pyramid of infinite length we need to use a frustrum of a pyramid to represent a viewing volume. This is shown in the following figure.

A front and back clipping plane intersects the pyramid. The volume within the pyramid between the front and back clipping planes is the viewing frustum. Objects are visible only when they are in this volume. The viewing frustum is defined by fov (field of view) and by the distances of the front and back clipping planes, specified in z-coordinates. Once the viewing volume is specified we need to create a projection matrix which would apply the perspective projection to the coordinates of the cube. These modified coordinates are then used to render the shape on the screen (2D-plane). While actually rendering shapes using Direct3D it relieves us of the burden of forming the projection matrix. we need to only specify fov and the distances of the front and back plane from the eye. The entire process is illustrated in following figure.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Transformations There are three basic transformations that can be applied to any 3D objects. These are translation, rotation and scaling. These transformations are discussed below. The Translation transformation involves movement of the object in the x, y, or z direction. When we move the object in these directions the coordinates of the object at the new position would be different from the original coordinates. We can calculate the new coordinates using simple equations. However, from the point of view of programming convenience if we store the coordinates in one matrix and the distance by which the object is being translated ( in x, y, and z direction ) in another and carry out simple matrix multiplication then the resultant matrix would contain the new set of coordinates. Similar matrix operations can be performed on Rotation and Scaling operations. 1) Translation If x, y, and z are the coordinates of a point which is to be translated by a distance Tx, Ty and Tz, then the matrix multiplication that would be carried out is as under: Here x', y' and z' are the new coordinates of the point.

2) Rotation This transformation involves rotation of an object around x, y or z axis.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


For example, the following transformation rotates the point (x, y, z) around the x-axis, producing a new point (x', y', z').

The following transformation rotates the point around the y-axis

The following transformation rotates the point around the z-axis.

3) Scaling The scaling transformation involves increasing or decreasing the size of an object. The following transformation scales the point (x, y, z) by values Sx, Sy and Sz in the x, y, and z directions to a new point (x', y', z').

Other than programming convenience using matrices for performing transformations offers one more advantage. We can combine the effects of two or more transformation matrices by multiplying the matrices representing these transformations. This means that, to rotate a object and then translate it to some location, we don't need to apply two multiplication's. Instead, we can multiply the rotation and translation matrices to produce a composite matrix that contains effects of rotation and translation. This resultant matrix is then multiplied with the coordinate matrix to yield new coordinates. Direct3D provides us methods to set up all the matrices for translation, rotation and scaling as well as it provides a method that provides a matrix that represents the cumulative effects of all the

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


applied transformations. Thus Direct3D helps the user to concentrate on the logical aspect of the game relieving him from the burden of performing complex mathematical operations. 3D Objects Let us have a look at how a simple cube is formed in 3D. Before building the cube lets take a look at the basic 3D primitives which serve as the building blocks to create a cube and more complex objects. A 3D primitive is a collection of vertices (points in 3D space identified by x, y and z) that form any 3D entity. Often, 3D primitives are polygons. A polygon is a closed 3D figure drawn by connecting at least three vertices. The simplest polygon is a triangle. Direct3D uses triangles to compose most of its polygons because all three vertices in a triangle are guaranteed to be coplanar. If three points are connected they always lie in the same plane. Consider a pyramid. It has four points and when they are connected all the three triangles do not lie in the same plane i.e. the vertices are non-coplanar. Rendering of non-coplanar vertices is inefficient. Hence every 3D object be it a pyramid or a sphere, is built out of triangles due to their coplanar nature. Below is a sphere that is built from triangles.

Two triangles are used to create each face of the cube. A cube has a total six faces i.e. 12 such triangles are used to compose the complete cube. This is shown in following figure.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


System Management Using WMI... WMI (Windows Management Instrumentation) was previously available as a COM based API that was obviously complicated to use. .NET has provided an object-oriented, managed wrapper around this API and made the usage of WMI easy. .NET has provided a separate namespaces called System.Management and System.Management.Instrumentation to enable our application to browse and monitor processes, events, etc. Using the power of WMI in conjunction with .NET we can create a system utility like SPY++.

The new Modifier... We can use the new modifier for a method in the derived class that has the same signature (prototype declaration) as the base class method. Using the new modifier we can declare that a method is not an override of the base class method, but it is the new method that belongs to this class. Declaring the method as new hides the base class implementation of the method. The new modifier can be applied on non-virtual as well as virtual methods but not on abstract methods.
How do I read/write binary data from/to a file? Ans: To read binary data from a file we can use the BinaryReader class. To write binary data to a file we can use the BinaryWriter class. The Write( ) method of the BinaryWriter class writes data of type int, long, float, etc. to the file. Similarly, Read( ) method reads the data from file. Binary I/O is useful while reading or writing records.

How to perform custom validation? Ans: While creating ASP.NET application we often require to validate the input data. We can use various validation controls provided by the .NET for this purpose. There are controls to check whether fields are empty, to compare two values and to validate a value using regular expression. But what if we want that user should enter only numeric value in a text box? There is no built-in validation control for this purpose. In such a situation we can use CustomValidator control. To this control, we need to specify a function that is used for validating the value of the control. Whether value is right or wrong can be specified using the IsValid property of the control.
Binding Data With Controls... We often need to populate controls like combo box, list box, etc. using a data source. Instead of reading data from the data source and then adding it to items' collection of these controls, we can directly bind data sets to these controls so that the controls get populated with the data from specified dataset. Following code snippet shows how to bind data to a combo box named myCombobox. string ConnectionStr = System.Configuration.ConfigurationSettings.AppSettings [ "DbConnect" ] ; SqlConnection Connection = new SqlConnection ( ConnectionStr ) ; SqlDataAdapter DAdapter = new SqlDataAdapter ( "select Id from mytable", Connection ) ; DataSet ds = new DataSet( ) ; DAdapter.Fill ( ds, "mytable" ) ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


myCombobox.DataSource = ds.Tables [ "mytable" ].DefaultView ; myCombobox.DataBind( ) ;

COM Interoperability... COM components and .NET components are not compatible since they have different internal architectures. However, there are tools available in the .NET SDK for generating COM proxies for .NET components and .NET proxies for COM components. Using these proxies we can use COM components in .NET projects and vice versa. For using COM components in .NET application we can create the wrapper class either by using the 'TlbImp.exe' tool provided in the .NET SDK or by adding the COM reference through the Solution Explorer. To use a .NET component in a non-.NET project we have to first register the component using the RegAsm tool as well as create a corresponding COM type library file ('.tlb' file). To create a COM type library file we need to use the TlbExp tool.
Using Pointers In .NET... Pointers can be used in C#, but only in the blocks of code that we have specifically marked for pointer use. The keyword to do so is unsafe. We can mark individual methods, classes, structures, blocks of code or even local variables as unsafe. For example we can write: unsfae float myfunction( ) { // Can use pointers } unsfae class myclass { unsafe int *x ; } unsafe { // unsafe block }

Creating A Splash Screen... .NET by default does not expose any feature similar to the VC++ SplashScreen, but it can easily be replicated using a simple trick. The trick is to add a form to the application, strip it off all the borders and title bar, also disable it to have any presence on the task bar. Once this is done, wrap your Splash screen bitmap on to this form. Add a timer control to the form and set it to the necessary delay. On the timer_click event, dispose the form. Your authentic splash screen is ready. Now make sure that this form is displayed every time your application starts. Best way to do this is to show the splash screen in the Load event of the application window.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com Structure Of Manifest... The assembly metadata that describes the assembly is called the Manifest. A manifest contains: (a) The identity of the assembly, consisting of its name, version and culture. (b) Names of all the files in the assembly. (c) Whether all the types defined in the assembly are visible to other assemblies or private to one. (d) A hash of all files in the assembly. (e) Details of any security permissions that clients need to have in order to be able to run the assembly.
The With - End With keywords... The keywords With - End With execute a series of statements written between With and End With making repeated reference to a single object of the structure or class. For example the statements e.name = "Satish" e.age = 25 e.sal = 4500 can be written using With - End With as With e .name = "Satish" .age = 25 .sal = 4500 End With How to invoke two handlers for one event? Ans: For one event we can add two handlers. For example, if we click on a button, by default Click event handler gets called. If we want to call some other handler also, we can do so by writing the handler as sub Funname ( ) Handles ControlName.Click. ----End Sub Painting On Form... Suppose we want to display a string at the center of the form. We would do so in Paint event handler as shown below: private void Form1_Paint ( object sender, System.Windows.Forms.PaintEventArgs e ) { Graphics g = e.Graphics ; Font font = new Font ( "Arial", 20 ) ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


g.DrawString ( "Hi", font, Brushes.Blue, ClientRectangle.Width / 2, ClientRectangle.Height / 2 ) ; } We want that if we resize the form, the text at previous position should get erased and should get displayed at the new center of the form. Actually, when the form is resized, Paint event gets generated and form gets invalidated. Then why doesn't the string get displayed at new position? This is because, only that portion of the form gets invalidated, which is being resized. Hence, string remains at its original position. To correct this problem, we must add the Resize event handler and call Invalidate( ) from it. Invalidate( ) invalidates the entire form. Of Paths & Regions... A graphics path is a shape constructed from complex curves and straight lines. The object of GraphicsPath class represents a path. In the following code snippet, we have created a shape of a telephone and added the path object gp to an object of Region class. This object of Region class specifies the area of the window. Add this code in the constructor after call to InitializeComponent( ) method and execute the program. You would appreciate the output. GraphicsPath gp = new GraphicsPath( ) ; gp.AddLine ( 495, 175, 565, 300 ) ; gp.AddLine ( 565, 340, 70, 340 ) ; gp.AddLine ( 70, 300, 140, 175 ) ; gp.AddLine ( 210, 175, 210, 170 ) ; gp.AddLine ( 135, 170, 122, 195 ) ; gp.AddLine ( 70, 195, 55, 155 ) ; gp.AddLine ( 55, 120, 580, 120 ) ; gp.AddLine ( 580, 155, 565, 195 ) ; gp.AddLine ( 513, 195, 500, 170 ) ; gp.AddLine ( 425, 170, 425, 175 ) ; Region = new Region ( gp ) ;

How to run another application from current running application? Ans: To run an application from within a currently running aplication call Start( ) method as shown below: Imports System.Diagnostics Public Class Form1 Private Sub Button1_Click ( ByVal sender As System.Object, ByVal e As System.EventArgs ) Handles Button1.Click Process.Start ( "IExplore", "http://www.funducode.com/" ) End Sub End Class How do I write code to get the list of fonts available on machine in a combo-box? Ans: Create a Windows application. Add a combo box on form. Add code to Load event as shown below: Private Sub Form1_Load ( ByVal sender As System.Object, ByVal e As System.EventArgs ) Handles MyBase.Load

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Dim f( ) As FontFamily = FontFamily.Families Dim l As FontFamily For Each l In f ComboBox1.Items.Add ( l.GetName ( 0 ) ) Next End Sub Thread State... A thread can be in more than one state at any given time. For example, suppose a thread is in the WaitSleepJoin state because a Sleep( ) method was called on it. Now if another thread calls Suspend( ) on this thread, the thread will be in both the WaitSleepJoin and the SuspendRequested states at the same time. In this case, as soon as the sleep time expires instead of moving to the Running state, the thread goes into the Suspended state. Creating TextBox That Accepts Only Digits...... .NET IDE provides various properties that let us change the behavior of controls. For example, we can specify whether a textbox should be a multiline text box or a single line text box. However, there is no property using which we could specify that a textbox would take only digits and would reject any other character. If we want to create such a textbox, we must write code for it. We must check whether the character being typed in the text box is a digit or not. If it is a digit, then only we would show the character in the text box, otherwise we won't. Here is the code that achieves this. private int m_k ; private void textBox1_KeyDown ( object sender, KeyEventArgs e ) { m_k = e.KeyValue ; } private void textBox1_KeyPress ( object sender, KeyPressEventArgs e ) { if ( m_k >= 48 && m_k <= 57 ) e.Handled = false ; else e.Handled = true ; } How do I add a property to a user control that allows user to select a value from combo box? Ans: Almost every WinForm control has properties that allow us to select a value from a combo box. We can add such property to a user control by defining an enum in the control class and declaring a property of that type. For example, in the following code, we have declared a property named Message of type MSGVALUE. MSGVALUE is an enum that defines enumerated types A, B and C. When the type of a property is an enum, .NET adds a combo box to display the enumerated values. public enum MSGVALUE { A = 0, B = 1, C = 2

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


}; MSGVALUE msg ; public MSGVALUE Message { get { return msg ; } set { msg = value ; } } We can use the Process component to start a process from our application or browse the processes running on the system. The Process component can be dragged from the 'Components' tab of the ToolBox. Following code starts the 'explorer.exe' process. process1.StartInfo.FileName = "C:\\WINNT\\explorer.exe"; process1.Start( ) ; We can browse the processes using the GetProcesses( ) static method. Data Binding With WinForm Controls... .NET provides an ability that binds a control with a field in the data source. Binding data with control actually means binding a property of a control with a column of a data source. When the form is loaded the data bound property gets evaluated and the value returned is displayed in the control. For example, the Text property of TextBox control can be bound to a column of a data source. Following statements bind data of the 'PatientName' column of 'PatientInfo' table with Text property. Data of zeroth row will get displayed in the text box named txtname. Binding bname = new Binding ( "Text", m_ds, "PatientInfo.PatientName" ) ; txtname.DataBindings.Add ( bname ) ; Here, m_ds is a reference to DataSet object that is filled with data of a data source.

Difference Between Server-activated & Client-activated Objects... Serveractivated objects are so called because when the client calls new to create an instance of the remote class, only a proxy gets created in the client. The object does not get created or activated. The object gets created only when a method call is placed through the proxy. So, the server actually decides when the object should get created. Clientactivated objects, on the other hand, are created on the server the moment the client calls new. Thus here the client decides when the object should get created. Another difference between the two is that clientactivated objects can be activated using nonzeroargument constructors but serveractivated objects cannot. This is because for serveractivated objects, the calls to new dont map with the actual creation of the object. On the other hand client activated objects can be instantiated with any constructor as both the proxy and the object are created at the same time.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


How to copy an ASP.NET project? Ans: When we create a Web application, its project files get created in the C:\Inetput\wwwroot folder, whereas, the solution files get created in the My Documents\Visual Studio Projects folder. If we want to copy a Web application to some other machine, then copy the project folder in C:\Inetput\wwwroot folder of that machine and make the project folder as virtual folder. To declare it as a virtual folder run IIS, you will see the folder name under the Default Web Site tree. Right click on the folder name and select Properties. From the Execute Permissions combo box and select Scripts and Executables. After this, open the project by selecting 'File | New | Project' in the .NET IDE. Splitter Windows In .NET Earlier, we used to split the frame window using an MFC class. Each pane of the split window was represented by a separate view window. Moving the splitter actually resized the view windows. In .NET, working of splitter is totally different. .NET provides a Splitter control. This control allows the user to resize the docked control that is immediately before it in z-order. Therefore, to use the splitter control, place a control and dock it to the left/right side of the form. Then dock a splitter control to the same side of that container. How do I write code to shift focus on next control on pressing the Enter key? Ans: If forms KeyPreview property is set to true it receives the keyboard events first and then the control having focus also receives the events. We can use the KeyPreview property to filter the keys before a control receives it. For example, we want to design a registration form having many text boxes. If user enters a value and presses the Enter key, next textbox should get the focus. For this, instead of adding keyboard events to each textbox and check for the Enter key press, we can add the KeyDown event handler to the form and check whether the Enter key is pressed. Of course KeyPreview must be set to true. The code to shift the focus is given below. private void Form1_KeyDown ( object sender, KeyEventArgs e ) { if ( e.KeyCode == Keys.Return ) { Control c = GetNextControl ( ActiveControl, true ) ; c.Focus( ) ; } } The ActiveControl property returns the reference of the control that is currently selected. The GetNextControl( ) method returns the control next to the specified control in tab order. The focus is set on the next control using the Focus( ) method. The DateTime class offers an interesting feature. It allows us to add number of hours and minutes to the given DateTime instance. What a big deal? It does not add the values blindly. It updates the hour element if minutes exceed the value 60, and day if hours exceed the value 24. Previously, we had to do this manually by writing pair of ifs and elses. Following code snippet shows how to add 10 hours 45 minutes to the current time. DateTime t = DateTime.Now ; t.AddHours ( 10 ) ; t.AddMinutes ( 45 ) ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


How to check whether a key is pressed in combination with Shift or Toggle keys? Ans: The KeyEventArgs class has a property called Modifiers that contains the status of the modifier keys such as Ctrl, Alt and Shift. So, to check whether Ctrl + A is pressed, we can write the if condition as follows. private void textBox1_KeyPress ( object sender, KeyPressEventArgs e ) { if ( ( e.KeyCode == Keys.A ) && ( e.Modifiers == Keys.Control ) ) MessageBox.Show ( "Ctrl + A pressed" ) ; } Where e is of type KeyEventArgs class. Keys is an enum that specifies the key codes and modifiers. Code Access Security... The Code access Security is a new concept brought in by the .NET framework. Code access security essentially involves granting permissions to an assembly. Code access security uses the location of assembly and other information about the identity of code as a primary factor in determining permissions to be granted to the assembly. This information about the identity of an assembly is called evidence. Once loaded in runtime, the code starts executing in the restricted environment depending upon permissions granted to it. If the code is not trusted enough to run or runs but performs an action for which it has no permissions, then a security exception is thrown. The code access security system means we can stop running of malicious code and also restrict the code to run in a restricted environment where we are sure that it wont do any damage to the resources. Industrial softwares are complex to create and involve work of several programmers. If one programmer is supposed to understand and use a class designed by another programmer, proper documentation of that class should exist. The documentation should reveal the role of that class in the software, functionality of each class member, meaning of parameters of every method of the class and so on. To facilitate the creation of such documentation, Visual Studio.NET provides XML documentation tool. This tool recognizes comments given in the source code. These comments should contain information programmer wishes to provide. Following example shows such a comment. /// <summary> /// Your documentation goes here /// </summary> Setting Security Policies... Sometimes it is necessary to turn off security for whichever reason. Security can be turned OFF by simply typing the following at command prompt. C:\>caspol security off To turn security back ON type on instead of off. The caspol utility can also be used to change the code groups membership condition, permission set, etc. This is shown in the following command. C:\> caspol.exe chggroup 1.2 FullTrust

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Here, 1.2 specifies the label of the code group. It can be any number like 1or 1.1. Instead of label we can mention the name of the group. FullTrust is name of the permission set to associate with the code group. The addgroup flag adds a new code group to the existing code group list. In the command C:\> caspol.exe addgroup 1.2.3 strong file \bin\Debug\trusted.dll noname noversion FullTrust 1.2.3 is the label of the parent code group. Next argument specifies the code that has a specific strong name, as designated by the file name, the assembly name as a string, and the assembly version. noname noversion indicates that no assembly name and version is used. How to add controls programmatically? Ans: We would add a button to the form and add a Click event handler to it. Firstly, declare a reference of the Button class. private Button btn = new Button( ) ; Then assign properties to the button in the InitializeComponent( ) method as shown below. We have also built a delegate for the Click event of the button. btn.Text = "OK" ; EventHandler e = new EventHandler ( btnClick ) ; btncont.Click += e ; Now add the control to the form by calling the Add( ) method. this.Controls.Add ( btn ) ; The Controls property returns a collection of child controls. The Add( ) method adds our control to that collection. We can write the Click event handler as shown below. private void btnClick ( object sender, EventArgs e ) { } How do I write code that displays a form as a modal dialog? Ans: Use ShowDialog( ) method which shows the form as a modal dialog box. Following code snippet demonstrates the use of this method. Private Sub Button1_Click ( ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click Dim test As New Form2 test.ShowDialog( ) End Sub The Handled Property... The Handled property can restrict the controls placed on the form from handling the keyboard events and allow them to be handled only at the form level. For this, forms Handled property

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


should be set to true. Setting the Handled property to true in the OnKeyPress( ) method indicates that the KeyPress event is already handled. The Handled property is also useful in a situation when we want that only certain characters should get entered in the textbox, others should not. For example, we want that a textbox should take only alphabets and should ignore digits and special symbols then the Handled property should be set to false if alphabets are entered and to true otherwise. This is to be done in the KeyPress event handler added for the textbox as shown below. private void textBox1_KeyPress ( object sender, KeyPressEventArgs e ) { if ( ( e.KeyChar >= 97 && e.KeyChar <= 122 ) || ( e.KeyChar >= 65 && e.KeyChar <= 91 ) ) e.Handled = false ; else e.Handled = true ; } The Buffer Class... The term buffer is related to memory, the Buffer class works on direct memory. This class can be used for arrays of primitive types and does not apply to objects. This class provides methods to copy bytes from one array of primitive types to another array of primitive types. In case of System.Array class, it carries an index to index copy. But in the Buffer class, it's from offset to offset. The Buffer class copies a specified number of bytes from a source array starting at a particular offset to a destination array starting at a particular offset. In the System.Buffer class we have the BlockCopy( ) member to copy from one array to another. We can also get a byte from an array, set a byte in an array, and obtain the length of an array. This class provides better performance for manipulating primitive types as comapred to those in the System.Array class.

Integer Types in VB.NET... Integer types in VB.Net are used to represent whole numbers. Depending on the amount of memory required to store an integer the data type in VB.net is categorized as, Byte, Short, Integer and Long. The following table lists the data type and its size. Data Type Byte Short Integer Long Size in Bytes 1 2 4 8

Following statement shows how we can declare an integer variable in VB.NET. Dim x, y As Integer

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Here x and y are two integer variables and as they are not initialised with any number, they would be initialised to 0. Dim i As Short = 12 The variable i declared in this statement would hold value 12. VB.NET provides logical operators, And and AndAlso that can be used to help evaluate expressions. Consider following statement, If age < 10 And number > 4 Then // code End If Here we want that if the value of age is greater than 10, then the second condition should not be evaluated. Since the conditions given above are connected using And, both the conditions would get evaluated. In other words, even if the first condition evaluates to false, And evaluates the second condition. However, in case of AndAlso operator, it evaluates the second condition only if the first condition evaluates to true. For example, If age < 10 AndAlso number > 4 Then // code End If If the value of age is greater than 10, the evaluation of the expression stops and the operator would return false. Thus, using AndAlso helps evaluating expressions efficiently.

There are two types of procedures in VB.NET-Functions and Subroutines. The basic difference between the two is that a subroutine does not return a value whereas a function returns a value. Function is a collection of logical statements which perform a specific task and return some value. Hence whenever you want to return something to a calling function use a function and to display something use a subroutine. Thus, for displaying a menu we would use a subroutine and for calculating a factorial of a number and returning it to the calling function we would use a function.
Constructor in VB .NET In VB.NET the constructor name is not same as the name of the class. A keyword New is used to define a constructor. Following code snippet shows how to declare a constructor: Class sample Dim i As Integer Sub New( ) i=5 End Sub End Class Module Module1 Sub Main( ) Dim obj As sample obj = New sample( ) End Sub

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


End Module In the above example in the class sample we have defined a constructor to initialise the data member i. In main( ) we have created an object obj of the class sample. As soon as the object gets created the constructor gets called and the value of i gets intialised to 5. We can use the MinValue and MaxValue properties to get the minimum as well as maximum range of each data type. This is shown in following example. Module Ranges Sub Main( ) Console.WriteLine("Byte Range: {0} to {1}", Byte.MinValue, Byte.MaxValue) Console.WriteLine("Short Range: {0} to {1}", Short.MinValue, Short.MaxValue) Console.WriteLine("Integer Range: {0} to {1}", Integer.MinValue, Integer.MaxValue) Console.WriteLine("Long Range: {0} to {1}", Long.MinValue, Long.MaxValue) End Sub End Module Namespaces... Much of interesting functionality available in VB .NET is provided by the .NET Framework Class Library. Namespaces are used to hold collection of related classes. Console I/O is provided by the .NET System.Console class. The WriteLine( ) method is used to display a line of text. System.Console.WriteLine ( "Hello World" ) Reference to System.Console.WriteLine may be shortened to Console.WriteLine if you import the System namespace. Import System ... Console.WriteLine ( "Hello World" ) The Import statement tells compiler to look in the System namespace before generating an error whenever an unknown class or function is referenced.

Value Types Vs Reference Types In VB.NET variables are either value types or of reference types. The difference between the value type and reference type is that the data of value type gets stored on the stack and that of the reference type gets stored on the heap. The variables of the value types directly contain the data, whereas, reference types contain references (or addresses) of the data. Examples of value types are the primitive data types integer, floating points, structures whereas examples of reference types are arrays and classes
Arrays... We can declare an array as shown below: Dim arr( ) As Integer arr = New Integer ( 5 ) { }

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Here, the first statement creates only a reference to one dimensional array. By default arr holds nothing. The second statement allocates memory for 5 integers. The space for arr is allocated on the stack. Space of array elements gets allocated on heap. The elements of arr would be 0 as by default array elements are initialised to zero. One more way of declaring an array is given below: Dim arr( ) As Integer = { 1, 2 , 3 ,4 } Here again arr is created on the stack and the actual array elements are created on the heap. These array elements are initialised with values 1, 2, 3, 4 respectively. Note that when we initialize an array at the same place where we are declaring it then there is no need of New statement. In .NET arrays are implemented as objects. An array gets automatically derived from System.Array class. This is because when we create an array a class gets created from the System.Array class. This class internally maintains an array. An object of this class is also created to which the array reference points. Hence using the reference we can call methods and access properties of the System.Array class. In VB.NET the lower bound of an array is always zero. Thus with the statement Dim arr(3) As Integer an array of 4 elements get created. VB.NET provides the flexibility to use Value types as Reference types, as and when required. Whenever a value type is converted into a reference type it is known as Boxing. On the other hand when a reference type is converted into value type it is known as Unboxing. Both the WriteLine( ) and the ReadLine( ) methods use this concept of Boxing and Unboxing respectively. For example, consider following statement: WriteLine ( Dim s As string, ParamArray arr( ) As Object ) Here, all the objects except the first are collected in the ParamArray of type Object. Hence there is no restriction on the number of parameters being printed in the list. In the WriteLine( ) method if we pass an integer variable, the compiler implicitly converts an integer variable ( value type ) into an object ( reference type ) using boxing and collects it as the first element of the ParamArray of objects. Readline( ) method is an example of Unboxing. ReadLine( ) always returns a string which is a reference type. This reference type is explicitly converted into the value type that we want. For example, using CInt we can convert a string into an Integer, which is a value type. Dim I As Integer I = CInt ( Console.ReadLine( ) ) How do I create a structure? Ans: The following code snippet shows how we can create a structure in VB.NET. Structure a Dim i As Integer Dim s As String Sub New ( ii as Integer, ss as String ) i = ii s = ss End Sub End Structure

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Note that we cannot explicitly mention a zero-argument constructor within a structure. A zeroargument constructor is always provided by the compiler. However writing a multiple argument constructor within a structure is allowed. Whenever we wish to group a few dissimilar data types, we must use structures because being a value type it gets allocated on the stack. Memory allocation on stack is always faster than on heap. However, if the structure is big then whenever we pass the structure variable as a parameter or assign it to another structure variable, the full contents of the structure variable gets copied. As against this for a class only the reference gets copied. It is more efficient to copy a 4 byte reference than copying the entire structure. Why memory allocation for value types is faster than for reference types? Ans: Memory allocation for value types is always faster than for reference types. This is because reference types are always accessed via references. Hence anytime our code refers to any member of an object on the heap, code must be generated and executed to dereference the reference in order to manipulate the object. This affects both size and speed. However in case of value types the variable itself represents an object. Hence there is no question of dereferencing in order to manipulate the object. This improves performance. What are Primitive data types? Ans: Data types that are directly supported by the compiler are called Primitive data types. Integers, Single, Double and Char types are all examples of primitive data types. Primitive data types map directly to the types that exist in the base class library. For example an Integer in VB.NET maps directly to System.Int32 type. How do I declare variables as read only in VB.NET? Ans: VB.NET provides a keyword ReadOnly which is used for variables which are to be initialized at the time of building the objects. The following code shows how to declare variables as ReadOnly. Module module1 Class hotel Public ReadOnly name As String Sub New ( ByVal n As String ) name = n End Sub End Class Sub main( ) Dim h As New hotel ( "Tuli" ) End Sub End Module We cannot assign any value to a ReadOnly Variable. Hence the statement h.name = "CP" would give us an error. i.e h.name cannot be written on the left side of the assignment operator. Properties In VB.NET... Properties of a class are actually methods that work like data members .The properties are used to store and retrieve the values to and from the data members of the class. The following code shows how to declare a property called Length within a class called sample.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Module Module1 Class sample Dim len As Integer Property Length( ) As Integer Get Return len End Get Set ( ByVal Value As Integer ) len = Value End Set End Property End Class Sub Main( ) Dim s As New sample( ) s.Length = 10 Dim l As Integer = s.Length Console.WriteLine( l ) End Sub End Module To store and retrieve the len data member of the class sample the Length property is used. A property has two special methods known as a Get accessor and a Set accessor. The Get accessor never accepts any value and the Set accessor never returns any value. The value collected by the Set accessor is stored in an implicit parameter called Value. The statement m.Length = 10 would invoke the Set accessor and the statement len = m.Length would invoke the Get accessor. Interfaces in VB.NET... Interfaces are similar to abstract classes. The following statements show how we can declare an interface called mouse. Interface mouse Sub lbuttondown ( x As Integer, y As Integer ) Sub rbuttondown ( x As Integer, y As Integer ) End Interface Any class can implement the above interface and can provide separate implementation of the functions defined in the interface. Note that an interface contains only declarations of functions and does not contain any definitions. Following code snippet shows how a class can implement the above interface. Class Mouse1 : Implements mouse Sub lbuttondown ( x As Integer, y As Integer ) Implements mouse.lbuttondown Console.WriteLine ( "Left Button : { 0 }, { 1 }", x, y ) End Sub Sub rbuttondown ( x As Integer, y As Integer ) Implements mouse.rbuttondown Console.WriteLine ( "Right Button : { 0 }, { 1 }", x, y ) End Sub End Class Virtual Functions in VB.NET In VB .NET the keyword Overridable is used to indicate that a function is virtual. The

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Overridable keyword in VB.NET is similar to the keyword virtual in C++. Following code snippet shows how we can design a base class that has a virtual function. Class shape Overridable Sub draw( ) Console.WriteLine( " Shape" ) End Sub End Class Any class that inherits the shape class can override the draw( ) method. For this it is necessary that draw( ) method should be preceded with the keyword Overrides in a derived class. This is shown in following code snippet. Class line : Inherits shape Overrides Sub draw( ) Console.WriteLine ( "Line" ) End Sub End Class Conversion Functions In VB.NET... VB.NET provides many conversion functions. Some of these functions are CInt, CBool, CStr, CLng, CDec, CSng, CShort. CInt function converts any numeric expression to an Integer value as shown below: Dim i As Integer i = CInt ( 10.5 ) CBool function convert expressions to Boolean values. Dim check As Boolean Dim a, b As Integer a = 15 b = 15 check = CBool (a = b ) // 'True is assigned in check CStr function converts a numeric value to String. Dim i As Double = 42.34 Dim s As String s = CStr ( i ) These functions are inline functions. Hence execution is faster because there is no call to a procedure to perform the conversion. Error Handling In VB.NET... The errors that occur at the time of execution of a program are known as exceptions. VB.NET provides a Try-Catch mechanism to handle exceptions. The Try block contains code expected to raise an exception. This code in the Try block executes until a statement, which raises an exception, is encountered. When an exception is encountered, the Catch block handles the exception by executing the code written in it. In the following program an

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


IndexOutOfRangeException is raised. The CLR creates an object of the IndexOutOfRangeException class and passes it to Catch block that accepts a reference to the IndexOutOfRangeException. Module Module1 Sub Main( ) Dim index As Integer = 6 Dim val As Integer = 30 Dim a ( 5 ) As Integer Try a ( index) = val Catch e As IndexOutOfRangeException Console.WriteLine ( " Index out of bounds" ) End Try Console.WriteLine( " Remaining program" ) End Sub End Module The output of the above program would be: Index out of bounds

How do I write code to navigate to previous and/or next record? Ans: Add code to the handlers that move record pointer to previous and next record respectively, as shown below: Private Sub Previous_Click ( ByVal sender As System.Object, ByVal e As System.EventArgs ) Handles Previous.Click Dim str As String 'dr is a private variable of type DataRowCollection added to Form class str = dr ( count ).Item ( 0 ) 'to move to previous record decrement count by 1 count -= 1 ' where count is a variable of type Integer If count < 0 Then count = 0 MsgBox ( "Reached First Record" ) End If End Sub Private Sub Next_Click ( ByVal sender As System.Object, ByVal e As System.EventArgs ) Handles Next.Click

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com 'to move to next record increment count by 1 count += 1 Dim str As String str = dr ( count ).Item ( 0 ) ' where dr is a variable of type DataRowCollection If Count >= dr.Count - 1 Then count = dr.Count - 2 MsgBox ( "Reached Last Record" ) End If End Sub
Virtual Functions in VB.NET In VB .NET the keyword Overridable is used to indicate that a function is virtual. The Overridable keyword in VB.NET is similar to the keyword virtual in C++. Following code snippet shows how we can design a base class that has a virtual function. Class shape Overridable Sub draw( ) Console.WriteLine( " Shape" ) End Sub End Class Any class that inherits the shape class can override the draw( ) method. For this it is necessary that draw( ) method should be preceded with the keyword Overrides in a derived class. This is shown in following code snippet. Class line : Inherits shape Overrides Sub draw( ) Console.WriteLine ( "Line" ) End Sub End Class How do I write pure virtual functions in VB.NET? Ans: In VB.NET the pure virtual functions are written by writing the keyword MustOverride against the name of the method. The keyword MustOverride specifies that the method written in the base class must be overridden in the derived class. Like pure virtual functions a MustOverride method cannot have a body. Consider the following example: MustInherit Class shape MustOverride Sub draw( ) End Class Class circle : Inherits shape Overrides Sub draw( ) Console.WriteLine ( "Circle" ) End Sub

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


End Class Here, since the method draw( ) is declared as MustInherit in the base class shape, any class that inherits the class shape must override the draw( ) method. Hence the class circle which inherits shape class provides its own implementation of the draw( ) method. How do I write code that would throw exceptions explicitly in VB.NET? Ans: In VB.NET the Throw statement is used to throw an exception explicitly. Class sample Sub fun ( i As Integer ) If i > 10 Then Throw New Exception ( "Value out of range" ) Else Console.WriteLine ( i ) End If End Sub End Class Module Module1 Sub Main( ) Dim m As New sample( ) Try m.fun ( 20 ) Catch e As Exception Console.WriteLine ( e.Message( ) ) End Try Console.WriteLine ( "Remaining Program" ) End Sub End Module Here, the parameter passed to the method fun( ) is greater than 20 hence an exception would be raised. The Catch block catches the exception and displays the message "Value out of Range". How do I write code to display two strings on two lines using Writeline( )? Ans: VB.NET provides a keyword NewLine which helps to achieve this purpose. In order to use this keyword we must import the namespace Microsoft.VisualBasic.ControlChars. Following statement shows how to use this keyword. Console.WriteLine ( "hi" & NewLine & "hello" ) How do I change the size of an array in VB.NET? Ans: VB.NET provides a keyword called Redim which enables us to change the size of an array that has been already declared. The following code snippet shows how to change the size of an array called arr from 6 elements to 11 elements. Dim arr ( 5 ), i As Integer For i = 0 To UBound ( arr ) arr ( i ) = i Next ReDim arr ( 10 ) 'The size of arr now becomes 11 ( as array always starts from 0th index) For i = 0 To UBound ( arr )

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


arr ( i ) = i * 10 Next Suppose we want to preserve the existing contents of an array then we have to use the keyword preserve along with Redim as shown below: Redim preserve arr ( 10 ) How do I write a class that cannot be inherited? Ans: VB.NET provides a keyword called NotInheritable which ensures that a class cannot be derived further. This is shown in following code snippet. NotInheritable Class shape Sub draw( ) Console.WriteLine ( "Shape" ) End Sub End Class Since the class shape is preceded with the keyword NotInheritable, any attempt to derive a class from the class shape leads to an error. How do I create a form of elliptical shape? Ans: To create a form of elliptical shape, write following code in the constructor of the Form1 class. Public Sub New( ) MyBase.New( ) Dim gp As New GraphicsPath( ) gp.AddEllipse ( 20, 20, 140, 40 ) Region = New Region ( gp ) End Sub Here, first we have instantiated an object of the GraphicsPath class. This GraphicsPath class has various methods which can be used to create various user defined shapes. Using the AddEllipse( ) method of this class we have first created an elliptical shape. We have then instantiated a new Region object and to its constructor we have passed this graphics path. Next to the Region property of the Form1 class we have assigned this newly created region. Due to this only that portion of the form would be visible which lies within this region. Note that for this it is necessary to import System.Drawing.Drawing2D namespace. How do I write code to create a mirror image? Ans: To create a mirror image write following code in Form1_Paint Event handler. Sub Form1_Paint ( s As Object, e As PaintEventArgs ) Handles MyBase.Paint Dim g As Graphics = e.Graphics Dim myimg As Image = Image.FromFile ( "C:\fcode.jpg" ) Dim mymat As Matrix = New Matrix( ) mymat.Scale ( -1, 1 ) mymat.Translate ( -350, 0 )

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


g.Transform = mymat g.DrawImage ( myimg, 50, 50 ) g.ResetTransform( ) End Sub Here first we have used the shared method FromFile( ) of the Image class. This would return a reference to image which we have collected in the variable myimg. In order to create a mirror image we have to make use of transformations. To create a transformation matrix we have first created an object of the Matrix class. We have first scaled the matrix by passing a -1 as the first parameter to the Scale( ) method. Due to this all the x coordinates would be multiplied by -1. After multiplying this matrix with the coordinates of the image the resultant image would be the mirror image of the original. When we scale the coordinates of an image by multiplying them with -1 the resulting coordinates become negative. Hence they would not be visible as top left corner of the form is 0, 0. To bring the image back in the form we have to translate it by some x and y values. For this we multiply the co-ordinates by a negative number to make the resultant coordinates positive. Next we have assigned this resultant transformation matrix to the Transform property of the Graphics object. There onwards everything that gets drawn would be multiplied with the transformation matrix. Finally for drawing the image we have used the DrawImage( ) method. What are Delegates and how do I declare a Delegate? Ans: The word delegate means a representation of a function. A delegate is implemented as an object that stores address of a method in it. The class of this object is called a delegate class and is derived from System.MultiCastDelegate class. The following statement shows how to declare a delegate class. delegate Sub del ( string ) When the compiler encounters this statement it creates a class named del and derives it from the System.MulticastDelegate class. Later when an object of the delegate class del is created, it can hold address of a method whose return type is void and receives a string. To store address of a method say fun( ) inside a delegate object we need to first create a delegate object. This is done as shown below: Dim d As New del ( AddressOf fun ) Here d is a reference to an object of del. The address of the fun( ) method is passed to the constructor of the delegate class which is created by the compiler. The constructor stores this address in the delegate object. To call the wrapped method we can now write the following statement: d ( "Hi" ) Here d delegates (represents) fun( ) in true sense. In VB..NET an Enum cannot have a circular definition. For example we cannot declare an Enum as shown below: Enum emp As Integer skilled = highlyskilled semiskilled highlyskilled unskilled

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


End Enum Here the value of skilled depends on its own value and hence is an error. We can however declare the Enum as shown below: Enum emp As Integer skilled semiskilled highlyskilled = skilled unskilled End Enum Now if we print the members of the Enum in the order in which they are defined then we will get output as 0, 1, 0 and 1. The member skilled gets initialized to 0, the semiskilled to 1 ( 0 +1), highlyskilled to 0 again and unskilled to 1 ( 0 + 1). How do I draw an icon on the form? Ans: To draw an icon on the form we need to create an object of the Icon class by supplying the file name of the '.ico' file and then calling the DrawIcon( ) method of the Graphics class. Suppose that the reference of the graphics object is in g, then we can write the following: Dim i As Icon New ( "C:\myicon.ico" ) g.DrawIcon ( i, 10, 20 ) where 10, 20 denote the top left coordinates from where the icon would be drawn. What is MergeOrder? When is it used? Ans: MergeOrder is a property of the MenuItem class. This property gets or sets a value indicating the relative position of the menu item when it is merged with another. For example, suppose we create an MDI application. Now we add a MainMenu control containing some MenuItems to both the parent and the child window. If the child window has a set of menu items that we want to display in the parent window's main menu, we can create a MainMenu as part of both the forms and set some values to the MergeOrder property of the MenuItems of both the forms. So now when the child window is activated, its MainMenu is merged with the MainMenu of the parent window. While merging, the order of the menu items is according to the MergeOrder property. How do ASP.NET pages support Cookieless Sessions? Ans: By default, ASP.NET pages, like ASP, use cookies to correlate the session state with every user. Hence if the browser does not support cookies, then there arises a problem. ASP.NET however supports cookieless session state. Cookieless sessions are enabled by adding cookieless = true to the sessionState element in the web.config file. In this case ASP.NET correlates users and the session states by passing the session id in the URL. The value seen in parenthesis in the browsers address bar is the session ID. Before returning the page to the client, ASP.NET inserts the session ID into the URL. When the page posts back to the server, ASP.NET strips the session ID from the URL and uses it to associate the request with the session. What is a Mobile Web Forms page?

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Ans: Mobile web forms page is a specialized Microsoft ASP.NET Web Forms page. As with any other Web Forms page, a mobile Web Forms page is a text file with an '.aspx' file extension. This page contains a set of mobile Web Form controls ASP.NET server controls that can adaptively render WML script. We can program mobile pages and controls by using device-independent properties, methods, and events. When supported device requests a mobile Web Forms page, the page and controls automatically produce a rendering suitable for the device. Ordinary ASP.NET Web Forms pages can contain only one form per page. However, because mobile devices typically have smaller screens, a mobile Web Forms page allows several forms to be defined. When a client accesses a page for the first time, the first form is shown by default. You can programmatically navigate to other forms. To be able to develop mobile applications and use Mobile SDK we need to download the MobileIT.exe and install the msi from msdn.microsoft.com How do I write code to show a bitmap in a picture box and save the picture along with changes if some drawing is done on it? Ans: Follow the steps as listed below: 1. On the form place a picture box named pb and a botton named save. 2. Add following variables in the form class. Dim sourcefile As String Dim i As Image Dim st, en As Point Dim p As Pen Dim newbitmap As Bitmap 3. Add following code in the constructor to show bitmap in the picture box. Public Sub New( ) MyBase.New( ) 'This call is required by the Windows Form Designer. InitializeComponent( ) 'Add any initialization after the InitializeComponent( ) call sourcefile = "C:\MyPicture.bmp" Try i = Image.FromFile ( sourcefile ) pb.Image = i newbitmap = New Bitmap ( i ) Catch ex As Exception MessageBox.Show ( ex.Message ) End Try End Sub 4. Create bitmap in memory using the Bitmap class. Then whatever drawing needs to be done in the MouseMove handler will be done on this bitmap by creating Graphics Context of the bitmap which in our case is gi. We will create Graphics context of Picture Box say g for example.Then write following code in the MouseMove handler. Private Sub pb_MouseMove ( ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs )

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Handles pb.MouseMove p = New Pen ( Color.Red ) Dim gi As Graphics = Graphics.FromImage ( newbitmap ) Dim g As Graphics g = pb.CreateGraphics If ( e.Button = MouseButtons.Left ) Then en = New Point ( e.X, e.Y ) g.DrawLine ( p, st, en ) gi.DrawLine ( p, st, en ) gi.Dispose( ) st = en End If End Sub 5. On clicking save button this image should get saved into another file say C:\MyPicture1.bmp. To do so we just have to call the Save function of the Bitmap class. Add following code to this function. Private Sub save_Click ( ByVal sender As System.Object, ByVal e As System.EventArgs) Handles save.Click Try Dim newfile As String = "C:\MyPicture1.bmp" newbitmap.Save ( newfile ) newbitmap.Dispose( ) Catch ex As Exception MessageBox.Show ( ex.Message ) End Try End Sub How do I write code to show check boxes within a listview control and on checking a particular check box the associated text should get written in the text box.? Every time checking the check box the text should get appended in the text box. And on unchecking a particular check box appropriate text should get erased from the text box Ans: Create an application and place a listview control named list and a text box named message on the form. Set the CheckBoxes property of list view to true. Add the check boxes through the Items (Collection) property of the list view control. Set the Text property of each item. Now we want that when the check box in the list is checked the corresponding text should get displayed in the text box and when unchecked the text should get erased from the text box. For this add the ItemCheck handler in the form class and write following code in it. Private Sub list_ItemCheck ( ByVal sender As Object, ByVal e As System.Windows.Forms.ItemCheckEventArgs ) Handles list.ItemCheck Dim icoll As ListViewItemCollection = list.Items Dim litem As ListViewItem = icoll.Item(e.Index) Dim i As Integer If e.NewValue = CheckState.Checked Then message.Text = message.Text & litem.Text message.Text = message.Text & " " ElseIf e.NewValue = CheckState.Unchecked Then

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Dim l As Integer = litem.Text.Length i = message.Text.IndexOf(litem.Text) message.Text = message.Text.Remove(i, l + 1) End If End Sub How do I show a large size bitmap into a small size picture box by using the transformation techniques? Ans: Create a windows application. Place a picture box named pb and a button named Show on the form. On clicking the button the file should get displayed in the picture box. Add code shown below to the button handler. Private Sub Show_Click ( ByVal sender As System.Object, ByVal e As System.EventArgs ) Handles Button1.Click Dim i As Image i = Image.FromFile("C:\picutre.bmp") Dim w As Integer = i.Width ' image width Dim h As Integer = i.Height ' image height Dim pw As Integer = pb.Width ' picture box width Dim ph As Integer = pb.Height ' picture box height Dim perw As Single = pw * 100 / w Dim perh As Single = ph * 100 / h Dim mat As New Matrix() mat.Scale(perw / 100, perh / 100) Dim pbg As Graphics = pb.CreateGraphics pbg.Transform = mat pbg.DrawImage(i, 0, 0) End Sub To send mail via outlook express in VB.NET Create a Windows application and place a button SendMail named sendmail on the form and a text box named emailaddr on it. After writing the email address in the text box when the SendMail Button is clicked OutLook Express Dialog Box should get popped up having the email address which is written in the text box. For this write the following code in the sendmail button handler

Private Sub sendmail_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mailsend.Click If emailaddr.Text = "" then MessageBox.Show("Enter The Email Address") Return End If

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

System.Diagnostics.Process.Start("mailto:" & emailaddr) End Sub How do I make use of LinkLabel control in a program? Ans: Follow the steps listed below: 1. Create a Windows Application. 2. Place on it a LinkLabel control named as link. 3. Set the Text property of link as "http://www.funducode.com/". On clicking link an appropriate web page should get opened. To make it work add the LinkClicked event handler and write code to it as given below: Private Sub link_LinkClicked ( ByVal sender As Object, ByVal e As System.Windows.Forms.LinkLabelLinkClickedEventArgs ) Handles link.LinkClicked System.Diagnostics.Process.Start(link.Text ) End Sub How do I write code that sends an e-mail? Ans: Create a Windows Application. Place four Text Boxes labeled as emailaddr, fromaddr, emailmessage and emailsubject used forentering the destination email address, sending email address, writing message and writing subject respectively. Also add a button SendMail named sendmail on the form. On entering the email address in the text box and on writing the message in the emailmessage text box when the SendMail button is clicked the mail should be sent to the proper address. To do so we will use SMTPMail class, and to use it we need to add a reference in our solution. Click on 'View' menu and select 'Solution Explorer'. Right-click on 'references', select 'Add Reference' option. Then select 'System.Web.dll'. Click select and then press OK. As a result, System.Web reference will get added in our solution. Now, we will have to import the namespace System.Web.Mail. For that write the following import statement in the Form1.vb at the top. Imports System.Web.Mail Then, write following code in the Click event handler of the SendMail button. Private Sub sendmail_Click ( ByVal sender As System.Object, ByVal e As System.EventArgs ) Handles sendmail.Click If emailaddr.Text = "" Then MessageBox.Show ( "Please enter email address" ) Return End If Dim myMail As New MailMessage( ) myMail.From = fromaddr.Text myMail.To = emailaddr.Text myMail.Subject = emailsubject .Text myMail.BodyFormat = MailFormat.Text

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


myMail.Body = message.Text SmtpMail.Send ( myMail ) End Sub How do I write code that pops up a context sensitive menu on right clicking onto a combo box? Ans: Follow the steps given below. 1. Create a Windows Application and place a combo box named cb on the form. Add a context menu on the form named combomenu and add an item cadd in the menu. 2. Set the text property of the menu item cadd as "ADD". 3. Set the ContextMenu property of the combo box as combomenu. 4. Add the Click event handler for the cadd menu item and enter code given below in it. Private Sub cadd_Click ( ByVal sender As System.Object, ByVal e As System.EventArgs ) Handles cadd.Click If cb.FindStringExact(cb.Text) = -1 Then cb.Items.Add(cb.Text) End If End Sub Here, we have not only added a context sensitive menu but also given a provision that on clicking the menu item 'ADD", the text typed in the combo box should get added in the dropdown list. If the text is already present in the dropdown list it would not get added to the list. How do I write code that uses ListView control to display list of records? Ans: Create a Windows application and place three text boxes named empname, age, sal for writing name, age and salary of an employee. Place a button called 'Add' and a list view control on the form. On clicking 'Add' button information in all edit boxes should get added in the list view under appropriate column. Set the View property of list as Details. Click on the Columns property in the Property Window for list, add three columns to list in ColumnHeader Collection Editor and set their Text Properties as 'Name', 'Age', 'Salary' respectively. Then add following code in the Click Event handler of the 'Add' button. Private Sub adddata_Click ( ByVal sender As System.Object, ByVal e As System.EventArgs ) Handles adddata.Click Dim litem As New ListViewItem( ) litem.Text = empname.Text litem.SubItems.Add ( age.Text ) litem.SubItems.Add ( sal.Text ) list.Items.Add ( litem ) End Sub How do I write code that sends a mail via outlook express? Ans: Create a Windows application and place a button named sendmail and a text box named

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


emailaddr on the form. On adding the email address to the text box if sendmail button is clicked 'OutLook Express' dialog box should get popped up with an email address written in the text box. To get so write following code in the button handler. Private Sub sendmail_Click ( ByVal sender As System.Object, ByVal e As System.EventArgs ) Handles mailsend.Click If emailaddr.Text = "" then MessageBox.Show ( "Enter The Email Address" ) Return End If System.Diagnostics.Process.Start ( "mailto:" & emailaddr ) End Sub How do I write code that shows check boxes in the list view and displays the text in a message box when a check box is checked? Ans: Create a Windows application and place a list view control named as list on the form. Set its ShowCheckBoxes property to true and view property as List. Add items in the list by clicking on Items property in the 'Properties'. Set the Text property of each item in the 'ListViewItem Collection' editor. To be able to make use of ListviewCollection class write following statement in Form1.vb at the top. Imports System.Windows.Forms.ListView Now, add ItemCheck event handler of list and write following code in the ItemCheck event handler. Private Sub list_ItemCheck ( ByVal sender As Object, ByVal e As System.Windows.Forms.ItemCheckEventArgs ) Handles list.ItemCheck Dim icoll As ListViewItemCollection = list.Items Dim litem As ListViewItem = icoll.Item ( e.Index ) If e.NewValue = CheckState.Checked Then MessageBox.Show ( litem.Text ) End If End Sub How do I display an icon of an application in system tray and display context menu for it? Ans: Create a Windows application and place NotifyIcon control on the form. Name it as trayicon. Add an icon to your application and name it as myicon. Set the Icon property of trayicon as myicon. Place a ContextMenu control on the form and name it as trayconmenu. Add one item to the menu having text 'Exit' and name as ex. Set the ContextMenu property of trayicon as myconmenu. Add handler for click event for ex menu item and write following code in it. Private Sub ex_Click ( ByVal sender As System.Object, ByVal e As System.EventArgs ) Handles ex.Click Application.Exit( ) End Sub

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


How do I write code to display contents of a file in a multi-line text box? Ans: Create a Windows application. Place two text boxes named filepath and filetext, and two buttons named browse and open on the form. Set the two properties Mutiline and ScrollBars of filetext to True and Both respectively. Then drag OpenFileDialog control on the form. Name it as opendlg and set its Filter property to 'Text files (*.txt)|*.txt'. Add click event handlers for both the buttons browse and open. Write following code in button handler for browse:

Private Sub browse_Click ( ByVal sender As System.Object, ByVal e As System.EventArgs ) Handles browse.Click opendlg.ShowDialog( ) If opendlg.FileName <> "" Then filepath.Text = opendlg.FileName End If End Sub Here, we have used StreamReader class hence write following line at the top in Form1.Vb file Imports System.IO Now, add following code in the click event handler of open button. Private Sub open_Click ( ByVal sender As System.Object, ByVal e As System.EventArgs ) Handles open.Click Dim reader As StreamReader = New StreamReader ( filepath.Text ) filetext.Text = reader.ReadToEnd( ) reader.Close( ) End Sub

How do I write code to display a Splash Screen for an application? Ans: Create a Windows application. Add another form named SplashForm to the application by selection Project | Add | Windows Form menu item. Insert a picture box on the SplashForm. Copy a '.bmp' say 'Splash.bmp' to the project. Set the Image property of the picture box to the file name 'Splash.bmp'. Change the BackColor and BorderStyle property of SplashForm to White and none respectively. Set the TransparencyKey of SplashForm as White. Then write following code in the constructor of Form1. Public Sub New( ) MyBase.New() 'This call is required by the Windows Form Designer. InitializeComponent( ) 'Add any initialization after the InitializeComponent() call Dim f As New SplashForm( ) End Sub Write following code in constructor of SplashForm. Public Sub New( ) MyBase.New( ) 'This call is required by the Windows Form Designer. InitializeComponent( )

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


'Add any initialization after the InitializeComponent( ) call Show( ) Application.DoEvents( ) Thread.Sleep ( 1000 ) Dispose( ) End Sub

Accessing Database Using OLEDB.NET... Create a database called bank and add a table called account with three fields accno, name and balance. Create a console application. In this application we will connect to the database and display the contents of the table account on the console output. To be able to use class OLEDBDataReader write following line at the top in 'Module1.Vb'. Imports System.Data.OleDb Create the connection string and the command strings. Then create OleDbConnection object and OleDbCommand object. Using the command object execute the query. Write code in Sub Main( ) as shown below: Sub Main( ) Dim connectionstr As String = "Provider = Microsoft.Jet.OLEDB.4.0 ;Data Source = c:\bank.mdb" Dim commandstr As String = "SELECT accno, name, balance from account" Dim connection As New OleDbConnection ( connectionstr ) Dim command As New OleDbCommand ( commandstr, connection ) connection.Open( ) Dim r As OleDbDataReader = command.ExecuteReader( ) While r.Read( ) Console.WriteLine ( r(0) & r(1) & r(2) ) End While connection.Close( ) End Sub How do I declare variables as read only in VB.NET? Ans: VB.NET provides a keyword ReadOnly which is used for variables which are to be initialized at the time of building the objects. The following code shows how to declare variables as ReadOnly. Module module1 Class hotel Public ReadOnly name As String Sub New ( ByVal n As String ) name = n End Sub End Class Sub main( ) Dim h As New hotel ( "Tuli" ) End Sub

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


End Module We cannot assign any value to a ReadOnly Variable. Hence the statement h.name = "CP" would give us an error. i.e h.name cannot be written on the left side of the assignment operator. Properties In VB.NET... Properties of a class are actually methods that work like data members .The properties are used to store and retrieve the values to and from the data members of the class. The following code shows how to declare a property called Length within a class called sample. Module Module1 Class sample Dim len As Integer Property Length( ) As Integer Get Return len End Get Set ( ByVal Value As Integer ) len = Value End Set End Property End Class Sub Main( ) Dim s As New sample( ) s.Length = 10 Dim l As Integer = s.Length Console.WriteLine( l ) End Sub End Module To store and retrieve the len data member of the class sample the Length property is used. A property has two special methods known as a Get accessor and a Set accessor. The Get accessor never accepts any value and the Set accessor never returns any value. The value collected by the Set accessor is stored in an implicit parameter called Value. The statement m.Length = 10 would invoke the Set accessor and the statement len = m.Length would invoke the Get accessor.

What does .Net framework consist of? Ans: The .Net framework consist of the following: Class Library which contains Language Independent classes Virtual Machine which is known as Common Language Runtime used to run native code Development Environment comes in the form of Visual Studio.Net which supports VB, VC++ & C# to create Portable Executable files and components

What is Microsoft Intermediate Language (MSIL)? Ans: MSIL is a CPU-independent set of instructions. It is like bytecode in Java. MSIL code under .Net is stored in EXEs or DLLs. EXEs are known as (portable executable) file.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Once our source code is written, we compile it, and the language compiler translates it to MSIL code. Before the MSIL code can be executed it is converted to native code by Just In Time (JIT) Compilers. C# data types can be divided in two categories: value types and reference types. Value types are allocated on the stack. When we assign one instance of a value type to another instance of the value type, we get two separate copies of the same value in memory. int, byte, short, double, etc. are the examples of value type. Reference types are allocated on the heap. Assigning one instance of a reference type to another instance of the reference type results in two references pointing to the single object. All the user defined classes as well as string and object classes are of reference types. The object type is the ultimate base type of all types In C++ primitive data types were simple variables not objects. C++ did not provide any way to convert the variables into objects. Java made an attempt has been made to represent everything as an object. However, problem arises when primitive data types appear in the scene. Java separated the primitive data types from objects. Java treats primitive data types as variables but also provides wrapper classes to convert the primitive data types into objects. C# uses the third way. In C#, the basic types are actually value types but can also be used as objects. For using the value type variable as an object we do not require to use wrapper classes. Following code snippets show how an int variable can be used as an object. int n = 10 ; string s = n.ToString( ) ; string s = 10.ToString( ) ; Here, ToString( ) function of object class gets called. Why in C#, uninitialised variables do not contain garbage value? In C or C++ initial value of variable is garbage value. This is not so in C#. The reason is that all value types implicitly declare a public zero argument constructor called the default constructor. The default constructor initialises the instance with the value according to the value type. For example, an int is initialized with 0, bool with false, char with '\0', etc. Like any other constructor, the default constructor of a value type is invoked using the new operator. Because every value type implicitly has a public parameterless constructor, it is not possible for a struct type to contain an explicit declaration of a parameterless constructor. However, a struct type is permitted to declare parameterized constructors. checked and unchecked operators : Sometimes while performing mathematical calculations we may add two integers which results into a long. This results into an unpredictable result. C# provides two operators checked and unchecked which can be used to avoid such results. These operators control overflow checking for arithmetic operations and conversions of integral type. If an operation is checked and if overflow occurs an exception is thrown. If the operation is unchecked, the overflowing bits (higher bits) are discarded and the number corresponding to the remaining bits is stored. Consider the following code: public static void Main ( string args[ ] ) { int a = 60000, b = 50000, c = 0, d = 0 ; try {

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


d = checked ( a * b ) ; } catch ( System.OverflowException e ) { Console.WriteLine ( e ) ; } c=(a*b); Console.WriteLine ( "the result is {0} {1}",c , d ) ; } In the first case when ( a * b ) is checked an exception gets thrown as the result goes out of scope of an int variable. In the second case the result is -1294967296 0. checked and unchecked operators work for int, uint, long and ulong data types. Switch-case statements do not fall through in C#... Unlike C and C++, execution of a switch in C# is not permitted to 'fall through' to the next section. This is because writing break in a case section is necessary. Thus, the following code would get executed in C and would print all the statements but in C# it would flash an error. switch ( grade ) { case 'A' : Console.WriteLine ( "This is A" ) ; case 'B' : Console.WriteLine ( "This is B " ) case 'C' : Console.WriteLine ( "This is C" ) ; case 'F' : Console.WriteLine ( "This is F" ) ; } When execution of a case section is to be followed by another case section, we must use explicit goto statement at the end of the section. For example, goto case 'B' ; This will transfer the control to case 'B' section. We can specify an integer, character and string types in switch statement. Strings - quoted and @-quoted CSharp supports two types of string literals, quoted and @-quoted. Quoted strings are normal strings that support escape sequences. If we want the compiler not to process the escape sequences we can use @-quoted strings i.e we can preface the string with an @ symbol. The main advantage of @-quoted string is that it simplifies the expression of path names. For example, string s1 = @"C:\Articles\text.txt" ; // here the escape sequences are not expanded string s2 = "C:\\Articles\\text.txt" ; // here escape sequences are processed to get a literal backslash string s3 = "hi \t there" ; // output: hi there string s4 = @"hi \t there" ; // output: hi \t there How to create user-defined exceptions? We can create our own exceptions by creating a class and deriving it from System.Exception class. Creating our own exception class enables users of our class to take different actions based on that exception. For example, if we want that value of a variable, say x, should not exceed 10 then we can design our class like this.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

public class myexception : Exception { public string i ; public myexception ( string x ) : base ( x ) { } } Calling the base class constructor is mandatory here. We can throw this exception anywhere in the program in the following manner: if ( x > 10 ) throw new myexception ( "Value out of Range" ) ; The new modifier Suppose a base class has a virtual function and the virtual function is overridden in the derived class. If we store a reference of derived class in an object of base class and try invoking the function, the function from the derived class is called. If we don't override the virtual function, the function from the base class is called. But along with this, a warning is flashed. To remove this warning and call the function of the base class we have to add the a modifier called new to it. The new modifier is used to explicitly hide a member inherited from a base class. C# destructors and Finalize( ) method In C++ whenever an object gets destroyed the destructor of that class gets called. In C# the destructor does not work in this manner. A C# destructor is nothing but a Finalize( ) method in disguise. The Garbage Collector calls the Object.Finalize( ) method immediately before the object is collected (destroyed). We can not tell when the garbage collector gets called and when the object gets destroyed because C# runtime schedules garbage collections when it feels theyre necessary. It is quite possible that the destructor we wrote never gets called. If we write the destructor and the Finalize( ) method in the same class the compiler flashes error String Comparison In C# we can use == operator to compare two strings, but the comparison done will be case sensitive. Method Compare( ) can be used for both, case sensitive as well as case-insensitive string comparison. If we pass true as the last parameter to the Compare( ) method the comparison becomes case insensitive. Following code snippet illustrates this: string str1 = "hello" ; string str2 = "HELLO" ; bool chk1 = ( str1 == str2 ) ; // output is false int chk2 = ( String.Compare ( str1, str2, true ) ) ; // output is 0, meaning strings are equal Function Overloading Value, Reference, Output and Parameter Array can be used to overload a function. Consider the following program. public class Class1 { public static int Main ( string[] args )

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


{ int x = 10, y = 20, z = 30 ; Func ( x , y ) ; Console.WriteLine ( x + " " + y ) ; Func ( ref x, ref y ) ; Console.WriteLine ( x + " " + y ) ; int p, q ; Func ( out p, out q ) ; Console.WriteLine ( p + " " + q ) ; Func ( x, y, z ) ; Console.WriteLine ( x + " " + y + " " + z ) ; return 0 ; } public static void Func ( int a, int b ) { a++ ; b++ ; } public static void Func ( ref int a, ref int b ) { a++ ; b++ ; } public static void Func ( out int a, out int b ) { a = 88 ; b = 77 ; } public static void Func ( params int[] args ) { foreach ( int i in args ) i++ ; } } The output is as follows: 10 20 11 21 88 77 11 21 30 Here, we have overloaded the function Func( ). The first call to Func( ) calls the first function defined. Here the parameters are value parameters and after execution we see that the change is not reflected in Main( ). On the second call, the second function is invoked where parameters are reference parameters. Whatever changes are made in the function are reflected in Main( ). On the third call, the unassigned variables p and q (output parameters) get assigned and the values are reflected in Main. In the last function, we have used a parameter array, so the variables x, y and z are passed in the array. The changes are not reflected in Main( ). The WinCV Tool The WinCV Tool is a class viewer tool. It displays all methods, properties, events and fields of the specified class in C# syntax. In the left hand side pane we get the class name and the namespace in which the class is contained. We get the definition of the selected class in the right hand side pane. This side also gives us which assembly the class is defined in.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


We must type in our string in the 'Searching For' box. As we type, the WinCV tool displays all the classes that contain the search string. We can start the WinCV Tool by typing in wincv at the command prompt or clicking on the file in Windows Explorer. 'WinCV.exe' is present in 'C:\Program Files\Microsoft.Net\FrameworkSDK\Bin'. How do I create a transparent brush? Ans: We can create a transparent brush by changing the alpha component in the FromARGB( ) method of the Color class. To create the transparent brush we must set the alpha element to a value less than 255. The alpha value ranges from 0 (fully transparent) to 255 (fully opaque). The default value of alpha is 255 i.e. opaque. The first parameter passed to FromARGB( ) method is the alpha value. protected void Form1_Paint ( object sender, System.WinForms.PaintEventArgs e ) { Graphics d = e.Graphics ; SolidBrush s = new SolidBrush ( Color.FromARGB ( 255, 0, 0 ) ) ; Font f1 = new Font ( "Times New Roman", 20 ) ; d.DrawString ( "Hello", f1, s, 100, 100 ) ; Font f = new Font ( "Times New Roman", 200 ) ; SolidBrush s1 = new SolidBrush ( Color.FromARGB ( 150, 255, 255, 0 ) ) ; d.DrawString ( "Hello", f, s1, 50, 50 ) ; } Thus, the second string drawn is transparent and the first string becomes visible in background, which otherwise would have been overwritten Threading in C# In C# to start a new thread we create a new object of the class Thread. To the constructor of this class, an object of the class ThreadStart is passed. The ThreadStart class is a delegate that points to the method that should be executed first when a thread is started. When the Start( ) method is called, the new thread will begin executing at the ThreadStart delegate passed in the constructor. public static void NewThread1 ( ) { for ( int i = 0 ; i <= 500 ; i++ ) Console.WriteLine ( "Second thread " + i ) ; } public static int Main ( string [ ] args ) { Thread t1 = new Thread ( new ThreadStart ( NewThread1 ) ) ; t1.Start( ) ; for ( int i = 0 ; i <= 500 ; i ++ ) Console.WriteLine( "First thread " + i ) ; } Here since we have used threading both the loops will run simultaneously. How does the Garbage Collector work? Ans: The Garbage Collector takes information from the CLR (Common Language Runtime) about the running application. It obtains a list of objects that are directly referenced by the application. Then it finds out all indirect references through the direct references. After it finds out information about these objects, it cleans up the rest of them, and compacts the remaining heap.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


The Garbage Collector calls the Object.Finalize( ) method immediately before the object is collected. Programmers can use the Finalize( ) method to do any necessary cleanup when dealing with reference types. The using statement... Obtaining resources, executing them and disposing them off is done by the using statement. A resource is a class or structure that implements System.IDisposable.interface. The using statement is translated into 3 parts: acquisition, usage, and disposal. Consider the following program using System; namespace resourse1 { class Class1 { static void Main ( string[ ] args ) { using ( myclass m = new myclass( ) ) { m.myfunc( ) ; } } } } class myclass : IDisposable { public myclass( ) { Console.WriteLine ( "In Constructor" ) ; } public void myfunc( ) { Console.WriteLine ( "In myfunc" ) ; } public void Dispose( ) { Console.WriteLine ( "In Dispose" ) ; } } First the constructor gets called, then the myfunc( ) method and lastly the Dispose( ) method gets called. User Defined Conversions We can overload explicit and implicit conversions. We can define operators for a class to convert objects to and from other types. They are very similar to C++ type conversion operators. public class class1 { static void Main ( string[ ] args ) { mystr s = ( mystr ) "Hello" ; //Explicit conversion requires explicit casting s.show ( ) ; string s1 = s ; //Implicit conversion does not require explicit casting Console.WriteLine ( s1 ) ; } } public class mystr { string str ; mystr ( string st ) { str = st ; }

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


public static explicit operator mystr ( string s ) { return new mystr ( s ) ; } public static implicit operator string ( mystr s ) { return s.str ; } public void show ( ) { Console.WriteLine ( str ) ; } } The implicit and explicit modifiers determine the context a conversion will be done. The Conditional Attribute... Attributes are items of declarative information in our code. We have used the Conditional attribute here. This attribute marks a method as conditional. This means the function executes only if the preprocessing identifier is defined. #define x using System ; using System.Diagnostics ; class Class1 { static void Main ( string[ ] args ) { hello( ) ; } [ Conditional ( "x" ) ] public static void hello( ) { Console.WriteLine ( "hello world " ) ; } } If we comment out the #define directive, the function hello( ) would not get executed. File and FileInfo .Net offers two classes for file operations - the File class and the FileInfo class. The File class is derived from the Object class. It contains static methods and never gets instantiated. The FileInfo class is derived from FileSystemInfo class and has instance methods. This class can be instantiated. When we have to use a single file and perform many operations on it, we should use the FileInfo class. But if we want to perform a single operation on a file we must use the File class. This way we avoid the overhead of instantiating an object for just a single operation. But then when we have to marshal files we have to use the FileInfo class, because this class inherits from the MarshalByRefObject class used for marshalling data. A constructor initializer of the form base( ) causes a constructor from the direct base class to be invoked. A constructor initializer of the form this( ) causes a constructor from the class itself to be invoked. Consider the following program public class Class1 { static void Main ( string [ ] args ) { second s = new second ( ) ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


second s1 = new second ( 10 ) ; } } public class first { public first ( ) { Console.WriteLine ( "constructor of the base class" ) ; } public first ( int i ) { Console.WriteLine ( "one arg constructor of the base class" ) ; } } public class second: first { public second ( ) : this ( 10 ) { Console.WriteLine ( "constructor of the derived class" ) ; } public second ( int i ) : base ( 10 ) { Console.WriteLine ( "one arg of constructor of the derived class" ) ; } } The output would be : one arg constructor of the base class one arg constructor of the derived class constructor of derived class one arg constructor of the base class one arg constructor of the derived class When we call the zero argument constructor of class second, it first calls its own one argument constructor, this in turn first calls the zero argument constructor of class first. When we call the one argument constructor of class second, it first calls the one argument constructor of class first Application Domain... Application Domain means a security boundary between any two applications. This is used for isolation of applications. Before .Net every process had its own private virtual memory avoiding it to meddle with other processes memory. Now in .Net we have application domains. With managed IL code the runtime can assure that access to the memory of another application inside a single process can't happen. Multiple applications can run in a single process within multiple application domains. To execute an exe file in our program we have to write the following: AppDomain first = AppDomain.CreateDomain ( "test1.exe" , null , null ) ; first.ExecuteAssembly ( " test1.exe " ) ; Before running this second application we must make sure that we copy the .exe of the first application (test1.exe) in the 'bin / debug' folder of this application, so that the assembly is found. We cannot add a reference to it because references to only DLLs can be added and ours is an exe. The CreateDomain( ) methods creates a new application domain and the ExecuteAssembly( ) method executes the assembly given its file name. Shared and Private Assemblies...

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


There are two types of assemblies available: private assemblies and shared assemblies. A private assembly is used by only one application while a shared assembly is shared among different applications. By default when we compile a C# program, the assembly produced will be a private assembly. A private assembly is found either in the same directory as the application or within its subdirectories. With a private assembly it's not necessary to think about naming conflicts with other classes or versioning problems because each application has its own copy of the assembly. In shared assemblies we must be careful that the assembly must be unique, and therefore, have a unique name (called a strong name). Most of the shared assemblies are stored in a Global Assembly Cache. Delegates We normally pass data of any kind to a function. A situation may arise where we may want to pass a function to a function. This would seem a bit strange but this does happen. A method may need another method to do something. In such situation we may not even know which method to pass We may need to pass it at run time. But simply passing a function name to other function does not solve the problem because this approach causes problems with type safety. We cannot just pass methods directly because we need objects to access them. To tackle such situations Delegates have come into picture. Delegates are special types of objects used to wrap up details of methods we need to pass. Delegates are very similar to function pointers in C++. Delegate type is a class type derived from System.Delegate. Delegate types are implicitly sealed i.e. it is not permissible to derive from a delegate type. There are three steps in defining and using delegates: declaration, instantiation, and invocation. Consider the following example: public class Class1 { static void Main ( string [ ] args ) { myclass m = new myclass ( ) ; m.call ( ) ; } } class myclass { public delegate void myfunc ( ) ; void func1( ) { Console.WriteLine ( " In func1 " ) ; } void func2( ) { Console.WriteLine ( " In func2 " ) ; } public void call( ) { myfunc f = new myfunc ( func1 ) ; f(); f = new myfunc ( func2 ) ; f(); } }

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


In this program we have created a class called myclass. In Main( ) we created an object of this class through which we have called the call( ) function. In this call( ) function, we have created a delegate object called f and passed the name of the method to be used in it. So as the name suggests the delegate object is delegating the actual process of the method we call. Hence on writing f( ), func1( ) gets called. Next time we passed the name of the second function, func2( ). This time func2( ) is executed when we write f( ) Event An event is a member that enables the object to provide notifications. When such notifications are sent we need something to be done. This something is always done inside a method. Such methods that are called when an event is raised are known as event handlers. For example when a mouse is clicked the event sent is MouseClick and the event handler is OnCLick( ). The event model uses delegates to bind events to the methods used to handle them. The delegate allows other classes to register for event notification by specifying a handler method. When the event occurs, the delegate calls the bound method. Delegates can be bound to a single method or to multiple methods, referred to as multicasting. When creating a delegate for an event, we typically create a multicast event. A multicast delegate maintains an invocation list of the methods it is bound to. When an event is recorded by the application, the control raises the event by invoking the delegate for that event. The delegate in turn calls the bound method. In the most common case the delegate calls each bound method in the invocation list in turn, which provides a one-to-many notification. This strategy means that the control does not need to maintain a list of target objects for event notification - the delegate handles all registration and notification. Consider the following program: namespace handle { using System ; class Class1 { static void Main ( string[] args ) { keyboard k = new keyboard ( ) ; k.OnHit += new hit ( k.hit1 ) ; k.OnHit += new hit ( k.hit2 ) ; k.keyhit( ) ; k.OnHit -= new hit ( k.hit1 ) ; k.keyhit( ) ; } } public delegate void hit( ) ; public class keyboard { public event hit OnHit ; public void keyhit( ) { if ( OnHit != null ) { OnHit( ) ; }

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


} public void hit1( ) { Console.WriteLine ( "Key Hit1" ) ; } public void hit2( ) { Console.WriteLine ( "Key Hit2" ) ; } } } The output here is: Key Hit1 Key Hit2 Key Hit2 We have declared a class called keyboard. In this class we added an event called OnHit. Two simple functions hit1( ) and hit2( ) are also added. The keyhit( ) method raises the OnHit event. The notion of raising an event is precisely equivalent to invoking the delegate represented by the event. Outside the class, the OnHit member can only be used on the left hand side of the += and -= operators, as in k.OnHit += new hit ( k.hit1 ) which actually appends a delegate to the invocation list of the OnHit event and -= removes a delegate from the list. Hence as soon as we call k.keyhit( ) it raises the event and all functions are executed. Pointers (unsafe code) Pointers can be used in C# just as in C++ but only in blocks of code that we have specifically marked for pointer use. The keyword to do so is unsafe. 'unsafe' because there are potential risks associated with pointers such as memory leaks, overwriting of important information, stack overflow etc. Code using pointers is difficult to debug and will fail the memory type safety checks imposed by the Common Language Runtime (CLR). We can mark individual methods, classes, structs, blocks of code or even local variables as unsafe. For example we could write: unsafe float myfunction( ) { // can use pointers } unsafe class myclass { unsafe int *x ; } unsafe { // unsafe block } Declaring a pointer is different in C# than in C++, for example if we want to declare two integer pointers, we will write: int *x, y ; in C# as against

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


int *x, *y ; in C++. Once we've declared the pointers, we can use them as normal pointer variables using the 'address of' (&) and the 'value at' (*) operators. For the most part, C# relies on references for instances of classes, and the language has been designed in such a way that pointers are not required nearly as often as they are in C++. The .NET Data Providers There are two .NET data providers available, the SQL Server .NET Data Provider and the OLEDB .NET Data Provider. Depending on the design and data source for our application we can use any one of these two. The SQL Server .NET Data Provider uses its own protocol to communicate with the SQL Server. The OLEDB .NET Data Provider uses native OLEDB through COM interoperability to enable data access. To use the SQL Server .NET Data Provider, you must have access to Microsoft SQL Server 7.0 or later. SQL Server .NET Data Provider classes are located in the System.Data.SqlClient namespace. To use the OLEDB .NET Data Provider, you must use an OLE DB provider (we have used Microsoft Access). OLEDB .NET Data Provider classes are located in the System.Data.OleDb namespace. To use the OLEDB .NET Data Provider, you will have to include the System.Data.OleDb namespace in your applications. These .NET providers include the Connection object, the Command Object, the DataReader and the DataAdapter in their corresponding namespaces. For e.g. the Connection class in the SQL Server .NET Data Provider is written as SqlConnection and its equivalent in the OLEDB Service Provider is written as OleDbConnection. In the same way for all the four classes the corresponding names are prefaced with Sql or OleDb accordingly. Default Parameters In C#... Methods in C# cannot have default parameters. We cannot overload methods with default parameters. No such syntax exists in C#. myfunction ( int x = 0, int y = 10 ) { } If we want a function to initialize default values to the variables like default parameter mechanism, we'll have to simulate it. There is not specific syntax. We have to do it manually and initialize the variables in the beginning of the function definition as shown below. myfunction ( int x, int y ) { x=0; y = 10; } Using OLE DB .NET Data Provider in ADO.NET... using System; using System.Data; using System.Data.OleDb; class myclass {

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


static void Main ( string[ ] args ) { string str = "Provider = Microsoft.Jet.OLEDB.4.0 ; Data Source = c:\\bank.mdb" ; string cmd = "SELECT accno, name, balance from account" ; OleDbConnection con = new OleDbConnection ( str ) ; OleDbCommand com = new OleDbCommand ( cmd, con ) ; con.Open( ); OleDbDataReader r = com.ExecuteReader ( ) ; while ( r.Read ( ) ) Console.WriteLine ( r[0] + " " + r[1] + " " + r[2] ) ; con.Close ( ) ; } }

To make a connection, we pass the connection string to the OleDbConnection constructor. To the OleDbCommand constructor we pass the connection as well as the command string. The Open( ) method opens a database connection with the property settings specified by the connection string. The OleDbDataReader class reads a stream of rows from database. To create an OleDbDataReader class we have to call the ExecuteReader( ) method belonging to the OleDbCommand class. This method will execute the command and return an OleDbDataReader object. The Read( ) method iterates through the records advancing the OleDbDataReader by one record every time. we have used the ordinal indexer to access individual values of a row referenced by the OleDbDataReader. Using SQL Server .NET Data Provider... using System; using System.Data; using System.Data.SqlClient; class myclass { static void Main ( string[ ] args ) { string str = "server = kicit ; uid = icit ; pwd = ypk ; Database = bank" ; string cmd = "SELECT accno, name, balance from account" ; SqlConnection con = new SqlConnection ( str ) ; SqlCommand com = new SqlCommand ( cmd, con ) ; con.Open( ) ; SqlDataReader r = com.ExecuteReader ( ) ; while ( r.Read ( ) ) Console.WriteLine ( r[0] + " " + r[1] + " " + r[2] ) ; con.Close ( ) ; } } First we need to get connected to the database. To do so, we have to write a connection string. The connection string includes database name, server, database provider, user name, password. This connection string is stored in str. The command string is stored in cmd. cmd contains the query to be executed. To make a connection, we pass the connection string to the SqlConnection constructor. To the SqlCommand constructor we pass the connection as well as the command string. The Open( ) method opens a database connection with the property settings

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


specified by the connection string. The SqlDataReader class reads a stream of rows from an SQL Server database. To create an SqlDataReader class we have to call the ExecuteReader( ) method belonging to the SqlCommand class. This method will execute the command and return an SqlDataReader object. The Read( ) method iterates through the records advancing the SqlDataReader by one record every time. Here we have used the ordinal indexer to access individual values of a row referenced by the SqlDataReader. The ILDASM Tool... The ILDASM or the MSIL disassembler tool is used to view assemblies. We can run this tool by starting ildasm from the command line, with the assembly as argument or by selecting the 'File | Open' menu. The following figure shows an ildasm window with assemblies opened in it.

The tool shows the Manifest, Namespace, Class and Method in the assembly. It can also show Interfaces, Value types, Static methods, Fields, Static Fields, Events and Properties. Structure of an Assembly An assembly is made up of metadata , IL (Intermediate Language) code and resources. The Metadata consists of type metadata and an assembly metadata. Assembly Metadata which is referred to as the Manifest describes assembly. It contains following information. a. An identity, name, version and culture of an assembly. An assembly has a four part version number e.g. 1.0.1.1. which stands for <Major> . <Minor> . <Build> . <Revision> The use of these numbers is dependent on the configuration of our application. A good policy is to change the major or minor numbers if the version is incompatible with the previous versions. The build number is the number of days since Jan-1, 2000, and revision is the number of seconds since midnight local time. b. Names of all files in an assembly. c. Details of all types defined in an assembly.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


d. Whether the types defined in an assembly are visible to other assemblies or not. e. A hash of all files in an assembly. f. Names and hashes of other assemblies that an assembly may need as reference while execution g. Details of any security permissions that clients need to have in order to be able to run the assembly The type metadata consists of metadata that describes the exported types and methods. How do I change the underlying data type for an enum? Ans: The following program demonstrates how we can change the underlying data type (which is int by default) for an enum. We have provided an initial value to one of the members of the enum. using System ; namespace sample { enum color : byte { red, blue = 8, green } class Class1 { static void Main ( string[ ] args ) { Console.WriteLine ( color.green ) ; } } } The output of the program would be green. But here we have to be careful that we should not use a value, which is out of range. For example assigning a value like 500 to red in this program will result in error since we have declared that the enum is of type byte. Using, Console.WriteLine ( ( byte ) color.green ) instead of Console.WriteLine ( color.green ) in Main( ) would give the output as 9. This is because, all members towards the right of blue will be initialized to a value equivalent to blue's value plus the number of places it is far from blue. The value green is one place right from blue, its value will be 8 + 1 i.e. 9. This is not true for members on the left hand side. So in this case red will be initialized to 0 by the compiler. However we can initialize all the members with different values. How do I change the underlying data type for an enum? Ans: The following program demonstrates how we can change the underlying data type (which is int by default) for an enum. We have provided an initial value to one of the members of the enum. using System ; namespace sample { enum color : byte { red, blue = 8, green

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


} class Class1 { static void Main ( string[ ] args ) { Console.WriteLine ( color.green ) ; } } } The output of the program would be green. But here we have to be careful that we should not use a value, which is out of range. For example assigning a value like 500 to red in this program will result in error since we have declared that the enum is of type byte. Using, Console.WriteLine ( ( byte ) color.green ) instead of Console.WriteLine ( color.green ) in Main( ) would give the output as 9. This is because, all members towards the right of blue will be initialized to a value equivalent to blue's value plus the number of places it is far from blue. The value green is one place right from blue, its value will be 8 + 1 i.e. 9. This is not true for members on the left hand side. So in this case red will be initialized to 0 by the compiler. However we can initialize all the members with different values. An enum cannot have a circular definition. For example, enum color { red = yellow, blue, green, yellow, brown } The compiler will first try to give red yellow's value. But yellow's value depends on red's value. Hence yellow has no value yet and will be assigned a value later. This is circular dependency and is not allowed in enumerations. When we perform an assignment operation on two reference variables, the reference to the first object gets copied into the other reference variable. But this is not the case with strings. In spite of being a reference type an assignment operation on two string variables results in creation of a new object. The value of the right-hand side string object gets copied into the new object and the reference to this new object gets assigned to the reference variable on the left-hand side of the assignment operator. This is shown in the following code snippet. string s1 = "Good Morning" ; string s2 ; s2 = s1 ; s1 = "Wake Up" ; Console.WriteLine ( s1 ) ; Console.WriteLine ( s2 ) ; The output of the program would be, Wake up Good Morning Here we have created two string references s1 and s2. We have initialized s1 with a reference to an object containing Good Morning and kept s2 uninitialized. Then we have assigned s1 to s2. Normally both being references only the reference of s2 should have been assigned to s1.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


But this does not happen. Instead a new object gets created that holds the same value contained in the object referred by s1. Properties... In C#, we can manipulate data stored in a data member using a feature called Properties. The methods that we write as properties are known as accessors. There can be two accessors, a get accessor and a set accessor. The get accessor is invoked when we want to retrieve the value of the property, whereas the set accessor is invoked when we assign a value to the property If only get accessor is present the property is called a read-only property. If only set accessor is present then the property is called a write-only property. If both accessors are present, the property is said to be a read-write property. The following program demonstrates how we can create and access properties. using System ; namespace properties { public class sample { int width ; public int Width { get { return width ; } set { width = value ; } } } class Class1 { static void Main ( string[ ] args ) { sample m = new sample( ) ; m.Width = 10 ; int w = m.Width ; Console.WriteLine ( "Width: " + w ) ; } } } Here, the class sample, contains both the get and set properties for the data member width. In Main( ), the statement m.Width = 10 ; would invoke the set property whereas the statement int w = m.Width ; would invoke the get property. Properties Vs Data members... The advantage of using properties as against public data member is that, if we want we can perform some functionality in the accessor body. For example if we wish to initialize a lenght property, we can first check range for the length variable in the set accessor as shown in the following code snippet.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


set { if ( value > 10 ) length = value ; } As against this if length was just a data member, it would not have been possible for us to check range or perform any such functionality on it. Static Properties... The static modifier can be used to create properties that belong to a class and not to an individual object. We can write static properties for static data members only. To access these properties we have to use the class name instead of an object. For example, using System ; namespace sample { public class window { static int height ; public static int Height { get { return height ; } set { height = value ; } } } class Class1 { static void Main ( string[ ] args ) { window.Height = 10 ; Console.WriteLine ( "Window height: " + window.Height ) ; } } } Properties And Inheritance If we derive a class from a base class, which has a public property declared in it, the object of the derived class can also access the property of the base class. If the property of the base class is declared as virtual the derived class can override the base class property with its own version of the property. Abstract Properties... Properties in C# can also be declared as abstract. If we declare the property as abstract it is necessary to declare the class containing the property, as abstract. Since we cannot create the objects of the abstract class it becomes necessary to derive a class from it and implement the property.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Indexers... An Indexer is a special type of property. If a class contains an array as a data member, then, an indexer lets us access the array within the class, using an object, as though the object itself were an array. This is done using the [ ] operator. For example, consider a class myclass which has an int array as a data member and we create an object a of that class. Here we can access the elements of the array by using the expressions a[0], a[1], a[2] and so on. The following code snippet shows how to declare an indexer: public int this [ int index ] { get { // code } set { // code } } Exception Handling In C#... C# uses a more systematic approach to tackle exceptions. The .NET CLR checks for the runtime errors and raises exceptions to inform the program that an error has occurred. It also handles these exceptions if the program has not handled it. In C# the exceptions are in the form of objects of exception classes. All exception classes are derived from the System.Exception class. An exception object cannot be "thrown" or "caught" unless their classes are inherited from the System.Exception class. When we say an exception is thrown, it means that the CLR creates an object of the class on heap and passes its reference to the program. There are several standard exceptions provided by the .NET framework. We can also create user-defined exceptions. The exception thrown by the code written in one .NET compliant language can be caught in another .NET compliant language LinearGradientBrush... The LinearGradientBrush is used for gradient filling. To the constructor of a LinearGradientBrush we pass two Point objects and two Color objects. Point is a structure representing x and y coordinates. The two Point objects specify the starting and ending point of the gradient fill, while the Color objects represent the starting and ending colors of the gradient fill. An important point to note is that the y coordinates of both the points must be same for the gradient fill to be filled horizontally. If the y coordinate of the second point passed to the constructor of the LinearGradientBrush class does not match with the y coordinate of the first point, the gradient fill does not remain horizontal. Line Caps Line caps specify shape of the end points of the lines. We can set the line caps using the SetLineCap( ) method. This method accepts 3 parameters. The first two parameters specify LineCap enumeration representing the cap style at the beginning and end of a line. The last parameter specifies the DashCap enumeration that is used to specify the beginning and end of a dash line. Multiple Methods In A Delegate... A delegate can wrap even more than one method. For this, it maintains a linked list. The delegate then points to the head of such a linked list. This means that when such a delegate is invoked, it

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


calls all the methods that form the linked list. All delegate classes are derived from System.MulticastDelegate class. Hence, instead of the statements c1 = new click ( MyForm1_click ) ; mouseclick( ) ; c1 = new click ( button_click ) ; mouseclick( ) ; we can simply write c1 += new click ( MyForm1_click ) ; c1 += new click ( button_click ) ; mouseclick( ) ; The delegate c1 inside the mouseclick( ) method would now call both the methods. Here we are simply adding both the methods in a list and hence both would be called. Rest of the program remains same. Capacity... By default, the capacity of the ArrayList is to hold 16 elements. If the number of elements exceeds 16 then the capacity of the array list automatically gets doubled by allocating new area of memory. If we want, we can increase or decrease the capacity of the array list using the Capacity property of ArrayList class. The Capacity property indicates the number of elements the ArrayList object is capable of holding. If we increase the capacity by saying arr.Capacity = 32 the array list arr would automatically get reallocated. The BitArray Class... The BitArray class represents an array of bool values. Each element of the BitArray contains either true or false. The BitArray class contains several overloaded constructors, except the zero-argument constructor. Following statements show how an object of the BitArray can be instantiated. int[ ] a = { 1, 2, 3 } ; BitArray b1 = new BitArray ( a ) ; BitArray b2 = new BitArray ( 5 ) ; BitArray b3 = new BitArray ( 5, true ) ; If we pass reference to another array as an argument to the BitArray constructor, the bit values of every element of that array get copied as the elements of the BitArray. For example, the bit values (1 or 0) of the element 1 would become first 32 elements (1 being a 32-bit number) in the array b1. Either true or false would get stored in b1 depending upon whether the bit is 1 or 0. The array b2 would get created with 5 elements and by default all the elements would be set to false. The array b3 would contain 5 elements where all the elements would be set to the bool value true. The lock keyword... C# provides us with a lock keyword to lock the shared object or resource. Whatever is written inside the parenthesis following the lock keyword gets locked for the current thread and no other thread is permitted to access that resource or object. This marks all the statements that follow the

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


lock keyword enclosed in a pair of braces as critical section. For example, if we wish to lock an array arr we would write, lock ( arr ) { //code } HTML controls... HTML controls are created from classes present in System.Web.UI.HtmlControls namespace. All HTML control classes derive, either directly or indirectly, from System.Web.UI.HtmlControls.HtmlControl. HTML control classes are instantiated by adding runat = "server" to ordinary HTML tags. For example, the following statement declares a standard HTML text input field. <input type="text"> But the following statement declares an instance of HtmlInputText. <input type="text" runat="server"/> Web Controls... Web Controls are server controls. By server controls we mean those controls, which execute on the server and not on the client. In ASP, controls were mere HTML tags. Whenever the browser used to find these HTML tags, the controls used to get displayed. However, in ASP.NET the controls do not get added as HTML tags. Instead, they are objects within the page. Hence we can change properties and add events for these controls just like we would do for controls used in WinForms. This is quite a big advantage over ASP. All the Web Controls are derived from the WebControl class present in the System.Web.UI.Control namespace. The code that gets added for Web Controls in the '.aspx' file is based on XML. Validation controls... Whenever we enter something on a Web Form form and submit it to the server it is called a postback. Validation controls provide a method of validating user input without writing any code. Whenever postback is initiated each control checks the control it is validating and changes its IsValid property accordingly. If the property is set to false it means that the user input is wrong. In such a case an error message is flashed. If the property is set to true the postback occurs. #warning And #error Directives... Instead of the compiler, if we want to flash a warning or raise an error at compile time we can use the #warning and #error directives. For example, if we write #warning Following code may give unpredictable results. a warning is flashed when the complier encounters a statement like this. It displays whatever text appears after the #warning directive. In this case it will be "Following code may give unpredictable result." On encountering a #warning the compilation does not stop. The #error directive is used to raise an error. #error x is not accessible.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


When the compiler encounters such a statement, it raises an error. The error raised in this case will be 'x is not accessible'. On encountering #error the compilation process will be stopped. These directives are used by programmers to remind themselves of tasks they might forget to do. For example, they can arrange to get reminded by giving warnings such as "This function is incomplete, you intended to write more code to make it fool proof". Programmers can frame some rules for themselves and raise warning, errors accordingly. The #region And #endregion Directives... The #region and #endregion directives are used to mark blocks of code. For example, #region // code #endregion These directives don't affect the compilation process. They are used for ease of maintaining the code in the editor. The editor in which we type our code is provided with a feature where on the left hand side of the window we see minus or plus signs. These signs denote the marking of blocks of code. We can click on the plus signs to expand the code and on the minus signs to collapse it back, just as we would close a node in a tree control. The #region and #endregion directives allow us to mark blocks of code in the same way and the block can be expanded and collapsed. These directives can also work across functions The #line directive... The #line directive can be used to alter the file name and line number information which is output by the compiler in warnings and error messages. Consider the following program: 1. #define x 2. using System ; 3. namespace sample 4. { 5. class Class1 6. { 7. static void Main ( string[ ] args ) 8. { 9. #line 100 "xyz.sc" 10. #if x 11. #warning false warning 12. #endif 13. } 14. } 15. } The line after the #line directive gets the specified line number. Hence in this program the line number of the #if directive would change to 100 from line number 10. The program flashes a warning "false warning" at line 101 instead of at line number 11 and the file name is changed to 'xyz.sc'. Complex programs having bulky code are written by many programmers and not just one. This directive is used by them to have their own line numbers, which helps them to identify errors or warnings in their code and in their files. Value Parameter

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


A parameter declared with no modifier (such as ref, out, params) is a value parameter. For example in the following function, void fun ( int x ) { } x is a value parameter. If we make a call to the function by saying: int i = 9 ; fun ( i ) ; the value of i gets copied in x. Here x is a totally different variable than i. Hence changing x would not affect i. This is similar to a call by value in C. enums... There are a few important points to note regarding enums which are given below: a. We can give same values to two enum members. b. An enum cannot have a circular definition. For example, enum color { red = yellow, blue, green, yellow, brown } Here, the compiler will first try to give red yellow's value. But yellow's value depends on red's value. Hence yellow has no value yet and will be assigned a value later. This is circular dependency and is not allowed. c. The value of enum members cannot be changed. d. An enum cannot have two members with the same name. e. We cannot inherit from enums. Jagged Array... A jagged array is an array of 1D arrays each of different length. We cannot create the jagged array in the same way as we create the rectangular array. The correct way to initialize the jagged array is as follows: int[ ] [ ] arr1 = new int [ 2 ] [ ] ; arr1 [ 0 ] = new int [ 3 ] { 3 , 5, 7, 1 } ; arr1 [ 1 ] = new int [ 2 ] { 11, 13 } ; The way to create a 3D jagged array is as follows: int[ ] [ ] [ ] arr = new int [ 2 ] [ ] [ ] ; arr [ 0 ] = new int [ 3 ] [ ] ; arr [ 0 ] [ 0 ] = new int [ 3 ] ; arr [ 0 ] [ 1 ] = new int [ 4 ] ; arr [ 0 ] [ 2 ] = new int [ 5] ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Here the 3D array consists of two 2D arrays. The first 2D array would consist of three 1D arrays, and finally all the three 1D arrays have different number of elements. TopMost property is used if we want that a WinForm should be displayed as the top-most form in an application. The TopMost property if set to true, displays the WinForm as the top-most form. The following code snippet demonstrates this. using System ; using System.Drawing ; using System.ComponentModel ; using System.WinForms ; using System.Data ; public class Form1 : System.WinForms.Form { public static void Main(string[ ] args) { Form1 F1 = new Form1( ) ; F1.TopMost = true ; Application.Run ( F1 ) ; } } The Keyword params... C# provides a keyword called params, which is used when we want to write a function that accepts variable number of arguments. For using the params keyword the argument must be declared as a single dimensional array. Once an argument is prefixed with the params keyword C# will accept any number of values (even none) for that argument. For example, public class sample { public int add ( params int[ ] no ) { int val = 0 ; foreach ( int n in no ) { val += n ; } return val ; } public static int Main ( string[ ] args ) { sample s = new sample( ) ; Console.WriteLine ( s.add( ) ) ; Console.WriteLine ( s.add ( 4, 3 ) ) ; Console.WriteLine ( s.add ( 5, 2, 3, 10 ) ) ; return 0 ; } }

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


As C# does not allow global methods or variables ,some times we may end up with a class containing only static members. When a class contains only static members there is no meaning in creating an instance of that class. We can prevent users from creating an instance of a class by introducing a private constructor within the class as shown below: public class Color { static int x = 100 ; static int y = 55 ; static int z = 43 ; private fun( ) { } } What is the significance of ref keyword? Ans: When we pass an array to a method, we pass its reference. What if we pass this reference using the ref keyword? Consider the following program. static void Main (string[] args) { int[ ] a = { 1, 2, 3, 4, 5 } ; change ( ref a ) ; foreach ( int i in a ) Console.WriteLine ( i ) ; } static void change ( ref int[ ] b ) { int[ ] arr = { 10, 11, 12, 13, 14 } ; b = arr ; } If you run the program output will be 10 11 12 13 14. Now remove the ref keyword and run the program again. You will get the output as 1 2 3 4 5. Thus, when we pass a reference using the ref keyword, we can modify the contents of the reference in the called method so that it would start pointing to a new memory location. Implementing ambiguous interface methods... Suppose, two interfaces have declared a method having same signature. If a class implements both the interfaces then it would create an ambiguous situation. To avoid this ambiguity, we must use explicit implementation of method as shown below. interface i1 { void f2( ) ; } interface i2 { void f2( ) ;

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


} class sample : i1, i2 { public void f2( ) { Console.WriteLine ( "i1.f2" ) ; } void i2.f2( ) { Console.WriteLine ( "i2.f2" ) ; } } Here, the method f2( ) is declared in i1 as well as in i2. We must implement at least one of them explicitly. To implement the method explicitly we have to use fully qualified name of the method. An important thing about explicitly implemented methods is that they are accessible only through the reference to the interface. We cannot access them using the reference to the implementing class like normal methods. The JIT Compiler The JIT (Just In Time) compiler is a crucial component of .NET framework. The program created in C# gets compiled into an IL (Intermediate Language) code. The JIT compiler converts this IL code into machine code, which is then executed. The JIT compiler does not compile entire code at once because it could hamper the performance of the program. It compiles the code at runtime, at the time the code is called. The code that is compiled gets stored until the execution comes to an end. This avoids recompilation of code. The reason why conversion from IL code to machine code takes place at runtime is that, the JIT first gets information of the processor type and convert the IL code so that it would run on that type of processor. Suppose we create two strings having exactly same literal as shown below: string s1 = hi there! ; string s2 = hi there! ; When the application is loaded in memory, CLR creates an empty hash table to store the strings used in the source code. The JIT compiler searches all the strings and fills the hash table with keys and values. In the hash table, the text is the key and reference is the value. So, when JIT comes across the first declaration i.e string s1 = hi there!, the text hi there! gets stored as a key and its reference as value. Later, it encounters s2 that has the same value. It does nothing since duplicate keys cannot exist in hash table. Whenever we use s1 or s2 in program, it will return the same reference from hash table. This mechanism avoids duplication of strings. If we use the == operator on reference types it compares two references and not the contents. But in case of strings, it works differently. If used on strings, == operator compares values not the references. If we want to compare the string references, we must cast the string references to object type. For example, string s1 = "hi" ; char[ ] ch = { 'h', 'i' } ; string s2 = new string ( ch ) ; if ( s1 == s2 )

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Console.WriteLine ( "Equality of value" ) ; if ( ( object ) s1 == ( object ) s2 ) Console.WriteLine ( "Equality of reference" ) ; How can I determine the type of an object at runtime? Ans: We can use the keyword is to know the type of an object at runtime. This is shown in following program. using System ; class myApp { public static void Main() { string str = "Hello!" ; int i = 25 ; Console.WriteLine ( "{0} is {1} an integer ", s, ( IsInteger ( s ) ? "" : "not " ) ) ; Console.WriteLine ( "{0} is {1} an integer", i, ( IsInteger ( i ) ? "" : "not " ) ) ; } static bool IsInteger ( object obj ) { if ( obj is int || obj is long ) return true ; else return false ; } } The output of this program would be as given below: Hello is not an integer 25 is an integer Abstract Classes vs. Interfaces The main difference between an abstract class and an interface lies in their application i.e in the way they are used. The abstract classes always act as a base class of the related classes in the class hierarchy. For example, consider a hierarchycar and truck classes derived from four_wheeler class. The classes two_wheeler and four_wheeler derived from an abstract class vehicle. So, the abstract class vehicle is the base class in the class hierarchy. On the other hand one interface can be implemented by dissimilar classes. For example, there is an interface that compares two objects. This interface can be implemented by the classes like box, person and string, which are unrelated to each other The Anchor property We can anchor a control to one or more edges of its container. Anchoring a control ensures that even if size of the container changes, the anchored edges of control remain on the same position relative to the edges of the container. We can specify which edges we want to anchor using the

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Anchor property of the Form class. If the Anchor property of a control is set to None, then the distance between the edges of control and that of the container change if the container is resized. So, the control appears moving as the container is resized. Making Type Conversion Perfect C# is a strictly typed language. It allows widening conversion like int to float, char to int, etc. but not the narrowing conversion. For narrowing conversion we need to typecast the values. For example, int i ; float f ; f = 5.8f ; i = ( int ) f ; If we run this code in C#, we get the output 5 in i. But if we write this type of code in VB.NET i would contain 6 not 5 because in VB.NET the value gets rounded off. Thus, we get different output of the same code which may cause bugs if our code is ported to another language. To avoid this we must take help of the Convert class. Convert class provides methods to convert one type into another. This conversion is neutral across the languages. It means that the conversion result would be same irrespective of the language. String comparison done using == is case-sensitive, How do I do a case-insensitive string comparison? Ans: Use the String.Compare function. Its third parameter is a boolean which specifies whether case should be ignored or not. For example, "kicit" == "KIcIt" // returns false System.String.Compare( "kicit", "KIcIt", true ) // returns true Finalization Internals We can write the Finalize( ) method that gets called when an object is collected by Garbage Collector. However, finalizable objects cause increase in overhead on the part of CLR and takes longer time to clean up than non-finalizable objets. This is because of the following reason. For every finalizable object an entry is made in a separate 'finalization queue'. The entry is a reference referring to the object on the managed heap. When GC gets invoked, it checks whether the unreferenced object has an entry in the finalization queue. If it has, then the reference is removed from the finalization queue and is appended to yet another queue. When such an entry is made in the queue a dedicated thread gets invoked. This thread removes the reference from the queue and calls the Finalize( ) method of the object referred to by this reference. While this process is going on the object continues to exist on the managed heap as a referenced object. Next time when GC is invoked, it again checks whether an object has entry in the finalization queue. This time it doesn't find the entry. So, the object gets collected. Thus for a finalizable object GC needs to be invoked twice. Visual Inheritance Visual inheritance is a technique provided by Visual Studio.NET that allows us to reuse an existing form. That is, we can inherit an existing form to create a new derived form. Visual inheritance is useful when an extensive user interface with number of controls stands ready. Visual inheritance avoids repetition of creating the user interface. The form that we can inherit is

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


exported from a class library (.dll). One class library can export any number of forms. To create the base form, we must create a normal WindowsApplication and build it as a ClassLibrary by selecting the 'Output Type' as ClassLibrary. Once the form is ready we can derive another form in a new application by selecting the 'Add Inherited Form' option. Why operator overloaded methods are static in C#? Ans: C# provides overloaded operator methods as static methods. And so, the this reference is not passed to these methods. Since this reference is not available we have to pass two parameters to the overloaded binary operator methods. C++ programmers may find the syntax of overloaded operator methods a bit confusing. But this syntax ensures that we are never required to write friend functions. We were required to use a friend function in C++ to overload the binary operator when two operands were of different types. For example, If we want to write the following statement in C++, c2 = 10 + c1 ; we would have to define the + operator function as a friend function. Because this statement would get expanded as 10.operator+ (c1). But if we write the same statement in C#, it would get expanded as operator+ ( 10, c1 ). We can easily define an overloaded method that takes an int and an object. We don't need to define a friend function for this. Why in C#, uninitialised variables do not contain garbage value? Ans: In C or C++ initial value of variable is garbage value. This is not so in C#. The reason is that all value types implicitly declare a public zero-argument constructor called the default constructor. The default constructor initialises the instance with the value according to the value type. For example, an int is initialized with 0, bool with false, char with '\0', etc. Like any other constructor, the default constructor of a value type is invoked using the new operator. Because every value type implicitly has a public parameter less constructor, it is not possible for a struct type to contain an explicit declaration of a parameter less constructor. However, a struct type is permitted to declare parameterized constructors. There is a provision made by the .NET Framework that relieves the programmer from managing threads. This provision is called Thread Pooling. The concept behind thread pooling is that a thread manager manages a pool of threads called worker threads. The idea is that we just need to pass requests to launch threads to the thread pool manager instead of launching the threads ourselves. Many applications use multiple threads, but often those threads spend a great deal of time in the sleeping state waiting for an event to occur. When a wait operation completes, a worker thread from the thread pool executes the corresponding callback function. Why value types are sealed? Ans: The value types are implicitly made sealed to avoid complexities related to object slicing. This comes about because value types are stored inline when they are members of other types, and are also stored inline in arrays. Therefore, if we were to store a derived value type in a location where the base value type was expected, any extra fields included in the derived type would need to be sliced off. This can cause hard-to-diagnose bugs when the derived value type is retrieved. What is the C# equivalent of QueryInterface? Ans: Use keyword as as shown in following example.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


using System ; interface IPerson { string GetName( ) ; } interface IPerson2 : IPerson { int GetAge( ) ; } class CPerson : IPerson { public CPerson ( string name ) { m_name = name ; } // IPerson public string GetName( ) { return m_name ; } private string m_name ; } class CPerson2 : IPerson2 { public CPerson2 ( string name, int age ) { m_name = name ; m_age = age ; } // IPerson2 public string GetName( ) { return m_name ; } public int GetAge( ) { return m_age ; } private string m_name ; private int m_age ; } public class CApp { public static void Main( ) { CPerson rahul = new CPerson ( "Rahul" ) ; CPerson2 vidya = new CPerson2 ( "Vidya", 24 ) ; DisplayAge ( rahul ) ; DisplayAge ( vidya ) ; } static void DisplayAge( IPerson person ) { IPerson2 person2 = person as IPerson2 ; // QueryInterface lives on !!! if ( person2 != null )

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Console.WriteLine ( "{0} is {1} years old.", person2.GetName( ), person2.GetAge( ) ) ; else Console.WriteLine ( "Sorry, don't know {0}'s age.", person.GetName( ) ) ; } } On execution of this program it produces following output: Sorry, don't know Rahul's age. Vidya is 24 years old. How do I create non-rectangular form? Ans: If you see WindowsXP media player you would appreciate its Graphical User Interface. It displays the main window and controls in non-rectangular shapes carrying attractive bitmaps on them. Creating such GUI with previous versions of Windows was complicated. .NET has made it very easy. Here are the steps to create non-rectangular form. 1. Create a bitmap in 'Paint' application and paint its background with blue color (you can select any color). Save the file. 2. Create a Windows Application. 3. In 'Design' view open the 'Properties' window. Select the '.bmp' file we just created for BackgroundImage property of the form. 4. Set the FormBorderStyle property to None. This would hide the title bar of the form. 5. Set the TransparencyKey property to the background color of the '.bmp' file. In this case we would set it to blue. Run the application. Our form would get displayed in the shape and design as created in the '.bmp' file How do I shift the origin to the center of the client area and draw a line of 1 inch? Ans: Here is the code: private void Form1_Paint ( object sender, PaintEventArgs e ) { Graphics g = e.Graphics ; g.PageUnit = GraphicsUnit.Inch ; g.TranslateTransform ( ( ClientRectangle.Width / g.DpiX ) / 2, ( ClientRectangle.Height / g.DpiY ) / 2 ) ; Pen p = new Pen ( Color.Green, 1 / g.DpiX ) ; g.DrawLine ( p, 0, 0, 1, 0 ) ; } The PageUnit property sets the unit to an inch. We have called the TranslateTransform( ) method to shift the origin to the center of the client area. This method maps the world coordinates to page coordinates. Finally, we have created a pen having proper width and drawn the line. Since we have set the page unit to an inch, we must specify coordinates of line in inches. How do I invoke a method using reflection? Ans: The following example loads a user-created assembly, obtains a class type, creates its instance and invokes a method defined in the assembly.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


Assembly a = Assembly.LoadFrom ( "c:\\mymath.dll" ) ; Type t = a.GetType ( "mymath" ) ; MethodInfo m = t.GetMethod ( "add" ) ; Object obj = Activator.CreateInstance ( t ) ; Object[ ] arg = new Object [ 2 ] ; arg [ 0 ] = 10 ; arg [ 1 ] = 20 ; m.Invoke ( obj, arg ) ; This code snippet would invoke the add( ) method written in mymath class. The mymath class is in the 'mymath.dll' assembly.

How do I read non-public members from metadata? Ans: We use reflection technology to read metadata. We have various methods at hand like GetMethods( ), GetConstructors( ), GetFields( ), GetProperties( ), etc. that can be used to read the respective members from metadata. If we call these methods without passing any parameters, they return only public members, not the non-public members. To read the nonpublic members we must pass certain flags to them. The following statement shows how to pass the flags to read all the methods. mytype.GetMethods ( BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic ) ; These flags indicate that we intend to read the instance methods, methods that are not inherited from base type and methods that are public as well as non-public. The main design goal of C# was simplicity rather than pure power. We do give up a little processing power, but you get cool stuff like type safety and automatic garbage collection in return. C# can make our code stable and productive overall. C# offers several key benefits for programmers: Simplicity Consistency Modernity Object-orientation Type-safety Scalability Version support Compatibility Flexibility

Let's see what version support does C# provides: In C++, if a derived class contains a non-virtual function with a name abc( ) and the new version of a base class is shipped with a virtual function having the same name abc( ). This would result in an unpredictable result since the derived class version of abc( ) would get called now, which was not expected. Previously, there was nothing a programming language can do to retain the binary compatibility of new version of base class with existing derived class. This is not the case in C#. In C#, a function in derived class doesn't automatically become virtual if there is a virtual function with the same

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


name in the base class. To make the derived class function fall in the virtual chain we need to mark it with the override keyword. We can create two types of user-defined controls - Custom Controls and User or Composite Controls. Custom controls display user interface by making calls to a Graphics object. Custom controls are typically derived from the Control class. The Control class implements the very basic functionality required by classes that display information to the user. It handles user inputs through the keyboard. It handles message routing and security. There is limited design-time support for creating custom controls. User or Composite controls are composed of other existing controls and hence we need not specify the user interface for User controls. User controls are derived from the UserControl class. The UserControl class is also derived from the Control class There is full design-time support for creating user controls with the Visual Studio .NET Windows Forms Designer. The PrintDocument component... .NET supports printing through methods and properties of the PrintDocument component. The PrintDocument component is available in the toolbox and when added to a form, it appears in the component tray at the bottom of the Windows' Forms Designer. This is because the PrintDocument component is not visible at runtime. The PrintDocument class represents the PrintDocument component and falls under the System.Drawing.Printing namespace. Typically in a printing application we call the Print( ) method of the PrintDocument class. It also contains properties such as DefaultPageSettings, which gets or sets page settings that are used as defaults for all pages to be printed, PrinterSettings, which gets or sets the printer that prints the document. The class contains events like BeginPrint, EndPrint and PageEvent. BeginPrint is raised when the Print( ) method is called and before the first page of the document is printed. Here we can do any initializations if needed. EndPrint event is raised when the last page of the document has been printed. We can do cleaning up jobs here. The PrintPage event is raised when it's time to print the current page. We can write code in the handler of this event to do the desired printing. Hence the order of events raised when Print( ) method is called is BeginPrint, PrintPage and then EndPrint. The main design goal of C# was simplicity rather than pure power. We do give up a little processing power, but you get cool stuff like type safety and automatic garbage collection in return. C# can make our code stable and productive overall. C# offers several key benefits for programmers: Simplicity Consistency Modernity Object-orientation Type-safety Scalability Version support Compatibility Flexibility

Let's see what version support does C# provides: In C++, if a derived class contains a non-virtual function with a name abc( ) and the new version of a base class is shipped with a virtual function having the same name abc( ). This would result in an unpredictable result since the derived class version of abc( ) would get called now, which

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


was not expected. Previously, there was nothing a programming language can do to retain the binary compatibility of new version of base class with existing derived class. This is not the case in C#. In C#, a function in derived class doesn't automatically become virtual if there is a virtual function with the same name in the base class. To make the derived class function fall in the virtual chain we need to mark it with the override keyword.

Thread States... Ans: At times we may want to prevent our thread from getting CPU cycles till: 1. Passage of some time. 2. Some other thread completes some operation. 3. Some other thread terminates. We can achieve the above three scenarios by respectively calling the methods Thread.Sleep( ), Monitor.Wait( ) and Thread.Join( ) methods on our thread. Upon calling one of these three methods, our thread enters the WaitSleepJoin state. Once in this state we can transition out of it in the following three ways: 1. The sleeping time specified by the Sleep( ) method expires. 2. Another thread calls the Thread.Interrupt( ) method before the sleeping time expires. 3. Another thread calls the Monitor.Pulse( ) method or Monitor.PulseAll( ) method. Monitor.Pulse( ) moves the waiting thread into the Running state. Monitor.PulseAll( ) method moves the thread along with all the other waiting threads into the Running state. All the above three ways move the thread from the WaitSleepJoin state to the Running state. When a thread completes its execution, it goes into the Stopped state. The StopRequested state is reached when a thread is being requested to stop. There is no method available that we can invoke to manually force our thread in this state. Whenever an exception is thrown and the thread stops executing abruptly it goes into the Aborted state.
Printing With Different Units... In the Graphics methods we specify coordinates in two-dimensional coordinate system. The system has origin at left-top corner and x and y axes point to right and down respectively. All the methods take coordinates in pixels. The coordinates passed to Graphics methods are world coordinates. When we pass world coordinates to a method, they firstly get translated into page coordinates (logical coordinates) and then into device coordinates (physical coordinates). Ultimately, the shape gets drawn in device coordinates. In both the page and device coordinate system the measure of unit is same i.e. pixels. We can customize the coordinate system by setting a different measure of unit. Suppose we wish to print a line having one-inch length, for this we need to use the PageUnit

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


property of the Graphics object. The PageUnit property represents an object of the GraphicsUnit enumeration. This enumeration specifies the unit of measure for the given data. For example, the Inch member specifies that unit of measure is an inch, the Pixel member specifies that the unit of measure is the device pixel etc. .NET Remoting-Difference Between Server-activated Singleton And SingleCall Activation Modes... Whenever we register a server-activated object, we specify a mode. The two supported activation modes used for server-activated objects are WellKnownObjectMode.SingleCall and WellKnownObjectMode.Singleton. WellKnownObjectMode is an enumeration and SingleCall and Singleton are the members of this enumeration. The difference between the two activation modes is that if we specify SingleCall to be the activation mode, a new instance of remotable object would get created for each and every method call placed by any client. As against this, if we specify Singleton as the activation mode only one instance of remotable object would be created and it would process all method calls from all clients. What are Channels? Ans: A channel serves as a conduit for communication between the client and the remotable object. The channel listens for incoming messages and sends outgoing messages. It takes a stream of bytes, creates a package according to a particular protocol, and routes it to the final destination. The .NET Framework comes with two predefined channel classes, TcpChannel and HttpChannel. The TcpChannel uses a binary formatter to serialize data to binary stream and transport it using the TCP protocol. HttpChannel uses a SOAP formatter to serialize data and transport the messages to and from remote objects using the SOAP protocol. We can also use binary formatters with HttpChannel. Both these classes work as senders as well as receivers. The way data gets serialized before sending, it gets deserialized after it is received. The TcpChannel class serves as a combined channel, which combines the TcpServerChannel and TcpClientChannel for convenience. The TcpServerChannel listens and the TcpClientChannel transmits messages using the TCP protocol. These classes fall under the System.Runtime.Remoting.Channels.Tcp namespace. Similarly, the HttpChannel class also servers a combined channel, which combines the HttpServerChannel (listener) and HttpClientChannel (sender). .NET Remoting-Is there any other method to activate remote objects? Ans: Generally when we think of activating remote objects we create an object of the remotable class (which actually creates a proxy on the client and object on the server). The .NET Framework offers an alternative way to activate remote objects instead of calling new( ). To activate server-activated objects we may use the GetObject( ) method while we may use CreateInstance( ) for client-activated objects. Both these methods belong to the System.Activator class. If we use these methods, we need not use RegisterActivatedClientType( ) or RegisterWellKnownClientType( ) methods to register the remotable class on the server. .NET Remoting- Which is better, Programmatic or Declarative Configuration? Ans: If we perform the registrations programmatically, and later if we wish to change the

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


registration data (for example, the machine or port) we need to make changes in the source code and re-compile the applications. As against this, if registrations are declarative all we need to do is simply make changes in the '.config' file through 'Notepad' or any other text editor and run the applications without recompilation. On the negative side the security factor is very low in declarative registration. Anybody can modify (or even delete!) the '.config' file that you create thus, leading to a trouble. On the other hand nobody can tamper with your registration data if its done programmatically. You would have to weigh out the convenience and security considerations as per the needs of your application. .NET Remoting-Lifetime Of A Remotable Object... For SingleCall server-activated objects, the duration of lifetime of an object is exactly one method. After this the object gets collected by the garbage collector. For Singleton server-activated objects and client-activated objects, a Lease Manager controls the lifetime. Each instance of such objects is leased to the client for a given amount of fixed time. The lease starts when the object is created. By default, each Singleton server-activated or clientactivated object is given a 5 minute lease. When the time expires the object is garbage collected. During the lifetime of the object any client can increase or decrease the lifetime value of the object by default for 2 minutes. Another way that .NET Remoting uses to control the object's lifetime is using sponsorship. Both server and client can act as sponsors for a particular instance of the remotable class. When the lease of an object finishes, before destroying the object the sponsors get a chance to renew the lease. What are HTML controls and Web controls and how do they differ? Ans: ASP.NET supports two distinctly different types of server controls: HTML controls and Web controls. HTML controls are instances of classes defined in the System.Web.UI.HtmlControls namespace. When you add runat="server" to a conventional HTML tag (as in <input type = "text" runat="server">), the .NET Framework responds by instantiating an HTML control. Web controls come from classes defined in System.Web.UI.WebControls. They're declared explicitly by prefixing class names with asp: and including runat="server" attribute (for example <asp:TextBox runat="server">). HTML controls exist primarily to ease the chore of migrating existing HTML forms to ASP.NET. Web controls are richer and more diverse in scope that HTML controls. Serializing Objects Using XML... XML and .NET together have provided a powerful feature of serializing objects in an XML document. In this process the public fields and properties of the class get stored in the form of elements and attributes. We can use the classes available in the System.Xml.Serialization namespace for serializing and de-serializing the objects. What do you mean by the LineJoin property? Ans: The LineJoin property of the Pen class gets or sets the join style for the ends of two consecutive lines drawn with this Pen object. For example, while drawing the rectangle if we specify the LineJoin property to be,

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


p.LineJoin = Drawing.Drawing2D.LineJoin.Round ; then the corners of the rectangle would become round. How to add Tooltips for various controls on a form? Ans: Suppose we have a Winform application with various controls and we wish to add different tooltips for each control. In such a case we need to drag the 'ToolTip' control on the form. As soon as we do this, the 'Properties' window for every control starts showing a 'ToolTip' on controlname property. Using this property we can set tooltips for the controls we want. For example, if we add a 'ToolTip' control named mytooltip on the form. The form has a button named mybutton. Now suppose we set the property to-"This is mybutton"-for a button called mybutton, then when we execute the program and moves the mouse on the button, a tooltip gets displayed. What actually happens behind the scene is that the wizard adds the following code to the form class: this.mytooltip.SetToolTip ( this.mybutton, "This is mybutton") ; What is Global.asax? Ans: Global.asax is an ASP.NET application file consisting of a class called Global. This class is derived from the HttpApplication class and contains code for responding to application-level events raised by ASP.NET. Following are some methods defined in the class: Application_Start( ):- Called when the site receives its very first request Session_Start( ):- Called when the session is first created Application_End( ) And Session_End( ): Called respectively when the application and session terminate Application_Error( ):- Called when an error occurs in the application

How do I write code if I want that the following statement should join the two corners of the form irrespective of its size? g.DrawLine ( 0, 0, 100, 100 ) ; Ans: Use the Graphics.ScaleTransform( ) method as shown below: void Form1_Paint ( object sender, PaintEventArgs e ) { Graphics g = e.Graphics ; g.ScaleTransform ( ClientSize.Width / 100.0f, ClientSize.Height / 100.0f ) ; Pen p = new Pen ( Color.Green, 1 / ( ClientSize.Width / 100.0f ) ) ; g.DrawLine ( p, 0, 0, 100, 100 ) ; } Difference Between Custom Control And User-Defined Control.. A custom control is the one which is created by extending an existing control like Label, Textbox, Buttons, etc. For example, we can derive a class from the TextBox class so that the user can enter only digits in it.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

A user-defined control is a set of one or more existing controls (WinForm or WebForm controls). The best example of user-defined control is a media player that is a combination of several buttons, slider control and other UI elements. A user-defined control is derived from the Forms UserControl class. If we want to create a control from scratch, we can do so by deriving a class from the Control class. Asynchronous Delegate Invocation Delegates normally work synchronously. That is, they invoke the method passed to them and return only when the method returns. We can also use delegates to make an asynchronous call to the method passed to it. It means that, the delegate would initiate the method and return immediately. To invoke a delegate asynchronously, call the BeginInvoke( ) method, which will queue the method to be run on a thread from a system thread pool. The BeginInvoke( ) method accepts a reference to the method that should get called when the method called by BeginInvoke( ) ends. What is thread pooling? Ans: While programming Windows versions prior to Windows 2000, developers often started a thread to perform a particular task and when the task was complete the thread would die. The starting and closing the thread was costly in performance point of view. So, Microsoft introduced a concept called thread pool in Windows 2000. And now in .NET, thread pool has been implemented in CLR itself. And so, all the managed applications can use thread pool. Now if a managed application starts a thread, it has to ask for a thread in the thread pool. The thread pool initiates the thread just like any other normal thread. But when the task is complete, thread wont get destroyed. It would go to the thread pool in suspended state. If application makes a request for thread, again this thread would wake up and perform the task. This saves lot of overhead. The thread pool takes the responsibility of creating and killing threads, calling a method asynchronously or after a time interval, etc. As we know the code that accesses a common resource when enclosed within Monitor.Enter( ) and Monitor.Exit( ) helps in synchronizing concurrently running threads. What if one thread calls Monitor.Enter( ) twice. Will it go into the wait state since lock has already been acquired? The answer is no. This is because Enter( ) always checks which thread has acquired the resource before making the thread wait. Initially when resource is not acquired, count in the syncblock is set to zeros. When Enter( ) is called for the first time count becomes 1. If Enter( ) is called again and it finds that the same thread has acquired the resource it just increments the count without making the thread wait. This behavior seems logical otherwise the thread would have gone into indefinite wait state expecting from itself to release the resource. The Exit( ) method then decrements the count. When the Exit( ) method finds that the count has reached zero, it releases the lock and makes the waiting thread as the ready thread. What is Stack Walk? Ans: .NET security models walk the stack to check whether a program accessing a code has permission to do so. Stack walks are an essential part of the security system. A stack walk operates in the following manner. Every time a method is called a new activation record will be put on the stack. This record contains the parameters passed to the method, if any, the address to return to when this function completes and any local variables. At certain stages during execution, the thread might need to

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


access a system resource, such as the file system. Before allowing this access the protected resource may demand a stack walk to verify that all functions in the call chain have permission to access the system resource. At this stage a stack walk will occur and each activation record is checked to see that callers do indeed have the required permission. Suppose we create two strings having exactly same literal only one object containing the string gets created and both the references refer to the same object. Let us understand how this works out. Suppose we create two strings as shown below. string s1 = "hi there! " ; string s2 = "hi there! " ; When the application gets loaded in memory, CLR creates an empty hashtable to store the string constants used in the source code. The JIT compiler searches all the strings and fills the hashtable with keys and values. In the hashtable, the text is the key and reference is the value. So, when JIT comes across the first declaration i.e string s1 = "hi there!", the text "hi there!" gets stored as a key and its reference as value. Later, it encounters s2 that has the same value. It does not create another entry with this value since duplicate keys cannot exist in hashtable. Whenever we use s1 or s2, it returns the same reference from hashtable. This mechanism avoids duplication of strings. As soon as we assign a different string constant to any of the references it starts referring to different object. A Few Points About virtual Keyword (a) virtual or abstract method cannot be private. This is necessary because, the class designer creates virtual or abstract methods when he wants that user should override them in derived classes. If we make them private, they would fail to serve the purpose. (b) C++ supports a concept of virtual base classes. In C++, a class can inherit the same class twice. This happens because of multiple inheritance. For example, a class der3 is derived from classes der1 and der2 both of which are derived from class base1. This results in der3 having two copies of base1s data. Now, if der3 refers to the data in base1, which of the two copies will it access? To avoid this ambiguous situation, base classes are declared as virtual. Such a situation would never occur in C#, as in C#, a class has exactly one base class. Hence, C# does not have virtual base classes As we know the code that accesses a common resource when enclosed within Monitor.Enter( ) and Monitor.Exit( ) helps in synchronizing concurrently running threads. What if one thread calls Monitor.Enter( ) twice. Will it go into the wait state since lock has already been acquired? The answer is no. This is because Enter( ) always checks which thread has acquired the resource before making the thread wait. Initially when resource is not acquired, count in the syncblock is set to zeros. When Enter( ) is called for the first time count becomes 1. If Enter( ) is called again and it finds that the same thread has acquired the resource it just increments the count without making the thread wait. This behavior seems logical otherwise the thread would have gone into indefinite wait state expecting from itself to release the resource. The Exit( ) method then

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


decrements the count. When the Exit( ) method finds that the count has reached zero, it releases the lock and makes the waiting thread as the ready thread What are parameterized commands? Ans: Often we require to execute the same command on a database repeatedly, in which only the values used in command are different. In such cases we can use parameterized commands. Parameterized commands are also useful in the commands where input values come from user input. They are also useful when values for only some of the fields in a row are to be stored. For example, suppose our database table consists of fields f1, f2, f3 . . . and so on, till f7. Suppose we have specified default values for f2, f3, f4 and f6 and we wish that f1, f5 and f7 be filled with values a, b and c respectively. Then the parameterized command will be "Insert into table1 { f1, f5, f7 } values ( @a, @b, @c )" The parameter is added to the command by using Parameters collection of the command object as shown below: com.Parameters.Add ( "@a", 10 ) ; com.Parameters.Add ( "@b", 230.0 ) ; com.Parameters.Add ( "@c", 170 ) ; where com is a reference to SqlCommand object. How do I write code to display tool tip for controls? Ans: We can display a tool tip for any control placed on a form. For this, we have to add a ToolTip control to the form. As soon as we add the ToolTip control a property named 'Tooltip on tip' gets added to the 'Properties' window of all the controls placed on the form. The string entered against this property gets displayed as the tool tip when mouse is moved over the control. How come only one ToolTip control manages to display tips for all the controls for which 'Tooltip on tip' property is set? When we set the 'Tooltip on tip' property of a control, a call to the ToolTip.SetToolTip( ) method gets added in the InitializeComponent( ) method as shown below: tip.SetToolTip ( button, "This is a Button" ) ; The reference to the control (in this case, button) is passed to the SetToolTip( ) method along with the tool tip text. The SetToolTip( ) method associates the text with the specified control. How do I write code to invoke a method dynamically? Ans: One of the uses of Reflections is that we can invoke a method dynamically. Following code snippet invokes a method fun( ) of sample class stored in 'emitassembly.dll'. Assembly a = Assembly.LoadFrom ( "emitassembly.dll" ) ; Type t = a.GetType ( "sample" ) ; Object o = Activator.CreateInstance ( t ) ; t.InvokeMember ( "fun", BindingFlags.InvokeMethod, null, o, null ) ; CreateInstance( ) creates an instance of the specified type and InvokeMember( ) method invokes the method specified as the first parameter.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


What are Thread States? Ans: From the time a thread is started until it gets terminated a thread undergoes many transitions and is said to be in at least one of the several thread states. The methods that control the transitions from one state to another belong to either the Thread or the Monitor class. Both these classes belong to the System.Threading namespace. At any given time a thread can be in one or more of the states such asUnstarted, Running, WaitSleepJoin, Suspended, SuspendRequested, Aborted, AbortRequested, Stopped and StopRequested. All these states are members of the ThreadState enumeration declared in System.Threading namespace. Using checked And unchecked Operators Every primitive data type has a fixed size and can store only that much value which can be accommodated in its size. For example a variable of an int type cannot contain a value larger than 2147483647. In an integer arithmetic operation a value greater than 2147483647 causes overflow. This may cause an incorrect output. .NET provides two keywords checked and unchecked to check whether integer arithmetic operations occur in a checked context or unchecked context. In a checked context CLR throws an OverflowException if the overflow occurs. In the following code snippet, addition of i and j would result in a value greater than 2147483647. Because we have added i and j in the checked context, it would throw the OverflowException. int i = Int32.MaxValue ; int j = Int32.MaxValue ; int s = 0 ; try { s = checked ( i + j ) ; } catch ( OverflowException o ) { Console.WriteLine ( "Overflow occurred" ) ; } s = unchecked ( i + j ) ; Console.WriteLine ( s ) ; By default, arithmetic operations are done in an unchecked context. The addition performed in an unchecked context would result in an incorrect output being stored in s Nondeterministic Behavior Of Destructors... In C++, we can define a destructor in a class to perform the clean up jobs. .NET framework also allows to define destructors. But destructors in .NET are different than those in C++. In C++, the destructor gets called when the object is destroyed. In .NET also destructor is called when the object is destroyed. However, when the object would get destroyed is undeterministic. Because, the object is destroyed only when the Garbage Collector is invoked. So, when the destructor of the object would get called is also Nondeterministic. Calling Web Serivce Asynchronously... WebServices support asynchronous communication. In the asynchronous communication, the

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com


client continues processing other tasks as it waits for a response from server. The client responds to the result of the service request when it becomes available. Following code shows how to call a WebService called temperature. temperature t = new temperature ; AsyncCallback cb = new AsyncCallback ( callbackfunc ) ; t.BeginWebMethodName ( 20.5f, cb, t ) ; The value 20.5f is the parameter passed to the web method. The callback function callbackfunc( ) is defined as shown below: public void callbackfunc ( IAsyncResult ar ) { temperature t = ( temperature ) ar.AsyncState ; t.EndWebMethodName ( ar ) ; } How do I shift the origin to the center of the client area and draw a line of 1 inch? Ans: Here is the code: private void Form1_Paint ( object sender, PaintEventArgs e ) { Graphics g = e.Graphics ; g.PageUnit = GraphicsUnit.Inch ; g.TranslateTransform ( ( ClientRectangle.Width / g.DpiX ) / 2, ( ClientRectangle.Height / g.DpiY ) / 2 ) ; Pen p = new Pen ( Color.Green, 1 / g.DpiX ) ; g.DrawLine ( p, 0, 0, 1, 0 ) ; } The PageUnit property sets the unit to an inch. We have called the TranslateTransform( ) method to shift the origin to the center of the client area. This method maps the world coordinates to page coordinates. Finally, we have created a pen having proper width and drawn the line. Since we have set the page unit to an inch, we must specify coordinates of line in inches. How do I invoke a method using reflection? Ans: The following example loads a user-created assembly, obtains a class type, creates its instance and invokes a method defined in the assembly. Assembly a = Assembly.LoadFrom ( "c:\\mymath.dll" ) ; Type t = a.GetType ( "mymath" ) ; MethodInfo m = t.GetMethod ( "add" ) ; Object obj = Activator.CreateInstance ( t ) ; Object[ ] arg = new Object [ 2 ] ; arg [ 0 ] = 10 ; arg [ 1 ] = 20 ; m.Invoke ( obj, arg ) ; This code snippet would invoke the add( ) method written in mymath class. The mymath class is in the 'mymath.dll' assembly.

Compiled by rmshankar@yahoo.com

Documents downloaded from www.funducode.com

Compiled by rmshankar@yahoo.com

You might also like