Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Copying text from screen 3

Status
Not open for further replies.

gwar2k1

Programmer
Apr 17, 2003
387
0
0
GB
Hey i was debating wether to start a new thread or continue the arrows thread but new topic = new thread so here it is.

I was wondering if there is a way to take text from a specified part of the screen and store it ready to be re-insterted...

What Im doing is a password entry style thing: a frame(x1,y1,x2,y2) will popup in the middle of the screen w/o clearing the contents of its surrounding (but anything it covers and within it is cleared) then the user is asked for their password. If its correct that's no problem, it will progress to a new screen which is the simple case of clrscr but if they get it wrong or decide they dont want to enter the password anymore (pressing #27 Esc) the frame will be cleared and the text should return.

Thinking about it and what I was told in the arrows thread, I should use window(x1,y1,x2,y2). Thing is, I dont find the TP Help file helpful with the window function.
Is it possible to place a window over text and then close that window and the text still be there?

If there is a "special" way to do it without window I'd feel slightly more comfortable... unless its another OO solution *must learn OO*

Thanks for your time

~*Gwar3k1*~
"To the pressure, everything's just like: an illusion. I'll be losing you before long..."
 
You could try this:

Code:
type
  full_screen = array[0..3999] of char;

var
  colorvideo : boolean;
  monoscreen : full_screen ABSOLUTE $b000:0000;
  colorscreen : full_screen ABSOLUTE $b800:0000;
  

PROCEDURE save_screen(VAR ecran : full_screen);
BEGIN
  IF colorvideo THEN
    ecran := colorscreen
  ELSE
    ecran := monoscreen;
END;

PROCEDURE restore_screen(VAR ecran : full_screen);
BEGIN
  IF colorvideo THEN
    colorscreen := ecran
  ELSE
    monoscreen := ecran;
END;

procedure process
var
  screen1 : full_screen;
begin
  {...so some stuff...}
  save_screen (screen1);
  {... do other stuff that alters the screen}
  {... bring your screen back the way it was}
  restore_screen (screen1);
end;


BEGIN
  colorvideo := LASTMODE <> mono;
  IF colorvideo THEN
    screensegment := $b800
  ELSE
    screensegment := $b000;
  process;
END.

cheers,

Realm174
 
The window procedure is entirely artificial: it only masks a part of the screen as usable and remaps coordinates. But it doesn't save the underlying data (note that there's no procedure to close a &quot;window&quot;).
The only reason I ever used the window procedure, is for scrolling a part of the screen.

What you need is an extended window function to which you pass two co-ordinates and a buffer. In this function you save the screen content in the buffer and generate a window with Pascal's window procedure. You also need a close procedure to which you pass the buffer.
There are several ways to program these routines:
- rough system (programmer needs to know what he's doing): createwindow(x1,y1,x2,y2,buffer) and closewindow(x1,y1,x2,y2,buffer). Buffer is raw data.
- somewhat easier to use: createwindow(x1,y1,x2,y2,buffer) and closewindow(buffer). Here the buffer contains the co-ordinates.
- even easier: handle:=createwindow(x1,y1,x2,y2) and closewindow(handle). The buffer and co-ordinates are stored internally (e.g. in the IMPLEMENTATION part of a unit) and a reference to the buffer is returned by create. This implementation needs a more complicated datastructure to store multiple buffers, but is very easy to use.
- object oriented: new(win,init(x1,y1,x2,y2)) and dispose(win,done). With this construct you don't need a datastructure to hold buffers (each window has a buffer as one of its private variables). It becomes more difficult to randomly create and destroy windows, though. Consider this:
Code:
new(win1,init(10,10,20,20));
new(win2,init(15,15,25,25));
dispose(win1,done);
dispose(win2.done);
When destroying win1, you *should* tell win2 to redraw. So you end up with some sort of more global structure to store overlapping windows (in a decent OO system, this would be taken care of by the parent of win1 and win2).

Another issue is to retrieve the screen data, this can be done with the following construct:
Code:
TYPE screenchar = record
                    ch : char;
                    attr : byte;
                  end;
VAR screen : array[1..25,1..80] of screenchar absolute $B800:$0000; { nobody uses monochrome displays these days, so the screen starts at B800h }
Each element in this array represents a character that can be accessed like you would access the screen with gotoxy.
Example:
Code:
gotoxy(10,20); write('A');
is equivalent to
Code:
screen[10,20].ch:='A';

The latter has the advantage that it's faster and that you can also read a co-ordinate.
The attribute byte consists of the following:
bit 7: blink switch, if 1 => character blinks
bit 6-4: background color
bit 3-0: foreground color



Regards,
Bert Vingerhoets
vingerhoetsbert@hotmail.com
Don't worry what people think about you. They're too busy wondering what you think about them.
 
monoscreen : full_screen ABSOLUTE $b000:0000;
colorscreen : full_screen ABSOLUTE $b800:0000;

Bad idea--this bombs if you compile in protected mode.

full_screen_ptr = ^full_screen;
Monoscreen : full_screen_ptr;
colorscreen : full_screen_ptr;

monoscreen := Ptr(SegB000, 0);
colorscreen := Ptr(SegB800, 0);

AS for nobody using mono screens, I wouldn't go quite that far. We have a dozen still in use in combination with color screens. I do agree the B800 assumption is safe, though--most video cards do not correctly honor the dual card setup, in combination the mono screens can only be used by software that can handle them directly with minimal help from the bios.
 
Hmm. All of that from every1 (besides NOPIK's very brief input, lol) is very helpful and deserves a star.

I think I'm going to go with BertV's array idea if I can think of a way to implement it. I know how I'd write it to srceen but reading from the screen is different.

Quick question about windows: do they automatically add the scroll if you fill them?

Thanks all

~*Gwar3k1*~
&quot;To the pressure, everything's just like: an illusion. I'll be losing you before long...&quot;
 
A window is miniature version of the full screen, i.e. left upper corner has co-ordinate (1,1) and it scrolls. The only way to &quot;remove&quot; a &quot;window&quot; is by using window(1,1,80,25) (if you forget to do this, you'll now that scrolling is supported :)).

Regards,
Bert Vingerhoets
vingerhoetsbert@hotmail.com
Don't worry what people think about you. They're too busy wondering what you think about them.
 
Realm what units are you using? Ive got CRT and DOS but it says screensegment is an unknown identifier

~*Gwar3k1*~
&quot;To the pressure, everything's just like: an illusion. I'll be losing you before long...&quot;
 

Loren: Good point... this source is coming from a unit I've been building over the years... these particular procedures are way older than my current computer... I pasted them as-is in here. As a matter of fact, I use them all the time, personally never had any problems compiling/running programs that used them. But I'll take your word for it.. :)

GWAR: Oh, sorry, forgot to paste that one in... Screensegment is just a word variable.. :)

Cheers,

Realm174
 
k thanks *tries it*

~*Gwar3k1*~
&quot;To the pressure, everything's just like: an illusion. I'll be losing you before long...&quot;
 
So long as you stay in real mode, SegB800 and $B800 are the same thing. However, in protected mode, $B800 is a runtime error. I much prefer to work in protected mode.
 
LorenPechtel wrote:

full_screen_ptr = ^full_screen;
Monoscreen : full_screen_ptr;
colorscreen : full_screen_ptr;

So... um...

that goes in the type part right? then these:

monoscreen := Ptr(SegB000, 0);
colorscreen := Ptr(SegB800, 0);

would go in the constant part like this:

monoscreen = Ptr(SegB000, 0);
colorscreen = Ptr(SegB800, 0);


???

~*Gwar3k1*~
&quot;To the pressure, everything's just like: an illusion. I'll be losing you before long...&quot;
 
You have to use the initialization section rather than constant initialization when using the SegXXXX variables.
 
Ah ok, so the Variable declaration is still the same, using ABSOLUTE?

~*Gwar3k1*~
&quot;To the pressure, everything's just like: an illusion. I'll be losing you before long...&quot;
 
No. In protected mode you can't absolute to a memory location, period--the only legal use of absolute is to put two variables on top of each other. You must build a pointer to it instead.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top