Container Classes Versus Control Classes (134314)
The information in this article applies to:
- Microsoft Visual FoxPro for Windows 3.0
This article was previously published under Q134314 SUMMARY
There are two main Visual FoxPro base classes, the Control class and the
Container class. This article compares and contrasts them.
MORE INFORMATIONBuilt-in Control Classes
CheckBox
ComboBox
CommandButton
Control
Custom
EditBox
Header
Image
Label
Line
ListBox
OLEBoundControl
OLEControl
OptionButton
Shape
Spinner
TextBox
Timer
Built-in Container Classes
Column
CommandGroup
Container
Form
Formset
Grid
OptionGroup
Page
PageFrame
Toolbar
Differences Between the Two Base Classes
These two base classes are different when it comes to how objects within
each class can be referenced and manipulated. Member objects within Control
classes can only be manipulated at the design time of the class. These
objects cannot be referenced from outside the class at run time. In
contrast, objects within Container classes can be manipulated individually
at design time or run time, and they can be referenced from outside the
class by calling methods or setting properties (this applies to members and
methods not defined as PROTECTED).
How Subclassing Works for Container and Control Classes
If a Container is subclassed and child member objects are added to it
(Command Buttons, for example), then when an object is instantiated from
this container subclass, all methods and properties of any of the child
member objects as well those of the parent (the Container subclass) may be
accessed as long as they are not protected.
If a Control is subclassed and member objects are added to it, then when
this Control is instantiated, only methods and properties of the Control
class itself may be accessed, and then only if they are not protected. The
methods and properties of child member objects contained in the control
cannot be accessed from outside the control. These child members can only
be accessed from within the control (a method in the control can set a
property or call a method in a child member of the control). All methods
and properties of child members of controls are automatically protected.
Member objects must be added to Controls at design time with the ADD OBJECT
clause of the DEFINE CLASS command. Member objects may be added to
containers either at design time (with the ADD OBJECT clause) or at run
time (with the .AddObject() method).
Code Sample
*****************************************************************
* Start of CNTVSCTL.PRG
* This program contrasts Container and Control classes
*****************************************************************
ON ERROR DO errhand ;
WITH ERROR( ), MESSAGE( ) && Traps unknown member error
oForm1 = CREATEOBJECT( 'frmform1', 'Form with Container', 'cntContainer' )
oForm1.VISIBLE = .T.
oForm2 = CREATEOBJECT( 'frmform1', 'Form with Control', 'ctlControl' )
oForm2.LEFT = 310
oForm2.VISIBLE = .T.
READ EVENTS
ON ERROR
DEFINE CLASS frmForm1 AS FORM
WIDTH = 300
SCALEMODE = 3
PROCEDURE INIT
PARAMETERS cformcaption cobj2add
THIS.CAPTION = cformcaption
THIS.ADDOBJECT( 'oAddedobject', cobj2add )
THIS.ADDOBJECT( 'oFormbutton', 'cmdbutton2' )
THIS.oformbutton.VISIBLE = .T.
THIS.oAddedobject.VISIBLE = .T.
ENDPROC
PROCEDURE DESTROY
CLEAR EVENTS
ENDPROC
ENDDEFINE
DEFINE CLASS cntContainer AS CONTAINER
ADD OBJECT oCenter AS center_it
CAPTION = 'Container'
HEIGHT = 120
PROCEDURE INIT
THIS.ADDOBJECT( 'ocmdButton', 'cmdbutton', 'Container Button' )
THIS.ocmdButton.VISIBLE = .T.
THIS.TOP = THIS.oCenter.T_B_center( THISFORM.HEIGHT, THIS.HEIGHT )
THIS.LEFT = THIS.oCenter.L_R_center( THISFORM.WIDTH, THIS.WIDTH )
ENDPROC
PROCEDURE Call_click
PARAMETERS cClickText
THIS.ocmdButton.CLICK( cClickText )
ENDPROC
ENDDEFINE
DEFINE CLASS ctlControl AS CONTROL
ADD OBJECT oCenter AS center_it
ADD OBJECT 'ocmdButton' AS 'cmdButton' NOINIT
* Cannot do ADDOBJECT() in INIT PROCEDURE (at run time) in Control.
* Must add with ADD OBJECT clause of DEFINE CLASS command.
CAPTION = 'Control'
HEIGHT = 120
PROCEDURE INIT
* The following command calls the ocmdButton INIT and passes
* the desired button caption to the INIT
THIS.ocmdButton.INIT( 'Control Button' )
THIS.TOP = THIS.oCenter.T_B_center( THISFORM.HEIGHT, THIS.HEIGHT )
THIS.LEFT = THIS.oCenter.L_R_center( THISFORM.WIDTH, THIS.WIDTH )
ENDPROC
PROCEDURE Call_click
PARAMETERS cClickText
THIS.ocmdButton.CLICK( cClickText )
ENDPROC
ENDDEFINE
DEFINE CLASS cmdbutton AS COMMANDBUTTON
PROCEDURE INIT
PARAMETERS cButtonCaption
THIS.WIDTH = 125
THIS.TOP = THIS.PARENT.oCenter.T_B_center ;
( THIS.PARENT.HEIGHT, THIS.HEIGHT )
THIS.LEFT = THIS.PARENT.oCenter.L_R_center ;
( THIS.PARENT.WIDTH, THIS.WIDTH )
THIS.CAPTION = cButtonCaption
ENDPROC
PROCEDURE CLICK
PARAMETERS cClickText
WAIT WINDOW IIF(TYPE('cClickText') = 'C', cClickText ;
,THIS.PARENT.CAPTION+' Button'+' Click in '+ '"' ;
+THIS.PARENT.CAPTION+'"') TIMEOUT 5
ENDPROC
ENDDEFINE
DEFINE CLASS cmdbutton2 AS COMMANDBUTTON
TOP = 215
CAPTION = 'Form Button'
PROCEDURE INIT
THIS.LEFT = (THIS.PARENT.WIDTH-THIS.WIDTH)/2
ENDPROC
PROCEDURE CLICK && Passes wait window message to display
* The following line causes an error when calling Click event
* of ocmdbutton in Control, but works properly when called
* in Container.
THIS.PARENT.oAddedobject.ocmdButton.CLICK('Click Event for ';
+'"'+THIS.PARENT.oAddedobject.CAPTION+' Button"'+' in ' ;
+'"'+THIS.PARENT.oAddedobject.CAPTION+'"'+' Called from '+'"' ;
+THIS.CAPTION+'"'+' Click')
THIS.PARENT.oAddedobject.Call_click( 'Click Event for ';
+'"'+THIS.PARENT.oAddedobject.CAPTION+' Button"' ;
+' Called Through Call_Click Procedure in '+'"' ;
+THISFORM.oAddedobject.CAPTION+'"')
ENDPROC
ENDDEFINE
* Define a class to center buttons, containers, & controls:
DEFINE CLASS center_it AS CUSTOM && s
FUNCTION T_B_center
PARAMETERS ncontheight nobjheight
RETURN (ncontheight-nobjheight)/2
ENDFUNC
FUNCTION L_R_center
PARAMETERS ncontwidth nobjwidth
RETURN (ncontwidth-nobjwidth)/2
ENDFUNC
ENDDEFINE
PROCEDURE errhand
PARAMETERS nError, cMess
DO CASE
CASE nerror = 1925
= MESSAGEBOX('Error # '+ALLTRIM(STR(nError))+ '. '+cMess;
+CHR(13)+CHR(13) ;
+'Member ocmdButton is unknown outside of Control!',48)
OTHERWISE
= MESSAGEBOX('Error # '+ALLTRIM(STR(nerror))+'. '+cMess)
ENDCASE
ENDPROC
Modification Type: | Major | Last Reviewed: | 8/13/1999 |
---|
Keywords: | KB134314 |
---|
|