Tag Archives: programming

What I’m doing to become a better developer

There was a meme going around about 5 steps people will take to become a better developer. I’m not a famous enough blogger to get tagged, but I’ll share my 2 cents anyway. There’s nothing like publicizing something to make you committed: 

  • Read more source code from other projects (especially .Net projects)

Now that I’ve started my own large, non-trivial application, more problems quickly become apparent–how do you structure an application, handle communication? The overall infrastructure becomes vitally important. Unlike DocView in MFC, .Net does not have a standard MVC-style architecture to build on top of.

It makes no sense to iterate over and over to come up with patterns that others have already solved well.

Projects I want to look at: Paint.Net, RSS Bandit, SharpDevelop, Rotor, Mono

  • Become a refactoring fiend

It takes a lot of work, but refactoring code whenever you can/should really pays dividends. I’m doing this in my current personal project, and even though it’s taken a few hours to do some of the major refactoring, it was worth it because implementing new features becomes nearly painless once the structure of the code allowed it. It’s a little harder to do at work, but I have done a little. I want to take this to the next level by always taking the time to restructure the existing code whenever the opportunity presents itself. Thankfully, I’ve spent a lot of time developing unit tests. This will help me use design patterns more thoughtfully, as well as become familiar with some of the more esoteric refactoring patterns in Martin Fowler’s Refactoring.

There are too many good books to name, but those are two of the best ones. I go through books quickly. Some books are worth reading over and over until the concepts become part of you. Of course, for that to happen, you have to actually implement the ideas into your projects. I definitely learned things in Code Complete my first time through that I have made part of me–so much so, that I probably couldn’t tell you what they were. But I know I could do better.

  • Exercise

Huh? That’s not related to programming! au contraire! Self-improvement is a lot more than learning more about your field–it’s training your body and mind to be in better shape. If I feel better, I think better. Now that I have my iPod nano and all the podcasts I could want, I have no excuse not to exercise more than I do. I’ve been getting better, but I have a ways to improve. A healthy body directly correlates to a healthy mind.

  • Build more original Lego models

Another one that isn’t really about programming?! Not so fast. I’ve built Legos for a while, but rarely have designed and built my own models. That needs to change. I have 12,000 Legos–I need to be exercising creativity, design processes, and hard work to achieve some original results. And I want to have fun.

Some other things I want to do:

These are other things I’m interested in trying out this year, but don’t have specific goals in mind yet:

  • Look into WPF — maybe good for UI for my BrickBuilder project?
  • learn more about COM. This has been slowly fading on the priority list. Is there a good reason to learn about COM these days, other than legacy support?
  • Continuous integration — I want to know more about it, but not sure how it would fit into our scenario at work. Once we get our staging server up, it might be a better fit.

Mouse tilt wheel horizontal scrolling in C#

In my current project, I’m using a custom ListView-like control to give my WinForms app a very rich interactive experience. This control does not implement mouse wheel scrolling like the Microsoft ListView implementation does so it was up to me to add it. You can use the knowledge in this article to implement full scrolling support in your own custom controls.

The custom component was derived from Control, which does provide the virtual function OnMouseWheel to handle vertical scrolling. The component also exposes the two scrollbars to manipulate.

First, take a look at Best Practices for Supporting Microsoft Mouse and Keyboard Devices, a good place to start learning about advanced mouse handling in Windows. Note that all of this requires IntelliPoint software to be installed.

Getting Started

Here’s some example code to get started with:

public class MyListView : GlacialComponents.Controls.GlacialList 
    { 

    }

Vertical Scrolling

As long as we’re talking about horizontal scrolling, let’s go ahead and discuss vertical scrolling with the mouse wheel. Add this override to the class:

protected override void OnMouseWheel(MouseEventArgs e)
        {
            base.OnMouseWheel(e);
           
        }

It’s overriding from the Control class, not GlacialList. Assuming you’ve read the MS documentation referenced about, you’ll know that the scroll message includes the number of ticks, which is usually a multiple of 120. We need to accumulate this number and then scroll our view a corresponding amount.

First, some class variables:

        private const int WHEEL_DELTA = 120; 
        private int _wheelPos = 0; 
        private int _wheelHPos = 0;

The _wheelHPos variable will be used later for horizontal scrolling. Then we modify our function to read like this:

protected override void OnMouseWheel(MouseEventArgs e)
        {
            base.OnMouseWheel(e);

            _wheelPos += e.Delta;

            while (_wheelPos >= WHEEL_DELTA)
            {
                ScrollLine(-1);
                _wheelPos -= WHEEL_DELTA;
            }

            while (_wheelPos <= -120)
            {
                ScrollLine(1);
                _wheelPos += WHEEL_DELTA;
            }
            Refresh();
           
        }

After we accumulate the value, we scroll one line per WHEEL_DELTA value. (This code could certainly be optimized, but I think this version is clear.) After the scrolling we tell the view to refresh itself. The Best Practices recommend handling partial-line scrolling. In my case, since I just need to manipulate the scrollbars by one unit at a time it’s not applicable, but I encourage you to understand their sample code.

The ScrollLine() function will be application-dependent. For this class, it just needs to modify the scrollbars that were provided.

private void ScrollLine(int numLines) 
        { 
            vPanelScrollBar.Value = Math.Max(vPanelScrollBar.Minimum,
                             Math.Min(vPanelScrollBar.Maximum, 
                vPanelScrollBar.Value + numLines)); 
        }

Horizontal Scrolling

That was fairly easy. Horizontal scrolling with the tilt-wheel is only a little more complex. This is because it’s not natively supported by the .Net Framework, and to a certain extent it’s not really supported on Windows XP. Full native support of the tilt wheel starts in Windows Vista.

Fortunately the IntelliPoint drivers fake it for us by sending our listview window a WM_MOUSEHWHEEL message anyway. Since .Net 2.0 doesn’t know what to do with this message (not sure about .Net 3.0), we need to take control of the message-handling and manually handle this message. The WndProc function is the function that handles all of this and it is virtual just for this purpose.

protected override void WndProc(ref Message m) 
        { 
            base.WndProc(ref m); 
            if (m.HWnd != this.Handle) 
            { 
                return; 
            } 
            switch (m.Msg) 
            { 
                case Win32Messages.WM_MOUSEHWHEEL: 
                    FireMouseHWheel(m.WParam, m.LParam); 
                    m.Result = (IntPtr)1; 
                    break; 
                default: 
                    break; 

            } 
        }

If you’ve done Win32 programming this will look very familiar, if a little out of place in .Net code. There are a few things going on here. First of all, you must call the base-class version of WndProc or your window will be very unexciting and quite broken. Take a look at WndProc for any control in Reflector to see all the work it’s doing.

Next, there is the Win32Messages class. This is an abstract class of my own creation that serves merely as a place to put definitions for Windows’ message definitions.

abstract class Win32Messages 
    { 
        public const int WM_MOUSEHWHEEL = 0x020E;//discovered via Spy++ 
    }

So how did I know it was supposed to be have the value of 0x020E? Well, I could look in the Vista SDK where it’s defined, or I could read the Best Practices document referenced before. I didn’t find that page until after I had finished this implementation and I just used Spy++ to discover the messages coming to my window when I hit the tilt button:

SpyHorizTiltWheelMsg

Before we get to the FireMouseHWheel function, notice that m.Result is set to 1. This is because the docs state that the message handling must return 1 to indicate to Intellitype that we’ve handled the message.

There are two versions of this function. One takes the raw WPARAM and LPARAM values from the message and the other takes more meaningful values. As you can guess, one should probably call the other.

        public event EventHandler<MouseEventArgs> MouseHWheel; 
        protected void FireMouseHWheel(IntPtr wParam, IntPtr lParam) 
        { 
            Int32 tilt = (Int16)Utils.HIWORD(wParam); 
            Int32 keys = Utils.LOWORD(wParam); 
            Int32 x = Utils.LOWORD(lParam); 
            Int32 y = Utils.HIWORD(lParam); 

            FireMouseHWheel(MouseButtons.None, 0, x, y, tilt); 
        } 

        protected void FireMouseHWheel(MouseButtons buttons,
            int clicks, int x, int y, int delta) 
        { 
            MouseEventArgs args = new MouseEventArgs(buttons,
                                         clicks, x, y, delta); 
            OnMouseHWheel(args); 
            //let everybody else have a crack at it 
            if (MouseHWheel != null) 
            { 
                MouseHWheel(this, args); 
            } 
        }

I declare an event that takes the same type of arguments as the vertical MouseWheel handler above. The first FireMouseHWheel function converts wParam and lParam into the real values according to the specification given. I ignore the keys value and pass the others to the second function which calls my handler and also raises the event to give class consumers the opportunity to be notified as well.

To “crack” the values, I have some simple utility functions:

abstract class Utils 
    { 
        internal static Int32 HIWORD(IntPtr ptr) 
        { 
            Int32 val32 = ptr.ToInt32(); 
            return ((val32 >> 16) & 0xFFFF); 
        } 

        internal static Int32 LOWORD(IntPtr ptr) 
        { 
            Int32 val32 = ptr.ToInt32(); 
            return (val32 & 0xFFFF); 
        } 

    }

The OnMouseHWheel is very similar to its cousin for vertical scrolling:

protected virtual void OnMouseHWheel(MouseEventArgs e) 
        { 
            _wheelHPos += e.Delta; 
            const int pixelsToMove = 3; 
            while (_wheelHPos >= WHEEL_DELTA) 
            { 
                ScrollHorizontal(pixelsToMove); 
                _wheelHPos -= WHEEL_DELTA; 
            } 

            while (_wheelHPos <= -120) 
            { 
                ScrollHorizontal(-pixelsToMove); 
                _wheelHPos += WHEEL_DELTA; 
            } 
            Refresh(); 
        }

The pixelsToMove variable is noteworthy because it’s hard-coded to 3. It is kind of arbitrary because it really depends on the application and how the scrollbars are used. I’ve set it to 3 as a good value for my application.

The ScrollHorizontal function is similar to ScrollVertical and is also application-specific:

private void ScrollHorizontal(int amount) 
        { 
            hPanelScrollBar.Value = Math.Max(hPanelScrollBar.Minimum,
                   Math.Min(hPanelScrollBar.Maximum - hPanelScrollBar.mWidth, 
                hPanelScrollBar.Value + amount)); 
        }
 

Potential Issues

The Best Practices document states:

When an application receives a WM_MOUSEHWHEEL message, it is responsible for retrieving the characters-to-scroll user setting (SPI_GETWHEELSCROLLCHARS) by using the SystemParametersInfo API. This setting will not be available on Windows 2000 and Windows XP, so use the value of 1. IntelliType Pro and IntelliPoint will maintain a substitute value for the characters-to-scroll user setting and send the correct number of WM_MOUSEHWHEEL messages.

(Emphasis mine) Notice that last phrase. IntelliPoint can potentially send multiple WM_MOUSEHWHEEL messages for a single tilting action. This means that my strategy of refreshing on every message might not be entirely wise. It really depends on how long it takes to refresh the control. If it can be done smoothly and instantly, then this might not matter. Otherwise, you might need to come up with a way of accumulating ticks over multiple messages and scrolling all at once, perhaps after a timer expires. In my case, I think I’ll ignore this issue for now. I don’t really care if the control refreshes too often.

Have fun adding horizontal scrolling to your app!

Simulating a Server in .Net (C#)

I recently had a need to simulate an FTP server connection in some unit tests. Rather than developing a full test-server, for this purpose, I could easily simulate an FTP stream by creating it in memory, and then passing that stream to the functions  that expect it:

public Stream CreateTestStream(string text) { byte[] buff = Encoding.ASCII.GetBytes(text); return new MemoryStream(buff, false); }

This function merely accepts text (FTP is text-based after all), and returns a memory stream. I can then use it in a unit test:

[Test] [ExpectedException(typeof(FtpException),"InvalidResponse")] public void FtpResponse_Constructor_BadStream_InvalidCode() { using (Stream s = CreateTestStream("NoErrorCode")) { FtpResponse response = new FtpResponse(s); } }

Setting the minimum Windows version supported (C++)

Recently, I was trying to use the Shell function SHGetFolderPath. Despite including the correct header file (shlobj.h), the compiler wasn’t recognizing it. My code looked like this:

CString strPath; HRESULT hResult = SHGetFolderPath( NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, strPath.GetBufferSetLength(MAX_PATH)); strPath.ReleaseBuffer();

What I did was lookup the definition of SHGFP_TYPE_CURRENT in shlobj.h, and found this:

#if (NTDDI_VERSION >= NTDDI_WIN2K) SHSTDAPI_(void) SHFlushSFCache(void); typedef enum { SHGFP_TYPE_CURRENT = 0, // current value for user, verify it exists SHGFP_TYPE_DEFAULT = 1, // default value, may not exist } SHGFP_TYPE; SHFOLDERAPI SHGetFolderPathA(HWND hwnd, int csidl, HANDLE hToken, DWORD dwFlags, __out_ecount(MAX_PATH) LPSTR pszPath); SHFOLDERAPI SHGetFolderPathW(HWND hwnd, int csidl, HANDLE hToken, DWORD dwFlags, __out_ecount(MAX_PATH) LPWSTR pszPath); //etc...

It’s that first line that got me. My DDI version wasn’t >= that of Win2k’s. The solution is to modify the stdafx.h file. Before, it read:

#ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0400 #endif

That 0x0400 defines Windows 95 as the minimum supported OS. I don’t really care about 9x support, so I changed it to read like this:

#ifndef _WIN32_WINNT //define Windows 2000 as minimum necessary OS #define _WIN32_WINNT 0x0500 #endif

Importance of disposing MailMessage objects

Always, always, always follow the suggested usage patterns of disposable objects. I had a strange problem recently where e-mail messages with attachments weren’t releasing the lock on the files for a long time. I was using the System.Net.Mail namespace, specifically the Attachment and MailMessage classes.

Disposable objects represent resources not directly under control by the CLR–and this includes SMTP connections. By not calling dispose, the mail message was just sitting around, not getting sent. Why this is the case when I explicitly call SmtpClient.Send is unclear. The main symptom of this problem was that files that I attached to the e-mail message were still locked when I tried to delete them immediately after the send.

Something like this will do:

using (MailMessage msg = new MailMessage()) 
{ 
    msg.Attachments.Add(...); 
    client.Send(msg); 
}

Changes in .Net 1.1. and 2.0 E-Mail classes

I recently (re?)learned a harsh lesson at work. We migrated a critical application’s e-mail client code to use System.Net.Mail‘s classes instead of those in the deprecated System.Web.Mail.

After doing this, we immediately had three problems, mostly with the Attachment class:

  1. Our automated test software could no longer read the attachments
  2. Attachments started having names of Directory_Directory_FileName (they were just Filename)
  3. The software could no longer delete the attachment files from disk after they were e-mailed (the file was still in use).

With problem 1, it turned out that the default encoding in the old MailAttachment class was 7Bit and the test program (which I didn’t write) was directly scraping the mail queue (on a Linux system) and reading the encoded text, looking for recognizable tokens. The new class’s default encoding was Base64–gibberish, to this test program. It wouldn’t really matter to our end-users, but the taking the “easy” way out in writing the test program locked us into an encoding. It just so happens, though, that 7Bit encoding is preferable in our circumstances, even for end-users (Base64 adds significant e-mail overhead–some of our users pay by kilobyte).

The 2nd problem took me a little longer to figure out. At first I thought it was a bug in the attachment naming code, but I couldn’t find anything either in code or the file system. It turns out that the name of the file that the Attachment class is giving includes the directory structure in the name–this seems quite odd–I mean, how often do you want a file name like that? So I manually set the ContentDisposition.FileName property to be just the filename.

I still haven’t completely figured out #3. I think it’s because the MailMessage class is locking the file during send, and not releasing it as early as the old class. In any case, I haven’t directly solved the problem, just come up with a semi-elegant workaround.

Lessons:

  1. Don’t assume default settings are the same across framework upgrades.
  2. Build unit tests to test the assumed stuff–even the stuff controlled by the framework. Don’t assume it’s doing exactly what you want with default settings.
  3. Most importabtly, if your functionality depends on specific settings, then explicitly specify them–don’t ever leave them to chance.

Thankfully, these were relatively easy to diagnose and caused minimal to moderate impact.

Why you shouldn’t catch System.Exception

There are probably many reasons, but my favorite is that, if you are resorting to catching anything at all, you probably don’t understand the code well.

For example, in complicated parsing of text, it is often easier to just put a huge try {…} catch (Exception ex) {…} around the entire thing, rather than take the time necessary to understand how your code works, and where exactly things could go wrong.

It is much better to go through the code line-by-line and prove to yourself that that there are only a few places of possible unknown exception behavior. Obviously, exceptions are meant to catch things you can’t reliably predict, but in most code, there are large areas of things like string manipulation, arithmetic, or other simple procedures, that will not throw an exception. It makes sense to delineate these areas, and surround only the trouble spots with try-catch.

For example, look at this fragment:

string strDelimiters = ":, ;"; 
try 
{ 
    string[] tempStrings = message.Split(strDelimiters.ToCharArray()); 
    string[] subStrings = new string[tempStrings.Length]; 
    int numSubStrings = 0; 
    //remove empty substrings 
    for (int i=0;i<tempStrings.Length;i++) 
    { 
        if (tempStrings[i] != null && tempStrings[i].Length > 0) 
        { 
            subStrings[numSubStrings] = tempStrings[i]; 
            numSubStrings++; 
        } 
    } 
...

 There is no reason to surround this with a try {} catch{} block. Doing so lets you off the hook of digging into this and realizing how bad it is, especially with .Net 2.0. 🙂

Visual Studio 2003 and 2005 Default Keyboard Shortcuts Cheat Sheet

My first book, C# 4.0 How-To is now shipping! If you like tips you can use, check it out!

I wanted to have a quick-reference sheet available to help me learn the Visual Studio keyboard commands. Surprisingly, I couldn’t find a handy printable reference. So I made one. It doesn’t contain ALL the shortcuts. For that, you can go to the online reference or this code that prints out all of your existing shortcuts.

If you just want a two-page reference sheet, handy to print front-to-back, to help you learn the shortcuts, download the PDF I created.

A screen shot of it…

Visual Studio 2003 & 2005 Default Keyboard Shortcuts Screenshot

Queue multiple GUI updates into a single update event (C# .Net)

I’m writing a simple utility that involves scanning a hard disk and updating a display with the latest status. There are potentially many, many, many, many, MANY changes that happen to the display in very quick succession and sending an update event which triggers a screen refresh for every single state change would be an enormous bottleneck.

I implemented a simple queueing scenario where all the updated objects are queued for up to 200ms before being batched into a single event. The GUI can then update the display for every changed object all at once.

First, the queue:

private DateTime lastUpdateSent = DateTime.MinValue; //queue updated folders to limit the number of screen updates List<FolderObject> updatedFoldersQueue = new List<FolderObject>();

A simple list. Then I have a function which is called to handle the actual event generation:

private void FireUpdate(FolderObject folder) { if (this.OnFolderUpdated!=null) { try { if (!folder.Dirty) { folder.Dirty = true; updatedFoldersQueue.Add(folder); } TimeSpan diff = DateTime.Now - lastUpdateSent; if (diff.TotalMilliseconds > 200){ FolderUpdatedEventArgs args = new FolderUpdatedEventArgs(updatedFoldersQueue); int numFolders = updatedFoldersQueue.Count; //reinitialize queue updatedFoldersQueue = new List<FolderObject>(numFolders); OnFolderUpdated(this, args); Thread.Sleep(0); lastUpdateSent = DateTime.Now; } } catch (Exception ex) { System.Diagnostics.Trace.WriteLine(ex.Message); System.Diagnostics.Trace.WriteLine(ex.StackTrace); } } }

The folder.Dirty flag merely prevents a folder from being queued twice. The TimeSpan diff is the important bit. By checking the time difference between now and the last updated time, we can ensure that updates only get sent as often as the display–and our eyes–can handle them. The Thread.Sleep(0) ensures that the GUI thread gets a chance to draw–this is supposed to be interactive, after all.

Don’t use CArchive with native C++ type bool

I recently ran into an issue where I was trying to serialize a bool variable from a CArchive object.

Archiving it out, with this code, works fine:

//CArchive ar;
bool bFill;
ar << bFill;

But this code:

ar >> bFill

has problems. It compiles fine under Visual Studio 2003, but errors out under Visual C++ 6 with this error:

C2679: binary ‘>>’
: no operator defined which takes a right-hand operand of type ‘bool’
(or there is no acceptable conversion)

Very weird. There is some explanation here.

My resolution? Use BOOL instead. Sure, it’s actually an int and takes 4 bytes, not 1, but that’s a not a big deal in this case. And it’s more clear than using BYTE.