Board index » delphi » A Perplexing Pascal Problem

A Perplexing Pascal Problem

I'm creating a program that has a main menu screen and the time and date
stamped near the top.  My question is: how can I refresh the clock, so that
it's always up to date and still use my menu effectively?  

I've tried looping with the ReadKey varible, but that paused and didn't update
the clock until a key was pressed.  Then I tried using KeyPressed, but that
only returns a boolean result (just TRUE or FALSE) , and would be useless in a
menu.

Any help would be appreciated!]

b...@agate.net
http://www.agate.net/~borg/

 

Re:A Perplexing Pascal Problem


Quote
In article <4k1cih$...@service-2.agate.net> b...@agate.net writes:
>I'm creating a program that has a main menu screen and the time and date
>stamped near the top.  My question is: how can I refresh the clock, so that
>it's always up to date and still use my menu effectively?  

The best way all around is to hook int $1c (user timer interrupt) and have
it update your clock by quickly drawing it to the screen.  If there are
times in your program when you don't want the clock to display, you can code
in a global boolean that can tell the interrupt handler not to display the
clock.  Using this method is a little more advanced, but you can just set it
free and not need to worry about it while your program runs.  All you have
to do is set it in motion with setintvec and getintvec when your program
starts, and clean up after it when your program ends.

Partial code will look something like:

program screenclock;

uses
  DOS;

const
  drawclock : boolean = true;

var
  oldclock : procedure;
  oldexit : pointer;

{$F+}

procedure myclock; interrupt;

begin
  if drawclock then
    {draw clock on screen}
  asm pushf; end;
  oldclock;
end;

procedure myexit;

begin
  setintvec($1c,@oldclock);
  exitproc := oldexit;
end;

begin
  getintvec ($1c,@oldclock);
  setintvec ($1c,@myclock);
  oldexit := exitproc; {this is important!!!}
end.

Quote
>I've tried looping with the ReadKey varible, but that paused and didn't update
>the clock until a key was pressed.  Then I tried using KeyPressed, but that
>only returns a boolean result (just TRUE or FALSE) , and would be useless in a
>menu.

If you insist on doing something like this, it *can* be done.  And, yes, you
need KeyPressed:

procedure mymenuinput;

var
  ch : char;
  exitcondition : boolean;

begin
  exitcondition := false; {don't quit first time through}
  {any setup code here}
  repeat
    drawclock;
    if KeyPressed then
      begin
        ch := readkey;
        case ch of
          #0 : begin
                 ch := readkey;
                 case ch of
                   {handle extended keys here}
                 end;
               end;
          {handle standard keys here}
        end;
      end;
  until exitcondition; {=true implied}
end;

That sort of thing works, but depending on how (in)efficient your code is,
the clock could be a bit jerky.

Quote
>Any help would be appreciated!]

I think this should get you going in the right direction.  :-)

Quote
>b...@agate.net
>http://www.agate.net/~borg/

--
Scott F. Earnest           | We now return you to our regularly scheduled
sc...@whiplash.res.cmu.edu | chaos and mayhem. . . .

Re:A Perplexing Pascal Problem


I have a similar problem, i'd great appreciate it if someone replies

w/ an answer quickly.  OK i have a scrolling message, which i figured

how to code, and i'd like that scrolling message to appear

on the bottom of my main menu. But i don't want that scrolling messsage

to effect my choice out of the main menu.   I think i'm suppose to

use interrupt vectors or related commands.  But i have no idea on how

to use em.  I need higher help.  Someone please write me email on hte

answer on how to do this. I'd great appreciate it.

am...@nitco.com  <--------someone write me back w/ an answer!

Re:A Perplexing Pascal Problem


Quote
b...@agate.net wrote:
>... My question is: how can I refresh the clock, so that
>it's always up to date and still use my menu effectively?  
>I've tried looping with the ReadKey varible, but that paused and didn't update
>the clock until a key was pressed.  Then I tried using KeyPressed, but that
>only returns a boolean result (just TRUE or FALSE) , and would be useless in a
>menu.

You have mentioned already the two elements to use in your program.
Use KeyPressed To see if any key is pressed. If not, update the clock,
if required. If there is KeyPressed returns TRUE, get the key with the
ReadKey function. Please keep in mind that special keys like F5 and
PageDown result in two key presses!
You could code a special ReadKey function to get the key and update
the screen simultaneously.

Function ReadKeyAndUpdateClock: Char;
  Begin
  While Not KeyPressed Do
    Begin
    UpdateClock;
    End;
  ReadKeyAndUpdateClock:=ReadKey;
  End;

--
rvd...@ect.nl        
Ruud Th. van der Ham

Re:A Perplexing Pascal Problem


Quote
b...@agate.net wrote:
>I'm creating a program that has a main menu screen and the time and date
>stamped near the top.  My question is: how can I refresh the clock, so that
>it's always up to date and still use my menu effectively?  

Try something like this:

repeat
  {your clock refresh & display function}
until KeyPressed;

Hope this helps!

Re:A Perplexing Pascal Problem


Quote
In article <4k1pja$...@aegis.nitco.com>, am...@nitco.com wrote:
>I have a similar problem, i'd great appreciate it if someone replies
>w/ an answer quickly.  OK i have a scrolling message, which i figured
>how to code, and i'd like that scrolling message to appear
>on the bottom of my main menu. But i don't want that scrolling messsage
>to effect my choice out of the main menu.   I think i'm suppose to
>use interrupt vectors or related commands.  But i have no idea on how
>to use em.  I need higher help.  Someone please write me email on hte
>answer on how to do this. I'd great appreciate it.
>am...@nitco.com  <--------someone write me back w/ an answer!

Just use the WINDOW procedure.
--
John Stockton, Surrey, UK.  Turnpike v1.12.  MIME.

Re:A Perplexing Pascal Problem


Quote
In <4k1cih$...@service-2.agate.net>, b...@agate.net writes:
>I'm creating a program that has a main menu screen and the time and date
>stamped near the top.  My question is: how can I refresh the clock, so that
>it's always up to date and still use my menu effectively?  

>I've tried looping with the ReadKey varible, but that paused and didn't update
>the clock until a key was pressed.  Then I tried using KeyPressed, but that
>only returns a boolean result (just TRUE or FALSE) , and would be useless in a
>menu.

>Any help would be appreciated!]

>b...@agate.net
>http://www.agate.net/~borg/

You need to set it up as an interrupt procedure, chain it to the clock
tic interrupt, and then forget about it.

--
Wayne D. Hoxsie Jr.  Team OS/2   <hoxs...@crl.com>
The Lab BBS, Alton IL, 618-462-0767
{*word*30} the ``Communications Decency Act!''
`finger' or `http://www.crl.com/~hoxsiew' for a PGP key.

Re:A Perplexing Pascal Problem


Quote
b...@agate.net writes:
> I'm creating a program that has a main menu screen and the time and date
> stamped near the top.  My question is: how can I refresh the clock, so that
> it's always up to date and still use my menu effectively?  

> I've tried looping with the ReadKey varible, but that paused and didn't updat
> the clock until a key was pressed.  Then I tried using KeyPressed, but that
> only returns a boolean result (just TRUE or FALSE) , and would be useless in
> menu.

Here's some psuedocode to give you the idea:

repeat
  if keypressed then
    get_keyboard_input
  else
    display_datetime
until done

"done" is a boolean you set when the user select the "exit the menu"
option.
Leonard Erickson (aka Shadow)
 sha...@krypton.rain.com   <--preferred
leon...@qiclab.scn.rain.com        <--last resort

Re:A Perplexing Pascal Problem


In article <scott.235.00168...@whiplash.res.cmu.edu>, From
sc...@whiplash.res.cmu.edu (Scott F. Earnest), the following was
written:

Quote
> program screenclock

> uses
> DOS;

> const
> drawclock : boolean = true;

> var
> oldclock : procedure;
> oldexit : pointer;

> {$F+}

> procedure myclock; interrupt;

> begin
> if drawclock then
> {draw clock on screen}
> asm pushf; end;
> oldclock;
> end;

> procedure myexit;

> begin
> setintvec($1c,@oldclock);
> exitproc := oldexit;
> end;

> begin
> getintvec ($1c,@oldclock);
> setintvec ($1c,@myclock);
> oldexit := exitproc; {this is important!!!}
> end.

But then you get a BIG problem: To get the time you usually need
int 21h (used by GetTime). And calling a int-21-function from an
interrupt procedure is *very* dangerous.
And I don't know how to get the time out of the bios ram... it
ought to be quite complicated. How about checking the InDos flag
(I tried it, but it didn't work at all)?

   Basti

--
-----------------------------------------------------------------------
       Bastisoft      101674.2...@compuserve.com

       Fleestedt, Germany
-----------------------------------------------------------------------

Re:A Perplexing Pascal Problem


Quote
b...@agate.net wrote:

> I'm creating a program that has a main menu screen and the time and date
> stamped near the top.  My question is: how can I refresh the clock, so that
> it's always up to date and still use my menu effectively?

> I've tried looping with the ReadKey varible, but that paused and didn't update
> the clock until a key was pressed.  Then I tried using KeyPressed, but that
> only returns a boolean result (just TRUE or FALSE) , and would be useless in a
> menu.

> Any help would be appreciated!]

> b...@agate.net
> http://www.agate.net/~borg/

simple enough...

put in a keypressed loop.

function GetSomeText :string;
var
  ch : char;
  Temp : String;
  finished : boolean;
begin
  temp := '';
  finished := False;

  While (NOT finished) do
  begin
   while (Not KeyPressed) do
   DrawTimeBar;  {this is where you'd stick in your time update function}
   ch := readkey;
   if ch = #13 then finished := true else
   temp := temp + ch;  
  end;

  GetSomeText := temp;
end;

hope this helps!

--
Regards,
Michael Mattsson.

Re:A Perplexing Pascal Problem


Quote
b...@agate.net wrote:
>I'm creating a program that has a main menu screen and the time and date
>stamped near the top.  My question is: how can I refresh the clock, so that
>it's always up to date and still use my menu effectively?  
>I've tried looping with the ReadKey varible, but that paused and didn't update
>the clock until a key was pressed.  Then I tried using KeyPressed, but that
>only returns a boolean result (just TRUE or FALSE) , and would be useless in a
>menu.

Try using a combo.  Stick this in your loop:
if keypressed then c:= readkey;

Execution of your program will not stop and wait.  When a key is
pressed it is read (with out pressing ENTER) into the c char.  Then do
a case or whatever on c.

hne...@ac.net

Re:A Perplexing Pascal Problem


Somebody before Jack Neely (hne...@ac.net) wrote:
:
: >I've tried looping with the ReadKey varible, but that paused and didn't update
: >the clock until a key was pressed.  Then I tried using KeyPressed, but that
: >only returns a boolean result (just TRUE or FALSE) , and would be useless in a
: >menu.
:
: Try using a combo.  Stick this in your loop:
: if keypressed then c:= readkey;
Even better, I think the following loop would do the trick:

   {wait for input}
   repeat
      RefreshClock;   {put the necessary code here}
      until KeyPressed;
   {you only get to here when the user has pressed a key}
   C := ReadKey;

Voila!

Graham

Re:A Perplexing Pascal Problem


In article <4k90vm$...@dub-news-svc-1.compuserve.com>, Sebastian

Quote
Koppehel <101674.2...@compuserve.com> wrote:

>But then you get a BIG problem: To get the time you usually need
>int 21h (used by GetTime). And calling a int-21-function from an
>interrupt procedure is *very* dangerous.
>And I don't know how to get the time out of the bios ram... it
>ought to be quite complicated. How about checking the InDos flag
>(I tried it, but it didn't work at all)?

Access Seg0040:$006C as a longint (if using BP/TP rather than asm, then
protect with DI,...,EI {or, better, PushF,DI,...,PopF}); divide by about
18.2 to get seconds, then 60, 60.  The required divisor is pretty near
18.2, AFAIR; but you do NOT want to do FP work in an ISR, so *10, div
182.  Untested...
--
John Stockton, Surrey, UK.  J...@merlyn.demon.co.uk  Turnpike v1.12  MIME

Re:A Perplexing Pascal Problem


In article <jlJHhAAbTCbxE...@merlyn.demon.co.uk> Dr John Stockton <j...@merlyn.demon.co.uk> writes:

Quote
>In article <4k90vm$...@dub-news-svc-1.compuserve.com>, Sebastian
>Koppehel <101674.2...@compuserve.com> wrote:

>>But then you get a BIG problem: To get the time you usually need
>>int 21h (used by GetTime). And calling a int-21-function from an
>>interrupt procedure is *very* dangerous.

I never suggested calling DOS from the handler.  That would be a bad thing,
and there are far better ways than asking DOS.

Quote
>>And I don't know how to get the time out of the bios ram... it

Do you mean the BIOS segment, or CMOS?  If you're referring to CMOS, that's
also a bad thing -- The thing is set up so that every out reference to the
register port (70h, I think) *must* be followed directly by and in call to
the data port.  Experience has taught me that doing that incorrectly can
thrash a CMOS table, so I wouldn't recommend that as a solution.  :-P

Quote
>>ought to be quite complicated. How about checking the InDos flag
>>(I tried it, but it didn't work at all)?
>Access Seg0040:$006C as a longint (if using BP/TP rather than asm, then
>protect with DI,...,EI {or, better, PushF,DI,...,PopF}); divide by about
>18.2 to get seconds, then 60, 60.  The required divisor is pretty near
>18.2, AFAIR; but you do NOT want to do FP work in an ISR, so *10, div
>182.  Untested...

Looking through some old code I have, there's a good way to do this without
FP operations.  A clock TSR program attributed to Carlos Beguigne (I think
this program might be in SWAG, not sure) offers this solution (don't have
the code on hand to post at the moment, just my own hand-written notes):

var
  BIOSTicker : longint absolute $0040:$006c;

And from the interrupt handler:

Time := (1365*BIOSTicker) div 24852;

The hours (0-23) is Time div 3600.

Time := Time div 3600.

Now, the clock minutes are Time div 60, and the clock seconds are Time mod
60.

BTW 1365/24852 = 18.2065934066, a fairly good approximation.

If there's any interest for the full source, follow up and I'll post it to
the group.

Quote
>--
>John Stockton, Surrey, UK.  J...@merlyn.demon.co.uk  Turnpike v1.12  MIME

--
Scott F. Earnest           | We now return you to our regularly scheduled
sc...@whiplash.res.cmu.edu | chaos and mayhem. . . .

Other Threads