Click here to Skip to main content
12,405,303 members (66,551 online)
Click here to Skip to main content
Add your own
alternative version

Stats

213.5K views
1.2K downloads
62 bookmarked
Posted

Subclassing in .NET - The pure .NET way

, 22 Nov 2002 CPOL
Rate this:
Please Sign up or sign in to vote.
Capturing the Windows Messages for Windows Forms Controls

Introduction

If you are a Visual Basic 6 programmer then you are obviously aware of the sub-classing power. My article demonstrates the same thing for .NET. If you are a C# programmer, then you can easily change this code to fit into a C# Project. This project demonstrates how can you use the .NET way to subclass any control. This is the pure .NET way.

Using the code

Actually, you do not have to much to subclass your controls. What you have to do, is to create a class which should inherit from System.Windows.Forms.NativeWindow class. This class, as the name says, is the base class of a window. Using this class, you can use a function named AssignHandle which takes one parameter, the HWND of the object (control). And finally, you have to override a method named WndProc (method of NativeWindow Class). If you see the complete listing, then it will be clearer.

Imports System.Windows.Forms

Namespace theAngrycodeR
    'To Subclass any Control, You need to Inherit From 
    'NativeWindow Class

    Public Class SubClassing
        Inherits System.Windows.Forms.NativeWindow

        'Event Declaration. This event will be raised when any  
        'Message will be posted to the Control
        Public Event CallBackProc(ByRef m As Message)

        'Flag which indicates that either Event should be 
        'raised or not
        Private m_Subclassed As Boolean = False

        'During Creation of Object of this class, Pass the Handle 
        'of Control which you want to SubClass
        Public Sub New(ByVal handle As IntPtr)
            MyBase.AssignHandle(handle)
        End Sub

        'Terminate The SubClassing
        'There is no need to Create this Method. Cuz, 
        'when you will create the Object
        'Of this class, You will have the Method Named ReleaseHandle.
        'Just call that as you can see in this Sub

        'Public Sub RemoveHandle()
        '    MyBase.ReleaseHandle()
        'End Sub

        'To Enable or Disable Receiving Messages
        Public Property SubClass() As Boolean
            Get
                Return m_Subclassed
            End Get
            Set(ByVal Value As Boolean)
                m_Subclassed = Value
            End Set
        End Property

        Protected Overrides Sub WndProc(ByRef m As Message)
            If m_Subclassed Then 'If Subclassing is Enabled 
                RaiseEvent CallBackProc(m) 'then RaiseEvent
            End If
            MyBase.WndProc(m)
        End Sub

        Protected Overrides Sub Finalize()
            MyBase.Finalize()
        End Sub
    End Class

End Namespace

OK, you have prepared your class. Now come back in your form's code to use it. In the demo project, I used two command buttons and one text-box. And wrote the following code.

    Private Const WM_CLOSE As System.Int32 = &H10
    Private Const WM_QUERYENDSESSION As System.Int32 = &H11
    Private Const SC_CLOSE As System.Int32 = &HF060&
    Private Const WM_SYSCOMMAND As System.Int32 = &H112
    Private Const WM_KEYDOWN As System.Int32 = &H100
    Private Const WM_DESTROY As System.Int32 = &H2
    Private Const SC_MAXIMIZE As System.Int32 = &HF030
    Private Const SC_MINIMIZE As System.Int32 = &HF020
    Private Const SC_RESTORE As System.Int32 = &HF120

    'The Object of Subclassing to SubClass any Control
    Dim WithEvents abc As theAngrycodeR.SubClassing


#Region "Subclassing Current Form Only"
    'If you want to Subclass the Current Form only, 
    'then just remove these Comments 
    'You can not SubClass any Control using this method

    Protected Overrides Sub WndProc(ByRef m As Message)
        Select Case m.Msg
            'If from Meny Close Is Selected then
            Case Is = WM_SYSCOMMAND
                Select Case m.WParam.ToInt32
                    Case Is = SC_CLOSE
                        MsgBox("Closing")
                    Case Is = SC_MAXIMIZE
                        MsgBox("Maximize")
                    Case Is = SC_RESTORE
                        MsgBox("Restore")
                End Select

                Case Is = WM_DESTROY
                        MsgBox("Destroy")
            Case Is = WM_CLOSE
                MsgBox("Close")

            Case Is = WM_KEYDOWN
                MsgBox(m.HWnd.ToString)
                'MsgBox("Key Down : Virtual Code : " & m.HWnd.ToInt32 
                '& vbCrLf & "Key Data : " & m.LParam.ToInt32)
        End Select

                MyBase.WndProc(m)

    End Sub
#End Region

    Private Sub frmMain_Load(ByVal sender As System.Object, 
            ByVal e As System.EventArgs) Handles MyBase.Load
        abc = New theAngrycodeR.SubClassing(Button1.Handle)
        abc.SubClass = True
    End Sub

    Private Sub abc_CallBackProc(ByRef m As System.Windows.Forms.Message) 
            Handles abc.CallBackProc
        Const WM_MOUSELEAVE = &H2A3
        Const WM_MOUSEMOVE = &H200
        Const WM_MOUSEHOVER = &H2A1

        Select Case m.Msg
            Case WM_MOUSELEAVE
                TextBox1.Text += "Message Mouse Leave" & vbCrLf
            Case WM_MOUSEMOVE
                TextBox1.Text += "Message Mouse Moved" & vbCrLf
            Case WM_MOUSEHOVER
                TextBox1.Text += "Message Mouse Hover" & vbCrLf
        End Select
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, 
            ByVal e As System.EventArgs) Handles Button2.Click
        abc.ReleaseHandle()
    End Sub

Note that if you want to filter messages for the current form, then you can just write the code inside the WndProc method which is declared as Protected Overrides Sub WndProc ( ByRef m As Message ). For getting the messages for other windows, you can use the same code written above. The sample project is attached with this article. You can check this out and comment too.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Sameers.ME
Web Developer
Pakistan Pakistan
No Biography provided

You may also be interested in...

Comments and Discussions

 
Generalexternal windows Pin
Evs_1-Sep-08 10:16
memberEvs_1-Sep-08 10:16 
Generalconstants for subclassing Pin
Alessandro7714-Mar-06 22:34
memberAlessandro7714-Mar-06 22:34 
QuestionDebugging-please help! Pin
skyhi8-Jan-06 21:04
memberskyhi8-Jan-06 21:04 
QuestionPlease help me! Pin
Kunal Mukherjee28-Aug-05 7:33
memberKunal Mukherjee28-Aug-05 7:33 
QuestionSubclassing in a Windows Service? Pin
meraydin10-Apr-05 1:05
membermeraydin10-Apr-05 1:05 
QuestionSubclassing Menus? Pin
AndrewVos4-Mar-05 23:55
memberAndrewVos4-Mar-05 23:55 
GeneralHelp Me Pin
safirc6-Jul-04 18:11
membersafirc6-Jul-04 18:11 
GeneralOne Question Pin
bikash_r@hotmail.com5-Oct-03 3:39
memberbikash_r@hotmail.com5-Oct-03 3:39 
Generalanother subclassing question Pin
powerdude19-Jun-03 14:37
memberpowerdude19-Jun-03 14:37 
GeneralAttaching to Existing Window Pin
Detlef Grohs24-Feb-03 7:18
memberDetlef Grohs24-Feb-03 7:18 
QuestionSubclassing multiple controls? Pin
LeeDaviesVBSource29-Jan-03 8:07
memberLeeDaviesVBSource29-Jan-03 8:07 
GeneralExtender Controls Pin
Allann16-Jan-03 1:08
memberAllann16-Jan-03 1:08 
GeneralRe: Extender Controls Pin
Heath Stewart12-Feb-03 8:52
editorHeath Stewart12-Feb-03 8:52 
GeneralRe: Extender Controls Pin
Allann12-Feb-03 11:18
sussAllann12-Feb-03 11:18 
GeneralRe: Extender Controls Pin
Roger J18-Jul-03 0:32
memberRoger J18-Jul-03 0:32 
GeneralSubClassing... Pin
mikasa14-Jan-03 8:26
membermikasa14-Jan-03 8:26 
GeneralRe: SubClassing... Pin
Sameers (theAngrycodeR()14-Jan-03 10:15
memberSameers (theAngrycodeR()14-Jan-03 10:15 
GeneralThe PURE .Net way Pin
Chris Martinez12-Dec-02 5:15
sussChris Martinez12-Dec-02 5:15 
GeneralRe: The PURE .Net way Pin
Sameers (theAngrycodeR()17-Dec-02 12:21
memberSameers (theAngrycodeR()17-Dec-02 12:21 
GeneralRe: The PURE .Net way Pin
Cory Smith2-Jan-03 17:11
memberCory Smith2-Jan-03 17:11 
GeneralRe: The PURE .Net way Pin
mikasa23-Jan-03 5:15
membermikasa23-Jan-03 5:15 
GeneralRe: The PURE .Net way Pin
Sameers (theAngrycodeR()23-Jan-03 12:13
memberSameers (theAngrycodeR()23-Jan-03 12:13 
GeneralRe: The PURE .Net way Pin
Gnu27-Jan-03 6:13
memberGnu27-Jan-03 6:13 
GeneralRe: The PURE .Net way Pin
Michael Elope11-Jan-05 3:32
memberMichael Elope11-Jan-05 3:32 
AnswerRe: The PURE .Net way Pin
Wcohen5-Jan-06 6:18
memberWcohen5-Jan-06 6:18 
GeneralRe: The PURE .Net way Pin
snort20-Dec-06 3:38
membersnort20-Dec-06 3:38 
GeneralThanks, Pin
Stan Shannon24-Nov-02 3:18
memberStan Shannon24-Nov-02 3:18 
GeneralTopic a bit misleading Pin
leppie24-Nov-02 1:47
memberleppie24-Nov-02 1:47 
GeneralRe: Topic a bit misleading Pin
Cory Smith2-Jan-03 17:13
memberCory Smith2-Jan-03 17:13 
GeneralRe: Topic a bit misleading Pin
leppie3-Jan-03 6:09
memberleppie3-Jan-03 6:09 
GeneralRe: Topic a bit misleading Pin
Cory Smith3-Jan-03 6:21
memberCory Smith3-Jan-03 6:21 
GeneralRe: Topic a bit misleading Pin
Anonymous26-Aug-05 23:36
sussAnonymous26-Aug-05 23:36 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160721.1 | Last Updated 23 Nov 2002
Article Copyright 2002 by Sameers.ME
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid