[Back to STREAMS SWAG index] [Back to Main SWAG index] [Original]

    {
    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....

[Back to STREAMS SWAG index] [Back to Main SWAG index] [Original]