Redirecting events from one control to another is quite easy. I
recently needed it for an application that uses a number of
ComboBoxes to filter data in a DataGridView. It was very
confusing to the user when she selected an item in the ComboBox
and subsequently tried using the mouse wheel to scroll through
the data, that it would be the ComboBox, and not the DataGridView
that would be scrolling.
I decided to make a special ComboBox that would redirect Mouse
wheel events to the DataGridView, instead of trying to fix it by
manipulating focus. Manipulating focus gives you nothing but
problems in my experience.
The class i implemented for this solution just overrides the
WndProc function, which handles all the messages sent to the
control. It then reroutes mouse wheel events to another control
(the reciever) through the Win32 API function SendMessage.
That’s it…
public class ComboBoxMWRedirect : ComboBox { [DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern IntPtr SendMessage( IntPtr hWnd, int message, IntPtr WParam, IntPtr LParam); private const int WM_MOUSEWHEEL = 0x020A; private Control _reciever; //needed for designer support private ComboBoxMWRedirect() {} public ComboBoxMWRedirect(Control reciever) { _reciever = reciever; } protected override void WndProc(ref Message message) { if (message.Msg == WM_MOUSEWHEEL) { //route mouse wheel messages to the reciever SendMessage( _reciever.Handle, message.Msg, message.WParam, message.LParam); } else { //route all other messages on to the base class base.WndProc(ref message); } } }
Now to have one of your ComboBoxes redirect the mouse wheel, just
use one of these instead, and specify the recieving control when
you call the constructor. If, for instance, i want to redirect to
a DataGridView calle dataGridView1 i would construct the
redirecting ComboBox like this:
ComboBoxMWRedirect cb = new ComboBoxMWRedirect(dataGridView1);
The code can also be used to avoid the Mouse wheel event
altogether. Just change the WndProc overridde to the code below,
and mouse wheel events will be ignored.
protected override void WndProc(ref Message message) { //avoid mouse wheel events if (message.Msg != WM_MOUSEWHEEL) base.WndProc(ref message); }
Overriding WndProc gives you a lot of power and control over what happens in your application. This particular (very limited) example handles MouseWheel events on a ComboBox, but you can really use this to do a lot of very powerful stuff, like disabling the keyboard or parts of it, routing messages to other controls, broadcasting messages to have several controls react to the same message, etc. etc.
Logitech’s SetPoint software is causing severe problems for
people using ActiveSync to sync with their mobile devices.
The incompatibility between SetPoint and ActiveSync causes
programs running on the affected computer to loose focus for
about half a second every four seconds or so – making it next to
impossible to work on the computer.
The problem seems to be caused by a Microosoft Outlook process
that is started in the background by ActiveSync when ActiveSync
tries to sync with the connected device. It is really between
this background Outlook process and the Logitech SetPoint
software the incompatibility lies. They have a really hard time
existing at the same time.
Luckily there are a few solutions.
This solution really is as simple as it sounds. If Outlook runs
already when the device is plugged in ActiveSync will hook itself
up to the existing Outlook instance which doesn’t cause the focus
problems with SetPoint.
For most users this will be the ideal solution, since most people
that use Outlook as their mail/contacts/etc. program tends to
have it running all the time anyway. In fact, many people are
probably using this solution already without even knowing it
making them happily unaware of how crappy a piece of software
SetPoint really is.
This solution is admittedly not very elegant – but it will work.
This solution may seem very crude, but it is the one i usually end up doing when i need to sync to backup my contacts every once in a while.
This solution is ideal for those of you that really only plugin the device to recharge it (like me most of the time). When ActiveSync is set up to not sync anything, it will actually still sync the clock, but the main thing is – it wont fire up the background Outlook process that is the source of the problem…. Problem solved – If you don’t need the sync’ing.
Logitech and Microsoft call each other and solve the problem…..
I have presented a few solutions to this curious problem. A quick search of this problem on google will reveal numerous frustrated Logitech users dating back many years. It seems that neither Microsoft nor Logitech have any interest in solving this problem. It is a real shame since it has scared of people from buying Logitech products. They have some of the best hardware available on the market, but it is shamelessly ruined by poorly designed software.
Whenever your C#/.NET DataGridView reaches a certain size, it
tends to get really slow to scroll. Depending on the speed of
your computer this may be more or less noticeable. In an
application i did for a client this became a real problem due to
a combination of lots of DataGridView cells and fairly slow
computers.
Luckily the solution turned out to be simple…
Turning on double buffering seems to solve the problem. Normally double buffering would only help reduce flickering, since painting is being done to an off-screen buffer, but for the DataGridView it also significantly reduces the amount of functions being called internally in the DataGridView – thus reducing processor load and increasing speed. (statistics gathered with the Eqatec Tracer)
For some reason Microsoft has decided to hide the DoubleBuffered
property from DataGridView. Luckily you can set it anyway with
reflection.
public static class ExtensionMethods { public static void DoubleBuffered(this DataGridView dgv, bool setting) { Type dgvType = dgv.GetType(); PropertyInfo pi = dgvType.GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic); pi.SetValue(dgv, setting, null); } }
Just drop the above class into your project somewhere, or add the
function to your existing extension methods.
The extension method allows you to set the DoubleBuffered
property on your DataGridView in the following manner:
dataGridView1.DoubleBuffered(true);
You now have a smooth scrolling DataGridView
Thread priorities in the .NET framework are more complex than many developers think. Setting Thread priority is more than just adjusting the ThreadPriority of a Thread. You also have to take into account the priority of the process to which the threads belong.
Setting ThreadPriority to one of the values possible with C# will
only shift the priority of the thread up and down within a class
of priorities shared by the whole process. This means that even
setting ThreadPriority to ThreadPriority.Highest will not
actually give the thread a high priority, compared to the system
processes. It will only give the thread a high priority compared
to other threads belonging to comparable processes.
I”l try to make it a bit clearer with this little css/ascii
illustration
In C# processes start with normal priority, so setting ThreadPriority.Highest under normal conditions wont make the thread higher priority than ThreadPriority.Lowest in a process running with a high priority class.
Take a look at this code:
class Program { static void Main(string[] args) { Thread t = new Thread(threadFunc); Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.RealTime; t.Priority = ThreadPriority.Highest; t.Start(); Console.ReadLine(); t.Abort(); } static void threadFunc() { while (true) {} } }
This code will make a thread/process that has the highest
possible priority you can set with C#. Luckily i have a dual-core
processor – otherwise that code would have frozen my computer.
Now it only uses up one of my cores frantically checking if true
is still true…
The magic here lies in assigning ProcessPriorityClass.RealTime to
the current process. Note that this is done in a process-wide
scope, and all the threads in the process will have their
priorities adjusted to fit in the new priority range. You can not
have threads with extremely high and extremely low priorities
within the same process.
Do not run off and adjust the priorities of all your programs, to
get the processing time they rightly deserve. Fixing problems by
raising priorities are very often a symptom of some greater
underlying problem in your code, and the correct way of fixing
things are most often to remove the bottlenecks in your program,
and leave the priorities alone. This holds especially true for
ProcessPriorityClass.RealTime, since this will potentially block
execution of critical system stuff like garbage collection or
keyboard and mouse input.
I would recommend against using anything higher than
ProcessPriorityClass.High
I used to use voluntary fall through a lot in switch statements in C and C++. In C# it is no longer as easy to do as before, since all cases of a C# switch are required to end with either break or goto. You can still do voluntary fall through. You just need to be very specific about it.
You can use the goto statement to jump from one case to another
in a C# switch. Just replace the usual break statement with a
goto pointing at the next case, and you have voluntary
fallthrough.
int i = 0; switch (i) { case 0: Console.Write("Voluntary fallthrough "); goto case 1; case 1: Console.Write("is still "); goto default; default: Console.Write("possible"); break; }
This code will print out “Voluntary fallthrough is still possible” on the console.
I have always been a big fan of goto statements… Not really
because of their usefulness, but more because everyone is always
hitting on them. It is a bit like cheering for the underdog in a
football match, which i almost always do. I have had a principle
of having at least 1 goto statement in all applications i have
done for some years now, and with voluntary fall through i may
actually have found a reasonable excuse for them
.
Here’s a few general guidelines when working with strings:
The StringBuilder is an often overlooked class,
that can be used to solve a lot of performance problems in your
applications.
To give an example of how ineffective the basic string can be,
take a look at the following code that builds 2 large strings by
concatenating 1000 times to the same string using String and
StringBuilder:
string s = string.Empty; for (int j = 0; j < 1000; j++) { s += "Test of string performance."; } StringBuilder sb = new StringBuilder(); for (int j = 0; j < 1000; j++) { sb.Append("Test of string performance."); }
Performance is measured on my HTC S710 moblie phone. The performance difference is very noticeable.
StringBuilder is almost 70 times faster than String in this particular example and initializing the StringBuilder with enough capacity up front will shave another 2ms off. I have done tons of optimizations on Compact Framework applications over the years, and the first thing i usually do is replace String with StringBuilder in code similar to the above example.
Strings in the .NET framework are immutable – meaning that once
they are created they can not be changed. It is a design decision
from the .NET framework designers, that allows for a lot of
optimizations, but also cost performance under certain
circumstances.
This is the main reason the String concatenation from before is
so slow. Every time the strings are concatenated, a new String is
created, and the old one is left for the garbage collector. At
least a thousand strings of increasing size are created, copied
and garbage collected for no good reason. It is amazingly
ineffective.
The StringBuilder is the thing to use, when handling and
manipulating large strings. It holds the string in an internal
array that it grows as needed. This enables a very fast append
that only rarely allocates anything new. In my test the
StringBuilder initially had a capacity of 64 bytes, and grew to
double size whenever needed, but implementations may vary.
This behaviour means that you can optimize performance even
further by initializing the StringBuilder to a size that is
slightly larger than what you expect the final string to be –
thereby removing the need to ever re-allocate.
I always assumed that using String.Format() to splice strings
with variables was the fastest way of doing it. Tests show,
however, that it is not…
I have made test of 4 different ways of accomplishing the same
thing:
//using string string x = "Test of string performance." + 1 + 2 + "hello"; string x = string.Format("Test of string performance.{0}{1}{2}", 1, 2, "hello"); //using StringBuilder sb.Append("Test of string performance.").Append(1).Append(2).Append("hello"); sb.AppendFormat("Test of string performance.{0}{1}{2}", 1, 2, "hello");
The results are similar for both the String and StringBuilder. Using the +operator or chained appends is roughly twice as fast as using the Format() method. This came as a bit of a surprise to me.
I programmed a Windows CE application last month that had as a
requirement that only one instance could run at the same time.
Had it been Windows Mobile, this had been handled by the OS, but
on Windows CE you have to take care of this yourself.
I was a bit surprised that there is no easy way of accomplishing
this. Searching the internet gave me basically no easy answer
either, but there seems to be 3 standard ways of accomplishing
this.
Obviously the first two have the problem that they may break the
program, if the program exits without resetting the
file/registry-key used as a pseudo-mutex. They are also very
crude and not very elegant…. But that’s up to personal taste i
guess.
I went for the third choice; The named mutex.
The .NET Compact Framework does not support named mutexes.
Luckily Windows CE does however, and it can be imported through a
few functions in coredll.dll.
A named mutex is an object created by the OS with a name
specified on creation. The actual functionality of the object is
not very interesting right now. The interesting bit is that only
one object can exist with any given name. If you try to create
another object with the same name, you get an error.
Basically, if you create a named mutex with the name of the
application itself, this can be used to ensure that only one
instance of the application can be run.
I decided to wrap it all up nicely in a class, so that it will be easy to use. The class is called SingleInstanceApplication, and here is what i came up with:
using System; using System.Windows.Forms; using System.Runtime.InteropServices; using System.Reflection; namespace Bitmatic { static class SingleInstanceApplication { [DllImport("coredll.dll", SetLastError = true)] public static extern IntPtr CreateMutex(IntPtr Attr, bool Own, string Name); [DllImport("coredll.dll", SetLastError = true)] public static extern bool ReleaseMutex(IntPtr hMutex); const long ERROR_ALREADY_EXISTS = 183; public static void Run(Form frm) { string name = Assembly.GetExecutingAssembly().GetName().Name; IntPtr mutexHandle = CreateMutex(IntPtr.Zero, true, name); long error = Marshal.GetLastWin32Error(); if (error != ERROR_ALREADY_EXISTS) Application.Run(frm); ReleaseMutex(mutexHandle); } } }
Feel free to steal….
The class imports the two native functions for creating and
destroying mutexes, and has only a single public function.
The Run function tries to create a mutex with the name of the
application. It then checks the error code returned, to see if
the mutex already exists, and if it doesn’t; starts the
application. Finally it releases the mutex.
Very simple, and quite a bit more elegant than the file/registry
based solutions.
Using the class is very very simple. Just add the class itself to your project, open up Program.cs and replace:
[MTAThread] static void Main() { Application.Run(new Form1()); }
with:
[MTAThread] static void Main() { SingleInstanceApplication.Run(new Form1()); }
You only really changed one line, and now you have an application that is guaranteed to run only as a single instance.
Many of my projects use a lot of secondary files. It can be images, icons, xml-files, text, sound, whatever…. These files pose a couple of problems for me:
Luckily there is a fairly easy solution to parts of these problems. Embed the file in the assembly.
The actual embedding of a file in an assembly in Visual Studio
2008 is very easy indeed. You just add the file to the project,
and set the build action to “Embedded Resource”.
The compiler will then automagically embed the file in the
assembly, where it will be accessible during runtime, to use as
you wish. Of course this will make your assembly grow, and with
many files, it may grow a lot, but this is usually no problem.
You can embed any type of file, and you can arrange the files any
way you want in project folders and the like.
Getting the file out of the assembly is almost as easy as getting
it in there. It uses functions from the System.Reflection to
access the assembly itself, so adding a “using
System.Reflection;” to your code is advisable.
There are basically two functions worth noting here:
So getting hold of the first resource in an assembly is as easy as:
Assembly A = Assembly.GetExecutingAssembly();
string[] names = A.GetManifestResourceNames();
Stream S = A.GetManifestResourceStream(names[0]);
The above example should get the point across. It is very easy to
gain access to an embedded resource as you would access any
file.
A more practical example, is using an embedded resource file to
set the image of a PictureBox control. It could look like this:
Assembly A = Assembly.GetExecutingAssembly();
Stream S = A.GetManifestResourceStream("MyProject.Images.jakob.gif");
pictureBox.Image = Image.FromStream(s);
In the example here, the actual name of the resource is shown. “MyProject.Images.jakob.gif” is the name of a resource called “jakob.gif” belonging to the project named “MyProject”, and placed in a project folder with the name “Images”. This is a fairly ease naming convention, that makes all resource names unique and easy to figure out. If you ever have doubts about the name of a resource, just call GetManifestResourceNames(), and it will tell you the names.
I’m going to finish by showing you a nice trick, that shows of the functions i outlined above. It is a function that iterates through all the resources in an assembly, and saves them to disk. It handles the files as raw byte arrays, so it should work with any file. I have tested it on gif, zip and pdf files, and it works like a charm.
private void SaveAllResources() { Assembly A = Assembly.GetExecutingAssembly(); string[] names = A.GetManifestResourceNames(); foreach (string filename in names) { Stream S = A.GetManifestResourceStream(filename); byte[] rawFile = new byte[S.Length]; //Read the data from the assembly S.Read(rawFile, 0, (int)S.Length); //Save the data to the hard drive using (FileStream fs = new FileStream(filename, FileMode.Create)) { fs.Write(rawFile, 0, (int)S.Length); } } }
Have fun embedding
Just wanted to share with everyone that there is a .NET Profiler that works with the Compact Framework. It is made by a Danish company called Eqatec and best of all; It is completely free.
I have been looking for something like this for several years,
but until the Eqatec profiler, no profiler has been able to
profile mobile applications. When working with the Compact
Framework you often find yourself in situation where performance
is an issue. Many times you can make educated guesses as to where
the bottlenecks may be, but at other times you are left pretty
clueless.
Attach a decent profiler, and your bottlenecks will be clear as
ice.
When the Eqatec profiler was released I immediately put it
into work with profiling an application that had some performance
issues during initial startup. We had tried solving these by
guesswork, but it hadn’t helped a lot.
Within 2 hours of attaching the profiler, I had cut the startup
time to a fraction of what it was before.
There is a small issue that you need to be aware of with this profiler. Because of the way it works, by instrumenting the code, it adds a little bit of overhead to every function call. This means that small functions that get called a lot will appear to be more time consuming than they really are, because most of the time used is actually the overhead. This is something to look out for, when deciding which functions to try to optimize. It would be really nice if Eqatec could find a way to compensate for this overhead.
Other than that the profiler works like a charm. And by the way – I am not paid to write this, I just like the product a lot.
With the .NET framework it has become very easy to
programmatically download content from the internet. Using the
WebClient class from the System.Net downloading a file from the
net becomes as easy as specifying the address to download.
There are several different ways to accomplish this depending on
the type of file you want to get, and also the content of the
file.
The following code uses a WebClient to download the file returned
by http://bitmatic.com. The file is returned as a string, so it
can be directly assigned to, for instance, a RichTextBox. With
basically one line of code you have built yourself a (very)
primitive web-browser. The method is very good if you just want a
simple textual presentation of a web-content, or you need to work
with the content in a textual manner with regular expressions or
something similar.
using (WebClient client = new WebClient()) { richTextBox.Text = client.DownloadString("http://bitmatic.com"); }
The WebClient object is scoped with the “using”-keyword. This is because it uses ressources that needs to be disposed properly. You could of course just ignore this and let the garbage collector dispose of it at some indefinite time, but that way you will run the risk of running out of ressources before the garbage collector cleans up (and don’t even think about calling the garbage collector manually… just don’t). You could also call client.Dispose(), but i mostly prefer the “using” syntax.
Downloading and saving a file to your local filesystem is equally
easy. Just supply an address and a filename to the DownloadFile
method, and you have downloaded a file. You can download both
using http and ftp with this method. The framework will handle
this for you in a transparent way.
using (WebClient client = new WebClient()) { client.DownloadFile("http://bitmatic.com", "bitmatic.html"); }
This code saves the content at http://bitmatic.com in a file called “bitmatic.html” on the local file system.
Lastly i want to mention a method that returns the content as a
byte array. This will mostly be usefull for binary files, since
the text encoding may be lost when using this method. You could
look into the ResponseHeaders property of the WebClient after
getting the data, they may contain information about encoding if
the content was a text file, but really, you should just use
DownloadString for text files.
using (WebClient client = new WebClient()) { byte[] bArr = client.DownloadData("http://bitmatic.com"); }
The WebClient is a very powerfull class, and the tiny code examples above should only serve as an appetizer. The class also allows you to do all the operations asynchronously, and perform uploads as well as downloads. If you start to look into modifying the headers that are sent you could get really creative. Take a look at the msdn article about WebClient for further inspiration.