Dear Allegro-Programmers,
I have a serious problem with the GUI-Objektd_edit_proc( ).
Could you kindly give me your advice and/or opinion concerning this problem.
The GUI-function d_edit_proc( ) allows letters and/or miscellaneous other characters.
For the input of double-values this, however, does not make any sense.
My user-defined function should suppress certain characters during the input (for example: letters the tilde-char etc.).
During the input, the function should replace a comma by a KEY_STOP.
Although I have studied the allegro-documentation for several times as well as various examples with concern to the GUI-Programming of Shawn Hargreaves and Revin Guillen (GUI-CLINIC), I am not capable of solving this problem.
Please let me know whether this change of the GUI-function d_edit_proc ( ) is possible and meaningsful or if there is any easy example of a customary dialogue-procedure using the d_edit_proc ( ) by parsing the input string.
If there is no easy solution for the problem and my problem is not as trivial as it may seem at first glance, I can provide you with my code-fragments by giving more details of the problem.
Many thanks for your help.
Christian
I'm not sure I entirely understand what you are saying. Are you wanting an input box that only accepts numbers as a double value? If so then you can override the d_edit_proc to ignore all character input, and if the '.' character is encountered accept only one instance, all others ignored. From there the string value can be converted to a double value via atof() or atol().
First a warning: English is not my mother tongue. For the question I had a native next to me. Now he is gone.
Yes exatly this is the problem. I don't know wether "overwrite" is what I'm trying to do. The edit-funktion of the parent-object "d_edit_proc()" like toggling between Insert- and overwerite modus, the home and the end-key etc. should work further on.
The GUI-player provides the edit-dialog (here: for double-values) and should call my custom function, whenever a key is pressed.
The following paraphrase of the Allegro Doc is concerning the problem:
If the object deals with the keypress it should return D_USED_CHAR, otherwise
it should return D_O_K to allow the default keyboard interface to operate.
First the code for the dialog:
DIALOG the_dialog[] = { /* (proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) (dp2) (dp3) */ {indouble, 264, 248, 184, 16, 0, 0, 0, 0, sizeof(the_string)-1, 0, (void*)the_string, NULL, NULL }, ... };
Further the code fragment for the keys I want to 'block'.
| 1 | |
| 2 | int indouble(int msg, DIALOG *d, int c){ |
| 3 | int ret; |
| 4 | |
| 5 | ret = d_edit_proc(msg, d, c); |
| 6 | |
| 7 | switch(msg){ |
| 8 | case MSG_START: |
| 9 | punkt = 0; |
| 10 | case MSG_CHAR: |
| 11 | if(key[KEY_A] || key[KEY_B] || key[KEY_C] || |
| 12 | key[KEY_D] || key[KEY_E] || key[KEY_F] || |
| 13 | key[KEY_G] || key[KEY_H] || key[KEY_I] || |
| 14 | key[KEY_J] || key[KEY_K] || key[KEY_L] || |
| 15 | key[KEY_M] || key[KEY_N] || key[KEY_O] || |
| 16 | key[KEY_P] || key[KEY_Q] || key[KEY_R] || |
| 17 | key[KEY_S] || key[KEY_T] || key[KEY_U] || |
| 18 | key[KEY_V] || key[KEY_W] || key[KEY_X] || |
| 19 | key[KEY_Y] || key[KEY_Z] || key[KEY_COMMA]){ |
| 20 | return D_USED_CHAR; |
| 21 | } |
| 22 | } //Ende switch |
| 23 | return ret; |
| 24 | } |
When I'trying to replace the 'COMMA' by a full stop I get a little confused.
But now I would like to hear your feedback for the basic code.
Thanks for your help.
The int c parameter will contain the full scancode/ascii code of the key being pressed so you should not have to use the key array. By FULL_STOP I think you mean the '.' key? I think you have the right idea anyway, be sure to call d_edit_proc at the end of your custom function for default handling of other methods.
[edit]
I see, you are calling d_edit_proc at the beginning, rather you should call it at the end.
[/edit]
Hello Steve,
(...)be sure to call d_edit_proc at the end of your custom function for default handling of other methods. (...)
That was an impotant hint. Thanks!
I try this.
You mean parsing and manipulating the string is the right idea.
There are other manipulations I have to do, like accepting one '-' character only at the beginning of the string, only one '.' character etc.
For the moment I write some little aplication for mechanics.
There is an other question left.
The dialog element "d->dp" points to the beginning of the string. To access the third character of the string "d->dp[3]" dosn't work.
Could you kindly give me a hint to that?
Many thanks !
The dialog element "d->dp" points to the beginning of the string. To access the third character of the string "d->dp[3]" dosn't work.
Could you kindly give me a hint to that?
d->dp[2]
or maybe (char *)(d->dp)[2] or something similar...
Hello miran,
Thanks for your help.
I had a look on your skinnable GUI-System - great 
Before I'm capable of changing the behavior of the Allegro GUI, I have to work with the GUI basics.
Germans would say: "Langsam ernährt sich das Eichhörnchen !"
[raises hand]
Ummm I have a skinnable GUI too... but I guess Mirans is better and more updated than mine 
[/raises hand]
Oh well... still check mine out in my sig, you may get some ideas of which one you want to use.
Christian: What you are trying to do sounds complicated; a far easier and straightforward solution would be to just accept any kind of input and check later, i.e. when you read data back from the dialog. At that time you can throw an error message if the input cannot be interpreted as a double, or just set it to a default value.
I once wrote a custom edit box dialog procedure, because I also needed that "numbers only" input behaviour:
| 1 | // customized edit box, allowing only floating point numbers to be typed |
| 2 | int d_fedit_proc(int msg, DIALOG *obj, int c) |
| 3 | { |
| 4 | char low = (char)c; |
| 5 | char high = (char)((int)(c >> 8)); |
| 6 | int ret; |
| 7 | |
| 8 | // catch invalid character input for floating point |
| 9 | if((msg==MSG_CHAR)||(msg==MSG_UCHAR)) |
| 10 | { |
| 11 | if((obj->d2>0)&&(low==45)) // disallow -(ascii 45) anywhere but at pos 0 |
| 12 | return D_O_K; |
| 13 | |
| 14 | // disallow anything BUT 0-9,-,. (ascii[48,57],45,46) |
| 15 | // and ESC,ENTER,BACKSPACE(ascii 27,13,8) |
| 16 | // and DEL,LEFT,RIGHT |
| 17 | if(((low<48)||(low>57))&&(low!=45)&&(low!=46) |
| 18 | &&(low!=27)&&(low!=13)&&(low!=8) |
| 19 | &&(high!=KEY_DEL)&&(high!=KEY_LEFT)&&(high!=KEY_RIGHT) |
| 20 | &&(high!=KEY_ENTER)) |
| 21 | return D_O_K; |
| 22 | } |
| 23 | |
| 24 | // make use of standard edit proc to handle everything else |
| 25 | ret = d_edit_proc(msg,obj,c); |
| 26 | |
| 27 | return ret; |
| 28 | } |
I now have modified it to (hopefully, as this is untested) replace ',' with '.' on input. The idea I based this on was to check in the custom proc, if the input was ',' and then send it as '.' to the default edit proc, by changing the c parameter of the message:
| 1 | // customized edit box, allowing only floating point numbers to be typed |
| 2 | int d_fedit_proc(int msg, DIALOG *obj, int c) |
| 3 | { |
| 4 | char low = (char)c; |
| 5 | char high = (char)((int)(c >> 8)); |
| 6 | int ret; |
| 7 | |
| 8 | // catch invalid character input for floating point |
| 9 | if((msg==MSG_CHAR)||(msg==MSG_UCHAR)) |
| 10 | { |
| 11 | if((obj->d2>0)&&(low==45)) // disallow -(ascii 45) anywhere but at pos 0 |
| 12 | return D_O_K; |
| 13 | |
| 14 | // disallow anything BUT 0-9,-,.,',' (ascii[48,57],45,46,44) |
| 15 | // and ESC,ENTER,BACKSPACE(ascii 27,13,8) |
| 16 | // and DEL,LEFT,RIGHT |
| 17 | if(((low<48)||(low>57))&&(low!=45)&&(low!=46)&&(low!=44) |
| 18 | &&(low!=27)&&(low!=13)&&(low!=8) |
| 19 | &&(high!=KEY_DEL)&&(high!=KEY_LEFT)&&(high!=KEY_RIGHT) |
| 20 | &&(high!=KEY_ENTER)) |
| 21 | return D_O_K; |
| 22 | } |
| 23 | |
| 24 | // make use of standard edit proc to handle everything else |
| 25 | if((low==44)&&((msg==MSG_CHAR)||(msg==MSG_UCHAR))) // if ',' is the key |
| 26 | { |
| 27 | int modc = high; |
| 28 | modc = modc << 8; |
| 29 | modc += 46; // (ascii 46 is '.') |
| 30 | ret = d_edit_proc(msg,obj,modc); |
| 31 | } |
| 32 | else |
| 33 | ret = d_edit_proc(msg,obj,c); |
| 34 | |
| 35 | return ret; |
| 36 | } |
This still has a few issues though. First - is only allowed at the beginning, but actually this proc will happily let you enter two -- or even more, so you still need to parse the string to decide what input is valid, before passing the parameters on to the default d_edit_proc. Also this proc doesn't prevent entering multiple '.'s.
I still think it's a good idea though to modify the parameters, before passing them on to d_edit_proc to get the desired behaviour.