home *** CD-ROM | disk | FTP | other *** search
- {
- 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....