home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / database / bfast / browse.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-20  |  18.5 KB  |  788 lines

  1. //------------------------------------------------------
  2. // browse.cpp
  3. //------------
  4. //
  5. // extern "C" function used
  6. // area
  7. // SetCursor
  8. //
  9. //------------------------------------------------------
  10. //#include <iostream.h>
  11. //#include <dos.h>
  12. //#include <stdio.h>
  13. //#include <string.h>
  14.  
  15. #include <conio.h>
  16.  
  17. #include "jobcode.h"
  18. #include "browse.hpp"
  19.  
  20. extern helpscr();
  21.  
  22. static void cleararea(int StartRow, int StartCol, int StopRow,
  23.           int StopCol, int ch, int Attr);
  24. static void printxy(int x,int y, char* str, int color);
  25. static void printn(int x,int y, char* str, int color, int num);
  26. static void printch(int x,int y, int ch, int color);
  27.  
  28. static unsigned char far *PtrVideoMode = (unsigned char far*)0x00400049;
  29.  
  30. #define MAX_WIDTH 78
  31.  
  32. Browse::Browse(Btrieve *xbfhd, int pt, int pl, int pb, int pr,
  33.     int pno_target_fld, char* ptarget_fld[],
  34.     int pmaincolor, int ptitlecolor,int pfldcolor, int penhcolor)
  35. {
  36.     int i,width;
  37.     bfhd=xbfhd;
  38.     t=pt,l=pl,b=pb,r=pr;
  39.     maincolor=pmaincolor;
  40.     enhcolor=penhcolor;
  41.     titlecolor=ptitlecolor;
  42.     titlespacechar=32;
  43. //    spacechar=177;
  44.     spacechar=179;
  45.  
  46.     filterNo=0;
  47.  
  48.     no_rec_on_scr=b-t;      // take one out for title
  49.     no_target_fld=pno_target_fld;
  50.     target_fld=new int [no_target_fld];
  51.     fld_width=new int [no_target_fld];
  52.     fld_color=new int [no_target_fld];
  53.  
  54.     for (i=0;i<no_target_fld;i++)
  55.         {
  56.         target_fld[i]=bfhd->fPost(ptarget_fld[i]);
  57.         switch (bfhd->fType(target_fld[i]))
  58.             {
  59.             case 'c':
  60.             case 'y':       // Date
  61.                 width=bfhd->fWidth(target_fld[i])-1;
  62.                 break;
  63.             case 'i':
  64.                 width=10;
  65.                 break;
  66.             case 'l':
  67.             case 'd':
  68.             case 'f':
  69.                 width=10;
  70.                 break;
  71.             }
  72.         fld_width[i]= width > strlen(ptarget_fld[i]) ?
  73.             width : strlen(ptarget_fld[i]);
  74.         fld_width[i]=                               // avoid field width is
  75.             fld_width[i]>r-l+1 ? r-l+1:fld_width[i];// greater than scr width
  76.         fld_color[i]=pfldcolor;
  77.         }
  78.     // 
  79.     // determine the start and end field on screen
  80.     //
  81.     StartField(0);
  82.  
  83.     MoveTop();
  84. }
  85.  
  86. Browse::Browse(Btrieve *xbfhd, int pt, int pl, int pb, int pr,
  87.     int pno_target_fld, int ptarget_fld[],
  88.     int pmaincolor, int ptitlecolor,int pfldcolor, int penhcolor)
  89. {
  90.     int i,width;
  91.     bfhd=xbfhd;
  92.     t=pt,l=pl,b=pb,r=pr;
  93.     maincolor=pmaincolor;
  94.     enhcolor=penhcolor;
  95.     titlecolor=ptitlecolor;
  96.     titlespacechar=32;
  97. //    spacechar=177;
  98.     spacechar=179;
  99.  
  100.     filterNo=0;
  101.  
  102.     no_rec_on_scr=b-t;      // take one out for title
  103.     no_target_fld=pno_target_fld;
  104.     target_fld=new int [no_target_fld];
  105.     fld_width=new int [no_target_fld];
  106.     fld_color=new int [no_target_fld];
  107.  
  108.     for (i=0;i<no_target_fld;i++)
  109.         {
  110.         target_fld[i]=ptarget_fld[i];
  111.         switch (bfhd->fType(ptarget_fld[i]))
  112.             {
  113.             case 'c':
  114.             case 'y':       // Date
  115.                 width=bfhd->fWidth(ptarget_fld[i])-1;
  116.                 break;
  117.             case 'i':
  118.                 width=10;
  119.                 break;
  120.             case 'l':
  121.             case 'd':
  122.             case 'f':
  123.                 width=10;
  124.                 break;
  125.             }
  126.         fld_width[i]= width > strlen(bfhd->fName(ptarget_fld[i])) ?
  127.             width : strlen(bfhd->fName(ptarget_fld[i]));
  128.         fld_width[i]=                               // avoid field width is
  129.             fld_width[i]>r-l+1 ? r-l+1:fld_width[i];// greater than scr width
  130.         fld_color[i]=pfldcolor;
  131.         }
  132.     // 
  133.     // determine the start and end field on screen
  134.     //
  135.     StartField(0);
  136.  
  137.     MoveTop();
  138. }
  139.  
  140. Browse::Browse(Btrieve *xbfhd, int pt, int pl, int pb, int pr,
  141.     int pmaincolor, int ptitlecolor,int pfldcolor, int penhcolor)
  142. {
  143.     int i,width;
  144.     bfhd=xbfhd;
  145.     t=pt,l=pl,b=pb,r=pr;
  146.     maincolor=pmaincolor;
  147.     enhcolor=penhcolor;
  148.     titlecolor=ptitlecolor;
  149.     titlespacechar=32;
  150. //    spacechar=177;
  151.     spacechar=179;
  152.  
  153.     filterNo=0;
  154.  
  155.     no_rec_on_scr=b-t;      // take one out for title
  156.     no_target_fld=bfhd->fNumber();
  157.     target_fld=new int [no_target_fld];
  158.     fld_width=new int [no_target_fld];
  159.     fld_color=new int [no_target_fld];
  160.  
  161.     for (i=0;i<no_target_fld;i++)
  162.         {
  163.         target_fld[i]=i;
  164.         switch (bfhd->fType(i))
  165.             {
  166.             case 'c':
  167.             case 'y':       // Date
  168.                 width=bfhd->fWidth(i)-1;
  169.                 break;
  170.             case 'i':
  171.                 width=10;
  172.                 break;
  173.             case 'l':
  174.             case 'd':
  175.             case 'f':
  176.                 width=10;
  177.                 break;
  178.             }
  179.         fld_width[i]= width > strlen(bfhd->fName(i)) ?
  180.             width : strlen(bfhd->fName(i));
  181.         fld_width[i]=                               // avoid field width is
  182.             fld_width[i]>r-l+1 ? r-l+1:fld_width[i];// greater than scr width
  183.         fld_color[i]=pfldcolor;
  184.         }
  185.     // 
  186.     // determine the start and end field on screen
  187.     //
  188.     StartField(0);
  189.  
  190.     MoveTop();
  191. }
  192.  
  193. Browse::~Browse()
  194. {
  195.     delete target_fld;
  196.     delete fld_width;
  197.     delete fld_color;
  198.     for (int i=0;i<filterNo;i++)
  199.         delete filterVal[i];
  200. }
  201.  
  202. void Browse::Paint()
  203. {
  204.     int x,y,i,j;
  205.  
  206.     x=t;
  207.     y=l;
  208.     for (j=LfRtScrFld[0];j<=LfRtScrFld[1];j++)
  209.         {
  210.         if (j!=LfRtScrFld[0])
  211.             {
  212.             y+=(fld_width[j-1]+1);
  213.             printch(x,y-1,titlespacechar,titlecolor);
  214.             }
  215.         cleararea(x,y,x,y+fld_width[j]-1,32,titlecolor);
  216.         printxy(x,y,bfhd->fName(target_fld[j]),titlecolor);
  217.         }
  218.     if (y+fld_width[j-1]<r)
  219.         {
  220.         cleararea(t,y+fld_width[j-1],t,r,32,titlecolor);
  221.         cleararea(t+1,y+fld_width[j-1],b,r,32,maincolor);
  222.         }
  223.     x++;
  224.  
  225.     scr_top=bfhd->GetPost();
  226.     for (i=0;i<b-t;i++)
  227.         {
  228.         y=l;
  229.         for (j=LfRtScrFld[0];j<=LfRtScrFld[1];j++)
  230.             {
  231.             if (j!=LfRtScrFld[0])
  232.                 {
  233.                 y+=(fld_width[j-1]+1);
  234.                 printch(x,y-1,spacechar,maincolor);
  235.                 }
  236.             DisplayOneField(x,y,j, fld_color[j]);
  237.             }
  238.         if (i==(b-t-1))          // reach the bottom line
  239.             break;
  240.         if (MoveDown())    // end of file
  241.             break;
  242.         x++;
  243.         }
  244.     scr_bot=bfhd->GetPost();
  245.     bfhd->GoTo(scr_top);
  246.     no_rec_on_scr=i+1;
  247.     if (t+no_rec_on_scr<b)
  248.         cleararea(t+no_rec_on_scr+1,l,b,r,32,maincolor);
  249. }
  250.  
  251. void Browse::DisplayOneField(int x, int y, int fno, int clr)
  252. {
  253.     char buf[80],*p;
  254.  
  255.     cleararea(x,y,x,y+fld_width[fno]-1,32,clr);
  256.  
  257.     switch (bfhd->fType(target_fld[fno]))
  258.         {
  259.         case 'c':
  260.             printn(x,y,bfhd->fStr(target_fld[fno]),clr,fld_width[fno]);
  261.             break;
  262.         case 'y':
  263.             p=bfhd->fStr(target_fld[fno]);
  264.             convertDate(p,buf);
  265.             printn(x,y,buf,clr,8);
  266.             break;
  267.         case 'i':
  268.             sprintf(buf,"%10.d",bfhd->fInt(target_fld[fno]));
  269.             printxy(x,y,buf,clr);
  270.             break;
  271.         case 'l':
  272.             sprintf(buf,"%10.ld",bfhd->fLong(target_fld[fno]));
  273.             printxy(x,y,buf,clr);
  274.             break;
  275.         case 'd':
  276.             sprintf(buf,"%10.2f",bfhd->fDouble(target_fld[fno]));
  277.             printxy(x,y,buf,clr);
  278.             break;
  279.         case 'f':
  280.             sprintf(buf,"%10.2f",bfhd->fFloat(target_fld[fno]));
  281.             printxy(x,y,buf,clr);
  282.             break;
  283.         }
  284. }
  285.  
  286. void Browse::FieldColor(int fno, int fcolor)
  287. {
  288.     fld_color[fno]=fcolor;
  289. }
  290.  
  291. void Browse::MainColor(int clr)
  292. {
  293.     maincolor=clr;
  294. }
  295.  
  296. void Browse::TitleColor(int clr)
  297. {
  298.     titlecolor=clr;
  299. }
  300.  
  301. void Browse::EnhancedColor(int clr)
  302. {
  303.     enhcolor=clr;
  304. }
  305.  
  306. Browse::Show(int simulate, int startFromTop)
  307. {
  308.     int i,rc,fld_post,repaint=0;
  309.  
  310.     cleararea(t,l,b,r,32,maincolor);
  311.  
  312.     if(startFromTop)        // start form top
  313.     {
  314.         MoveTop();
  315.         if (bfhd->Err())
  316.             return -1;
  317.     }
  318.     else                    // start from current position, default
  319.     {
  320.         if(!ValueOk())      // if current record's value OK, skip it
  321.         {
  322.             MoveDown();
  323.             if (bfhd->Err())
  324.                 return -1;
  325.         }
  326.     }
  327.     Paint();
  328.     row=t+1,col=l;
  329.     fld_post=LfRtScrFld[0];
  330.  
  331.     for (;;)
  332.     {
  333.         if (repaint)
  334.         {
  335.             repaint=0;
  336.             Paint();
  337.         }
  338.         if (simulate==0)
  339.             area(row,col,row,col+fld_width[fld_post]-1,enhcolor);
  340.         SetCursor(row,col);
  341.         rc=waitKey(simulate);
  342.         if (simulate==0)
  343.             area(row,col,row,col+fld_width[fld_post]-1,fld_color[fld_post]);
  344.  
  345.         if (rc==ESC)
  346.             break;
  347.         if (rc==ENTER)
  348.         {
  349.             bfhd->GoTo(scr_top);
  350.             for (i=0;i<row-(t+1);i++)
  351.                 if (MoveDown())
  352.                     break;
  353.             break;
  354.         }
  355.         switch (rc)
  356.         {
  357.             case UP:
  358.                 if (row==t+1)   // reach the top line
  359.                 {
  360.                     bfhd->GoTo(scr_top);
  361.                     if (!MoveUp())
  362.                         repaint=1;
  363.                     else
  364.                         bfhd->GoTo(scr_top);
  365.                 }
  366.                 else
  367.                     row--;
  368.                 break;
  369.             case DOWN:
  370.                 if (row>=t+no_rec_on_scr)
  371.                 {
  372.                     bfhd->GoTo(scr_bot);
  373.                     if (!MoveDown())
  374.                     {
  375.                         bfhd->GoTo(scr_top);
  376.                         MoveDown();
  377.                         repaint=1;
  378.                     }
  379.                     else
  380.                         bfhd->GoTo(scr_top);
  381.                 }
  382.                 else
  383.                     row++;
  384.                 break;
  385.             case RIGHT:
  386.             case TAB:
  387.                 bfhd->GoTo(scr_top);
  388.                 if (fld_post<LfRtScrFld[1])
  389.                 {
  390.                     col+=(fld_width[fld_post]+1);
  391.                     fld_post++;
  392.                 }
  393.                 else        // over boundary
  394.                 {
  395.                     if (LfRtScrFld[1]<no_target_fld-1)// more field on the right
  396.                     {
  397.                         StartField(LfRtScrFld[1]+1);
  398.                         repaint=1;
  399.                         fld_post=LfRtScrFld[0];
  400.                         col=l;
  401.                     }
  402.                 }
  403.                 break;
  404.             case LEFT:
  405.             case SHIFT_TAB:
  406.                 bfhd->GoTo(scr_top);
  407.                 if (fld_post>LfRtScrFld[0])
  408.                 {
  409.                     fld_post--;
  410.                     col-=(fld_width[fld_post]+1);
  411.                 }
  412.                 else
  413.                  {
  414.                     if (LfRtScrFld[0]>0)       // more field on the left
  415.                     {
  416.                         EndField(LfRtScrFld[0]-1);
  417.                         repaint=1;
  418.                         fld_post=LfRtScrFld[0];
  419.                         col=l;
  420.                     }
  421.                 }
  422.                 break;
  423.             case PGDN:
  424.                 bfhd->GoTo(scr_bot);
  425.                 if (!MoveDown())
  426.                 {
  427.                     row=t+1;
  428.                     repaint=1;
  429.                 }
  430.                 else
  431.                     bfhd->GoTo(scr_top);
  432.                 break;
  433.             case PGUP:
  434.                 bfhd->GoTo(scr_top);
  435.                 if (!MoveUp())
  436.                 {
  437.                     for (i=1;i<b-t;i++)
  438.                     {
  439.                         if (MoveUp())
  440.                             break;
  441.                     }
  442.                     row=t+1;
  443.                     repaint=1;
  444.                 }
  445.                 else
  446.                     bfhd->GoTo(scr_top);
  447.                 break;
  448.             case CTRL_HOME:
  449.                 MoveTop();
  450.                 row=t+1;
  451.                 repaint=1;
  452.                 break;
  453.             case CTRL_END:
  454.                 MoveEnd();
  455.                 for (i=1;i<b-t;i++)
  456.                 {
  457.                     if (MoveUp())
  458.                         break;
  459.                 }
  460.                 row=t+1;
  461.                 repaint=1;
  462.                 break;
  463.             case HOME:
  464.                 bfhd->GoTo(scr_top);
  465.                 StartField(0);
  466.                 fld_post=LfRtScrFld[0];
  467.                 col=l;
  468.                 repaint=1;
  469.                 break;
  470.             case END:
  471.                 bfhd->GoTo(scr_top);
  472.                 EndField(no_target_fld-1);
  473.                 fld_post=LfRtScrFld[0];
  474.                 col=l;
  475.                 repaint=1;
  476.                 break;
  477.             case F5:
  478.                 Seek(NULL);
  479.                 row=t+1;
  480.                 repaint=1;
  481.                 break;
  482.         }
  483.     }
  484.     return rc;
  485. }
  486.  
  487. void Browse::StartField(int pfld)
  488. {
  489.     int i,total_scr_width=0;
  490.  
  491.     for (i=pfld;i<no_target_fld;i++)
  492.         {
  493.         total_scr_width+=fld_width[i];
  494.         total_scr_width+=1;             // space between field
  495.         if (total_scr_width > r-l+1)
  496.             break;
  497.         }
  498.     LfRtScrFld[0]=pfld;
  499.     LfRtScrFld[1]=i-1;
  500. }
  501.  
  502. void Browse::EndField(int pfld)
  503. {
  504.     int i,space=0,total_scr_width=0;
  505.  
  506.     for (i=pfld;i>=0;i--)
  507.         {
  508.         total_scr_width+=fld_width[i];
  509.         total_scr_width+=1;             // space between field
  510.         if (total_scr_width > r-l+1)
  511.             break;
  512.         }
  513.     LfRtScrFld[0]=i+1;
  514.     LfRtScrFld[1]=pfld;
  515.  
  516. }
  517.  
  518. static void cleararea(int StartRow, int StartCol, int StopRow,
  519.           int StopCol, int ch, int Attr)
  520. {
  521.  
  522.     register int Row, Col;
  523.     int CharPerRow, Delta;
  524.     char far *Video;
  525. //    unsigned char far *PtrVideoMode = (unsigned char far*)0x00400049;
  526.     if(*PtrVideoMode ==7)
  527.         Video=(char far *)MK_FP(0xb000,0000);
  528.     else
  529.         Video=(char far *)MK_FP(0xb800,0000);
  530.     Video+=(StartRow*160+StartCol*2);
  531.  
  532.     CharPerRow = StopCol-StartCol+1;
  533.  
  534.     Delta = 160-(StopCol-StartCol+1)*2;
  535.  
  536.     for(Row=1; Row<= StopRow - StartRow+1; ++Row)
  537.         {
  538.         for(Col=1; Col<=CharPerRow; ++Col)
  539.             {
  540.             *Video++=(char)ch;
  541.             *Video++=(char)Attr;
  542.             }
  543.         Video += Delta;
  544.         }
  545. }
  546.  
  547. static void printxy(int x,int y, char* str, int color)
  548. {
  549.     int num=strlen(str);
  550.     printn(x,y,str,color,num);
  551. }
  552. static void printn(int x,int y, char* str, int color, int num)
  553. {
  554.     register int row, col;
  555.     char far *video;
  556. //    unsigned char far *PtrVideoMode = (unsigned char far*)0x00400049;
  557.     if(*PtrVideoMode ==7)
  558.         video=(char far *)MK_FP(0xb000,0000);
  559.     else
  560.         video=(char far *)MK_FP(0xb800,0000);
  561.     video+=(x*160+y*2);
  562.  
  563.     for (int i=0;i<num;i++)
  564.         {
  565.         *video++=*str++;
  566.         *video++=color;
  567.         if (*str=='\0')
  568.             break;
  569.         }
  570.  
  571. }
  572.  
  573. static void printch(int x,int y, int ch, int color)
  574. {
  575.     register int row, col;
  576.     char far *video;
  577.     if(*PtrVideoMode ==7)
  578.         video=(char far *)MK_FP(0xb000,0000);
  579.     else
  580.         video=(char far *)MK_FP(0xb800,0000);
  581.     video+=(x*160+y*2);
  582.     *video++=ch;
  583.     *video=color;
  584. }
  585.  
  586. int Browse::waitKey(int tick)
  587. {
  588.     static int count=0;
  589.     int rc;
  590.     union  REGS  regs ;
  591.     regs.h.ah = 0x7 ;
  592.     while(1)
  593.     {
  594.         if(kbhit())
  595.         {
  596.             int86( 0x21, ®s, ®s ) ;
  597.  
  598.             if ( regs.h.al != 0 )
  599.             {
  600.                 rc=(int) regs.h.al ;
  601.                 break;
  602.             }
  603.             int86( 0x21, ®s, ®s ) ;
  604.             rc=(int) (regs.h.al << 8) ;
  605.             if(rc==F1)
  606.                 helpscr();
  607.             else
  608.                 break;
  609.         }
  610.         if (tick==0)
  611.             continue;
  612.         if (count++>tick)
  613.         {
  614.             count=0;
  615.             Paint();
  616.         }
  617.     }
  618.     return (rc);
  619. }
  620.  
  621. void Browse::GapChar(int ch)
  622. {
  623.     spacechar=ch;
  624. }
  625.  
  626. int Browse::Seek(char* target)
  627. {
  628.     int oldrow,oldcol;
  629.     cleararea(t,l,t,r,32,titlecolor);
  630.     printxy(t,l,"Search?",titlecolor);
  631.  
  632.     if (target==NULL)
  633.     {
  634.         int len=bfhd->KeyLength(bfhd->ActiveIndex());
  635.         char* buf=new char [len];
  636.         memset(buf,32,len);
  637.         buf[len-1]='\0';
  638.  
  639.         oldrow=ClockRow,oldcol=ClockCol;
  640.         ClockRow=-1,ClockCol=-1;
  641.  
  642.         GETc(t,l+8,buf);    UpperGET();
  643.         int rc=ReadGETs(ESC,ENTER,F4,0);
  644.  
  645.         ClockRow=oldrow,ClockCol=oldcol;
  646.  
  647.         if (rc!=ESC)
  648.             bfhd->GetGEqual(buf);
  649.  
  650.         delete buf;
  651.     }
  652.     else
  653.         bfhd->GetGEqual(target);
  654.  
  655.     return bfhd->Err();
  656. }
  657.  
  658. void Browse::KillFilter()
  659. {
  660.     filterNo--;
  661.     delete filterVal[filterNo];
  662. }
  663.  
  664. void Browse::Filter(char* pfldname, char* pfldval)
  665. {
  666.     filterNo++;
  667.     filterFld[filterNo-1]=bfhd->fPost(pfldname);
  668.  
  669.     int pwidth=bfhd->fWidth(filterFld[filterNo-1]);
  670.     filterVal[filterNo-1]=new char [pwidth];
  671.     //
  672.     // pad rest space with ASC(32)
  673.     //
  674.     int len=strlen(pfldval)+1;
  675.     memcpy(filterVal[filterNo-1],pfldval,len);
  676.     for (int i=len-1;i<pwidth-1;i++)
  677.         filterVal[filterNo-1][i]=32;
  678.     filterVal[filterNo-1][pwidth-1]='\0';
  679. }
  680.  
  681. void Browse::Filter(int pfldno, char* pfldval)
  682. {
  683.  
  684.     filterNo++;
  685.     filterFld[filterNo-1]=pfldno;
  686.     int pwidth=bfhd->fWidth(filterFld[filterNo-1]);
  687.  
  688.     filterVal[filterNo-1]=new char [pwidth];
  689.  
  690.     int len=strlen(pfldval)+1;
  691.     memcpy(filterVal[filterNo-1],pfldval,len);
  692.  
  693.     for (int i=len-1;i<pwidth-1;i++)
  694.         filterVal[filterNo-1][i]=32;
  695.     filterVal[filterNo-1][pwidth-1]='\0';
  696. }
  697.  
  698. //----------------------------------
  699. // only char field is filterable now
  700. //
  701. //----------------------------------
  702. Browse::ValueOk()
  703. {
  704.     int i,ok;
  705.     ok=1;
  706.     for (i=0;i<filterNo;i++)
  707.     {
  708.         if (strcmp(bfhd->fStr(filterFld[i]),(char*)filterVal[i]))
  709.         {
  710.             ok=0;
  711.             break;
  712.         }
  713.     }
  714.     return ok;
  715. }
  716.  
  717. Browse::MoveTop()
  718. {
  719.     bfhd->GetFirst();
  720.     if (filterNo>0)     // any filter
  721.     {
  722.         for (;;)
  723.         {
  724.             if (ValueOk() || bfhd->Err())
  725.                 break;
  726.             bfhd->GetNext();
  727.         }
  728.     }
  729.     return bfhd->Err();
  730. }
  731.  
  732. Browse::MoveEnd()
  733. {
  734.     bfhd->GetLast();
  735.     if (filterNo>0)     // any filter
  736.     {
  737.         for (;;)
  738.         {
  739.             if (ValueOk() || bfhd->Err())
  740.                 break;
  741.             bfhd->GetPrev();
  742.         }
  743.     }
  744.     return bfhd->Err();
  745. }
  746.  
  747. Browse::MoveUp()
  748. {
  749.     bfhd->GetPrev();
  750.     if (filterNo>0)     // any filter
  751.     {
  752.         for (;;)
  753.         {
  754.             if (ValueOk() || bfhd->Err())
  755.                 break;
  756.             bfhd->GetPrev();
  757.         }
  758.     }
  759.     return bfhd->Err();
  760. }
  761.  
  762. Browse::MoveDown()
  763. {
  764.     bfhd->GetNext();
  765.     if (filterNo>0)     // any filter
  766.     {
  767.         for (;;)
  768.         {
  769.             if (ValueOk() || bfhd->Err())
  770.                 break;
  771.             bfhd->GetNext();
  772.         }
  773.     }
  774.     return bfhd->Err();
  775. }
  776. //
  777. // return the top rec position
  778. //
  779. long Browse::TopRecNum()
  780. {
  781.     return scr_top;
  782. }
  783.  
  784. long Browse::BotRecNum()
  785. {
  786.     return scr_bot;
  787. }
  788.