Subclassing & encapulating controls

Xancholy

Well-known member
Joined
Aug 29, 2006
Messages
143
Programming Experience
Beginner
Please can somone help me understand how to subclass or encapsulate a control so that I can govern some of the control's default behaviour.

Eg: allow focus in Mytextbox only when user double clicks (double-click to edit)

Thanks very much
 
You simply declare a class and inherit the TextBox class:
VB.NET:
Expand Collapse Copy
Public Class TextBoxEx
    Inherits TextBox

    '...

End Class
That's exactly how it's always done. It's exactly how you create all your forms, by inheriting the Form class. Just as with forms, you can then add whatever code you like to modify the class's behaviour.
 
They are completely different concepts but they are both founding principles of OOP.

Encapsulation refers to the fact that a type, i.e. a class or structure, encapsulates, i.e. encloses within, all the data (properties and fields) and behaviour (methods and events) of an object of that type. The idea is that you don't have just one place where all your variables and functions go no matter what they do. You create a type for each entity you want to represent, whether that entity be physical, e.g. a Person, or more abstract, e.g. a database connection. Each of those types will contain all the variables and functions that relate specifically to that entity. Where you need to use that entity in your code you simply create an instance of the type and you then have a simple, well defined interface to interact with and all the heavy lifting is done internally by the type.

Subclassing is not really an OOP concept but rather the accepted name for the act of implementing inheritance. Inheritance is the actual concept, and refers to the fact that one type can inherit all the data and behaviour from another type and then just add whatever is specific to itself, rather than recreating all the existing functionality of the existing type.

In some other languages, like C/C++, they have superclasses and subclasses, where the subclass inherits, or is derived from, the superclass. The act of deriving a subclass from a superclass is known as "subclassing". The term "subclassing" doesn't get used much in .NET because the terms "superclass" and "subclass" are not used. In .NET you have base classes and derived classes. When you define a new type that inherits from an existing type, the existing type is the base class and the new type is the derived class. The derived type inherits all the data and behvaiour of the base type and then adds its own to that.

As an example of how these OOP concepts work together, consider what happens when you add a form to a project. What you're doing is deriving a new class the Form base class. The Form class encapsulates all the data and behaviour of a Form object, so you inherit all that for free. You then add your own data and behaviour, thereby encapsulating that within your own derived class.

Note that "subclassing" in .NET apps actually refers to another, very specific process. Rather than inheriting a UI class you can hook into its Windows message queue. This allows you to preview any and all message that get sent from the OS to a window, where a window is any control, including a form. You are then able to divert or modify these message to alter the way a control behaves. This is something that is rarely done and you will probably never have to do. In the event that you do though, it is achieved by inheriting the NativeWindow class and providing it with the handle of the windw you want to subclass. You then override the WndProc method of your class and it will receive all the messages that the specified window does.
 
Thank you very much for your kind explanation.

There are some controls that I can't seem to subclass and control. Take for example the quicktime control. Double-clicking it starts the associated movie - natural behaviour of the control.

I install quicktime and then from the quicktime folder add the axQTControl to my toolbox.

I've included in my code
VB.NET:
Expand Collapse Copy
Imports QTOControlLib
Imports QTOLibrary

I then get it to preload a movie in the form load event

VB.NET:
Expand Collapse Copy
AxQTControl1.URL = "c:\videos\movie.mpg"
AxQTControl1.AutoPlay = false

Clicking/Double clicking on the quicktime control stops and starts the movie. This is undesirable as I need to control the movie from my own player buttons.

How can use subclassing on the quicktime control and disable click/doubleclick on the quicktime control.

Thanks for any help.
 
Last edited:
The QuickTime control is an ActiveX control. That's a COM component, not a .NET component. The rules are quite different there. You may well be able to use the subclassing technique I mentioned using the NativeWindow class but I'm not 100% sure as I've never tried.

http://support.microsoft.com/kb/311317
 
You would use the NativeWindow example and only pass the message if it wasn't a WM_LBUTTONDOWN message. This is a integer constant of value 201.
 
Thanks John. Can you experts see what I am doing wrong ?

I have added the nativewindow code & class and my embedded quicktime control is named axQTControl1 but can't figure out how to pass on the quicktime window name to trap the mousedown.

Here's what I am experimenting with...

VB.NET:
Expand Collapse Copy
Public Class SubclassHWND
    Inherits NativeWindow

    Private Const WM_LBUTTONDOWN As Integer = &H102

    Protected Overloads Overrides Sub WndProc(ByRef m As Message)
        ' do whatever custom processing you need for
        ' this message

        Select Case m.Msg
            Case WM_LBUTTONDOWN
                ' Disable mousedown
                Select Case m.WParam.ToInt32
                    Case 201 'Capture mousedown
                        ' Do nothing here to disable the default message handling.
                        MessageBox.Show("you clicked")
                    Case Else
                        'It is important to pass unhandled messages back to the default message handler.
                        MyBase.WndProc(m)
                End Select
            Case Else
                'It is important to pass unhandled messages back to the default message handler.
                MyBase.WndProc(m)
        End Select

    End Sub
End Class
 
The message is WM_LBUTTONDOWN, not WM_CHAR.
 
i saw that & amended the code and our postings crossed. Please can you check the code again and see if you spot any error ?
 
You would use the NativeWindow example and only pass the message if it wasn't a WM_LBUTTONDOWN message. This is a integer constant of value 201.
Read that again and amend your code. Also remove the WParam stuff.
 
Read it again and removed the wparam stuff. Does this look right ? Still doesn't work though - so it must be wrong...

VB.NET:
Expand Collapse Copy
Public Class SubclassHWND
    Inherits NativeWindow

    Private Const WM_LBUTTONDOWN As Integer = &H102

    Protected Overloads Overrides Sub WndProc(ByRef m As Message)
        ' do whatever custom processing you need for
        ' this message

        Select Case m.Msg
            Case WM_LBUTTONDOWN
                ' Disable mousedown
                MessageBox.Show("you clicked")
            Case Else
                'It is important to pass unhandled messages back to the default message handler.
                MyBase.WndProc(m)
        End Select

    End Sub
End Class
 
This is a integer constant of value 201.
Do you think it is unclear what I'm talking about here?
 
I'm sorry -I know it is clear in your mind but it is unclear to me. It's not that I am not trying.

OK, I think you mean this line ?
VB.NET:
Expand Collapse Copy
Private Const WM_LBUTTONDOWN As Integer = [COLOR="Red"]&H102[/COLOR]
 
Back
Top