Event orders...

Dumping events

I'm often surprised (or is it dismayed) when questions pop up
in news groups surrounding things like event orders for winforms or
webforms applications... this isn't rocket science... we're given
all the tools to make this easy to figure out!



Lets do a winforms 2.0 app as an example... first off, the earliest
point at which can easily get involved is the constructor... 
lets have a look:


public partial class Form1 : Form
{
public Form1()
{
AttachToAllEvents();
InitializeComponent();
}


So I'm going to attach to all the events before the forms
components are initialized... now lets have a look at the
"AttachToAllEvents" method.


private void AttachToAllEvents()
{
Type type = GetType();

foreach (EventInfo info in type.GetEvents())
{
string eventName = info.Name;

EventHandlerWrapper wrapper = new EventHandlerWrapper(new EventHandler(
delegate
{
Console.WriteLine("{0}: EventName: {1}, IsVisible: {2}, IsHandleCreated: {3}, HasChildren: {4}, IsDisposed: {5}",
DateTime.Now, eventName, this.Visible, this.IsHandleCreated, this.HasChildren,
this.IsDisposed);
}));

wrapper.Attach(this, info);
}
}



Only magic there is we're using a class called
"EventHandlerWrapper" - what's that... well, it's used to
create a strongly typed delegate for attaching to an event.



The reason we need this at all is because
EventInfo.AddEventHandler(...) is fussy about the kind of
delegate you supply, so if you pass in an "EventHandler" for
a "CancelEventHandler" event, it'll throw an exception
complaining about it's inability to cast between them... there
might be an easier way to do this, but I haven't come across it so
far.


public class EventHandlerWrapper
{
private EventHandler _handler;
private static readonly MethodInfo _methodInfo;

static EventHandlerWrapper()
{
_methodInfo = typeof(EventHandlerWrapper).GetMethod("InvokeHandler", BindingFlags.NonPublic | BindingFlags.Instance);
}

public EventHandlerWrapper(EventHandler handler)
{
if (handler == null) throw new ArgumentNullException("handler");
_handler = handler;
}

public void Attach(object target, EventInfo info)
{
Delegate wrappedHandler = Delegate.CreateDelegate(info.EventHandlerType, this, _methodInfo);
info.AddEventHandler(target, wrappedHandler);
}

private void InvokeHandler(object sender, EventArgs args)
{
_handler(sender, args);
}
}



With a little brain power I'm sure I could've done this without the
separate wrapper class, but this is probably a little easier to
read at any rate.


Results..?

So.. onto the results - once we run the code and see exactly
what order events are happening in, we can then make a pretty table
that may not render in most browsers because I cut 'n pasted it
from Excel 2007 ;o)



cellpadding="0" cellspacing="0" width="563">

height="20" width="162"> EventName

width="81">  IsVisible

width="128">  IsHandleCreated

width="100">  HasChildren

width="92">  IsDisposed


height="20"> Resize
 False
 False
 False
 False


height="20"> SizeChanged
 False
 False
 False
 False


height="20"> ClientSizeChanged
 False
 False
 False
 False


height="20"> ClientSizeChanged
 False
 False
 False
 False


height="20"> ControlAdded
 False
 False
 True
 False


height="20"> ControlAdded
 False
 False
 True
 False


height="20"> StyleChanged
 False
 False
 True
 False


height="20"> TextChanged
 False
 False
 True
 False


height="20"> Move
 False
 True
 True
 False


height="20"> LocationChanged
 False
 True
 True
 False


height="20"> HandleCreated
 False
 True
 True
 False


height="20"> Invalidated
 False
 True
 True
 False


height="20"> StyleChanged
 False
 True
 True
 False


height="20"> ChangeUICues
 True
 True
 True
 False


height="20"> Invalidated
 True
 True
 True
 False


height="20"> BindingContextChanged
 True
 True
 True
 False


height="20"> Load
 True
 True
 True
 False


height="20"> Layout
 True
 True
 True
 False


height="20"> VisibleChanged
 True
 True
 True
 False


height="20"> Activated
 True
 True
 True
 False


height="20"> Shown
 True
 True
 True
 False


height="20"> Paint
 True
 True
 True
 False


height="20"> Paint
 True
 True
 True
 False


height="20"> Paint
 True
 True
 True
 False


height="20"> MouseCaptureChanged
 True
 True
 True
 False


height="20"> Closing
 True
 True
 True
 False


height="20"> FormClosing
 True
 True
 True
 False


height="20"> Closed
 True
 True
 True
 False


height="20"> FormClosed
 True
 True
 True
 False


height="20"> Deactivate
 True
 True
 True
 False


height="20"> HandleDestroyed
 True
 True
 True
 False


height="20"> Disposed
 False
 False
 False
 False





The main thing to keep in mind when doing something like this is to
avoid making assumptions - we may not be the first or last to
attach to the events (depending on the complexity of the form) -
and events can trigger other events... which could explain the
ordering of some of this data i.e. changes in visibility and handle
creation... if anything we are viewing the order of consequences,
as opposed to the true order in which the events are invoked (to
get that we'd need to override all the OnXXXX methods of the form
class... which would be a good job for dynamic
proxy
:)
Read More

Thankyou mr tortoise...

I've been using tortoise SVN for a couple of years now... but I'd never seen this dialog before when renaming files with similar name patterns... probably old news to some people, but it pleased me no end, very helpful!


It's these kinds of features that I like about an explorer based SCM client... I find IDE integrated source control just bugs me now days (like Team System which I use for codeplex).

Read More

Minor fix to wix shortcuts..

In the last post about WiX shortcuts I detailed how to make an unisntall link... it was actually slightly wrong ;o) ... well at least if your product Id wasn't surrounded with braces... so here's the offending line fixed for product Guid's that aren't surrounded with braces (which is generally what you should be using in a WiX file)


As you were...
Read More

WiX shortcuts...

(Long) Shortcuts

Shortcuts are a basic concept in installers... and doing them with WiX is easy... once you know how... I just spent the last 10 minutes trying to get an Icon assigned to an advertised shortcut, here's how you do it...




Name="SomeCompany.SomeProduct.HostApp.exe"
DiskId="1"
Source="....buildSomeCompany.SomeProduct.HostApp.exe"
Vital="yes">


Id="SomeCompanySomeProductHostAppShortcut"
Directory="ProgramMenuDir"
Name="My Product"
WorkingDirectory="INSTALLDIR"
Description="SomeProduct Application"
Icon="HostAppShortcutIcon.exe">


SourceFile="....buildSomeCompany.SomeProduct.HostApp.exe" />






The oddity is the way the Icon must be named with an ".exe" extension for it to work....  For non-advertised shortcuts you can get away with just leaving the icon out altogether.



Now something else my client wanted that I had to wrestle with a bit... how to create an uninstall shortcut for your product in the program menu's directory... here's how I achieved it, by creating a shortcut to msiexec.exe - I'm damn sure there must be easier way though, this is very clunky, but at least it works for now - if anyone knows an easier way then drop me a comment...

Personally I think uninstall links in the program menu are a waste of time... but in this case I wasn't the target audience I guess :P



Note: The "$(var.PRODUCTGUID)" refers to a constant being passed to WiX from my continuous integration build (I have a custom msbuild task for generating a single unique productId guid per revision in SVN)...



First off I define a couple of custom actions...




I then evaluate them as part of the "InstallExecuteSequence" ... this doesn't actually have to be run before "FindRelatedProducts"... you can evaluate them quite late in the installation process.



  




And then we can create our shortcut...


    






You might be wondering why I place a dummy registry entry in there... well it's because otherwise you end up with an ICE 38 error - which seems daft to me, but then I don't really know enough about the windows installer architecture to dispute ICE's errors ;o) (ICE stands for Internal Consistency Evaluator(s) - which is used to validate the installer produced by WiX - have a look here for more info).



At any rate... I like the way WiX works... I would never go back to a gui-based setup project tool again, they might be fine for small projects, but once your project grows it just starts to suck hard... why? well... 4 reasons off the top of my head:
  • You can't diff between versions easily... just what did you coworker change in the setup last checkin?
  • Lack of global search and replace...
  • Generally a little more difficult to fit into CI builds.
  • Some of the products require you to use regasm or CLR code to register assemblies for com interop.


I just wish there was a decent cookbook... WiX has been going for over 2 years now, and It still seems a little hard to find decent information, I mostly rely on the official stuff... and of course examining how some open source projects have build their installers.
I might post a little bit on upgrades next time, that's the other task that took me a little time to get sorted, might proove useful to someone starting out with WiX... who could say.



BTW - I haven't forgotten about my LINQ series... It's just on the back burner at the moment.
Read More

There are some changes in the wind...

Changes in the wind...


I'm looking at expanding my operation (Dev Defined Limited) - after having come to the conclusion that I can't support my current client base, and certainly can't offer them enough business continuity should I be put out of action - short of taking key man insurance out on myself ;o) - I need to start growing.

At any rate I've decided to do a few things:

  1. Start engaging old clients (and finding new clients) to queue up more work beyond my capacity.
  2. Taking on additional staff to both do that work, and transfer knowledge about existing clients and solutions.


Which brings me to the point of this post, I'm going to be looking for a couple of additional development staff (both senior).

So if you're a flexible senior developer, with a strong .Net background who wants to help build a development shop up, and is looking for opportunities to stretch their legs and play with some new and interesting technologies (instead of just reading about them on blogs) then why not drop me a line?

Our projects cover a wide variety of areas, looking back over the past 8 months some of the more interesting bits of work have been:

  • A client server system for audio identification, using WCF, Base4.Net with a Monorail based web front-end.
  • Rich message processing system for Seismic Technologies, a large solution that included a rich winforms based remote configuration interface, integrated IronPython scripting, heavy use of dependency injection, WSE 3.0 and IoC.
  • Library for media transformations (designed to plug-in to the SyzmkRMP product, but also for other users) - including an Audio/Video encoding library that wraps up DirectShow.Net which was open-sourced as the Splicer project on codeplex.


Starting package would be $85K + 5 weeks holiday, Pay review after 6 months.

And on the flip-side of that coin, I'm looking for additional project/product development work to take on board, so if you have a project that you think would benefit from our unique set of skills and experience and a team of developers with a focus on innovative solutions, drop us an email.

Read More