One of my drivers was to seperate out the actual processing code from the UI code. This is mainly because I ahve a tendency to jam all the code into the Main (or whatever) .pas file.

I didn't do a thread approach, as I have never used threats before and haven't quite got my head around them. So how I handled the UI updates/responses was to do a couple of thing, first I declared a custom event handler as:

  TCountChangeEvent = procedure (Sender: TObject) of object;
I then declared a property of my processing class as an instance of that. So:

property CountChange: TCountChangeEvent read FCountChange write SetCountChange;
This way when my processing class made a change to the word count I'd fire an event. I could have used a TNotifyEvent but I wanted to try creating a custom event.

The next thing I did, which isn't strickly a good thing, was the declare my Constructor as:

Constructor Create(AFileName: String; AOwner: TApplication);
I did this so I could issue ProcessMessages commands, where if I had used a thread I wouldn't have to do such a thing.

I came across an issue I don't like, though it might be corrected in D2007. I used the
if x in y then DoSomething;
Where Y is a set.

The probelm is you can't do something like
if x not in y then DoSomething;
What I also considered was how I was going to store the word count, I decided on a class (definitely overkill), however because I decided on a class I could do the following:
  idx: Integer;
  idx := FWords.IndexOf(S1);
  if idx = -1 then
    FItemCount := TWordCountItem.Create;
    FWords.AddObject(S1, FItemCount);
    FItemCount := TWordCountItem(FWords.Objects[idx]);
Of course as Liz pointed out without proper cleanup at the end, it leaks. I think I got lazy because previously I had used TObjectList wich does the cleanup automatically for you.

As for the actual UI itself, I used a TPageControl, some panels and two TListviews. I really like TListView controls. Of course Ihad one do my top twenty list by sorting and knocking everything past the 20th item off the list. Visually it looked good, speed wise... it was slow depending on the number of words to be gone through.

besides the bits from what Liz mentioned, I'd probably redesign the processing class. I'm not sure if I'd use a thread process but I found that when I wanted to tweak soemthing, I had a hard time locating it.

That's about it, you can find the full code and such

Be warned it ain't pretty.