Interview with Stephen Teilhet, author of "Subclassing and Hooking With Visual Basic"


vbRad: Let's clear up one thing for our readers. This book is NOT about prostitution, right?
steilhet: Yes, you are one of the few that made that connection. Actually, I used to joke about it when the book was in its infancy and I got a lot of strange looks.
vbRad: Seriously speaking, did the publisher give you any grief about the book title? After all, "hooking" means something else entirely outside the scope of Windows programming.
steilhet: No, actually, my original idea was just a book about using hooks within the VB realm and he (Ron Petrusha) prompted me to add subclassing to the book. Which worked out great, since subclassing and hooking are very similar in ways.
vbRad: Speaking of the title, could you please give our readers (who haven't been exposed to it) a quick definition of what subclassing/hooking is all about?
steilhet: In simplest terms, both techniques intercept windows messages that are sent back and forth in the system. If you've ever used a tool such as Spy++ you can see the amount and types of messages that are passed between objects in the Windows OS. This is where the similarities end, though. Subclassing and each of the 15 different hooks intercept different messages at different points in the message stream. For this reason it is important to do your homework before choosing a particuar hook or type of subclassing in which to use for an application.
vbRad: What real-world experience do you have with subclassing/hooking that will make your readers feel confident that you are the right source for this type of information? (i.e. how did you come to work with hooking/subclassing)
steilhet: There are two projects that I have worked on that come to mind. On each project the requirement was to use VB, but I also needed more control over the application windows that was allowed through VB. Some examples are controling the size and position of the form. Once I progressed through these projects, I became more and more interested in these techniques and started to study them on my own. In doing so I was also able to help numerous others in debugging and completing projects in which subclassing and hooking were being used. In fact, these techniques are used throughout MFC projects in VC++ and I was able to help several people debug code and also help them get a better understanding of what MFC was doing. I also have at least one personal project that I take on by myself every so often, they always involve learning how something works. In this instance it was how automated test applications operated. I learned that by using several hooks WH_CBT, WH_JOURNALRECORD, and WH_JOURNALPLAYBACK to name a few, I could create a fully functional test application. At that time I was planning on writing an article on the technique, but John Robbins beat me to the punch with two articles that he wrote in the MSDN magazine.
vbRad: Speaking of hooks like WH_JOURNALRECORD, is it possible to extend these or other hooks to intercept other system activities (like disk writing activity), or are Windows pretty much limited to the ones you describe in the book (i.e. the 15 hooks).
steilhet: Unfortunately, I know of no way to extend these hooks. They are built-in to the operating system to intercept specific messages at specific points. There is a web site (www.sysinternals.com) that specialize in very low level techniques which employ techniques used in device driver building to watch hardware events such as writing to the disk, but this is much more involved that using the Windows hooks. There is a documented 16th hook (WH_HARDWARE) that was never incorporated in any version of Windows. To my knowledge, it is not slated to be incorporated into Windows either. This hook may have been intended for system activities such as watching for disk or other hardware activity to occur.
vbRad: That's too bad, it would have been useful :-) What are the downsides to subclassing/hooking for an average VB programmer working for a standard corporation? Would you classify subclassing/hooking to be "safe code"?
steilhet: I would definately classify subclassing/hooking to be "safe code", but only if you really understand what you are doing. I remember my first foray into subclassing was to copy some subclassing code out of a magazine and use it. Had it not worked correctly with my other code, I could have encountered stack overflow conditions, frozen the application (or all applications, possibly), or some other fault may have occured. This is not a technique to be taken lightly. If you do not know the implications of using subclassing/hooking it may seem that this type of code is unsafe. In writing the code for the book, I ran into many problems, but most of them were easily corrected. In some cases I may have simply not discarded a message and let it pass on to its destination window. I remember one particularly bad debugging instance when my app would infinately recurse whenever I started it. By using Spy++ I could see that it was actually setting up an infinite loop whenever I would subclass a text box and print out every message that was being written to it. As it happened, whenever text is written to a text box, many messages are sent to that text box in order to write the text in its client area. Each of those message were being picked up and written to the text box, and on and on, so that it never stopped writing text to the text box. This brings up a good point, get to know and love tools such as Spy++ when debugging subclassing/hooking code.
vbRad: Other than Spy++, which can be a bit scary for someone who takes an initial foray into the world of windows messages, what other tools would you recommend Also, how often does something come up in your daily work that requires use of subclassing or hooking and necessitates use of tools like Spy++?
steilhet: Here are some of the tools that I use, note that most of them are not as useful as Spy++ for subclassing/hooking: Process Explorer, DebugView, Depends, File Monitor, Registry Monitor, Process Viewer, WinDiff, Fusion Log Viewer (.NET only), ILDasm (.NET only), and of course Spy++. There are others, but I do not use them nearly as often. For subclassing/hooking there really is not substitute for Spy++. Subclassing and hooking rely almost entirely on the messages sent between objects in the Windows OS, therefore, Spy++, which watches messages, is the best tool to see what is going on inside of your applications (or others for that matter). The Depends and Process Viewer tools are great for looking at the internal makeup of a DLL, EXE, or an entire process. This helps a lot with system hook, which are set up inside of Win32 DLL's and pulled in to other running processes. I know Spy++ may spit out a lot of information, but learing how to use it can make a world of difference when debugging an app that uses subclassing and/or hooking. As for how often subclassing/hooking projects come up in my daily work, I would have to say not often. Although, I have had to do some investigative/debugging work with a lot of legacy code that uses subclassing, in these instances I have frequently resorted to Spy++ to see what is happening. It is often hard to get new projects going that employ subclassing/hooking because of the lack of knowlege about it (especially in the VB community) or thinking that it is a secret art available only to the most proficient C++ developers. It is my hope that this book will eradicate that lack of knowlege and allow others to use these techniques safely and efficiently.
vbRad: That's true. Subclassing does have a bit of that stigma, also associated in part that it is difficult to get good information about it. Hopefully this book will dispel this myth and help programmers see what it is all about. It has certainly helped me clear up some things that were fuzzy in the past. You have a chapter in the book on .NET. It seems that subclassing won't be used as much, because it is incorporated into the framework, while hooks are not. Does this apply to VB.NET only or to C# as well? Does C# provide an easier way to handle hooks? Would a hook then be an "unmanaged code" in the .NET framework?
steilhet: Actually, it is a very small effort to port either the subclassing or hooking code from VB.NET to C#. Hooks are actually a little more simple to use in C# due to the way that delegates are declared and used in C# versus VB.NET. The filter function that you write for the hook in any .NET language will be managed, but you must call out to unamanaged code via P/Invoke to call the SetWindowHookEx and UnHookWindowsHookEx API functions when setting and removing the hooks. The syntax for calling out to unmanaged API's via P/Invoke is slightly different in VB.NET and C#.
vbRad: You state in the book that it is impossible to subclass a window in another process. There is a product out there from Desaware that claims to do just that. What method, in your opinion, do they use to achieve this functionality? Do they simply hook in to the entire Windows message stream and filter out all the unnecessary messages?
steilhet: Yes, I remember reading that too. To do this you would need to create a system wide hook using C++. You would then determine if you need to use the WH_CALLWNDPROC hook (intercepts only sent messages) or the WH_GETMESSAGE hook (intercepts only posted messages) or both. This system wide hook would then be created inside of a Win32 DLL and injected into every running process. Your filter function for the hook is contained inside the DLL and is injected into each of the processes as well. This filter function then needs to look for messages directed towards one or more windows in which you want to "subclass". This is obviously very simplified. There is much more to it. There is a book "Advanced Windows" by Jeffrey Richter that describes this process in some better detail although it is entirely in C++. I did mention in the book that using these hooks one could in essence subclass a window outside of its process. I did not go into this since it mainly involves using C++ and the book was focused more towards the VB and VB.NET developer. Actually, it is kind of misleading, you are really using hooks to simulate subclassing a window in another process. Using hooks outside of your applications process (system-wide hooks) are very interesting, but beware, they are much more difficult to debug and they pose a serious drain on system wide performance if not used correctly (sometimes even when used correctly, they can put a drain on system performance). So, use this technique with caution.
vbRad: And the last question. Having never written a book before, what compelled you to start writing?
steilhet: It might sound a little silly, but at my previous job I was getting very bored with what I was doing. I was working on building another database access interface (a VB form with a bunch of text boxes on it). There were a few times where I had some down time while I was waiting for components to be developed by other groups. During these times my mind never stayed at rest, I was always coming up with ideas. One of them manifested itself through an article I wrote for VBPJ (Feb 2000) entitled "Making your boolean logic error free". That was my very first foray into professional writing. I was planning more articles on using the various hooks from within VB, but as the ideas grew I toyed with the idea of writing a book. At first it was almost a joke, but as the ideas grew in size and number I took a chance with a reputable publisher (O'Reilly and Associates) and sent in a 12 page proposal. The editor called me up and interviewed me to make sure I would be willing to put in the time and that I was serious about the book. Afterwards, he decided to take a chance on me and the rest is history. Writing this book has been very fulfilling for me, it has been especially fulfilling for me intellectually. I have grown to love writing and have plans in the works for a new .NET book. You will be pleased to know that it is not just another how to write VB.NET or C# code it is much more involved. It will basically begin where those books leave off.
vbRad: That's great, because I am kind of bored with those types of books already - they rehash what should be (will be?) in the online help anyway. Thanks for taking the time to do the interview, I wish you continued luck with this and the next book. We
steilhet: One more thing, I should mention that the code on the O'Reilly web site uses the Beta 1 version of VB.NET for the examples in chapters 22 & 23. I need to update that code to reflect the changes in Beta 2
vbRad: We'll look forward to the updated code.
steilhet: Thanks, for having me.


 


Want more reviews and sample chapters? Click here.