* Sample call from a commandbutton.click on form oExplorer = NewObject('udfobjcollector','objectexplorer.prg') * No container passed - defaults to thisform * However here we didn't add but created object - IOW udfobjcollector is not part of thisform * Class type is not lightweight 'relation' but 'custom' just in case it might be added to form lnCount = oExplorer.GetCollection(thisform) wait window ltrim(str(lnCount)) && Show count oExplorer.listcollection() && List them *Objectexplorer.prg Define CLASS udfobjcollector AS custom Name = "udfobjcollector" *-- Array containing all object names for container [Object ref to a container]. *-- ie: this.FillCollection(thisform) - all thisform object names are in collection Dimension acollection[1] procedure GetCollection Lparameters toContainerObject, tlRecursing with this .FillCollection( iif(type('toContainerObject')='O',toContainerObject,thisform) ) return iif(type(".aCollection") = "L",0,alen(.aCollection)) endwith Endproc *-- Method to fill collection array aCollection with members of all contained objects Protected Procedure fillcollection Lparameters oContainerObject, tlRecursing With this If !tlRecursing Dimension .acollection[1] && Reset array .acollection=.f. Endif Local ix, nMembers, lnExpand, oObjectRef, aContainerObjects[1] nMembers = amembers(aContainerObjects, oContainerObject,2) For ix = 1 to nMembers && Start collecting lnExpand = iif(type(".aCollection[1]")= "L",0,1) Dimension .acollection[alen(.aCollection,1)+lnExpand] oObjectRef = eval("oContainerObject."+aContainerObjects[ix]) lcHierarchy = sys(1272,oObjectRef) .acollection[alen(.aCollection,1)] = ; stuff(lcHierarchy,1,at('.',lcHierarchy),'thisform.') .fillcollection(oObjectRef, .T.) && Recurse Endfor Endwith * Handle _screen and _vfp to also collect their objects * ... code removed to save space - use only for form and its container objects... Endproc Procedure listcollection If type("this.aCollection[1]") = "L" Wait window nowait "No members" Return Endif lcOldSafety = set("safety") Set safety off Set textmerge on Set textmerge to ("cobjects.txt") noshow overwrite Set textmerge on For each cObjectName in this.acollection \<< cObjectName >> Endfor Set textmerge to Set textmerge off Set safety &lcOldSafety Modi comm ("cobjects.txt") Endproc EnddefinePS: Type of recursion used here would bomb if container nesting exceeds 128 but I didn't care it here for I never do it in a form :)