SWAGOLX.EXE (c) 1993 GDSOFT ALL RIGHTS RESERVED 00002 STREAM HANDLING ROUTINES 1 05-28-9313:57ALL SWAG SUPPORT TEAM STREAMS1.PAS IMPORT 48 ·┐∙ {πI have a question about registration of Objects to allow themπto be Put on the TDosStream. I want to Write my own Get Function,πbut I don't know the name of Variable or even address which pointsπto the Array of Records of just registered Objects. I would likeπto search For appriopriate Record on my own. Is it possible in TV6.0ππHere si an article that was posted some time ago about locatingπthe tStreamRec suite in memory: I think it is what you want:ππ> BJ> I am looking For the location of the RegisterTypesπ> BJ> Variables. if you make an Register of your Object- where itπ> BJ> is stored ? Can I access it through a standard Variable ?π>if you look up the definition of TStreamRec on page 380 of the TVisionπ>manual a lot may become clearer to your.ππ As any Typed Constants (another name could be initialized Variables)π the tStreamRecs are stored in the DATA segment. The actual content is :π PStreamRec = ^TStreamRec;π TStreamRec = Recordπ ObjType: Word;π VmtLink: Word;π Load: Pointer;π Store: Pointer;π Next: Word; <====== this is the link to a next tStreamRecπ end;π When registering a View , the Procedure RegisterType simply addsπ the new tStreamRec at the top of a stack by filling in the fieldπ Next (a Word only) since the segment is always DSEG.π This Field now points to the offset in DSEG of theπ previously registered view...π The top of the stack is located in a Word Variableπ which is private to the Objects Unit... No way to get it ???ππ The trick is to register an extra dummy view after all your Realπ registrations.π The private topofStack(???) Variable will now point to the offset ofπ the Dummy View, and THE NEXT field of the dummy view will pointπ to THE LAST REGISTERED VIEW. This is the beginning of the threadπ were are looking For....π Just follow back the NEXT Fields Until a value of 0 that indicatesπ the end of the stack (i.e; the first registered view )π The following Program prints out the Stack of all the tSreamRecπ starting from the dummy view back to the tView streamRec whichπ is normally the first registered item.π We are using the technique to avoid the infamous Runtime error 212π ( registration of an already registered Type ) , quite commonπ if you include the registration process in the initialization partπ of Units . Simply Write a Function IsRegistered that take asπ a parameter a tStreamRec and return True if member of the Stack .π ( code is Really similar to the exemple below )π Replace any call to RegisterType(MyStreamRec) byπ if not IsRegistered (MyStreamRec) then RegisterType(MyStreamRec)π---------------------------------------------------------------------------}πProgram ShowStreamRecs;π{ (C) P.Pollet National Institute For Applied Sciences (inSA)π Lyon France 1992 ppollet@cismibm.univ-lyon1.fr }πUses Drivers,Objects,views,Dialogs,Menus;πConstπ RDummyView: TStreamRec = (π ObjType: $FFFF;π VmtLink: 0;π Load: NIL;π Store: NILπ );πFunction PtrtoStr(P:Pointer):String;π{ convert a Ptr to Hex representation }πVar S:String;π Param:Array[0..1] of LongInt;πbeginπ Param[0]:=Seg(P^);π Param[1]:=ofs(P^);π FormatStr(S,'%x:%x',Param);π PtrtoStr:=Sπend;πFunction WordtoHex(W:Word):String;π{ convert a Word to Hex representation }πVar S:String;π Param: LongInt;πbeginπ Param:=W;π FormatStr(S,'%x',Param);π WordtoHex:=Sπend;πProcedure ShowThem;π{ show the stack or the tStreamrec in DSeg }πVar Base:Word;π Pt:PstreamRec;π Procedure ShowArec (Var R:tstreamRec);π { display Info on the tstreamrec R}π { the Var is only to Pass the Real Address of Rπ and not the address of its copy on the stack !!! }π beginπ With R doπ beginπ Writeln ('AT =',PtrtoStr(@R)); { gives the address of the StreamRec}π Writeln ('ObjType =',ObjType); { what Object is it see TV6 doc}π Writeln ('VTMLink =',VmTlink); { offset of VMT table also in DSEG }π Writeln ('LOAD =',PtrtoStr(Load)); { address of Load Constructor }π Writeln ('StoRE =',PtrtoStr(Store)); { address of store method }π Writeln ('Next =',WordtoHex(Next)); { offset in DSEG of next item }π Writeln;π endπ end;πbeginπ Base:=ofs(RDummyView); { start at Dummy view }π Repeatπ Pt:=Ptr(DSeg,Base); {Real address is DSG:base}π ShowARec(Pt^); {Display this tStreamRec }π Base:=Pt^.Next; { move to previous item }π Until Base=0 { Until first reached }πend;πbeginπ {Assign(Output,'RegType.log');}π ReWrite(Output);π RegisterViews; { register some from TV }π RegisterDialogs;π RegisterMenus;π RegisterType(RDummyView); { doN'T ForGET the DummyView at Last ! }π ShowThem;π Close(Output)πend.π(*πThis is a partial print out of the output ...πAT =86DC:2 { my Dumy View }πObjType =65535πVTMLink =0πLOAD =0:0πStoRE =0:0πNext =128 <---- { Real offset of the first VIEW }π |πAT =86DC:128 <---- { the last register View }πObjType =42 { it is tStatusLine Type =42 }πVTMLink =184πLOAD =79AB:1A84πStoRE =79AB:22E9πNext =11A <----π |πAT =86DC:11A <---- { this is tMenuBox }πObjType =41πVTMLink =100πLOAD =79AB:247πStoRE =79AB:1171πNext =10Cπ...................................π cut to save spaceπ...................................πAT =86DC:91A { this is the first registered }πObjType =1 { tView Type =1 }πVTMLink =1726πLOAD =7F1C:2C1πStoRE =7F1C:18FEπNext =0 {<----- Next =0 so Last One of the Stack }πHope it helps you ... Let me know ...ππof course With TP7, since you have the sources code, you mayπmodify the OBjECTS Unit( ?) to move the Typed Constant that points atπthe top of the list from the Implementation part of the Unit to theπInterface part....π 2 05-28-9313:57ALL SWAG SUPPORT TEAM STREAMS2.PAS IMPORT 9 ·┐å╪ {π> I would like to start on a Program that reads a certain File. Theπ> problem is that the Records are of different lenghts. The Fileπ> structure is as follows: One File contains the header For each Recordπ> which is kept in a seperate File. The header has a Word Variable whichπ> is the size of the Record in the other File. It also has a Integerπ> With points to the Record number in the other File.ππThe easiest way is to use streams. Here's a sketch:ππ}ππUsesπ Objects;ππVarπ S : TDosStream;π data : Array[1..1000] of Byte; { Big enough For anything }π Position : LongInt; { The position of the item }π Size : Word; { The size of the item }πbeginπ S.init('dataFile',stOpenRead);ππ { Now determine Position and Size from the other File somehow }ππ S.Seek(Position);π S.Read(data,Size);π if S.Status <> stOK thenπ beginπ Writeln('Stream error ',S.Status,' With error info ',S.ErrorInfo);π S.Reset;π end;πend.