Tuesday, March 31, 2009

.Net Memory Leaks. It IS possible!

3 comments:
Let's face it; us .NET Developers have it pretty good these days. Ask any seasoned C++ programmer, and they'll undoubtedly have a few horror stories about an app they once worked on which had a memory leak somewhere someplace, and how hard it was to track down. When working in an unmanaged environment, this is part of the deal. Memory management is in your hands. When working in a managed environment, you just sit back and let the Garbage Collector do the dirty work. Therefore, it can be easy to simply assume that when coding in .NET you don't need to worry about memory leaks ever. Well, that's not entirely true as I'll demonstrate here.

The premise is simple. If you have an object, we'll call it Foo, and this object holds a reference to an object that we'll call Bar. Now, Bar, has an event that can be raised at any time. Our Foo object registers for this event. Now, when our Foo object goes out of scope, and we lose a reference to it, if we DIDN'T unhook from the Bar event, Bar is still holding a reference to this object, and the Garbage Collector can't claim that memory back. We however, no longer have a reference to it directly, which now result in a nasty memory leak. Here's a simple demo app:

First, let's create a class that raises an event. We'll call is EventRaiser:

    public class EventRaiser
    {
        private string stringValue;
 
        public string StringValue
        {
            get { return this.stringValue; }
            set
            {
                if (this.stringValue != value)
                {
                    this.stringValue = value;
                    if (this.StringValueChanged != null)
                    {
                        this.StringValueChanged(this, new EventArgs());
                    }
                }
            }
        }
 
        public event EventHandler StringValueChanged;
    }


This class is nothing special, it just has a property called StringValue. Every time StringValue is changed, we raise our StringValueChanged event.

Now, let's create a class that will have a reference to an EventRaiser object and will register for the StringValueChanged event:

    public class MemoryLeak
    {
        private byte[] allocatedMemory;
        private EventRaiser raiser;
 
        public MemoryLeak(EventRaiser raiser)
        {
            this.raiser = raiser;
            //allocate some memory to mimic a real life object
            this.allocatedMemory = new byte[10000]; 
            raiser.StringValueChanged += new EventHandler(raiser_StringValueChanged);
        }
 
        private void raiser_StringValueChanged(object sender, EventArgs e)
        {
 
        }
    }


Here we create a MemoryLeak class. This class takes as a parameter in the constructor an object of type EventRaiser. It then allocates a large array of bytes, just to make the object a larger object in memory. It then hooks up to the EventRaiser's StringValueChanged event assigning it the raiser_StringValueChanged method. This is key! We're assigning a delegate to the EventRaiser class which therefore gives our EventRaiser object a reference to this MemoryLeak object. Remember, delegates are objects like any other and can hold on to references of other objects. Therefore, the EventRaiser.StringValueChanged event (delegate) holds on to a reference of our MemoryLeak object.

Now, here's some code to demonstrate:

    public class Program
    {
        private static EventRaiser raiser;
        public static void Main(string[] args)
        {
            raiser = new EventRaiser();
            for (int i = 0; i <= 1000; i++)
            {
                CreateLeak();
            }
 
            Console.WriteLine("Press any key to continue...");
            Console.ReadKey(true);
        }
 
        private static void CreateLeak()
        {
            MemoryLeak memoryLeak = new MemoryLeak(raiser);
            memoryLeak = null;
            GC.Collect();
            long memory = GC.GetTotalMemory(true);
            Console.WriteLine("Memory being used: {0:0,0}", memory);
        }
    }


Simple console app that has a private field of type EventRaiser. In our main method, after we new up the EventRaiser, we call our CreateLeak method. All this method is doing is creating a new MemoryLeak object, pasing in the EventRaiser to the constructor. (At this point, the MemoryLeak will hook up to the StringValueChanged event of the EventRaiser.) Then, we assign the memoryLeak reference to null, which in a normal case would make the old MemoryLeak object subject to Garbage Collection. So, we call GC.Collect to force a collection, and then we output the amount of managed memory being used, using the GC.GetTotalMemory() method.

If you run this program, you'll notice that the amount of memory just keeps growing, and never goes down!! If you bump up the amount of bytes allocated in the MemoryLeak class, or bump up the number in the for loop in the main method, you'll get an OutOfMemoryException really quickly!

The simplest way to avoid this kind of mess, is to take advantage of the IDiposable interface. Let's add that to our MemoryLeak class and unhook from the event in the Dispose method:

    public class MemoryLeak : IDisposable
    {
        private byte[] allocatedMemory;
        private EventRaiser raiser;
 
        public MemoryLeak(EventRaiser raiser)
        {
            this.raiser = raiser;
            //allocate some memory to mimic a real life object
            this.allocatedMemory = new byte[10000]; 
            raiser.StringValueChanged += new EventHandler(raiser_StringValueChanged);
        }
 
        private void raiser_StringValueChanged(object sender, EventArgs e)
        {
 
        }
 
        public void Dispose()
        {
            this.raiser.StringValueChanged -= this.raiser_StringValueChanged;
        }
 
    }


As you can see, in the Dispose method, we just unhook from the EventRaiser's StringValueChanged event. Now, we'll modify our main method to actually call the Dispose method:

        private static void CreateLeak()
        {
            MemoryLeak memoryLeak = new MemoryLeak(raiser);
            memoryLeak.Dispose();
            memoryLeak = null;
            GC.Collect();
            long memory = GC.GetTotalMemory(true);
            Console.WriteLine("Memory being used: {0:0,0}", memory);
        }


Before we assign memoryLeak to null, we just call the Dispose method (or you can wrap the MemoryLeak assignment in a using statement). Now, run the program and what do you know?! The total memory being used stays the same throughout! Crisis averted.

So, to anyone that thinks memory management in a managed world isn't important, think again. Yes, you don't activley have to play a role in the management of memory in your app, but you DO need to be conscious about it and understand what's going on.

Sunday, March 29, 2009

WinForms Drag & Drop. A simple example to get you started.

No comments:
When using computers these days, we've all gotten accustomed to dragging and dropping things from one place to another. We do it all the time, and it gives your application that extra usability factor that the end user will appreciate. At work, I was working on an app that gave the user the ability to "Screen" on various columns of data. The user needed to have the ability to choose specifically which fields they want to screen on. So, we came up with the idea of having two treeviews. On the left hand side were all the available columns in the database and on the right was an empty treeview. The user would then be able to drag and drop fields from one to the other. So, here's the basic way of implementing Drag / Drop in your windows app.

For simplicity in this example, I decided to go with a Listbox on the left and a Treeview on the right. The idea here will be simple. The user will be able to drag an item from the left, and move it to the treeview on the right. We will have to track where the user "drops" the item, so that we can place it under the proper parent node. Here's what the sample form looks like:




When the form loads, we'll click on the Populate controls button. That will add the next 10 dates to the listbox on the left. It will also add two parents nodes to the treeview as well as two subnodes to each of the parent nodes.

Here's the full code, I'll go through and explain it all as best I can:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
 
namespace SetFocusDemo.DragDropSample
{
    public partial class DragDropSample : Form
    {
        public DragDropSample()
        {
            InitializeComponent();
 
            this.treeView1.AllowDrop = true;
            this.listBox1.AllowDrop = true;
 
            this.listBox1.MouseDown += new MouseEventHandler(listBox1_MouseDown);
            this.listBox1.DragOver += new DragEventHandler(listBox1_DragOver);
 
            this.treeView1.DragEnter += new DragEventHandler(treeView1_DragEnter);
            this.treeView1.DragDrop += new DragEventHandler(treeView1_DragDrop);
 
        }
 
        private void buttonPopulate_Click(object sender, EventArgs e)
        {
            this.PopulateListBox();
            this.PopulateTreeView();
        }
 
        private void PopulateListBox()
        {
            for (int i = 0; i <= 10; i++)
            {
                this.listBox1.Items.Add(DateTime.Now.AddDays(i));
            }
        }
 
        private void PopulateTreeView()
        {
            for (int i = 1; i <= 2; i++)
            {
                TreeNode node = new TreeNode("Node" + i);
                for (int j = 1; j <= 2; j++)
                {
                    node.Nodes.Add("SubNode" + j);
                }
                this.treeView1.Nodes.Add(node);
            }
        }
 
        private void listBox1_MouseDown(object sender, MouseEventArgs e)
        {
            this.listBox1.DoDragDrop(this.listBox1.SelectedItem, DragDropEffects.Move);
        }
 
        private void listBox1_DragOver(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.Move;
        }
 
        private void treeView1_DragEnter(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.Move;
        }
 
        private void treeView1_DragDrop(object sender, DragEventArgs e)
        {
 
            TreeNode nodeToDropIn = this.treeView1.GetNodeAt(this.treeView1.PointToClient(new Point(e.X, e.Y)));
            if (nodeToDropIn == null) { return; }
            if (nodeToDropIn.Level > 0)
            {
                nodeToDropIn = nodeToDropIn.Parent;
            }
 
            object data = e.Data.GetData(typeof(DateTime));
            if (data == null) { return; }
            nodeToDropIn.Nodes.Add(data.ToString());
            this.listBox1.Items.Remove(data);
        }
    }
}


Ok, let's start with the constructor. First thing you need to make sure, is that if you want a control to be a "Drop Target" you need to set the "AllowDrop" property to true. You'll also notice that we're setting the "AllowDrop" property of the listbox. Even though we won't actually be dropping anything in the listbox, the only way to get the correct icon while dragging out of the listbox, is to set it's AllowDrop to true as well.

            this.listBox1.MouseDown += new MouseEventHandler(listBox1_MouseDown);
            this.listBox1.DragOver += new DragEventHandler(listBox1_DragOver);
 
            this.treeView1.DragEnter += new DragEventHandler(treeView1_DragEnter);
            this.treeView1.DragDrop += new DragEventHandler(treeView1_DragDrop);


Here, we hook up to all the events that we'll need to make this happen. I'll explain it when we get to the handlers.

        private void buttonPopulate_Click(object sender, EventArgs e)
        {
            this.PopulateListBox();
            this.PopulateTreeView();
        }
 
        private void PopulateListBox()
        {
            for (int i = 0; i <= 10; i++)
            {
                this.listBox1.Items.Add(DateTime.Now.AddDays(i));
            }
        }
 
        private void PopulateTreeView()
        {
            for (int i = 1; i <= 2; i++)
            {
                TreeNode node = new TreeNode("Node" + i);
                for (int j = 1; j <= 2; j++)
                {
                    node.Nodes.Add("SubNode" + j);
                }
                this.treeView1.Nodes.Add(node);
            }
        }


This is just some demo code to set up are controls. In the PopulateListBox() method we just do a for loop from 0 to 10 and add the date for the next 10 days to the listbox. In the PopulateTreeView() method, we just put two parent nodes along with two child nodes in the treeview. Again, this is just for the purpose of this demo.

        private void listBox1_MouseDown(object sender, MouseEventArgs e)
        {
            this.listBox1.DoDragDrop(this.listBox1.SelectedItem, DragDropEffects.Move);
        }


Here's where it starts getting interesting. The first event we deal with, is the "MouseDown" on the listbox. This kicks off the Drag / Drop; when the user actually clicks on an item. Here, we call "DoDragDrop" on the listbox. The arguments that the DoDragDrop method expect are "object data", and "DragDropEffects allowedEffects". The data in the first argument, is the actual object that you want to move from one control to the other. In our case, we just grab the listbox selected item, which will be a DateTime. We then use the Move drag effect, which gives the nice visual mouse cursor we expect for a move.

        private void listBox1_DragOver(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.Move;
        }


The next event we handle is the listbox DragOver event. Since we called the DoDragDrop in the mousedown, when the user starts to "drag" the item out, the DragOver event is now raised in the listbox. We are only dealing with this event so that we can continue to show the "move" mouse cursor.

Once the user leaves the Listbox, the DragLeave event is raised. In this case I'm not handling it because I have no need for it, but if you do need it, it does get raised.

        private void treeView1_DragEnter(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.Move;
        }


The next event we're listening for is the "DragEnter" on the Treeview. At this point, the user has clicked his mouse on one of the dates, dragged it out of the listbox, and now moved his mouse into the treeview. All we're doing here, is just setting the DragEffects to move so that we can continue to show the correct mouse cursor.

        private void treeView1_DragDrop(object sender, DragEventArgs e)
        {
 
            TreeNode nodeToDropIn = this.treeView1.GetNodeAt(this.treeView1.PointToClient(new Point(e.X, e.Y)));
            if (nodeToDropIn == null) { return; }
            if (nodeToDropIn.Level > 0)
            {
                nodeToDropIn = nodeToDropIn.Parent;
            }
 
            object data = e.Data.GetData(typeof(DateTime));
            if (data == null) { return; }
            nodeToDropIn.Nodes.Add(data.ToString());
            this.listBox1.Items.Remove(data);
        }


Finally, we actually deal with the "main event" (pun intended). This is where the user finally lets go of the mouse and "Drops" the item into the TreeView. First we need to determine where the user let go of his mouse. There's a very helpful method on the TreeView called "GetNodeAt(Point pt)" which takes a Point as a parameter, and gives you back the TreeNode at that location. The Point that's passed to us through the DragEventArgs is in screen coordinates. Therefore, we first need to call "PointToClient" to get us the coordinates relative to the TreeView. Once we have that, we can get the exact node where the user let go of the mouse.

Now, we just need to determine if the node where the user dropped the item is a parent node or a child node. This is the business rule I decided to set up for this example; that the user can only drag a date into the treeview as a subnode. We will not allow them to add parent nodes. Therefore, we first need to determine if the node is a parent or a sub. Once we have the parent node, we will add the dropped item as a subnode.

            object data = e.Data.GetData(typeof(DateTime));
            if (data == null) { return; }


Here we retrieve the item that was brought over from the listbox through the eventargs. We call the GetData method to actually retrieve the item which in our case is a DateTime object.

            nodeToDropIn.Nodes.Add(data.ToString());
            this.listBox1.Items.Remove(data);


Once that's done, we just add it as a node, and remove the item from the listbox. Run the sample and try it yourself. Click the Populate Button and then drag items from the listbox to the treeview. Cool stuff no?

I admit, it's a bit of a pain to get this all to work, but the end result is worth it. Users are accustomed to drag and drop and will appreciate the extra touch in your app.

Wednesday, March 25, 2009

Cool IEnumberable extension method. Useful in ASP.NET MVC

4 comments:
So recently at work we started revamping our site and we've decided to use ASP.NET MVC. I'm not going to cover ASP.NET MVC in this blog post (hopefully in the future) but in short, it's Microsoft's new Web Framework that doesn't use WebForms. No more postbacks for every little thing! Woohoo! However, without WebForms, that means no more ASP.NET controls. Therefore, it was useful for us in a few places to be able to generate an HTML table from a collection of various different objects. So, I ended up writing a really cool extension method which I think can be beneficial since it covers generics, and reflection (two topics that wasn't explored thoroughly enough in SetFocus IMO).

So, first I'll show the code, then I'll do my best to explain:

        public static string ToHtmlTable<T>(this IEnumerable<T> list,string tableSyle, string headerStyle, string rowStyle, string alternateRowStyle)
        {
            var result = new StringBuilder();
            if (String.IsNullOrEmpty(tableSyle))
            {
                result.Append("<table id=\"" + typeof(T).Name + "Table\">");
            }
            else
            {
                result.Append("<table id=\"" + typeof(T).Name + "Table\" class=\"" + tableSyle + "\">");
            }
 
            var propertyArray = typeof(T).GetProperties();
 
            foreach (var prop in propertyArray)
            {
                if (String.IsNullOrEmpty(headerStyle))
                {
                    result.AppendFormat("<th>{0}</th>", prop.Name);
                }
                else
                {
                    result.AppendFormat("<th class=\"{0}\">{1}</th>",headerStyle, prop.Name);
                }
            }
 
 
            for (int i = 0; i < list.Count(); i++)
            {
                if (!String.IsNullOrEmpty(rowStyle) && !String.IsNullOrEmpty(alternateRowStyle))
                {
                    result.AppendFormat("<tr class=\"{0}\">", i%2==0 ? rowStyle : alternateRowStyle);
                }
 
                else
                {
                    result.AppendFormat("<tr>");
                }
                foreach (var prop in propertyArray)
                {
                    object value = prop.GetValue(list.ElementAt(i), null);
                    result.AppendFormat("<td>{0}</td>", value ?? String.Empty);
                }
                result.AppendLine("</tr>");
            }
 
            result.Append("</table>");
 
            return result.ToString();
        }


Ok, let's start with the parameters:

        public static string ToHtmlTable<T>(this IEnumerable<T> list,string tableSyle, string headerStyle, string rowStyle, string alternateRowStyle)


This will allow us to pass in the CSS class of each piece in the HTML table. The way it's coded is that you can pass in null or empty strings and it'll ignore it. Otherwise, it'll enter that as the class name. IE:

<table class="tableClass">


Also notice that the method is generic, so any collection of any kind will work with this method.

            var result = new StringBuilder();
            if (String.IsNullOrEmpty(tableSyle))
            {
                result.Append("<table id=\"" + typeof(T).Name + "Table\">");
            }
            else
            {
                result.Append("<table id=\"" + typeof(T).Name + "Table\" class=\"" + tableSyle + "\">");
            }


Here we start building up the HTML table. If a CSS class was supplied for the table, then we put that in the table tag, otherwise, we don't put any class name. I gave it an ID based on the name of the type that T represents. This may be useful if you want to apply further CSS, so it's good practice to give every element an ID, but in our example we won't actually make use of it. I just left it there for completeness.

            var propertyArray = typeof(T).GetProperties();


Here's where we reflect over T to get an array of PropertyInfo objects. GetProperties returns a PropertyInfo[] array.

            foreach (var prop in propertyArray)
            {
                if (String.IsNullOrEmpty(headerStyle))
                {
                    result.AppendFormat("<th>{0}</th>", prop.Name);
                }
                else
                {
                    result.AppendFormat("<th class=\"{0}\">{1}</th>",headerStyle, prop.Name);
                }


Next, we want to set up the table headers. The headers of the HTML table will be the actual property name. So say you were passing in a List to this method, and your Car class had properties such as "Year", "Make" etc, then that's what would actually appear as the column headers. That's what the PropertyInfo.Name property represents.

            for (int i = 0; i < list.Count(); i++)
            {
                if (!String.IsNullOrEmpty(rowStyle) && !String.IsNullOrEmpty(alternateRowStyle))
                {
                    result.AppendFormat("<tr class=\"{0}\">", i%2==0 ? rowStyle : alternateRowStyle);
                }
 
                else
                {
                    result.AppendFormat("<tr>");
                }


Here we start enumerating the actual IEnumerable that was passed in. For every element in the collection, we want to add a row to our table. Thefore, we first open the tag. However, if the styles for rows are set (both rowStyle and alternateRowStyle) then we need to apply the appropriate class to the row. We can simply check if i is currently an even number (i % 2 == 0). If it is, then we're on a regular row, if it's odd, then we're on an alternate row. If no style is specified, just do a regular tag.

                foreach (var prop in propertyArray)
                {
                    object value = prop.GetValue(list.ElementAt(i), null);
                    result.AppendFormat("<td>{0}</td>", value ?? String.Empty);
                }
                result.AppendLine("</tr>");
            }


Now, we go back to using our PropertyInfo array. For each item in our collection, we want to enumerate over all of it's properties, and get the value for that property. Therefore, first we call the GetValue method on the current PropertyInfo. The first parameter to GetValue, is the object of whose value you want to get. The second one, is if parameters are neccessary to access that property like an indexer. We won't be dealing with that here so we just pass null.

Then, if value isn't null, we append that to the table, else we append a String.Empty. You'll notice the syntax is value ?? String.Empty. That's actually called the "null coalescing operator" It's basically a shorthand way of saying "If value isn't null, use value, else use String.Empty".

            result.Append("</table>");
 
            return result.ToString();
        }


Finally, we just close up the tag and then the tag. Then, we return the result. Now, let's actually test this!

Create a winforms project and add a button to the form, and a WebBrowser control. Then, create a simple Person class like this:

    public class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
    }


No big deal, simple class with three properties. Then, in the button click, create a new List and add a few Person objects to that list:
        private void button1_Click(object sender, EventArgs e)
        {
            var personList = new List<Person>();
            personList.Add(new Person
            {
                FirstName = "Alex",
                LastName = "Friedman",
                Age = 27
            });
 
            personList.Add(new Person
            {
                FirstName = "Jack",
                LastName = "Bauer",
                Age = 45
            });
 
            personList.Add(new Person
            {
                FirstName = "Cloe",
                LastName = "O'Brien",
                Age = 35
            });
 
            personList.Add(new Person
            {
                FirstName = "John",
                LastName = "Doe",
                Age = 30
            });
 
            string html = @"<style type = ""text/css""> .tableStyle{border: solid 5 green;} 
th.header{ background-color:#FF3300} tr.rowStyle { background-color:#33FFFF; 
border: solid 1 black; } tr.alternate { background-color:#99FF66; 
border: solid 1 black;}</style>";
            html += personList.ToHtmlTable("tableStyle", "header", "rowStyle", "alternate");
            this.webBrowser1.DocumentText = html;
        }


Then, I created an html string with all the different CSS styles to simulate a real life scenario where you'll actually have those classes in your CSS file. Finally, call the ToHtmlTable method, and set the webBrowser's DocumentText to the HTML. This is the result:





FirstNameLastNameAge
AlexFriedman27
JackBauer45
CloeO'Brien35
JohnDoe30


Yuck, those colors are nasty! But you get the idea. The nice thing is, since it's generic, and on IEnumerable, any collection of objects that you have can now be turned into an HTML table by calling this one method. Gotta love generics and reflection.

Monday, March 23, 2009

Calling unmanaged API's from within your C# app using P/Invoke.

No comments:
While the .NET Framework is HUGE and you generally can find anything you need to do, there are often times when you need to call unmanaged API's from within your code. For example, there are many great functions in the Windows API that simply have no wrapper or equivalent in the Framework. Or, say if you have a fully working and tested library that was written in unmanaged code (like C/C++) why rewrite the entire thing? Why not call into the existing library? That's where the idea of P/Invoke (Platform Invoke) comes into play. I'll demonstrate with a few examples:

The first one I'll show is actually a very simple one, but actually extremely useful. Many times when working in WinForms apps, I find myself needing a Console for debugging. It's much easier to do Console.Writeline's when there's an actual Console, rather than having to look in the tiny Output window in VS. Here's how you can do it. First, create a simple WindowsForm application and add a button on to the form. Then add these few lines of code:

        [DllImport("kernel32.dll")]
        public static extern bool AllocConsole();
 
        [DllImport("kernel32.dll")]
        public static extern bool FreeConsole();

You'll have to add this using statement at the top of your class:

using System.Runtime.InteropServices;

The "DllImport" attribute tells the CLR that this function lives outside the managed world. You then specify the dll where this function lives. You then just need to specify the function name and provide the signature. Here's what the actual AllocConole method looks like in the windows API:

C++
BOOL WINAPI AllocConsole(void);

So as long as you use the same name, it can map the function. You also need to make the method static, and mark it as extern.

Now, you can just call it like any other method. Add this code to the button1 click:

        private void button1_Click(object sender, EventArgs e)
        {
            AllocConsole();
            Console.WriteLine("Writing this to a console from a Windows App.");
        }

Run the program and click the button. You'll see a console window show up, and our message will be written to the console. The console will stick around though, as we never told it to go away. Add another button to your form and put this code in there:

        private void button2_Click(object sender, EventArgs e)
        {
            Console.WriteLine("Press any key to close the console.");
            Console.ReadKey(true);
            FreeConsole();
        }

Run it again, click the first button, then click the second. After you hit a key on your keyboard, the console will disappear. I'm only demonstrating this to give you an intro to P/Invoke, but you'll see, this AllocConsole stuff is actually real useful for debugging Windows Apps.

Now let's move on to another one that's a bit more complicated. In the C/C++ world, very often you'll find that functions take Structs instead of a list of parameters. I'm not a C++ guy myself, so don't ask me why, but that's the way it is. Therefore, in order to P/Invoke such a method, you need to recreate that struct in your C# app. Example:

If you've ever used any chatting program, you'll notice that when the chat window is minimized, if you receive an instant message, the minimized window in your taskbar starts to blink. There doesn't exist a way to do this in .NET unfortunately, therefore we will have to P/Invoke it. The Windows Function for this is called: FlashWindowEx. Now, if you click on that link, you'll notice that the signature for that method is:

BOOL WINAPI FlashWindowEx(

__in PFLASHWINFO pfwi
);
What on earth is _in and what's PFLASHWINFO??? Well, here's where it gets interesting. "_in" means that the parameter being passed in is actually a pointer to the parameter. Secondly, the PFLASHWINFO is a struct. On that page, you'll notice that in the documentation the PFLASHWINFO is a link that takes you to this page, which shows this:

typedef struct {

UINT cbSize;
HWND hwnd;
DWORD dwFlags;
UINT uCount;
DWORD dwTimeout;
} FLASHWINFO, *PFLASHWINFO;
Ok, we're getting somewhere, but looking at that list, (not being a C++ programmer) I can figure out UINT because we have uint in C#, but what's HWND? What's DWORD? How can I create a struct in C# if I don't know those datatypes? That's where you'll need this page. It's a great article on Code Project which has a huge list about halfway down that maps all the C++ data types to C#.

So, looking at that page, we can map everything we need. DWORD is a uint, and HWND is an IntPtr. (IntPtr is a .NET struct that basically represents a pointer. It's used very often when P/Invoking methods. For more info, see this article.)

So, let's create our struct:

    public struct FLASHWINFO
    {
        public uint cbSize;
        public IntPtr hwnd;
        public uint dwFlags;
        public uint uCount;
        public uint dwTimeout;
    }


Ok, we're getting somewhere. We have the struct, but remember, a POINTER to this struct was used to call the Windows API. Well, structs are valuetypes, so by passing a struct using the "ref" keyword, you're essentially doing the same thing. Therefore, we can now add this line to the top of our form:

        [DllImport("User32.dll")]
        public static extern bool FlashWindowEx(ref FLASHWINFO pfwi);

You'll notice that this time I'm calling User32.dll. How did I know that? Well, if you refer back to the original MSDN page that had the FlashWindowEx function declaration, you'll notice at the bottom of the page it says: DLL: User32.dll.

OK, so we set up the method and the P/Invoke, but how do we actually use this now? Let's add a third button to our Form. The basic premise will be when this button will be clicked, the window will minimize. Then, after about a second, i'll start blinking.

So, let's add a Flash method to our form:

        

        private void Flash()
        {
            FLASHWINFO pwfi = new FLASHWINFO();
            //assign the windows handle of our Form
            pwfi.hwnd = this.Handle;
            //size of the struct. Needed for the unmanaged world to allocated correct number of bytes
            pwfi.cbSize = Convert.ToUInt32(Marshal.SizeOf(typeof(FLASHWINFO)));
            //number of times to blink. We want max possible
            pwfi.uCount = uint.MaxValue;
            //the flash status. 2 = taskbar only
            pwfi.dwFlags = 2;
 
            FlashWindowEx(ref pwfi);
        }


First, look at thist page again. That explains what all the values in the struct represent. This way, we can know which values to assign to all the properties in our struct.

            FLASHWINFO pwfi = new FLASHWINFO();
            //assign the windows handle of our Form
            pwfi.hwnd = this.Handle;


So first we create an instance of the struct. Then, in Windows Programming, every Window has something that's called a "Handle". Here's a good explanation:

A handle is a reference for the operating system. It does not have the semantics of a programming reference but what it does do is allow the system resources to know what you are referring to when it is passed in an API call.
So, in .NET every Form has a Handle property that returns an IntPtr.

//size of the struct. Needed for the unmanaged world to allocated correct number of bytes
            pwfi.cbSize = Convert.ToUInt32(Marshal.SizeOf(typeof(FLASHWINFO)));


The next line is needed for the unmanaged world to know how many bytes to allocated for our struct. The Marshal class has alot of helper methods to interact with the unmanaged world.

//number of times to blink. We want max possible
            pwfi.uCount = uint.MaxValue;


The next piece is the uCount. This represents that number of times the icon should blink. We'll just assign it to the max possible. Our intention is to have it blink until the user brings the window back into view.

//the flash status. 2 = taskbar only
            pwfi.dwFlags = 2;


The next property is the dwFlags which according to MSDN is the flash status. If you look at that page you'll see that these are the options:

ValueMeaning
FLASHW_ALL
0x00000003

Flash both the window caption and taskbar button. This is equivalent to setting the FLASHW_CAPTION | FLASHW_TRAY flags.

FLASHW_CAPTION
0x00000001

Flash the window caption.

FLASHW_STOP
0

Stop flashing. The system restores the window to its original state.

FLASHW_TIMER
0x00000004

Flash continuously, until the FLASHW_STOP flag is set.

FLASHW_TIMERNOFG
0x0000000C

Flash continuously until the window comes to the foreground.

FLASHW_TRAY
0x00000002

Flash the taskbar button.

In our case we want just the icon to flash just in the tray. Therefore we set the value to 2.

FlashWindowEx(ref pwfi);

Finally, we just call the method.

At this point, the form will continue to blink. Therefore, we need a way to stop it. Let's create a StopFlashing method:

        private void StopFlashing()
        {
            FLASHWINFO pwfi = new FLASHWINFO();
            pwfi.hwnd = this.Handle;
            pwfi.cbSize = Convert.ToUInt32(Marshal.SizeOf(typeof(FLASHWINFO)));
            pwfi.uCount = uint.MaxValue;
            pwfi.dwFlags = 0;
 
            FlashWindowEx(ref pwfi);
        }

Really the same as before except the dwFlags is set to 0 which means stop. So, now here's the entired Form code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
 
namespace PInvokeTesting
{
    public struct FLASHWINFO
    {
        public uint cbSize;
        public IntPtr hwnd;
        public uint dwFlags;
        public uint uCount;
        public uint dwTimeout;
    }
 
    public partial class Form13 : Form
    {
        [DllImport("kernel32.dll")]
        public static extern bool AllocConsole();
 
        [DllImport("kernel32.dll")]
        public static extern bool FreeConsole();
 
        [DllImport("User32.dll")]
        public static extern bool FlashWindowEx(ref FLASHWINFO pfwi);
 
        public Form13()
        {
            InitializeComponent();
            this.Activated += new System.EventHandler(this.Form13_Activated);
        }
 
        public void Form13_Activated(object sender, EventArgs e)
        {
            this.StopFlashing();
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            AllocConsole();
            Console.WriteLine("Writing this to a console from a Windows App.");
        }
 
        private void button2_Click(object sender, EventArgs e)
        {
            Console.WriteLine("Press any key to close the console.");
            Console.ReadKey(true);
            FreeConsole();
        }
 
        private void button3_Click(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Minimized;
            this.Flash();
        }
 
        private void Flash()
        {
            FLASHWINFO pwfi = new FLASHWINFO();
            //assign the windows handle of our Form
            pwfi.hwnd = this.Handle;
            //size of the struct. Needed for the unmanaged world to allocated correct number of bytes
            pwfi.cbSize = Convert.ToUInt32(Marshal.SizeOf(typeof(FLASHWINFO)));
            //number of times to blink. We want max possible
            pwfi.uCount = uint.MaxValue;
            //the flash status. 2 = taskbar only
            pwfi.dwFlags = 2;
 
            FlashWindowEx(ref pwfi);
        }
 
        private void StopFlashing()
        {
            FLASHWINFO pwfi = new FLASHWINFO();
            pwfi.hwnd = this.Handle;
            pwfi.cbSize = Convert.ToUInt32(Marshal.SizeOf(typeof(FLASHWINFO)));
            pwfi.uCount = uint.MaxValue;
            pwfi.dwFlags = 0;
 
            FlashWindowEx(ref pwfi);
        }
 
    }
}

Run the program and click the button3. You'll see the window minimize, and start blinking. As soon as you bring it back up, it'll stop flashing.

This is just the tip of the iceberg with P/Invoke, but hopefully this gave you some idea as to what can be done.

Monday, March 16, 2009

New Features in C# 3.0 / .NET 3.5 Part 3

1 comment:
This is the third part of the New Features in C# 3.0 / .NET 3.5 series. Part 1 can be found here and Part 2 can be found here.

The next thing I'd like to cover is a new keyword introduced in .NET 3.5 which is the "var" keyword. From MSDN:

Local variables can be given an inferred "type" of var instead of an explicit type. The var keyword instructs the compiler to infer the type of the variable from the expression on the right side of the initialization statement. The inferred type may be a built-in type, an anonymous type, a user-defined type, or a type defined in the .NET Framework class library.
In simple terms, when declaring a local variable, you no longer need to specify what type of variable it is on the left hand side of the assignment call. For example:

   int x = 10;

is just the same as this:

   var y = 10;

It's important to note that this is NOT a dynamic type that's available in other languages like PHP or python. With dynamic types (which will be available in .NET 4.0) the compiler does NOT know at design time what Type the variable will be. It will be figured out at runtime. With C# type inference though, the compiler knows full well what the type will be. It can figure it out from what's on the right hand side. Now I know you're probably thinking "what's the point of this? how hard is it to just type a few extra letters?" Well, imagine if you have something like this:

Dictionary<string, List<StringBuilder>> dictionary = new Dictionary<string, List<StringBuilder>>();


Well don't you think it'd be neater if we had this?

var dictionary = new Dictionary<string, List<StringBuilder>>();

At first it may not seem like a big deal but you'll find yourself starting to use it quite often. The thing to point out though is that the "var" keyword can ONLY be used for variables that are local in scope. They can not be used for class level variables. This would NOT compile:

    public class MyClass
    {
        var myVariable = new StringBuilder(); //compile error
        public MyClass()
        {
            var varIable = new StringBuilder(); //this is fine
        }
    }

You're probably STILL thinking, "what's the use? Why bother??". Well, this leads me to the next new feature in .NET 3.5. The real reason these things were created was for something called "Anonymous Types". From MSDN:

Anonymous types provide a convenient way to encapsulate a set of read-only properties into a single object without having to first explicitly define a type. The type name is generated by the compiler and is not available at the source code level. The type of the properties is inferred by the compiler. The following example shows an anonymous type being initialized with two properties called Amount and Message.
Anonymous types allow you to create a new type on the fly. For example:

        public void MyMethod()
        {
            var myNewObject = new
            {
                stringProperty = "Hello, World!",
                intProperty = 1337,
                boolProperty = false
            };
        }

At this point, C# has actually created a new type for us with the read-only properties that we specified in our declaration of the Anonymous Type. Again, this type is only within the scope of this method, but we can now actually dot into myNewObject as if it were a real object from a concrete class. For example:

            var myNewObject = new
            {
                stringProperty = "Hello, World!",
                intProperty = 1337,
                boolProperty = false
            };
 
            Console.WriteLine(myNewObject.stringProperty); //output: "Hello, World!"
            Console.WriteLine(myNewObject.intProperty); //output: 1337
            Console.WriteLine(myNewObject.boolProperty); //output false

And this is what Intellisense looks like:



As you can see, Intellisense picks up all the properties of our Anonymous Type. The interesting thing here is that a concrete type is actually created for us by the compiler. By inspecting the IL this is what we find:



What's really interesting here, is that if somewhere else in your app you have another Anonymous Type that looks just like this one, the C# compiler is smart enough to only create one class of that Type. It has to be the exact same set of parameters with the same name and in the exact order.

To prove this, there's a known "hack" out there that allows you to actually return an anonymous type from a method (contrary to what I said before that Anonymous Types are only local in scope). Consider this:

        public object MyMethod()
        {
            var myNewObject = new
            {
                stringProperty = "Hello, World!",
                intProperty = 1337,
                boolProperty = false
            };
 
            return myNewObject;
        }

Our same anonymous type as before, only now we're actually returning this from a method. Now, here's the cool part:

        public T Cast<T>(object obj, T type)
        {
            return (T)obj;
        }

A generic method that takes Object as a parameter, then an object of type T as the second parameter. It then casts obj to the type of T. Here's how we can now use this:

       var obj = MyMethod();
       var myNewObj = Cast(obj, new { stringProperty = "",
intProperty = 0, boolProperty = false });



Now here's where we prove that C# only creates ONE class for that anonymous type. We passed in as the second parameter to the Cast method a new anonymous types with different values. However, since the parameters are the same and the order is the same, we can cast obj (the return value from our method) to the SAME TYPE as the new anonymous type. If C# created two separate classes, this would never work!

This isn't my trick, and I wouldn't recommend using this in production code, but it gets the point across.