Subclassing:
Note: This article assumes a basic level understanding of Windows API Programming.
Subclassing is a unique way of intercepting Windows messages. We will see more in detail on how it works! It’s very interesting and useful for people who want to do a kind of system programming using Visual Basic.
About Windows Messages:
Whenever a user sitting in front of a computer moves the Cursor, click a button – Windows will generate a Message for it and the OS will process these messages and does what needs to be done. Objective of this article is "How to catch these Windows Messages and we will see how it can be done in the coming sections".
Our first step is to create a Method (other words Message Handler) where we will be receiving Windows Messages, SetWindowLong API function is used to install a Message handler for a Form or for a particular Control or Object which has a window handle hWnd. More information about the parameters can be found in MSDN site.
Dim OldWindowProc as long
Private Sub Form_Load()
'Copy the SetWindowLong API Definition from API Text Viewer 'and place it in a New Module, say Module1
'Please note that API Text Viewer Tools comes with Visual Studio 'Tools
OldWindowProc = SetWindowLong( Form1.hwnd, GWL_WNDPROC, _ AddressOf NewWindowProc)
End Sub
AddressOf Operator works in the same way as Delegates in .NET, AddressOf NewWindowProcindicates that whenever VB Form receives any Actions/Events, it will call another event handler to handle & process it.
The above API Call informs the Windows that whenever there’s an event that is going to take place on Form1, redirect those messages to NewWindowProc Method. Incase, if the user click’s on the Form, then the Click Event will trigger the NewWindowProc Handler. This method should verify the windows message and take whatever action is appropriate. If that message is not handled in your NewWindowProc code, it should pass the message on to the original WindowProc for normal processing. This is really important. The NewWindowProc should return whatever code the original WindowProc returns.
Let us see how Windows Intercepts "Form Resize" Event with a sample code,
Now that we have informed the system to redirect all the Windows Messages on Form Object to NewWindowProc Method, let us see the definition of NewWindowProc Method. Please note that this Method can take a different Name but the number of arguments and the order in which the arguments are listed should not be changed.
Public Function NewWindowProc(ByVal hwnd As Long, ByVal msg As Long, ByVal wParam As Long,
lParam As WINDOWPOS) As Long
'You can take these constant values from API TEXT VIEWER which 'comes with Visual Studio Tools
Const WM_SYSCOMMAND = &H112
Const SC_SIZE = &HF000&
‘See if this is a WM_SYSCOMMAND message. – Windows Message System Command
If msg = WM_SYSCOMMAND Then
‘This is a WM_SYSCOMMAND message.
‘If the command is SC_SIZE, this is important because this is where
‘You are trying to capture Form Resize Event, whenever user re-sizes the
‘Form, wParam will return SC_SIZE value – we are not asking windows
‘to do anything when user Re-sizes the Form , just Exit Function
If (wParam And &HFFF0) = SC_SIZE Then Exit Function
End If
' If the user does anything other than Resize then we should allow the 'windows to continue its normal processing. ‘It’s really IMPORTANT!
NewWindowProc = CallWindowProc(OldWindowProc, hwnd, msg, wParam, lParam)
End Function
Whenever you Subclass an Object, it’s mandatory that you unloads the subclassed object at the end so as to restore the original WindowProc.
Private Sub Form_Unload(Cancel As Integer)
‘value for GWL_WNDPROC can be retrieved from API Text Viewer
SetWindowLong hwnd, GWL_WNDPROC, OldWindowProc
End Sub
Please read the below points before trying to Subclass any Object/Control,
-
When you have decided to subclass messages, its mandatory that you un-subclass your program before closing the application. You can take care of this in the Form_Unload event (or when you press the X button). However, if you use the stop your application in abnormal way by pressing Stop Button in the Toolbar, application will not call un-subclass. Visual Basic, and your program will crash, and you will lose any unsaved work.
-
Do not place any breakpoints into the WindowProc procedure, or try to debug it during run time, as Visual Basic will crash.
-
Subclassing is a vast field and you can do a lot of tricks with Windows. But we should always make sure that we write a "Safe Code" to implement Subclassing.
References:
Please refer to below links to acquire more knowledge about Subclassing,
http://support.microsoft.com/kb/311317
http://www.geocities.com/SiliconValley/Lab/1632/atch12.html
Read a nice article about Subclassing without Crashes from,
http://www.vbaccelerator.com/home/VB/Code/Libraries/Subclassing/SSubTimer/article.asp
Biography
I am a software developer and have worked on Microsoft technologies for about eight years now. I have always been fascinated by Microsoft technologies and with the advent of .NET , this fascination has reached new heights. I take a lot of interest in reading technical articles and equally enjoy writing them.