Home   Notes   Contact Me

C#

Local

Gotchas

External


Best Practices

WinForms Programming

  1. Move main out of where it is created by default, and into its own file, a good name for the file is Main.cs
  2. Initialize logging in main
  3. Put a Global try catch (that logs) in main
public class App
{
	public static void Main()
	{
		try {
			System.Windows.Forms.Application.ThreadException += System.Thread.ThreadExceptionEventHandler( OnAppException));
			
			string logfile = System.AppDomain.CurrentDomain.BaseDirectory + "TraceLog.txt";
			System.IO.TextWriter log = new System.IO.StreamWriter( logfile);
			
			if ( Globals.Trace) {
				System.Diagnostics.TextWriterTraceListener logger;
				logger = new System.Diagnostics.TextWriterTraceListener( log);
				System.Diagnostics.Trace.Listeners.Add( logger);
				System.Diagnostics.Trace.WriteLine("App starting: " + DateTime.Now);
			}
			
			System.Windows.Form.Application.Run( new MainForm() );
		} catch( Exception ex) {
			App.OnAppException( null, new ST.ThreadExceptionEventArgs(ex));
		}
	}

	private static void OnAppException( Object sender, System.Thread.ThreadExceptionEventArgs e)
	{
		Exception ex;
		ex = e.Exception;
		
		System.Windows.Forms.MessageBox.Show( "Halting due to error: " + ex.Message, "Fatal Error");
		
		T.WriteLine( "Global Exception Handler:");
		while( ex != null) {
			T.WriteLine( ex.GetType().FullName);
			T.Indent();
			T.WriteLine( "ExceptMess: " + ex.Message);
			T.WriteLine( "Trace: " + ex.StackTrace);
			T.Unindent();
			T.Flush();
			
			ex = ex.InnerException;
		}
		
		T.Close();
		System.Windows.Forms.Application.Exit();
	}
}

scope


Exceptions

Examples of the 2 types

try {
	throw new MyException();
} catch( MyException e) {
	// handle MyException here
} catch {
	// catch all for any exception type
} finally {
	// Clean up stuff here, even if a return happens from anywhere,
	// Unless the program is terminated in the catch block 
}

List of All Exceptions

In Visual Studio, goto Debug | Exceptions

Some info you can get in a catch about an Exception

System.Diagnostics.EventLog.WriteEntry( "XXX", ex.GetType().FullName);
System.Diagnostics.EventLog.WriteEntry( "XXX", ex.Message);
System.Diagnostics.EventLog.WriteEntry( "XXX", ex.StackTrace);

using (statement)

private void DrawBackground( Graphic g)
{
	using (Brush backBrush = new SolidBrush(BackColor))
	using (Pen borderPen = new Pen(BorderColor, 4))
	{
		g.FillRectangle(backBrush, new Rectangle(10, 10, 50, 50);
		g.DrawRectangle(borderPen, new Rectangle(8, 8, 54, 54);
	}
}

Random Notes

Inspired by Ten Traps in C# for C++ Programmers


.dlls, calling funcs in them

// sort of like this, but you cannot actually use classes, just functions:

[DllImport("apibridge.dll")] public static extern class CBridgeApiClass {};

File I/O

using System;
using System.IO;

TextWriter tw = new StreamWriter( "date.txt");
tw.WriteLine( DateTime.Now);
tw.Close();


TextReader tr = new StreamReader( "date.txt");
Console.WriteLine(tr.ReadLine());
tr.Close();

Strings


Resources


Gotchas

Some sort of problem going into a COM object that is in the reference list


Exitting

A Forms Application

// Note this only:
// 1) closes all windows
// 2) exits window message loops
// 3) returns from Application.Run()
// 4) so code after Application.Run() then gets executed (of which there is usually none)
Application.Exit()

A Program

System.Environment.Exit( int nStatus);

Bitmap from Resources

Ruth came up with this method (I think I saw a cleaner method, but neglected to note it):
// To Get it:
System.Reflection.Assembly assm = System.Reflection.Assembly.GetExecutingAssembly ();
System.IO.Stream stream = assm.GetManifestResourceStream ("afoNETExtension.command.bmp");
System.Drawing.Bitmap bitmap = (System.Drawing.Bitmap)System.Drawing.Image.FromStream (stream);
m_HBitmap = bitmap.GetHbitmap ();

// To supply the DeleteObject func from gdi32.dll:
[DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);

// To Release it:
DeleteObject (m_HBitmap);

Thread Synchronization

// Context-bound type with the Synchronization context attribute.
[Synchronization()]
public class SampleSyncronized : ContextBoundObject {

    // A method that does some work, and returns the square of the given number.
    public int Square(int i)  {

        Console.Write("The hash of the thread executing ");
        Console.WriteLine("SampleSyncronized.Square is: {0}", 
                             Thread.CurrentThread.GetHashCode());
        return i*i;
    }
}

CLS Compliance

Making code with compliant and non compliant parts be compliant:

using System;
// Assembly marked as compliant.
[assembly: CLSCompliantAttribute(true)]
// Class marked as compliant.
[CLSCompliantAttribute(true)]
public class MyCompliantClass {
   // Method marked as not compliant.
   [CLSCompliantAttribute(false)]
   public void ChangeValue(UInt32 value){ }
   public static void Main( ) {
   int i = 2;
   Console.WriteLine(i);
   }
}

Flags (type of Enumeration)

// A bit field enumeration
public enum SupportedSpeeds
{
  none = 0,
  b1200 = 1,
  b9600 = 2,
  b19200 = 4,
  b56000 = 8,
  All = b1200 | b9600 | b19200 | b56000,
}

SupportedSpeeds mySpeeds = b1200 | b19200;

Window, Setting its parent to a HWND from outside C#

[DllImport("user32.dll")]
public extern static int SetParent(int child ,int parent );

void setParent( int parent)
{
  SetParent( form.Handle.ToInt32(), parent);
}

MessageBox

System.Windows.Forms.MessageBox.Show( "Message Goes Here");

Parent, getting its 'this'

Parent classes 'this' is 'base'

Parent class, calling one of its methods

public class Parent
{
	public int getCount() {
		return 5;
	}
}

public class Child : Parent
{
  public int getCount() {
    return 7;
  }
  
  public int getParentsCount() {
		return getCount(); // Bad returns Child Count
		return base.getCount(); // returns parents count
  }
}


Form, setting its starting position

this.StartPosition = FormStartPosition.Manual;
this.Location = new Point( 0, 0);

File Open Dialog

OpenFileDialog dlg = new OpenFileDialog();
dlg.InitialDirectory = "C:\\";
dlg.Filter = "Images|*.img|All files|*.*";
if ( dlg.ShowDialog(this) == DialogResult.OK) 
{
}