{ I recently made a SCROLLBAR object. it's pretty good and draws it's strings directly to videomemory so no flashing etc. } UNIT scroller; { scrolbar.init(left, top, maxright, maxbottom, startvalue) if maxright and maxbottom are high enough the windowsize will be adjusted automatically to the longest string in the data-array. Mind that the scroller stops counting as soon as an empty string is encountered, and everything below it will not be displayed. in order to save memory your application may write directly to scrollbar.data. scrollbar.return contains the return value, i.e. the index of the chosen element in the data-array. scroll.bar.incr/decr take an integer and increases/decreases scrollbar.return scrollbar.update should be called after each scrollbar.incr/decr to display the changes. scrollbar.borderhit is a boolean that becomes true when the user attempts to go past the first/last item in the list. This should be used BEFORE scrollbar.update, as that procedure sets both booleans to False. scrollbar.stop closes the window and restores the screen. willem van de vis s0730076@let.rug.nl } Interface const max = 200; maxwidth = 20; type scrolldata = array[1..max] of string[maxwidth]; type Scrollbar = object private {erase private and public for tp6.0} top, bottom, left, right, total, width, len, y, b : integer; public data : scrolldata; return : integer; borderhit: boolean; constructor init(ileft,itop, iright,ibottom,iq: integer); destructor stop; procedure update; procedure incr(i : integer); procedure decr(d : integer); end; Implementation uses win, crt; constructor scrollbar.init; var q : integer; begin if ibottom > 24 then ibottom := 24; if itop < 2 then itop := 1; if ileft < 2 then ileft := 1; if iright > 78 then iright := 78; return := 1; b := 1; y := 1; bottom := ibottom; top := itop; len := (bottom - top)+1; left := ileft-1; right := iright; borderhit := false; total := 1; width := 1; while (total <= max) and (data[total] <> '') do begin if length(data[total]) > width then width := length(data[total]); data[total] := data[total] + ' '; inc(total); end; dec(total); if total = 0 then total := 1; if width < right - ileft then right := left + width else width := right-ileft; dec(right); if total < bottom - itop then bottom := itop + total-1; open_win(ileft, itop, right, bottom, lightgray, blue); if iq > 1 then scrollbar.incr(iq-1); end; destructor scrollbar.stop; begin close_win; end; procedure scrollbar.decr; begin if return - d < 1 then d := return-1; dec(return,d); if (y - d < 1) then begin b := return; y := 1; end else dec(y,d); if d = 0 then borderhit := true; end; procedure scrollbar.incr; begin if return + i > total then i := total - return; inc(return,i); if (y + i > len) then begin b := 1 + return - len; y := len; end else inc(y,i); if i = 0 then borderhit := true; end; procedure scrollbar.update; var i : integer; begin borderhit := false; for i := b to b + len-1 do if i <= total then if i - b + 1 = y then writeline(data[i],left, top+i-b, width, white,black) else writeline(data[i],left, top+i-b, width, lightgray,blue); end; end. Mind that no pointers are used so there IS a max to the number of lines displayed. It may be neccesary to adjust width en right etc. an example of an application: uses scroller,ill,crt,win; var scrol : scrollbar; r : char; chosen : string; F : TEXT; q : integer; begin assign(f, paramstr(1)); reset(f); q := 1; while (not eof(f)) and (q < 500) do begin readln(f,scrol.data[q]); if scrol.data[q] <> '' then inc(q); end; close(f); ini_win; scrol.init(2,2,80,18,1); r := '!'; while (r <> chr(13)) and (r <> chr(27)) do begin if scrol.borderhit then brom; scrol.update; r := readkey; case r of chr(72) : scrol.decr(1); chr(80) : scrol.incr(1); chr(73) : scrol.decr(10); chr(81) : scrol.incr(10); end; end; chosen := scrol.data[scrol.return]; scrol.stop; if r <> chr(27) then begin writeln(chosen); end; end.