May 08, 2024, 08:24:35 AM

News:

Own IWBasic 2.x ? -----> Get your free upgrade to 3.x now.........


Waiting DLL

Started by GWS, February 22, 2008, 08:29:07 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

GWS

Here's an experiment I've been playing with.

The idea is to add a few 'instructions' to the CBasic set that might be useful.

For a test, I've written three 'Wait' routines in EBasic, and made a dll which includes them.

They are 'WaitKey', 'WaitMouse', and 'WaitJoy'.
They were all supposed to work in either a console or a window program. ::)

I've attached a zip file which includes the test dll 'd1.dll', and two test programs for CBasic -
one a console test program, the other a window program.  In the window program, just edit the 'Waitkey' statement to try out the other two routines.

Did it work? - well yes and no.

The one I thought would be the easiest, proved the most difficult.  The 'WaitKey' function was supposed to work in either console or window mode.  It sort of works, but you'll see that if you press a key on the keyboard before it is requested, the keypress is still in the buffer and the program rushes on.  Despite having the old 'DO:UNTIL INKEY$ =""' in line to clear any previous presses - it doesn't work.  I can't see why ..  ::)  I've tried all sorts of workarounds, but I can't clear the buffer - must be doing something wrong.

I also tried 'GetKeyboardState', but I couldn't get that to indicate a random keypress correctly either ..  ::)

The EBasic code I used is in the dll.txt file - I always like to see what's in any dll  use ..  ;D

Any comments gratefully received ..  :)

Graham
Tomorrow may be too late ..

REDEBOLT

Graham,

Here is a code I wrote for EBasic.  It uses a "Sleep" command to avoid cpu lockup.
I'm not good at translating to CBasic.

' WaitKey.inc
DECLARE IMPORT, Sleep(Int dwmillisecs)
SUB WaitKey$(Opt raw=0 As Int),String
   String myinKey
   Do:Sleep(100):
      myinKey = InKey$(raw)
   Until myinKey<>""
   Return myinKey
ENDSUB

openconsole
PRINT "Here I am at waitkey$"
PRINT "Press any key to end"
WaitKey$()
closeconsole
end
Regards,
Bob

GWS

Thanks Bob ..  :) 

Same problem though .. if you press any key Before calling the 'WaitKey' function, it's still in the buffer, and WaitKey drops straight through without waiting for another key to be pressed.

The idea is, that the program should only start to check for a keypress after the function is called.

For some reason which I can't explain, the usual method (in a console program) of:
DO:UNTIL INKEY$ = ""
doesn't seem to be clearing the buffer.

It's a mystery ..  :)

Graham
Tomorrow may be too late ..

LarryMc

February 23, 2008, 01:10:40 PM #3 Last Edit: February 23, 2008, 01:23:05 PM by Larry McCaughn
An easy fix would be to clr the buffer before doing the loop:

SUB WaitKey$(Opt raw=0 As Int),String
   String myinKey

  ' need code here to see if raw<> 0 and save the value for use with inkey$ below

  'clears out any existing key in buffer
   Do:until InKey$=""

   Do:Sleep(100):
      myinKey = InKey$(raw)
   Until myinKey<>""
   Return myinKey
ENDSUB

Or that is how I would try it if I was trying to do that in CBasic, which I don't use.

But I guess that is the way you tried it also.

Are you having the problem with a console application AND a window application.
EBasic help says that for INKEY$ to work that the openconsole command has to be executed first and only works in console mode.

I just looked at the sourcecode for the $INKEY$ command for EBasic and it is definitely geared ONLY to the console window.

Looking at CBasic help also says it is only for use after an openconsole command.

Larry

LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

GWS

February 23, 2008, 03:10:59 PM #4 Last Edit: February 23, 2008, 03:18:08 PM by GWS
Hi Larry,

Yep, I realise inkey$ is a console only function  - what I was really after was a 'WaitKey' that would work in both console and window mode.

As it happens, I haven't yet even got it to work in console mode - which should be the easiest.

I'll try your idea of clearing it outside the function - but I was really hoping for all the work to be to be wrapped in the one statement.

[Nope .. I tried putting DO:UNTIL inkey$ = "" before the call, and it still sees a previously pressed key .. weird  ::)]

I'll keep looking - must be missing something somewhere ..  :)

Graham
Tomorrow may be too late ..

LarryMc

This does what you want in EBasic:
DECLARE IMPORT, Sleep(Int dwmillisecs)
DECLARE IMPORT ,GetStdHandle(num as int),int
DECLARE IMPORT ,FlushConsoleInputBuffer(handle as int),int

openconsole
print "here"
   Sleep(5000)
print "1"
WaitKey()
print "2"
   Do:until InKey$<>""

closeconsole
end

SUB WaitKey(opt raw=0 as int),string
   String myinKey
int handle

  'clears out any existing key in buffer
handle = GetStdHandle(-10)
FlushConsoleInputBuffer(handle)

   Do
Sleep(100)
      myinKey = InKey$(raw)
   Until myinKey<>""
   Return myinKey
endsub


In the example, the sleep(5000) gives me 5 secs to get something in the keyboard before WaitKey is called.

You don't need this sort of thing in windows because keboard input is handled with window messages about focus and such.

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

GWS

February 24, 2008, 09:58:35 AM #6 Last Edit: February 24, 2008, 10:00:53 AM by GWS
Thanks for looking at this Larry .. much appreciated.  :)

I've got it more or less working using the ideas you suggested.

The dll attached now has a working 'WaitKey' that works in both console and window mode - and you can specify which key you want to wait for.

In window mode, a key needs to be specified (eg: 0x0D for the Return key).
In console mode, use waitkey(0) if any key will do ..  :)

WaitJoy and WaitMouse seem to be OK.

Am I happy yet? - heck no .. not for 'WaitKey' anyway.

Look what we have here.  The original idea was to have a simple WaitKey statement that worked in console or window mode.
It seemed a simple enough thought, that a program should be able to tell if a key is pressed.

Years ago, with my Texas TI99, the Basic inkey$ was all you needed to check keyboard activity.

Now with years of advancement (and shelves full of good old games that have been broken by digital instead of analogue joysticks, pci soundcards no longer SoundBlaster compatible, and Direct X ) - we find it needs esoteric API commands to check if a key has been pressed.  Isn't progress wonderful.

Not only that, but it seems to depend on what type of screen you're looking at (console, ordinary window, or DX window) whether particular commands will work.  The 'WaitJoy' is a case for example where API stuff is needed to see it if you're not in a Direct Input mode. When I tried handling my joystick in a normal window I had to use joyGetPos(id:int,n:joyinfo) - otherwise it's as if my joystick isn't there. ::)

OK, these are just small and maybe not too useful tools in this little dll.  But it's the principal of the thing.

I've altered the window example for instance to show one situation where WaitKey could be used.  Here, a small window with no caption displays some information to the user and prompts to press a chosen key when he's read it.  The window goes away, and the program proceeds.  No big deal, but it avoids a bog-standard dialog box or message box where neither of those might be appropriate.

So WaitKey seems to be working .. but I'd rather not think about what's going on inside that simple command - it's not pretty ..  :)

all the best, :)

Graham
Tomorrow may be too late ..

LarryMc

Glad to see you got it working, Graham  ;D

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library