Here's a little trick I came up with to "handle" the "event" when the user clicks the close (X) button on Internet Explorer. I use quotes because there really isn't an event for this action, and what I do with it isn't really handling an event either. But it works!
Note: I mentioned, explicitly, Internet Explorer only in the introduction. As far as cross-browser functionality goes, I've tried this on both browsers: IE 6 and 7. Haha. Since this was for an internal project, we didn't have to support any other browsers. Go ahead and try it though; it shouldn't too far off from playing nice with FireFox, etc.
Okay, no more notes. Let's look at some code. There is a magical event named "onbeforeunload" that we can hook on the body tag of our web form. It fires, roughly, just before the window closes...tantamount to an "IsClosing" event. The bad news is that we just can't put a self.close() call in there, since we have no opportunity to react to OK vs. Cancel clicks or possibly get into managed code. The good news is that the OnClientClick events of our buttons fire before this event, so we can work around it!
This way, you can pretty much do the same thing in your onbeforeunload event as you do in your Cancel button's OnClientClick event. The one situation I don't cover is if you need to call code when the browser window is closing. You can try a __doPostBack in the onbeforeunload event, but I'm not going here since a cancel should really just close the window immediately. If you find yourself needing code in this situation, reconsider your approach. What I had to do was clone everything so that a cancel merely disposed and closed; an OK posted back, popped up a "Please wait" div with a pretty spinning div, and rebound the UI. After an OK, it's acceptable to post back: the users will intuitively expect the app to churn after an affirming action.
Here's some example markup: