Distinguish between Inkey code for <Ctrl-V> and <Ins> and <Ctrl-C> and <PageDn>

515 views
Skip to first unread message

Jayadev

unread,
Dec 18, 2015, 6:05:22 AM12/18/15
to Harbour Users
Hi,

In Inkey.ch the following definitions have the same numeric value and therefore it is not possible to distinguish one key from the other in Inkey() function.

#define K_CTRL_C                3     /*   Ctrl-C, PgDn, Ctrl-ScrollLock */
#define K_PGDN                  3     /*   PgDn, Ctrl-C                  */

#define K_INS                   22    /*   Ins, Ctrl-V                   */
#define K_CTRL_V                22    /*   Ctrl-V, Ins                   */

Is there any methodology in HARBOUR whereby we can have different values for the above inkey.

In xHarbour Inkey.ch there is a provision for HB_EXT_INKEY, so the numeric values are returned differently in inkey() function.

#define K_PGDN                  3     /*   PgDn, Ctrl-C                  */

#ifdef HB_EXT_INKEY

/* New control keys that do not overlap with other codes */

#define K_CTRL_C                515   /*   Ctrl-C                         */

Kindly guide.

Warm regards,

Jayadev

Mario Rossi

unread,
Dec 19, 2015, 3:44:01 AM12/19/15
to Harbour Users
HI Jayadev,
in general you can use the following functions that determine and return the status of the pressure of the "dead keys":

ft_Alt()
ft_CapLock()
ft_Ctrl()
ft_NumLock()
ft_Shift()

So, for example, to find out if you pressed Ctrl+V or INS, just that checks the return value of ft_Ctrl().
However there are cases where two key combinations have both the CTRL key, eg. CTRL+END and CTRL+W that return both 23, and the function ft_ctrl() is not of any use.

To overcome these problems I created my INKEY() function with its file .CH that assigns each keystroke a unique value and, therefore, just replace in their sources:

1) #INCLUDE "INKEY.CH"      ->     #INCLUDE "MYINKEY.CH"
2) INKEY()                            ->     MYINKEY()
3) LASTKEY()                       ->     MYLASTKEY()

I attach the file .CH, the source MYINKEY() and a source of example.
Fill with:

hbmk2 -gtwvt test.prg myinkey.prg hbnf.hbc hbct.hbc -run

I hope you can be useful

NB: The comments within the source, are in Italian but with google translate you should have no problems. In any case, I remain at your disposal.

Greetings
MYINKEY.CH
MYINKEY.PRG
TEST.PRG

Jayadev

unread,
Dec 19, 2015, 4:13:13 AM12/19/15
to Harbour Users
Hi Mario,

Many thanks for your prompt reply.  I shall test and revert.

Warm regards,

Jayadev

Maurizio la Cecilia

unread,
Dec 19, 2015, 6:18:29 AM12/19/15
to harbou...@googlegroups.com
My approach is based on testing the Ctrl key press and then decide what kind of keys was pressed:

k := Inkey( 0 )
if k == K_PGDN
   if IsKeyCtrl()
      /* Ctrl-C was pressed */
   else
     /* PgDn was pressed */
   endif
elseif k == K_INS
   if IsKeyCtrl()
      /* Ctrl-V was pressed */
   else
     /* Ins was pressed */
   endif     
/* and so on.... */
endif

function IsKeyCtrl()

   local nBits := hb_gtinfo( HB_GTI_KBDSHIFTS )

   return nBits == hb_bitor( nBits, HB_GTI_KBD_CTRL )

Best regards.
--
Maurizio
--
--
You received this message because you are subscribed to the Google
Groups "Harbour Users" group.
Unsubscribe: harbour-user...@googlegroups.com
Web: http://groups.google.com/group/harbour-users

---
You received this message because you are subscribed to the Google Groups "Harbour Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to harbour-user...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Jayadev Urath

unread,
Dec 19, 2015, 6:50:12 AM12/19/15
to Harbour Users
Hi Maurizio,

Thanks for your reply.  I shall test and revert.

Warm regards,

Jayadev

Jayadev Urath

unread,
Dec 19, 2015, 6:57:19 AM12/19/15
to Harbour Users
Hi,
Problem solved.  The following code is posted here for use by anybody facing the same problem.

  Set( _SET_EVENTMASK, HB_INKEY_ALL )
   #ifndef __XHARBOUR__
      hb_gtInfo( HB_GTI_INKEYFILTER, { | nKey |
         LOCAL nBits, lIsKeyCtrl
         SWITCH nKey
         CASE K_MWBACKWARD
            RETURN K_DOWN
         CASE K_MWFORWARD
            RETURN K_UP
         CASE K_CTRL_V
            nBits := hb_GtInfo( HB_GTI_KBDSHIFTS )
            lIsKeyCtrl := ( nBits == hb_BitOr( nBits, HB_GTI_KBD_CTRL ) )
            IF lIsKeyCtrl
               hb_GtInfo( HB_GTI_CLIPBOARDPASTE )
               RETURN 0
            else
               Set( _SET_INSERT, !Set( _SET_INSERT ) )   
               IF Set( _SET_INSERT )
                  SetCursor(SC_INSERT)     
               else
                  SetCursor(SC_NORMAL)  
               ENDIF
               RETURN 0
            ENDIF
         CASE K_CTRL_C
            nBits := hb_gtInfo( HB_GTI_KBDSHIFTS )
            lIsKeyCtrl := ( nBits == hb_BitOr( nBits, HB_GTI_KBD_CTRL ) )
            IF lIsKeyCtrl
               IF GetActive() != NIL
                  hb_gtInfo( HB_GTI_CLIPBOARDDATA, AllTrim(Transform( GetActive():VarGet(), "" )) )
                  RETURN 0
               ENDIF
            ENDIF
         CASE K_CTRL_X
            nBits := hb_gtInfo( HB_GTI_KBDSHIFTS )
            lIsKeyCtrl := ( nBits == hb_BitOr( nBits, HB_GTI_KBD_CTRL ) )
            IF lIsKeyCtrl
               IF GetActive() != NIL
                  hb_gtInfo( HB_GTI_CLIPBOARDDATA, Transform( GetActive():VarGet(), "" ) )
                  GetActive():DelEnd()
                  RETURN 0
               ENDIF
            ENDIF
         ENDSWITCH
      RETURN nKey
          } )
     #endif
 
This is a modified version of the code posted here by Jose.
https://groups.google.com/forum/#!searchin/harbour-users/jayadev/harbour-users/xr3iM2vbxi8/oejoimlXzWMJ

Warm regards,

Jayadev


On Sat, Dec 19, 2015 at 4:48 PM, Maurizio la Cecilia <m.lac...@gmail.com> wrote:

Jayadev Urath

unread,
Dec 19, 2015, 7:00:26 AM12/19/15
to Harbour Users
Thanks Mario and Maurizio.

Warm regards,

Jayadev

CV

unread,
Apr 18, 2020, 11:52:43 AM4/18/20
to Harbour Users
Hi!

Sorry for taking alive this old post, but I'm facing something similar and couldn't find the proper solution.
I'm converting a xharbour app to harbour, which uses extensively K_CTRL_letters (in xharbour they are well differentiated from any other key combination).

I tested 3 versions of the same application: one is console mode, the others are hibrid using gtwvg / gtwvw.
To show the problem, I write this piece of code:

-- prueba.prg --
#include 'inkey.ch'
function main()
*------------
local K

setmode(25,80)
cls
while .t.
       K := xhb_inkey(0)  // note the xhb prefix
       ? K 
       if k=K_ESC
          EXIT
       endif
enddo
return nil

-- eof --

The script to compile it in pure console mode follows:
-es1
-m
-n
-w3
-gc3

xhb.hbc
prueba.prg

When run, this is the behaviour while pressing Ctrl-Q, Ctrl-A, Ctrl-Z, Shift-Enter:
529
513
538
434
It is fine!

But if I just modify the script (adding gtwvg.hbc or gtwvw.hbc), as in:

-es1
-m
-n
-w3
-gc3

xhb.hbc
gtwvg.hbc   ## or gtwvw.hbc
prueba.prg

Then I get this (for the same key combinations):
17
1
26
13
These are the standard Ctrl-keys that Harbour use.

The same program under two different terminal drivers behaves in two different ways, while up to my understanding, should be the same.
Can anyone tell me what can I do when I use the second script model?
Any workaround should be really appreciated


Best regards
Claudio Voskian








Web: http://groups.google.com/group/harbour-users

---
You received this message because you are subscribed to the Google Groups "Harbour Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to harbou...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
--
You received this message because you are subscribed to the Google
Groups "Harbour Users" group.

Web: http://groups.google.com/group/harbour-users

---
You received this message because you are subscribed to the Google Groups "Harbour Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to harbou...@googlegroups.com.

Klas Engwall

unread,
Apr 18, 2020, 5:13:02 PM4/18/20
to harbou...@googlegroups.com
H Claudio,

Responding before the quote because of the long question and samples ...

I suspect that the explanation can be found here:
------
2013-04-26 14:31 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)
+ contrib/xhb/xhbinkey.ch
+ contrib/xhb/xhbkey.c
* contrib/xhb/xhb.hbp
* contrib/xhb/xhb.hbx
+ added support for xHarbour compatible extended Inkey() key codes
This functionality works with GTs which can operate on Harbour
extended key codes which are translated at runtime to xHarbour
extended keys (HB_EXT_INKEY).
+ added new PRG function:
xhb_Inkey( [ <nDelay> ] [ , <nKeyMask> ] ) -> <nKey>
which works like Inkey() but returns xHarbour extended key codes.
+ added new PRG function:
xhb_KeyTrans( <nExtKey> ) -> <nXhbKey>
which translates Harbour extended key code to xHarbour one.
------

I just tested your sample with gtwvt, and it worked just fine there to.
So I suspect that the two gts you mentioned have not been updated after
that commit (after all, one is a contrib and the other is an extra, so
they are not core gts).

Regarding workarounds, you can always check shift status with
nShiftBits := hb_gtinfo( HB_GTI_KBDSHIFTS )
and then check the ctrl key status with
if nShiftBits == hb_bitor( nShiftBits, HB_GTI_KBD_CTRL )
...
or some similar code. I use that approach to distinguish between arrow
keys and control keys. But as has been discussed in several old threads,
do it at the top and not under each case statement as in the sample in
the old post you quoted. And it only works with "real" keyboard input.

Regards,
Klas


> Sorry for taking alive this old post, but I'm facing something similar
> and couldn't find the proper solution.
> I'm converting a xharbour app to harbour, which uses *extensively*
> *gtwvg.hbc   ## or gtwvw.hbc*

CV

unread,
Apr 18, 2020, 7:47:41 PM4/18/20
to Harbour Users
Hi Klas

Thank you very much for your answer.
I will move my code to use that gt and try again, but ...

There is no GTWVT.HBC in my harbour 3.2 so I don't know how to use (or link) this GT.
Can you please tell me how to use it?
For the ones previously mentioned, I used gtwvg.hbc / gtwvw.hbc in my 2 *.hbp, and was working so far (I commented that line now).

For this test I have specified explicitly the library with -lgtwvt; when hbmk2 ends it recomends to add gtwvg.hbc ... If I add that line again my app doesn't recognize K_CTRL_letter properly (as it was).

Thank you again

Best regards!
Claudio Voskian

Klas Engwall

unread,
Apr 19, 2020, 3:14:58 AM4/19/20
to harbou...@googlegroups.com
Hi Claudio,

> Thank you very much for your answer.
> I will move my code to use that gt and try again, but ...

Unless you specifically need the special features of gtwvw or gtwvg,
gtwvt is a much better alternative than the default gtwin, IMHO.

> There is noGTWVT.HBC in my harbour 3.2 so I don't know how to use (or
> link) this GT.
> Can you please tell me how to use it?
> For the ones previously mentioned, I used gtwvg.hbc / gtwvw.hbc in my 2
> *.hbp, and was working so far (I commented that line now).
>
> For this test I have specified explicitly the library with *-lgtwvt*;
> when hbmk2 ends it recomends to add *gtwvg.hbc *... If I add that line
> again my app doesn't recognize K_CTRL_letter properly (as it was).

gtwvt is a core gt and lives, together with all the other core gts, in
src\rtl. It does not have, and does not need, a .hbc file. For your
little test app I just specified -gtwvt (note: no l) on the commandline:
hbmk2 claudio xhb.hbc -gtwvt

In my real applications I also specify:
request hb_gt_wvt_default
request hb_gt_wvt
at the top at the main module

The default font is a little thin, so I also specify these font settings:
hb_gtinfo( HB_GTI_FONTNAME, "Lucida Console" )
hb_gtinfo( HB_GTI_FONTWEIGHT, HB_GTI_FONTW_BOLD )
hb_gtinfo( HB_GTI_FONTSIZE, 17 )
hb_gtinfo( HB_GTI_FONTWIDTH, 9 )

Those size settings might be a little too large for some users, so
adjust them to your (their) liking. But gtwvt also allows resizing the
window by dragging the corners and by changing the font size settings at
runtime. I setup special hotkeys for that - very useful!

Regards,
Klas

CV

unread,
Apr 20, 2020, 9:54:39 AM4/20/20
to Harbour Users
Klas

You are a real master: with your advice I solved my need (I will reduce my three GT versions to just two or maybe one, using this GT).
I was close but not enough, as I don't know deeply this Harbour flavour and its characteristics.

I did a mod over inkeyapi.c, which worked really fine under pure console; then I discovered xhb.hbc... :(

I just added, by now, the line -gtwvt to the hbp, and everything works fine.

Anyway, I'm facing now another little trouble. 
Are there any sample of use for this GT (does it exist in the repo)? 
So I can make use of it (maybe the function names can be interpreted by its name, but what about the parameters they use?).

Best regards!
Claudio Voskian

José Quintas

unread,
Apr 20, 2020, 1:28:43 PM4/20/20
to harbou...@googlegroups.com

I use this:

   hb_gtInfo( HB_GTI_INKEYFILTER, { | nKey | MyInkeyFilter( nKey ) } )


#include "hbgtinfo.ch"
#include "inkey.ch"

FUNCTION MyInkeyFilter( nKey )

   LOCAL nBits, lIsKeyCtrl



   nBits      := hb_GtInfo( HB_GTI_KBDSHIFTS )
   lIsKeyCtrl := ( nBits == hb_BitOr( nBits, HB_GTI_KBD_CTRL ) )

   SWITCH nKey
   CASE HB_K_CLOSE     ; RETURN K_ESC
   //CASE HB_K_RESIZE    ; wvgSetAppWindow():InvalidateRect(); wvgSetAppWindow():Refresh(); RETURN NIL
   //CASE HB_GTE_RESIZED ; wvgSetAppWindow():InvalidateRect(); wvgSetAppWindow():Refresh(); RETURN NIL


   CASE K_MWBACKWARD   ; RETURN K_DOWN
   CASE K_MWFORWARD    ; RETURN K_UP

   CASE K_RBUTTONDOWN  ; RETURN K_ESC
   CASE K_RBUTTONUP    ; RETURN NIL
   CASE K_RDBLCLK      ; RETURN K_ESC
   CASE K_TAB          ; RETURN K_DOWN
   CASE K_SH_TAB       ; RETURN K_UP
   CASE K_CTRL_V


      IF lIsKeyCtrl
         hb_GtInfo( HB_GTI_CLIPBOARDPASTE )

         RETURN NIL
      ENDIF
   CASE K_CTRL_C


      IF lIsKeyCtrl
         IF GetActive() != NIL
            hb_gtInfo( HB_GTI_CLIPBOARDDATA, Transform( GetActive():VarGet(), "" ) )

            RETURN NIL


         ENDIF
      ENDIF
   ENDSWITCH

   RETURN nKey

José M. C. Quintas

Klas Engwall

unread,
Apr 20, 2020, 6:02:03 PM4/20/20
to harbou...@googlegroups.com
Hi Claudio,

> You are a *real master*: with your advice I solved my need (I will
> reduce my three GT versions to just two or maybe one, using this GT).
> I was close but not enough, as I don't know deeply this Harbour flavour
> and its characteristics.
>
> I did a mod over inkeyapi.c, which worked really fine under pure
> console; then I discovered xhb.hbc... :(
>
> I just added, by now, the line *-gtwvt* to the hbp, and everything works
> fine.
>
> Anyway, I'm facing now another little trouble.
> Are there any sample of use for this GT (does it exist in the repo)?
> So I can make use of it (maybe the function names can be interpreted by
> its name, but what about the parameters they use?).

HB_GtInfo() is the function that performs all the magic for all the GTs.
There are tons of arguments in include\hbgtinfo.ch that you can play
with. All GTs do not support all the options, but gtwvt supports many of
them.

There are a couple of wvt*.prg samples in the tests directory. And there
is a little wvtwin.prg that I have posted here a few times before - the
latest version is attached. It runs in a loop and allows resizing the
window in different ways - by entering various settings and by pressing
KP_CTRL_PLUS or KP_CTRL_MINUS (it has a couple of static logicals that
exist only because it runs in a loop, you wouldn't do that in a normal
application). But there exist many other HB_GtInfo() settings that just
aren't relevant for this specific test app.

Try it and see some of the things you can do in terms of window and font
settings. And check out include\hbgtinfo.ch, then ask more questions
here :-)

Regards,
Klas
wvtwin.zip

CV

unread,
Apr 21, 2020, 3:12:52 PM4/21/20
to Harbour Users
To Klas

Many thanks for the sample! Also I found the 2 examples included in the distro
Will investigate and get back here if needed.
Impressive: very easy to run in MT (something I emulate in a special way in my application while running under xHarbour)


To José

Your code (in fact I tested it before posting here), while working fine, is not enough for my need because there are still some conflicts between key combinations, like:
Ctrl-Z and Ctrl-Left arrow
Ctrl-B and Ctrl-Right arrow
There is no way to know which one the user pressed (I use that arrow key combinations for movement inside tbrowse).


Best regards for both of you!
Claudio Voskian
Reply all
Reply to author
Forward
0 new messages