Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Scanning all objects/controls on a form 3

Status
Not open for further replies.

vj

Programmer
Nov 18, 2000
58
0
0
MU
hi everyone,

i have a form with different controls , textboxes ,,, buttons ,, list boxes ,,, grids ,,, checkboxes ,,, etc etc ... can anyone tell me how i can scan or list all the controls i have on the form ?

thankx alot
Vijay

 
Pleas try

Code:
FOR EACH loctrl IN ThisForm.Controls
	MESSAGEBOX(loctrl.Name)
NEXT
* or
FOR lni=1 TO ThisForm.ControlCount
	loctrl=ThisForm.Controls[lni]
	MESSAGEBOX(loctrl.Name)
NEXT

Respectfully,
Vilhelm-Ion Praisach
Resita, Romania
 
Hi Vijay,

Vilhelm-Ion has given you a good answer. But keep in mind that, if any of the controls are themselves containers, you will need to drill down within them to find the contained controls. This would apply to grids, pageframes, pages, option groups, and a few others.

If this is likely to be an issue, let us know and I or someone will give you some more detailed code.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
In fact, I just found some of my code that visits each control on a form, recursively drilling down into container controls.

To use it, create a new method for your form, named VisitControls. Then, add the code shown below to the method. Finally, call the method, passing an object reference to the form itself. For example, call it from a button on the form, like this: [tt]THISFORM.VisitControls(THISFORM)[/tt].

Here is the code:

Code:
* Recursively visits the controls in the current container. 
LPARAMETERS toContainer

LOCAL loObject

* Perform the required action for the container itself.
* In this example, we are simply displaying the name of 
* the object. Add your own code here to do whatever you
* want to do with the object.
WAIT WINDOW toContainer.Name NOWAIT 

* Loop through the controls in the container
FOR EACH loObject IN toContainer.Objects

  IF PEMSTATUS(loObject, "objects", 5 )
    * Control has an objects collection, so is itself a container; 
    * call the method recursively
    this.VisitControls(loObject)
      
  ELSE
  
  	* Control is a non-container; perform the specified action. Again,
        * add your own code here to do whatever you want to with the control.
  	WAIT WINDOW loObject.Name NOWAIT 
  	
  ENDIF 
  
ENDFOR

You could improve the code, for example by calling another method of the form that executes some action on the control. You would do that in place of the WAIT WINDOWs in my example. Going one step further, you could add this method to your base form class, and create an abstract method to execute the action. But the above code should be enough to get started.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
hi everyone,

thankx for the replies ... i'v tried Vilhelm-Ion idea ... very nice and simple .... mike .. i'll try your code now .. but i have another small question ... i want the list of controls and also what type of control it is ?... if it is a combobox , listbox , grid , command button or options or check box ... ???

thankx
vijay
 
How about USE your.scx?
See Objname, Class, Classloc, Baseclass, Parent,....

Bye, Olaf.
 
...besides, staying with the code so fare, every control has it's baseclass, class, etc properties you can also list/display. The objects you have in the Container/Form.Objects array are having all the properties you also see in the property window, when in the form designer, so besides loObject.Name you also have loObject.Class, loObject.BaseClass, etc.

Simply set a breakpoint in the code, add loObject to the Watch Window and drill down to see what you get there.

Bye, Olaf.
 
i want the list of controls and also what type of control it is ?... if it is a combobox , listbox , grid , command button or options or check box ... ???

Take the same code that we have given you, but display the [tt] .Class [/tt] property as well as the [tt] .Name [/tt] property.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Just for fun, a non-recursive version.

Code:
PROCEDURE ctrlnonrec 
LPARAMETERS loStart
LOCAL laStack[200,2],lnLevel,loObj,lni,lcName,llCont,lnObj
STRTOFILE(CAST("Baseclass" AS C(20))+CAST("Class" AS C(30))+"Name"+CHR(13)+CHR(10),"txt.txt")
llCont=.F.
IF PEMSTATUS(m.loStart,"objects",5)
	lnObj=IIF(UPPER(m.loStart.baseclass)="GRID",m.loStart.columncount,m.loStart.objects.count)
	IF m.lnObj>0
		llCont=.T.
	ENDIF
ENDIF
IF m.llCont
	lnLevel=1
	laStack[m.lnLevel,1]=1
	laStack[m.lnLevel,2]=m.loStart
	DO WHILE m.lnLevel>0
		lnObj=IIF(UPPER(m.laStack[m.lnLevel,2].baseclass)="GRID",m.laStack[m.lnLevel,2].columncount,m.laStack[m.lnLevel,2].objects.count)
		IF m.laStack[m.lnLevel,1]<=m.lnObj
			loObj=m.laStack[m.lnLevel,2].objects(m.laStack[m.lnLevel,1])
			lcName=""
			FOR lni=1 TO m.lnLevel
				lcName=m.lcName+m.laStack[m.lni,2].name+"."
			NEXT
			lcName=m.lcName+m.loObj.Name
			STRTOFILE(CAST(m.loObj.baseclass AS C(20))+CAST(m.loObj.class AS C(30))+m.lcName+CHR(13)+CHR(10),"txt.txt",1)
			llCont=.F.
			IF PEMSTATUS(m.loObj,"objects",5)
				lnObj=IIF(UPPER(m.loObj.baseclass)="GRID",m.loObj.columncount,m.loObj.objects.count)
				IF m.lnObj>0
					llCont=.T.
				ENDIF
			ENDIF
			IF m.llCont
				lnLevel=m.lnLevel+1
				laStack[m.lnLevel,1]=1
				laStack[m.lnLevel,2]=m.loObj
			ELSE
				laStack[m.lnLevel,1]=m.laStack[m.lnLevel,1]+1
			ENDIF
		ELSE
			lnLevel=m.lnLevel-1
			IF m.lnLevel>0
				laStack[m.lnLevel,1]=m.laStack[m.lnLevel,1]+1
			ENDIF
		ENDIF
	ENDDO
ENDIF
RETURN

and a demo

Code:
PUBLIC oFrm
oFrm=CREATEOBJECT("MyForm")
oFrm.Show()

PROCEDURE ctrlnonrec 
LPARAMETERS loStart
LOCAL laStack[200,2],lnLevel,loObj,lni,lcName,llCont,lnObj
STRTOFILE(CAST("Baseclass" AS C(20))+CAST("Class" AS C(30))+"Name"+CHR(13)+CHR(10),"txt.txt")
llCont=.F.
IF PEMSTATUS(m.loStart,"objects",5)
	lnObj=IIF(UPPER(m.loStart.baseclass)="GRID",m.loStart.columncount,m.loStart.objects.count)
	IF m.lnObj>0
		llCont=.T.
	ENDIF
ENDIF
IF m.llCont
	lnLevel=1
	laStack[m.lnLevel,1]=1
	laStack[m.lnLevel,2]=m.loStart
	DO WHILE m.lnLevel>0
		lnObj=IIF(UPPER(m.laStack[m.lnLevel,2].baseclass)="GRID",m.laStack[m.lnLevel,2].columncount,m.laStack[m.lnLevel,2].objects.count)
		IF m.laStack[m.lnLevel,1]<=m.lnObj
			loObj=m.laStack[m.lnLevel,2].objects(m.laStack[m.lnLevel,1])
			lcName=""
			FOR lni=1 TO m.lnLevel
				lcName=m.lcName+m.laStack[m.lni,2].name+"."
			NEXT
			lcName=m.lcName+m.loObj.Name
			STRTOFILE(CAST(m.loObj.baseclass AS C(20))+CAST(m.loObj.class AS C(30))+m.lcName+CHR(13)+CHR(10),"txt.txt",1)
			llCont=.F.
			IF PEMSTATUS(m.loObj,"objects",5)
				lnObj=IIF(UPPER(m.loObj.baseclass)="GRID",m.loObj.columncount,m.loObj.objects.count)
				IF m.lnObj>0
					llCont=.T.
				ENDIF
			ENDIF
			IF m.llCont
				lnLevel=m.lnLevel+1
				laStack[m.lnLevel,1]=1
				laStack[m.lnLevel,2]=m.loObj
			ELSE
				laStack[m.lnLevel,1]=m.laStack[m.lnLevel,1]+1
			ENDIF
		ELSE
			lnLevel=m.lnLevel-1
			IF m.lnLevel>0
				laStack[m.lnLevel,1]=m.laStack[m.lnLevel,1]+1
			ENDIF
		ENDIF
	ENDDO
ENDIF
RETURN

DEFINE CLASS MyForm as Form
	height=300
	ADD OBJECT txt as textbox
	ADD OBJECT cmd as commandbutton WITH top=280
	ADD OBJECT cmd2 as commandbutton WITH top=280,left=150
	ADD OBJECT pg as pageframe WITH pagecount=3
	ADD OBJECT grd as grid WITH columncount=3,top=25
	ADD OBJECT ct as container
	ADD OBJECT op as optiongroup WITH ButtonCount=3
	ADD OBJECT ob as commandgroup WITH ButtonCount=5
	PROCEDURE init
		This.AddObject("txt2","textbox")
		This.grd.column1.AddObject("txt2","textbox")
		This.ct.AddObject("txt1","textbox")
		This.ct.AddObject("grd","grid")
		This.ct.grd.columncount=2
	ENDPROC
	PROCEDURE cmd.click
		DO ctrlnonrec  WITH ThisForm
		MODIFY FILE txt.txt
	ENDPROC 
ENDDEFINE

Respectfully,
Vilhelm-Ion Praisach
Resita, Romania
 
This upgraded version support collections and _vfp. Also infinite loops are avoided.

This is the procedure:
Code:
PROCEDURE ctrlnonrec 
LPARAMETERS loStart
LOCAL laStack[200,2],lnLevel,loObj,lni,lcName,llCont,lnObj
IF VARTYPE(m.loStart)!="O" OR ISNULL(m.loStart) && test for not an object
	STRTOFILE(TRANSFORM(m.loStart)+" is not an object","txt.txt")
	RETURN
ENDIF
llCont=.F.
IF PEMSTATUS(m.loStart,"objects",5) OR UPPER(m.loStart.baseclass)="COLLECTION"
	lnObj=IIF(!PEMSTATUS(m.loStart,"baseclass",5),m.loStart.objects.count,; && _vfp
			IIF(UPPER(m.loStart.baseclass)="COLLECTION",m.loStart.count,; && collection
				IIF(UPPER(m.loStart.baseclass)="GRID",m.loStart.columncount,; && grid
					m.loStart.objects.count)))
	IF m.lnObj>0
		llCont=.T.
		STRTOFILE(CAST("Baseclass" AS C(20))+CAST("Class" AS C(30))+"Name"+CHR(13)+CHR(10),"txt.txt") && txt file header
	ENDIF
ENDIF
IF m.llCont
	lnLevel=1
	laStack[m.lnLevel,1]=1
	laStack[m.lnLevel,2]=m.loStart
	DO WHILE m.lnLevel>0
		lnObj=IIF(!PEMSTATUS(m.laStack[m.lnLevel,2],"baseclass",5),m.laStack[m.lnLevel,2].objects.count,; && _vfp
				IIF(UPPER(m.laStack[m.lnLevel,2].baseclass)="COLLECTION",m.laStack[m.lnLevel,2].count,; && collection
					IIF(UPPER(m.laStack[m.lnLevel,2].baseclass)="GRID",m.laStack[m.lnLevel,2].columncount,; && grid
						m.laStack[m.lnLevel,2].objects.count)))
		IF m.laStack[m.lnLevel,1]<=m.lnObj
			IF m.laStack[m.lnLevel,2]=_vfp
					loObj=m.laStack[m.lnLevel,2].objects(m.laStack[m.lnLevel,1])
			ELSE
				IF UPPER(m.laStack[m.lnLevel,2].baseclass)="COLLECTION"
					loObj=m.laStack[m.lnLevel,2]
					loObj=m.loObj.item(m.laStack[m.lnLevel,1])
				ELSE
					loObj=m.laStack[m.lnLevel,2].objects(m.laStack[m.lnLevel,1])
				ENDIF
			ENDIF
			m.llCont=VARTYPE(loObj)="O" AND !ISNULL(loObj) && check for nonobjects in collections
			IF m.llCont && check for infinite loop in collections
				FOR lni=1 TO m.lnLevel-1
					IF m.laStack[m.lnLevel,2]=m.laStack[m.lni,2] && regular objects
						m.llCont=.F.
						EXIT
					ENDIF
					IF PEMSTATUS(m.laStack[m.lnLevel,2],"hwnd",5) AND PEMSTATUS(m.laStack[m.lni,2],"hwnd",5) && forms and _vfp
						IF m.laStack[m.lnLevel,2].hwnd=m.laStack[m.lni,2].hwnd
							m.llCont=.F.
							EXIT
						ENDIF
					ENDIF
				NEXT
			ENDIF
			IF m.llCont
				lcName=""
				FOR lni=1 TO m.lnLevel
					lcName=m.lcName+m.laStack[m.lni,2].name+"."
				NEXT
				lcName=m.lcName+m.loObj.Name
				IF PEMSTATUS(m.loObj,"baseclass",5) && precautions for _vfp
					STRTOFILE(CAST(m.loObj.baseclass AS C(20))+CAST(m.loObj.class AS C(30))+m.lcName+CHR(13)+CHR(10),"txt.txt",1)
				ELSE
					STRTOFILE(CAST("_vfp" AS C(20))+CAST("_vfp" AS C(30))+m.lcName+CHR(13)+CHR(10),"txt.txt",1)
				ENDIF
				llCont=.F.
				IF PEMSTATUS(m.loObj,"objects",5) OR IIF(!PEMSTATUS(m.loObj,"baseclass",5),.F.,UPPER(m.loObj.baseclass)="COLLECTION")
					lnObj=IIF(!PEMSTATUS(m.loObj,"baseclass",5),m.loObj.objects.count,; && _vfp
							IIF(UPPER(m.loObj.baseclass)="COLLECTION",m.loObj.count,; && collection
								IIF(UPPER(m.loObj.baseclass)="GRID",m.loObj.columncount,; && grid
									m.loObj.objects.count)))
					IF m.lnObj>0
						llCont=.T.
					ENDIF
				ENDIF
				IF m.llCont
					lnLevel=m.lnLevel+1
					laStack[m.lnLevel,1]=1
					laStack[m.lnLevel,2]=m.loObj
				ELSE
					laStack[m.lnLevel,1]=m.laStack[m.lnLevel,1]+1
				ENDIF
			ELSE
				laStack[m.lnLevel,1]=m.laStack[m.lnLevel,1]+1
			ENDIF
		ELSE
			lnLevel=m.lnLevel-1
			IF m.lnLevel>0
				laStack[m.lnLevel,1]=m.laStack[m.lnLevel,1]+1
			ENDIF
		ENDIF
	ENDDO
ELSE
	STRTOFILE(m.loStart.Name+" has no collection","txt.txt")
ENDIF
RETURN

This is the demo :
Code:
PUBLIC oFrm
oFrm=CREATEOBJECT("MyForm")
oFrm.Show()

PROCEDURE ctrlnonrec 
LPARAMETERS loStart
LOCAL laStack[200,2],lnLevel,loObj,lni,lcName,llCont,lnObj
IF VARTYPE(m.loStart)!="O" OR ISNULL(m.loStart) && test for not an object
	STRTOFILE(TRANSFORM(m.loStart)+" is not an object","txt.txt")
	RETURN
ENDIF
llCont=.F.
IF PEMSTATUS(m.loStart,"objects",5) OR UPPER(m.loStart.baseclass)="COLLECTION"
	lnObj=IIF(!PEMSTATUS(m.loStart,"baseclass",5),m.loStart.objects.count,; && _vfp
			IIF(UPPER(m.loStart.baseclass)="COLLECTION",m.loStart.count,; && collection
				IIF(UPPER(m.loStart.baseclass)="GRID",m.loStart.columncount,; && grid
					m.loStart.objects.count)))
	IF m.lnObj>0
		llCont=.T.
		STRTOFILE(CAST("Baseclass" AS C(20))+CAST("Class" AS C(30))+"Name"+CHR(13)+CHR(10),"txt.txt") && txt file header
	ENDIF
ENDIF
IF m.llCont
	lnLevel=1
	laStack[m.lnLevel,1]=1
	laStack[m.lnLevel,2]=m.loStart
	DO WHILE m.lnLevel>0
		lnObj=IIF(!PEMSTATUS(m.laStack[m.lnLevel,2],"baseclass",5),m.laStack[m.lnLevel,2].objects.count,; && _vfp
				IIF(UPPER(m.laStack[m.lnLevel,2].baseclass)="COLLECTION",m.laStack[m.lnLevel,2].count,; && collection
					IIF(UPPER(m.laStack[m.lnLevel,2].baseclass)="GRID",m.laStack[m.lnLevel,2].columncount,; && grid
						m.laStack[m.lnLevel,2].objects.count)))
		IF m.laStack[m.lnLevel,1]<=m.lnObj
			IF m.laStack[m.lnLevel,2]=_vfp
					loObj=m.laStack[m.lnLevel,2].objects(m.laStack[m.lnLevel,1])
			ELSE
				IF UPPER(m.laStack[m.lnLevel,2].baseclass)="COLLECTION"
					loObj=m.laStack[m.lnLevel,2]
					loObj=m.loObj.item(m.laStack[m.lnLevel,1])
				ELSE
					loObj=m.laStack[m.lnLevel,2].objects(m.laStack[m.lnLevel,1])
				ENDIF
			ENDIF
			m.llCont=VARTYPE(loObj)="O" AND !ISNULL(loObj) && check for nonobjects in collections
			IF m.llCont && check for infinite loop in collections
				FOR lni=1 TO m.lnLevel-1
					IF m.laStack[m.lnLevel,2]=m.laStack[m.lni,2] && regular objects
						m.llCont=.F.
						EXIT
					ENDIF
					IF PEMSTATUS(m.laStack[m.lnLevel,2],"hwnd",5) AND PEMSTATUS(m.laStack[m.lni,2],"hwnd",5) && forms and _vfp
						IF m.laStack[m.lnLevel,2].hwnd=m.laStack[m.lni,2].hwnd
							m.llCont=.F.
							EXIT
						ENDIF
					ENDIF
				NEXT
			ENDIF
			IF m.llCont
				lcName=""
				FOR lni=1 TO m.lnLevel
					lcName=m.lcName+m.laStack[m.lni,2].name+"."
				NEXT
				lcName=m.lcName+m.loObj.Name
				IF PEMSTATUS(m.loObj,"baseclass",5) && precautions for _vfp
					STRTOFILE(CAST(m.loObj.baseclass AS C(20))+CAST(m.loObj.class AS C(30))+m.lcName+CHR(13)+CHR(10),"txt.txt",1)
				ELSE
					STRTOFILE(CAST("_vfp" AS C(20))+CAST("_vfp" AS C(30))+m.lcName+CHR(13)+CHR(10),"txt.txt",1)
				ENDIF
				llCont=.F.
				IF PEMSTATUS(m.loObj,"objects",5) OR IIF(!PEMSTATUS(m.loObj,"baseclass",5),.F.,UPPER(m.loObj.baseclass)="COLLECTION")
					lnObj=IIF(!PEMSTATUS(m.loObj,"baseclass",5),m.loObj.objects.count,; && _vfp
							IIF(UPPER(m.loObj.baseclass)="COLLECTION",m.loObj.count,; && collection
								IIF(UPPER(m.loObj.baseclass)="GRID",m.loObj.columncount,; && grid
									m.loObj.objects.count)))
					IF m.lnObj>0
						llCont=.T.
					ENDIF
				ENDIF
				IF m.llCont
					lnLevel=m.lnLevel+1
					laStack[m.lnLevel,1]=1
					laStack[m.lnLevel,2]=m.loObj
				ELSE
					laStack[m.lnLevel,1]=m.laStack[m.lnLevel,1]+1
				ENDIF
			ELSE
				laStack[m.lnLevel,1]=m.laStack[m.lnLevel,1]+1
			ENDIF
		ELSE
			lnLevel=m.lnLevel-1
			IF m.lnLevel>0
				laStack[m.lnLevel,1]=m.laStack[m.lnLevel,1]+1
			ENDIF
		ENDIF
	ENDDO
ELSE
	STRTOFILE(m.loStart.Name+" has no collection","txt.txt")
ENDIF
RETURN

DEFINE CLASS MyForm as Form
	height=300
	ADD OBJECT txt as textbox
	ADD OBJECT cmd as commandbutton WITH top=280
	ADD OBJECT cmd2 as commandbutton WITH top=280,left=150
	ADD OBJECT pg as pageframe WITH pagecount=3
	ADD OBJECT grd as grid WITH columncount=3,top=25
	ADD OBJECT ct as container
	ADD OBJECT op as optiongroup WITH ButtonCount=3
	ADD OBJECT ob as commandgroup WITH ButtonCount=5
	ADD OBJECT cl as collection
	ADD OBJECT teeview as olecontrol WITH oleclass="Mscomctllib.treectrl.2",width=100,height=100,left=200
	PROCEDURE init
		This.AddObject("txt2","textbox")
		This.grd.column1.AddObject("txt2","textbox")
		This.ct.AddObject("txt1","textbox")
		This.ct.AddObject("grd","grid")
		This.ct.grd.columncount=2
		thisform.TeeView.Nodes.Add(, 1, SYS(2015),'One node')
		this.cl.add("txt1")
		this.cl.add(ThisForm.txt)
		this.cl.add("txt2")
		this.cl.add(ThisForm.ct)
*		this.cl.add(ThisForm) && test for infinite loop
*		this.cl.add(_vfp) && combinations: thisform(here)+thisform(in cmd.click), thisform+_vfp, _vfp+_vfp, _vfp+thisform
	ENDPROC
	PROCEDURE cmd.click
		DO ctrlnonrec  WITH ThisForm
*		DO ctrlnonrec  WITH _vfp
*		DO ctrlnonrec  WITH ThisForm.cl
*		DO ctrlnonrec  WITH ThisForm.cl(1) && test for not an object
*		DO ctrlnonrec  WITH ThisForm.txt && test for no collection
		MODIFY FILE txt.txt
	ENDPROC 
ENDDEFINE

Respectfully,
Vilhelm-Ion Praisach
Resita, Romania
 
Upgraded Mr. Mike Lewis's VisitControl with support for collections and _vfp, but without avoiding infinite loops.
My idea is to put visited controls in an array or something and compare the current container with them.

Code:
PUBLIC oFrm
oFrm=CREATEOBJECT("MyForm")
oFrm.Show()

DEFINE CLASS MyForm as Form
	height=300
	ADD OBJECT txt as textbox
	ADD OBJECT cmd as commandbutton WITH top=280
	ADD OBJECT cmd2 as commandbutton WITH top=280,left=150
	ADD OBJECT pg as pageframe WITH pagecount=3
	ADD OBJECT grd as grid WITH columncount=3,top=25
	ADD OBJECT ct as container
	ADD OBJECT op as optiongroup WITH ButtonCount=3
	ADD OBJECT ob as commandgroup WITH ButtonCount=5
	ADD OBJECT cl as collection
	ADD OBJECT teeview as olecontrol WITH oleclass="Mscomctllib.treectrl.2",width=100,height=100,left=200
	PROCEDURE VisitControls
		* Recursively visits the controls in the current container. 
		LPARAMETERS toContainer
		LOCAL loObject,llCol
		* Perform the required action for the container itself.
		* In this example, we are simply displaying the name of 
		* the object. Add your own code here to do whatever you
		* want to do with the object.
		IF VARTYPE(m.toContainer)<>"O" OR ISNULL(m.toContainer)
			STRTOFILE(m.toContainer+" is not an object"+CHR(13)+CHR(10),"txt.txt",1)
			RETURN
		ENDIF
		IF PEMSTATUS(m.toContainer, "objects", 5 ) OR UPPER(m.toContainer.baseclass)="COLLECTION"
			IF PEMSTATUS(m.toContainer,"baseclass",5) && precautions for _vfp
				STRTOFILE(CAST(m.toContainer.baseclass AS C(20))+CAST(m.toContainer.class AS C(30))+m.toContainer.Name+CHR(13)+CHR(10),"txt.txt",1)
			ELSE
				STRTOFILE(CAST("_vfp" AS C(20))+CAST("_vfp" AS C(30))+m.toContainer.Name+CHR(13)+CHR(10),"txt.txt",1)
			ENDIF
			* Loop through the controls in the container
			llCol=.F. && check for collections
			IF PEMSTATUS(m.toContainer,"baseclass",5)
				IF UPPER(m.toContainer.baseclass)="COLLECTION" && collections
					llCol=.T.
				ENDIF
			ENDIF
			IF m.llCol && collection
				FOR EACH loObject IN m.toContainer
				    IF VARTYPE(loObject)="O" AND !ISNULL(loObject)
					  IF PEMSTATUS(loObject, "objects", 5 ) OR UPPER(m.loObject.baseclass)="COLLECTION"
					    * Control has an objects collection, so is itself a container; 
					    * call the method recursively
						    this.VisitControls(loObject)
					  ELSE
					  	* Control is a non-container; perform the specified action. Again,
					        * add your own code here to do whatever you want to with the control.
					  	STRTOFILE(CAST(m.loObject.baseclass AS C(20))+CAST(m.loObject.class AS C(30))+m.loObject.Name+CHR(13)+CHR(10),"txt.txt",1)
					  ENDIF 
					ENDIF
				  
				ENDFOR 
			ELSE && other type
				FOR EACH loObject IN m.toContainer.Objects
				  IF PEMSTATUS(loObject, "objects", 5 ) OR UPPER(m.loObject.baseclass)="COLLECTION"
				    * Control has an objects collection, so is itself a container; 
				    * call the method recursively
				    IF VARTYPE(loObject)="O" AND !ISNULL(loObject)
					    this.VisitControls(loObject)
					ENDIF
				  ELSE
				  	* Control is a non-container; perform the specified action. Again,
				        * add your own code here to do whatever you want to with the control.
				  	STRTOFILE(CAST(m.loObject.baseclass AS C(20))+CAST(m.loObject.class AS C(30))+m.loObject.Name+CHR(13)+CHR(10),"txt.txt",1)
				  	
				  ENDIF 
				  
				ENDFOR 
			ENDIF
		ELSE
			STRTOFILE(CAST(m.toContainer.baseclass AS C(20))+CAST(m.toContainer.class AS C(30))+m.toContainer.Name+CHR(13)+CHR(10),"txt.txt",1)
		ENDIF
	ENDPROC
	PROCEDURE init
		This.AddObject("txt2","textbox")
		This.grd.column1.AddObject("txt2","textbox")
		This.ct.AddObject("txt1","textbox")
		This.ct.AddObject("grd","grid")
		This.ct.grd.columncount=2
		thisform.TeeView.Nodes.Add(, 1, SYS(2015),'One node')
		this.cl.add("txt1")
		this.cl.add(ThisForm.txt)
		this.cl.add("txt2")
		this.cl.add(ThisForm.ct)
*		this.cl.add(ThisForm) && test for infinite loop not implemented
*		this.cl.add(_vfp) && combinations: thisform(here)+thisform(in cmd.click), thisform+_vfp, _vfp+_vfp, _vfp+thisform
	ENDPROC
	PROCEDURE cmd.click
	ENDPROC 
	PROCEDURE cmd2.click
		STRTOFILE(CAST("Baseclass" AS C(20))+CAST("Class" AS C(30))+"Name"+CHR(13)+CHR(10),"txt.txt")
		ThisForm.VisitControls(ThisForm)
*		ThisForm.VisitControls(_vfp)
*		ThisForm.VisitControls(ThisForm.cl)
*		ThisForm.VisitControls(ThisForm.cl(1))
*		ThisForm.VisitControls(ThisForm.txt)
		MODIFY FILE txt.txt
	ENDPROC
ENDDEFINE


Respectfully,
Vilhelm-Ion Praisach
Resita, Romania
 
hi everyone again..

thankx for all the replies ... sorry did'nt get the time to work on this thread ... well .. actually the whole idea was to replicate a process of having to change the look and feel of the application with all the forms in it ... by defining colors and design style to the various controls on the forms ... but dont have time to play with that just right now ... i'v got something else to do now ... will come back .. when i have something ... but thankx for all the replies

thankx
vijay
 
Well, the right approach to doing global appearance changes isn't visiting every control on every form. It's subclassing the VFP base classes and using ONLY your own subclasses throughout the application. When you want to change appearance you change your class definitions and all of the instances inherit the changes.
 
Well, the right approach to doing global appearance changes isn't visiting every control on every form. It's subclassing the VFP base classes and using ONLY your own subclasses throughout the application. When you want to change appearance you change your class definitions and all of the instances inherit the changes.

That's assuming you want to make the changes at design time. I've worked on projects where the users needed to be able to change colours and fonts on the fly, and to apply those changes to all open forms. In those cases, you would need some method of visiting each control in turn to make the change.

Also, on my standard data entry form, I have a method that visits each control to toggle its edit mode status.

I assumed that Vijay wanted to do something more or less along those lines.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Well, there are other methods to cascade visual changes with the cascading Refresh() method and via .SetAll() of properties defined on all similar controls, eg Form.Setall("Fontname",gcFontname) or even your own properties, which handle changes on the class level by property_assign() methods, SetAll also allows to limit this to a certain class. It pays to have your own classes instead of base classes for that matter.

Bye, Olaf.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top