-----------------------------------------------------------------------
Copyright © 1997 Microsoft Corporation. All rights reserved.
You have a royalty-free right to use, modify, reproduce and distribute
the Sample Application Files (and/or any modified version) in any way
you find useful, if you agree that Microsoft has no warranty,
obligations or liability for any Sample Application Files.
-----------------------------------------------------------------------
Visual Basic Dbgwproc.dll
(Debug Object for AddressOf Subclassing)
June 13, 1997
1. Introduction:
Subclassing is a technique that enables you to intercept Windows
messages being sent to a form or control. By intercepting these
messages, you can then write your own code to change or extend the
behavior of the object. VB5 provides the AddressOf keyword, which can
be used to reroute Windows messages to your own message processing
procedure. Subclassing using the AddressOf is very efficient, but
makes debugging a project difficult. If the window you are
subclassing receives a message when you are in break mode, VB will
crash. The DbgWProc.Dll (Debug Object for AddressOf Subclassing)
enables you to debug normally while a subclass is active without
adding any unnecessary overhead to your finished product or
distributing an extra component.
For a more detailed discussion of the risks and rewards of subclassing,
and for additional sample code, please refer to the Books Online topic
"Passing Function Pointers to DLL Procedures and Type Libraries"
NOTE - Before jumping into subclassing with AddressOf
=====================================================
This is an advanced programming technique. It is very easy to crash VB
using these methods. In particular, the Stop button and End statement
are completely off limits for projects with an active subclass. It is
your responsibility as a programmer to correctly turn off the subclass
before VB shuts down.
Advantages
==========
Rolling your own subclass has the performance and distribution
advantages mentioned earlier, as well as the ability to process
messages at any time. Traditional, event based subclassing techniques
required with earlier versions of VB have the disadvantage of being
unable to process messages while a modal form is showing over the
subclassed window. For example, if you're relying on receiving
WM_PAINT or WM_DRAWITEM messages to properly display a custom window,
then you'll have to use AddressOf directly, or a subclassing component
which relies on an Implements based direct callback model instead of
the more common Event model.
Using DbgWProc.dll:
===================
To use the DbgWProc.Dll to enable debugging:
1) Copy DbgWProc.Dll to your Windows\System[32] or VB5 directory.
2) regsvr32 DbgWProc.Dll
3) Add a reference to 'Debug Object for AddressOf Subclassing'
4) In the Make tab of the Project Properties dialog, add the
DEBUGWINDOWPROC=-1 : USEGETPROP=-1 conditional compilation arguments
5) Now include the following code in your class, control, or form
module (this is only the parts of the subclassing code which
actually change):
'At the top of the file
Private m_wndprcNext As Long
#If DEBUGWINDOWPROC Then
Private m_SCHook As WindowProcHook
#End If
'In the SubClass procedure. For the finished version, this code is a
'single call to SetWindowLong
#If DEBUGWINDOWPROC Then
On Error Resume Next
Set m_SCHook = CreateWindowProcHook
If Err Then
MsgBox Err.Description
Err.Clear
UnSubClass
Exit Sub
End If
On Error GoTo 0
With m_SCHook
.SetMainProc AddressOf Form1Proc
m_wndprcNext = SetWindowLong(hWnd, GWL_WNDPROC, .ProcAddress)
.SetDebugProc m_wndprcNext
End With
#Else
m_wndprcNext = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf_
Form1Proc)
#End If
Each WindowProcHook object provides a ProcAddress value to
use in SetWindowLong. You call SetMainProc with AddressOf -
your subclassing procedure - and SetDebugProc with the original
window procedure. The WindowProcHook will call the debug
procedure directly if you're in break mode, skipping the
subclassing code and the invalid zero return produced by the
IDE. You can create up to 100 simulateous WindowProcHook
objects (hence the error trapping code), so be sure to release
them when they're not in use.
Samples
=======
SubClass.vbp contains two samples: The AboutBox (simple
sample which puts an AboutBox item on the system menu) and
DrawItem (advanced ownerdraw listbox OCX sample). Both
give the option of associating a subclassed hWnd with a class
instance using either SetWindowLong(GWL_USERDATA) or
SetProp/GetProp. USEGETPROP=-1 uses the more robust
SetProp/GetProp method, which also requires the Atomizer.cls
file.
To view these samples, load them (AboutBox\SubClass.vbp or
DrawItem\Group1.vbg) and press F5 to run them. To exit, close the
forms - do not press the Stop button.
To view DbgWProc in action, load the samples and begin single-stepping
through the code with the F8 key. As an alternative, put a breakpoint
in Friend Function WindowProc (in Form1 of the AboutBox sample and the
OwnerDrawListBox usercontrol of the DrawItem sample). Both of these
samples initiate subclassing with a routine called SubClass and end it
with a routine called UnSubClass. If you press the Stop button while
subclassing is active (between SubClass and UnSubClass), VB will GPF.
Note on Compiling after using DbgWproc.dll:
===========================================
Before you compile your final OCX or EXE file, change the
conditional compilation value for DEBUGWINDOWPROC to 0. If
you run a project which uses DbgWProc when the IDE isn't
active, it will give you a warning error message when the Dll
loads. This is meant to strongly discourage you from actually
shipping the Dll with your project (your users will see the
same message). Also be sure to remove the Dll from the list
distributed files in SetupWizard.
For more information and samples with AddressOf subclass, see
the Black-Belt column in the February and June '97 issues of the
Visual Basic Programmer's Journal magazine (www.windx.com).
- 1
- 2
前往页