#IF .F. Example: oSession = NEWOBJECT("SessionBase", "Session.PRG") oPrivate = oSession.Create("UseTable", "Data.VCX", "MyExample") oPrivate.Alias = "ProvInfo" ? oPrivate.Open() The oPrivate object operates in its own DS. I can be designed in the visual class designer, but when created by the Session, is private. #ENDIF DEFINE CLASS SessionBase AS Session DataSession = 2 && Private DSID = 0 && DataSessionID, but immutable. If you SET DATASESSION TO n && in this object, the DataSessionID can change. Use the DSID && to specify its original value. oParent = .NULL. DECLARE aChild[2,3] && We might have several objects living in this session. NewItemID = 1 && Number that corresponds to the last created object. Released = .F. && Lets us know if the Release has run. *************************** PROCEDURE Init (oParent) SET TALK OFF && Do this first, or things may be disrupted! CLS. IF VARTYPE(m.oParent) = "O" This.oParent = m.oParent ENDIF This.aChild = .NULL. SET DELETED ON SET EXCLUSIVE OFF SET MULTILOCKS ON SET NOTIFY OFF SET SAFETY OFF SET EXACT OFF SET NULLDISPLAY TO " " SET CENTURY ON This.DSID = This.DataSessionID && Now we know the original DataSessionID. RETURN ENDPROC *************************** PROCEDURE Create (ClassName, ClassLib, Token) * Create an object to live in this Session. * Pass the ClassName, ClassLib, and a Token Name or Number * that IDs the newly created object. LOCAL x, RetVal WITH This * First determine if already exists RetVal = .ReturnIfExists(m.Token) IF ISNULL(m.RetVal) * The requested token isn't currently in the array. * Intantiate the requested class. IF NOT EMPTY(m.ClassLib) IF ".PRG" $ m.ClassLib SET PROCEDURE TO (m.ClassLib) ADDITIVE ELSE SET CLASSLIB TO (m.ClassLib) ADDITIVE ENDIF ENDIF * If a Token isn't passed, use the next available array slot. IF VARTYPE(m.Token) = "N" .NewItemID = m.Token ELSE FOR x = 1 TO ALEN(.aChild,1) IF ISNULL(.aChild) x = m.x - 1 EXIT ENDIF ENDFOR .NewItemID = m.x + 1 ENDIF IF ALEN(.aChild,1) < .NewItemID DIMENSION .aChild[.NewItemID, 3] ENDIF .aChild[.NewItemID,1] = m.ClassName .aChild[.NewItemID,2] = CREATEOBJECT(m.ClassName) .aChild[.NewItemID,3] = m.Token RetVal = .aChild[.NewItemID,2] ENDIF RETURN m.RetVal ENDWITH ENDPROC *************************** PROCEDURE Release LOCAL x FOR x = 1 TO ALEN(This.aChild,1) IF NOT ISNULL(This.aChild[m.x,2]) This.aChild[m.x,2].Release() ENDIF ENDFOR This.Released = .T. RELEASE This ENDPROC *************************** PROCEDURE Destroy IF NOT This.Released This.Release() ENDIF ENDPROC *************************** PROCEDURE ReturnIfExists (Token) LOCAL RetVal RetVal = .NULL. IF INLIST(VARTYPE(m.Token),"C","N") IF VARTYPE(m.Token) = "N" && Token is Numeric. && Determine if it is a live element. IF m.Token <= ALEN(This.aChild,1) ; AND NOT ISNULL(This.aChild[m.Token,2]) RetVal = This.aChild[m.Token,2] ENDIF ELSE * Token is Character. See if it matches a token for a live element. FOR x = 1 TO ALEN(This.aChild,1) IF VARTYPE(This.aChild[m.x,3]) = "C" ; AND This.aChild[m.x,3] == m.Token Retval = This.aChild[m.x,2] ENDIF ENDFOR ENDIF ENDIF RETURN m.RetVal ENDPROC *************************** PROCEDURE ReadMe #IF .F. This class is to be used to hold any other object that requires it's own private data session. Use CREATEOBJECT(), not ADDOBJECT() to create an object based on this class. If you add this object to the _SCREEN no DataSession will becreated. If you add any object to the screen, then use AddObject to add this object to that object, no DataSession will be created. But..... If you add this object to a Form, you may change to this object's DataSessionID. Be advised that you may change the objectform's DataSessionID too, if they are currently the same. This is why we use the DSID. It shouldn't be changed. #ENDIF' ENDPROC ENDDEFINE