SET CONTROL ONKEYEVENT and HMG_GetLastCharacter()

General Help regarding HMG, Compilation, Linking, Samples

Moderator: Rathinagiri

Post Reply
User avatar
kcarmody
Posts: 152
Joined: Tue Oct 07, 2014 11:13 am
Contact:

SET CONTROL ONKEYEVENT and HMG_GetLastCharacter()

Post by kcarmody »

I am writing a simple word processor based on the rich edit box demo in SAMPLES\Controls\RichEditBox\. I would like to intercept keystrokes that the user is typing into the rich edit control.

In the DOC under Advanced / Read keyboard and mouse, I saw something that sounded like it might work:

Code: Select all

SET CONTROL <ControlName> OF <FormName> ONKEYEVENT <FuncName>
After the main window definition and before ACTIVATE WINDOW, I added

Code: Select all

SET CONTROL <RichEditBoxName> OF <MainWindowName> ONKEYEVENT MyKeyProc()
To start out, I made MyKeyProc() simply

Code: Select all

MsgInfo("last character = " + HMG_GetLastCharacter())
This behaved strangely. When I typed a character into the rich edit box, I got what looked like an infinite loop of MsgInfo's. The first MsgInfo showed "last character =", i.e. HMG_GetLastCharacter() returned an empty string, when I was expecting it to return the key I just pressed. Every MsgInfo after that showed the last character as the character I typed, but it keep doing this forever. I never was able to type another character and had to kill the program with Task Manager.

Question 1: What is the purpose of SET CONTROL ... ONKEYEVENT? Is it buggy?

Next I got rid of the SET CONTROL statement and tried adding MyKeyProc() as an ON CHANGE method, i.e.

Code: Select all

@ ... RICHEDITBOX ... ON CHANGE MyKeyProc()
This time it behaved better but it was still strange. I got only one MsgInfo for each key I pressed, and as long as I pressed only alphabetic keys, the MsgInfo showed me the right key. But when I pressed Enter, the MsgInfo showed me the last alpha key that I pressed instead of the carriage return character. When I pressed Enter a second time, the MsgInfo then showed the last character as a carriage return. Similar results occur with Delete, Backspace, Ctrl-Z, etc. If I pressed Enter followed by Ctrl-Z, then the second MsgInfo showed a carriage return. I got no MsgInfo's when I pressed Insert, an arrow key, Home, End, etc.

So it looks like HMG_GetLastCharacter() is buggy. It returns the last character you typed, except when you type a control character, and then it returns the second last character you typed.

Question 2: Is there any way to intercept keystrokes coming into just one control? I'm aware of ON KEY, but this intercepts keystrokes typed into any control in the window.

I think that the DOC page that lists these features should also mention GetControlHandle().

Kevin
User avatar
srvet_claudio
Posts: 2193
Joined: Thu Feb 25, 2010 8:43 pm
Location: Uruguay
Contact:

Re: SET CONTROL ONKEYEVENT and HMG_GetLastCharacter()

Post by srvet_claudio »

Hi Kevin,
HMG_GetLastCharacter() returns the last character pressed but not cleaned de buffer, you need call after HMG_CleanLastCharacter() for avoid the loop.
Best regards.
Dr. Claudio Soto
(from Uruguay)
http://srvet.blogspot.com
User avatar
kcarmody
Posts: 152
Joined: Tue Oct 07, 2014 11:13 am
Contact:

Re: SET CONTROL ONKEYEVENT and HMG_GetLastCharacter()

Post by kcarmody »

Hi Claudio,
Thanks for the suggestion, but it did not fix the issue. The infinite loop of MsgInfo's from SET CONTROL remains. In MyKeyProc(), I added HMG_CleanLastCharacter() before HMG_GetLastCharacter(), but then HMG_GetLastCharacter() always returned an empty string and never the character I typed. I moved HMG_CleanLastCharacter() after HMG_GetLastCharacter(), but then HMG_GetLastCharacter() first returned an empty string, then the character, then an empty string each time afterwards. Adding the lCleanAll parameter did not affect anything: HMG_CleanLastCharacter(.T.) had the same effect as HMG_CleanLastCharacter().
Kevin
User avatar
srvet_claudio
Posts: 2193
Joined: Thu Feb 25, 2010 8:43 pm
Location: Uruguay
Contact:

Re: SET CONTROL ONKEYEVENT and HMG_GetLastCharacter()

Post by srvet_claudio »

kcarmody wrote:Hi Claudio,
Thanks for the suggestion, but it did not fix the issue. The infinite loop of MsgInfo's from SET CONTROL remains. In MyKeyProc(), I added HMG_CleanLastCharacter() before HMG_GetLastCharacter(), but then HMG_GetLastCharacter() always returned an empty string and never the character I typed. I moved HMG_CleanLastCharacter() after HMG_GetLastCharacter(), but then HMG_GetLastCharacter() first returned an empty string, then the character, then an empty string each time afterwards. Adding the lCleanAll parameter did not affect anything: HMG_CleanLastCharacter(.T.) had the same effect as HMG_CleanLastCharacter().
Kevin
Hi Kevin,
see this demo:

Code: Select all

FUNCTION MyKeyProc()
   IF .NOT. EMPTY ( HMG_GetLastCharacter() )   // this process only WM_CHAR message
      MsgInfo("Last Character = " + HMG_GetLastCharacter())
      HMG_CleanLastCharacter()
   ENDIF
RETURN NIL
Best regards.
Dr. Claudio Soto
(from Uruguay)
http://srvet.blogspot.com
User avatar
kcarmody
Posts: 152
Joined: Tue Oct 07, 2014 11:13 am
Contact:

Re: SET CONTROL ONKEYEVENT and HMG_GetLastCharacter()

Post by kcarmody »

Thank you both for your suggestions. I played around with it some more and found that the infinite loop only occurred if I pressed Enter on the MsgInfo. If I closed MsgInfo with the mouse, then the looping stopped. It seems that SET CONTROL reacts to the keystrokes going into MsgInfo as well as keystrokes going into the rich edit box. As Claudio says, testing for the empty string also stops the looping.

The return value of the SET CONTROL function is important, as mol says. It seems that any numeric or logical return value suppresses all keyboard input to the control, including Windows shortcuts. NIL or a string value enables the keyboard normally.
Post Reply