Subclassing

Subclassing is a technique that programmer's can use to intercept Windows messages. This works by replacing VB's default Window Procedure with your own, custom Window Procedure.

Every time the user does something, say, move the mouse, Windows sends a message to your form. Visual Basic normally handles and processes these messages and for some of them it creates events for. If you look at your form, the Click event is created and activated by Visual Basic when it receives a message from Windows telling it that the user has clicked on the form.

The problem is, Visual Basic doesn't create events for all of these messages, so we are left without ways of detecting certain things. For example, when the user resizes a form, VB creates an event Form_Resize. But this event only fires after the user has finished resizing the form.

Using subclassing, you can intercept this resize message, and, before the user has finished resizing, you can apply your own restrictions. This principle can be applied to many messages.

Subclassing as we now know it was made possible by the AddressOf keyword brought in with Visual Basic 5. Before that developers had to use a third-party control if they wanted to carry out subclassing.

The AddressOf keyword, which is only used several times in a complete subclassing routine, returns the address of a procedure. This may sound useless, but we can use it to get the address of our own Window Procedure.

Once we have the address of our Window Procedure, we can use the SetWindowLong API call to set our Window Procedure in place of VB's own one.

Now we have redirected the messages, all we need to do now is process them. A simple Window Procedure has the following arguments:

hWnd - The Window Handle (Long data type) usually the form you are going to subclass.
uMsg - The message sent by Windows.
wParam - Additional information about the message.
lParam - Additional information about the message.

Inside the Window Procedure, we use the Select Case statement to check which message is being sent. The different Cases will be the messages that we want to process. In theory, you could place every message here, but it would be slow to process and might cause the system to fail. So instead we just place our own messages and pass the rest onto VB's own Window Procedure.

When you come to closing down your application, be sure to pass control back to VB. Earlier in the proceedings, your code should store the value of your Window Procedure. If you don't restore full control back to VB, your program (and quite possibly Windows) is likely to crash. Many people choose Windows NT for their development OS as it is more stable, and only VB (IDE) or your application will go down, and not Windows.

Sam Huggill.

Articles