Where to put keyboard code

General FreeBASIC programming questions.
Gablea
Posts: 1104
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Where to put keyboard code

Post by Gablea »

Hi all

I am doing some experiments with FreeBASIC (so I can work on a better program) and so Far I have this

Code: Select all

#include "fbgfx.bi"
#include "vbcompat.bi"

Using FB '' Screen mode flags are in the FB namespace in lang FB

Declare Sub DisplayBackground (ByVal CurrentTime As String, ByVal CurrentDate As String)
Declare Sub DisplaySignedOnScreen

Screen 19, 32, 2, (GFX_WINDOWED Or GFX_NO_SWITCH)

Do
	ScreenSet 1, 0
		DisplayBackground(Format(Now,"HH:MM:ss"), Format(Now,"dd/MM/yyyy"))
	Wait &h3DA, 8
	ScreenCopy
Loop until inkey$ = chr$(27)
and this works fine (no flickering at all

I was wondering where in this example would I put the code that would display another screen?

What I want is something like


If InKey$ = chr$(13) then DisplaySignedOnScreen

But I am not sure where i would put it so the background loop would be called and then I know it would call this below

Code: Select all

Private Sub DisplaySignedOnScreen
	Dim DisplayWidth As Integer = 40

	Locate 5,5
	Print Chr(218) & String(DisplayWidth,Chr(196)) & Chr(191);
	Locate 6,5
	Print Chr(179) & String(DisplayWidth," ") & Chr(179);
	Locate 7,5
	Print Chr(179) & String(DisplayWidth," ") & Chr(179);
	Locate 8,5
	Print Chr(192) & String(DisplayWidth,Chr(196)) & Chr(217);
	
End Sub
would i add to the above sub the fucntion to call the background and then add the support to this for the keyboard?
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Where to put keyboard code

Post by fxm »

First, not necessary to put 'ScreenSet 1, 0' inside the loop:

Code: Select all

'.....
Screen 19, 32, 2, (GFX_WINDOWED Or GFX_NO_SWITCH)

ScreenSet 1, 0
Do
      DisplayBackground(Format(Now,"HH:MM:ss"), Format(Now,"dd/MM/yyyy"))
   Wait &h3DA, 8
   ScreenCopy
Loop until inkey = chr(27)
?:

Code: Select all

'.....
Screen 19, 32, 2, (GFX_WINDOWED Or GFX_NO_SWITCH)

ScreenSet 1, 0
Dim as string s
Do
      DisplayBackground(Format(Now,"HH:MM:ss"), Format(Now,"dd/MM/yyyy"))
      s = inkey
      If s = chr(13) then DisplaySignedOnScreen()
   Wait &h3DA, 8
   ScreenCopy
Loop until s = chr(27)
badidea
Posts: 2586
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Where to put keyboard code

Post by badidea »

Do you want to do things (e.g. handle user input) while the DisplaySignedOnScreen is shown?
Or is it just some pop-up info screen until some key (e.g. escape) is pressed again?
And should other things in the main loop continue to work, or is it ok is this is disabled/halted while the DisplaySignedOnScreen is up?
Gablea
Posts: 1104
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Re: Where to put keyboard code

Post by Gablea »

badidea wrote:Do you want to do things (e.g. handle user input) while the DisplaySignedOnScreen is shown?
Or is it just some pop-up info screen until some key (e.g. escape) is pressed again?
And should other things in the main loop continue to work, or is it ok is this is disabled/halted while the DisplaySignedOnScreen is up?
Ideally I would like to handle keyboard input when DisplaySignedOnScreen is called (so the user can enter thier user ID and password)

and I would love for the main loop to continue to work (so the time and date is always up top date)
Gablea
Posts: 1104
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Re: Where to put keyboard code

Post by Gablea »

fxm wrote:First, not necessary to put 'ScreenSet 1, 0' inside the loop:
Sorry i must have assumed I would have to set the none active screen each time

So would any print go to the non viewed screen? if I used Put (0,0), BackGround_Loading, PSet would thet print be put on the none viewed screen
and when ScreenCopy is used become visible?
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Where to put keyboard code

Post by fxm »

Yes.
Gablea
Posts: 1104
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Re: Where to put keyboard code

Post by Gablea »

fxm wrote:Yes.
Well i never know that I have learnt something new today :) Thank-you fxm.

For some reason I have found this way is smoother then with screen lock and unlock (the seconds are always correct)
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Where to put keyboard code

Post by fxm »

Gablea wrote:Ideally I would like to handle keyboard input when DisplaySignedOnScreen is called (so the user can enter thier user ID and password)
and I would love for the main loop to continue to work (so the time and date is always up top date)
The more elegant and powerful would be to use an independent thread to update the date and time, but this is also the more complex to code and debug.
See the article 'How to Manage a Critical Section of the code of a Thread in FB', and finally the last post 'User input-line function, but fully thread safe!'.
Last edited by fxm on Jan 12, 2019 19:37, edited 1 time in total.
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Where to put keyboard code

Post by dodicat »

Keeping it dead simple Gablea, forget screenset, I see no flicker here.

Code: Select all

#include "fbgfx.bi"
#include "vbcompat.bi"

Using FB '' Screen mode flags are in the FB namespace in lang FB

Declare Sub DisplayBackground(as string)' (ByVal CurrentTime As String, ByVal CurrentDate As String)
Declare Sub DisplaySignedOnScreen(as string)

Screen 19, 32, , (GFX_WINDOWED Or GFX_NO_SWITCH)

dim as string key,info
Do
    key=inkey
    
   DisplayBackground(info)
   
   if key=chr(13) then DisplaySignedOnScreen(info)
  
   sleep 1,1
Loop until key = chr(27)

sub displaybackground(info as string)
    locate 2
    print Format(Now,"HH:MM:ss")
    locate 9
    print "Do stuff"
    print info
    end sub
    
Private Sub DisplaySignedOnScreen(s as string)
   Dim DisplayWidth As Integer = 40
   Locate 5,5
   Print Chr(218) & String(DisplayWidth,Chr(196)) & Chr(191);
   Locate 6,5
   Print Chr(179) & String(DisplayWidth," ") & Chr(179);
   Locate 7,5
   Print Chr(179) & String(DisplayWidth," ") & Chr(179);
   Locate 8,5
   Print Chr(192) & String(DisplayWidth,Chr(196)) & Chr(217);
   locate 7,9
   input "Enter something ";s
   cls
End Sub  
Gablea
Posts: 1104
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Re: Where to put keyboard code

Post by Gablea »

dodicat wrote:Keeping it dead simple Gablea, forget screenset, I see no flicker here.

Code: Select all

#include "fbgfx.bi"
#include "vbcompat.bi"

Using FB '' Screen mode flags are in the FB namespace in lang FB

Declare Sub DisplayBackground(as string)' (ByVal CurrentTime As String, ByVal CurrentDate As String)
Declare Sub DisplaySignedOnScreen(as string)

Screen 19, 32, , (GFX_WINDOWED Or GFX_NO_SWITCH)

dim as string key,info
Do
    key=inkey
    
   DisplayBackground(info)
   
   if key=chr(13) then DisplaySignedOnScreen(info)
  
   sleep 1,1
Loop until key = chr(27)

sub displaybackground(info as string)
    locate 2
    print Format(Now,"HH:MM:ss")
    locate 9
    print "Do stuff"
    print info
    end sub
    
Private Sub DisplaySignedOnScreen(s as string)
   Dim DisplayWidth As Integer = 40
   Locate 5,5
   Print Chr(218) & String(DisplayWidth,Chr(196)) & Chr(191);
   Locate 6,5
   Print Chr(179) & String(DisplayWidth," ") & Chr(179);
   Locate 7,5
   Print Chr(179) & String(DisplayWidth," ") & Chr(179);
   Locate 8,5
   Print Chr(192) & String(DisplayWidth,Chr(196)) & Chr(217);
   locate 7,9
   input "Enter something ";s
   cls
End Sub  

I agree I see no screen flickering but when the DisplaySignedOnScreen is called the clock stops i would love to have the time always updating independent to anything else

would the background not be a thread on its own and i do thing on top of it?
badidea
Posts: 2586
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Where to put keyboard code

Post by badidea »

No screenset nor threading:

Code: Select all

#include "fbgfx.bi"
#include "vbcompat.bi"

const as integer BACKGROUND_SCREEN = 1
const as integer SIGNED_ON_SCREEN = 2
const as integer SCRN_W = 800, SCRN_H = 600 

sub DisplayBackground()
	line(60, 60)-(SCRN_W - 60, SCRN_H - 60), &h00440044, bf
	draw string (70, 70), "BACKGROUND_SCREEN"
	draw string (70, 90), format(now, "yyyy-mm-dd hh:mm:ss")
end sub

sub DisplaySignedOnScreen(userName as string)
	line(160, 160)-(SCRN_W - 160, SCRN_H - 160), &h00004444, bf
	draw string (170, 170), "SIGNED_ON_SCREEN"
	draw string (170, 190), "userName: " + userName
end sub

screenres SCRN_W, SCRN_H, 32
width SCRN_W \ 8, SCRN_H \ 16

dim as string key
dim as integer quit
dim as integer state = BACKGROUND_SCREEN
dim as string userName = "Me"
do
	key = inkey
	select case state
	case BACKGROUND_SCREEN
		select case key
		case chr(13)
			state = SIGNED_ON_SCREEN
		case chr(27)
			quit = 1
		case else
		end select
	case SIGNED_ON_SCREEN
		select case key
		case chr(27)
			state = BACKGROUND_SCREEN
		case chr(33) to chr(126) 'somwhat normal characters
			userName += key
		case chr(8) 'backspace
			if len(userName) > 0 then
				userName = left(userName, len(userName) - 1)
			end if
		case else
		end select
	end select

	screenlock
	DisplayBackground() 'always
	locate 1, 1: print "state: " + str(state);
	select case state
	case BACKGROUND_SCREEN
		locate 2, 1: print "Press <ENTER> for SignedOnScreen";
		locate 3, 1: print "Press <ESCAPE> to exit program  ";
	case SIGNED_ON_SCREEN
		DisplaySignedOnScreen(userName)
		locate 2, 1: print "Press <ESCAPE> to go back       ";
		locate 3, 1: print "Try typing user name ...        ";
	end select
	screenunlock

	sleep 1, 1
loop until quit
Time keeps running while typing :-p
For 20 different screens, this select case thing becomes a bit long.
Gablea
Posts: 1104
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Re: Where to put keyboard code

Post by Gablea »

badidea wrote:No screenset nor threading: Time keeps running while typing :-p
That was just want I was looking for (could I use that to control a RS232 scanner) Now I just have to work out how to use your code badidea :D

or could I throw the Scanner code into a thread on its own? (I know threads would mean I could not support a dos version of the app)
badidea
Posts: 2586
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Where to put keyboard code

Post by badidea »

I don't know how the scanner works. Is it like a secondary keyboard with input via inkey as well?
Gablea
Posts: 1104
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Re: Where to put keyboard code

Post by Gablea »

The Scanner commuicates to the system via RS232 but outputs acual ascii codes

This is what i have used in the past to control the scanner

Code: Select all

Sub SaleScreen
	ScannerFucntion = "SaleScreen"
	
	ScreenLock
		SalescreenDisplay 'Displays the graphical bmp image of the sale screen
		DisplaySalescreenMenu(MenuBeingDisplayed)
		DisplayFunctionKeyLabels
		DisplayTaskBar(1)
	ScreenUnLock
	
	Select Case ScannerType
		Case "Com", "COM", "com"
			Do : DisplayTaskBar(1) : ProcessKey_SaleScreen(GetKeyNB) : SelectSerialScanner 
			Loop
		
		Case"KBW", "kbw"," Kbw", ""
			Do : DisplayTaskBar(1) : ProcessKey_SaleScreen(GetKeyNB) 
			Loop
	End Select	
	
End Sub

Code: Select all

Private Sub SelectSerialScanner
   Do While LOC(BarcodeReader) > 0 
      Buffer = ""
	      
      buffer = Input(1,BarcodeReader)
      	      
      If buffer <> Chr(Val(ScannerPrefix)) Then 
         dim a as string = buffer
            dim result as string
               For x as integer = 0 to len(a) -1
                  If instr(chr(a[x]),any "0123456789" & Chr(Val(ScannerPrefix))) then
                     result += chr(a[x])
                  End If 
               Next x
	         datareceived += result
      End If
	
		'If DebugMode = 1 Then
 			Open Cons For Output As #DebugConsole
				Print #DebugConsole, "Data From Scanner"
				Print #DebugConsole, datareceived
			Close #DebugConsole
		'End If
	
      If buffer = Chr(Val(ScannerPrefix)) Then      'tells NPOS the scanner is done
	      If RemoveNumber > 0 then
				Dim Temp as string = mid$(datareceived, RemoveNumber, len(datareceived))
					datareceived = ""
					datareceived = Temp
	      End If
			ScannerFucntionSub(datareceived)
			datareceived = ""	      
      End If
   Loop 		
End Sub

Code: Select all

Private Sub ScannerFucntionSub(ByVal BarcodeNumber As String)
	datareceived = ""
	 	   Buffer = ""
	 	   
	Select Case ScannerFucntion
		Case "SaleScreen"
			SubTotalPressed = 0
			FindProduct(BarcodeNumber)
					
		Case "Salescreen_PriceCheck"
			FindProduct_PriceCheck(BarcodeNumber, "SaleScreen")
				
		Case "SignedOff_PriceCheck"
			FindProduct_PriceCheck(BarcodeNumber, "SignedOff_PriceCheck")
				
		Case "GiftCard"

	End Select
end Sub
BUT I am very open to new ideas as how to handle to serial scanner or way to improve on what I have so the system is as quick as it can be
badidea
Posts: 2586
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Where to put keyboard code

Post by badidea »

Important is, for updating the time every second always, that the scanner is 'non-blocking'.
This seems to be the case:
1. Poll: Is there data waiting [ LOC(BarcodeReader) > 0 ]
2. Read the data (quickly).
3. Exit (continue doing other stuff like updating the time)

If all this happens within a second, then no problem.
But what happens if [ buffer = Chr(Val(ScannerPrefix)) ] is never true? Can this happen? Then all else stops.
A time-out could solve this. Where the user gets some error message like "Scanner error, try again".
Post Reply