How to get what has been typed


How do you intercept what has been typed in keyboard?

I have setup in SetAlerts PROCEDURE, ALERT() for keys, and in Window Events AlertKeys I have set up CASE KEYCODE().

Problem is that this intercepts keys from CASE that have been pressed, and what is typed does not show on screen. How can I get what is typed, but that character should also show up in entry field.

I want to enable button so that data can be saved, what I mean is ?OK{PROP:Disable} = FALSE.

Thank you for any suggestions.

You’ll have to subclass the window. That will give you all the Windows low level messages that are occurring. Your subclass function will let all those messages continue on to Clarion (by calling the original WndProc), but also gives you the opportunity to snoop on what’s happening.

Look for WndProc in the help.

You don’t say what kind of control you are working with?

If its an ENTRY you could add the IMM attribute which will send an EVENT:NewSelection “whenever the control’s contents or the cursor position changes”. In that Event you can check ?Feq{PROP:ScreenText} to see if there is any content. A Backspace may have trigger the event and erased the data so PROP:ScreenText returns blank.

I don’t like a UI where a control is disabled for some non-obvious reason. It creates confusion. I would rather popup like message(‘You must enter a password’) so it is obvious.

This is procedure to edit data, and I want to know when user actually edits data so that OK button is enabled.

People usually click on OK button, even when they do not enter new data. So I want to disable OK button, since I do not want to trigger LOG that something is edited, when actually is not.

I would keep a copy of the entire record when the form opened. Then compare that in OK or you could in event accepted

Orig_Ven:Record. String(Size(Ven;Record))

If this is a regular ABC form then the window manager is already saving a copy of the buffer.
You can use this code in the TakeCompleted method before Parent call or in the ?OK take accepted.
if SELF.Primary.Me.EqualBuffer(SELF.Saved)
!Means they did not make any changes
!they did make any changes


How can I get what is typed, but that character should also show up in entry field. I want to enable button so that data can be saved, what I mean is ?OK{PROP:Disable} = FALSE .

You can use IMM/EVENT:NewSelection as Carl said. Also, you can use TIMER()/EVENT:Timer, here’s and example.

Thank you all for suggestions. Since this application is gonna be used by max 5 users, I have decided to temporarily use CTRL+E to enable OK button.

I will add, at some point copy of record and then compare it.

@Rick_UpperPark, application is regular ABC. I have tried with suggested code, but problem is that SELF.Primary is pointing to NULL value. So program crashes. I have tried with SELF.Primary.Init(FILEMANAGER, ), but app is crashing here too. I do not know how to initialize object.

Among other things discussed here
It sounds like your code to add a LOG entry is running too soon.
I’d look around for a more accurate location to add the LOG entry,
possibly try ThisWindow.TakeCompleted

Is this window a Form template? I.e. you have a Save Button extension so your file appears in the Data pad under “Update Record on Disk” ?

If no you will not have Primary, you will have to keep a copy the of file like I noted.

@MarkGoldberg I will try that too.

@CarlBarnes It is window from template, but I did not add Save Button from ABC Control Templates. It is button from Toolbox. Now I know why SELF.Primary is NULL, and why is Save button in templates.

Thank you all for answers, you helped me a lot, and I definitely learned new stuff in Clarion.

Little update on SELF.Primary and NULL pointing, if somebody else gets stuck.

SELF.Primary needs to be initialized. From Help file:

The WindowManagerClass does not initialize the Primary property. Your derived Init method should initialize the Primary property if the procedure does database updates. See the Conceptual Example.

When all data is loaded, and ready to be saved to buffer:

SELF.Saved = Access:FILE.SaveBuffer()
SELF.Primary &= Relate:FILE

Then will SELF.Primary.Me.EqualBuffer(SELF.Saved) work.