Where to put keyboard code

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

Where to put keyboard code

Postby Gablea » Jan 12, 2019 16:57

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
Posts: 9177
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Where to put keyboard code

Postby fxm » Jan 12, 2019 17:10

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: 1542
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Where to put keyboard code

Postby badidea » Jan 12, 2019 17:24

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: 1049
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Re: Where to put keyboard code

Postby Gablea » Jan 12, 2019 18:48

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: 1049
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Re: Where to put keyboard code

Postby Gablea » Jan 12, 2019 18:50

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
Posts: 9177
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Where to put keyboard code

Postby fxm » Jan 12, 2019 18:59

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

Re: Where to put keyboard code

Postby Gablea » Jan 12, 2019 19:11

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
Posts: 9177
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Where to put keyboard code

Postby fxm » Jan 12, 2019 19:25

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: 5936
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Where to put keyboard code

Postby dodicat » Jan 12, 2019 19:27

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: 1049
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Re: Where to put keyboard code

Postby Gablea » Jan 12, 2019 20:13

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: 1542
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Where to put keyboard code

Postby badidea » Jan 12, 2019 20:13

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: 1049
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Re: Where to put keyboard code

Postby Gablea » Jan 12, 2019 20:17

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: 1542
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Where to put keyboard code

Postby badidea » Jan 12, 2019 20:22

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

Re: Where to put keyboard code

Postby Gablea » Jan 12, 2019 20:27

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: 1542
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Where to put keyboard code

Postby badidea » Jan 12, 2019 21:09

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".

Return to “General”

Who is online

Users browsing this forum: Bing [Bot] and 17 guests