Click here to Skip to main content
15,895,256 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am subclassing edit control to accept only decimal numbers.

Everything works fine, and the only thing left for me is processing the case when user selects portion of the text and presses Delete key ( VK_DELETE ).

My question is following:

Does pressing a Delete key ( VK_DELETE ) sends some message like WM_CLEAR that I can use for my processing, or do I have to handle WM_KEYDOWN in my subclassing procedure and do the processing there?

Thank you.

Best regards.
Posted
Comments
Sergey Alexandrovich Kryukov 16-Mar-14 13:10pm    
You can easily find it out using message spy application. Not clear why would you need to handle VK_DELETE in any non-default way at all. You only need to allow decimal digits as input characters (and, don't forget, backspace, the "character" 0x08).
—SA
AlwaysLearningNewStuff 16-Mar-14 22:47pm    
Mr.Kryukov,

First off thank you for taking time to see this post and thank you for replying.

This will take a while so please forgive me for a lengthy comment. If you have further questions I will understand, and I will answer them as always.

Here is the problem:

I have a dialog box with lots of edit controls, radio buttons and other stuff and it has a purpose to communicate with a database.

Dialog box can both read and edit the data from a database, and there is the problem.

The maximal allowed length of the decimal number is 10, and here is the critical case:

Let us say user enters .123456789 into database. This will be stored as 0.123456789 which is longer than maximal allowed length by 1 character ( the leading zero was added ).

User may make a mistake by clicking the wrong radio button, for example, and will decide to correct it. My dialog box has an option of reloading the data and user will do that in order to make the above mentioned correction.

Now I have a dilemma:

If I truncate the data I will lose the part of the information that may be important. I consider this a bad coding and unacceptable option.

If I just load the data into edit control it will have 0.123456789 text which is 11 characters long.

Imagine that user corrects the before mentioned mistake by clicking on the correct radio button and hits "Edit" button.

Now I will use GetWindowText( hwndOfMyEditControl, myStringVariable, 10 ); to store back the text from the edit control and get buffer overflow since eleven characters can't stay in an array of 10 characters.

Therefore to fix this problem I have decided to forbid the user to leave out the leading numbers.

This makes -.23 and other similar formats invalid.

If user enters -123.456 ( where red text represents current selection ) and presses Delete, I will get -.23. The user may continue to add numbers at the end of the number, thus getting the critical case I have described ( he could just add seven consecutive nines and get something like -.239999999 which is eleven characters long and again I will get buffer overflow ).

I do not how to handle this case properly, so I have decided to subclass the edit control and just forbid the format where leading numbers are left out, as I have already mentioned.

That is why I needed to properly handle every deleting ( WM_CUT, WM_CLEAR, backspace and Delete ).

I have posted this question on StackOverflow as well, and got an interesting answer:

The poster used Spy++ on Notepad to actually determine that only WM_KEYDOWN and WM_KEYUP messages are sent when user presses Delete. Therefore I have implemented my handling of Delete via WM_KEYDOWN.

If you have a better way to reccomend for protection of the above mentioned buffer overflow, I would highly appreciate it, as always. After all we learn new and useful things aslong as we live, right?

I aain apologize for the lengthy comment, but I wanted to explain the problem properly, and I never spare "words" to do that.

Best regards.

1 solution

The detail explained in your comment are more important than the question itself, where you did not tell us the most important things. The problem is purely artificial, and here is the root of it: "This will be stored as 0.123456789 which is longer than maximal allowed". That said, you are string strings representing numbers in the database. This is totally wrong, wasteful, unreliable. You need to store data of numeric types. Generally, this is a weird trend haunting many beginners these days: working with strings representing data instead of data itself. This is very bad.

And of course, in the UI, you should better filter out unwanted characters. For example, if you enter fractional data, you may need to allow only digits, decimal delimiter (remember, it depends on culture!) and, optionally + or - (you may want to make it depending on the allowed range), and also backspace. This filtering is the routine techniques. I don't think this is a problem for you.

As to handling VK_DELETE, you don't need to do anything but default. Please see my comment to the question.

—SA
 
Share this answer
 
Comments
AlwaysLearningNewStuff 17-Mar-14 1:13am    
There is a misunderstanding again between us. Let us try to clarify matters again:

I use _wtof_l( myDoubleVariable, _get_current_locale() ) to properly convert string to double.

I insert into database using ADO ( I havent learned ADO.NET yet ), by using Command object.

Everything works fine. When I type in edit control .23 my query successfully executes.

The point is that once I open database to check if it really executed well, I see 0.23 which is OK, since wtof adds automatically the leading zero.

If I now load this value into edit control I get 0.23 text, which is also OK, since that is a number stored in database.

However if I call GetWindowText there is a danger of buffer oferflow, due to reasons described in my comment.

Hopefully this clarifies thing better.

Thank you Mr.Kryukov for trying to help and for your patience.

Best regards.
Sergey Alexandrovich Kryukov 17-Mar-14 10:03am    
Why do you have strings in first place? To convert it to double? Don't store strings.
—SA
AlwaysLearningNewStuff 17-Mar-14 17:07pm    
I have a database with different fields like employee names, consumption of electric energy, phone number, company name etc.

I store numeric data as numbers, of course, but GetWindowText stores the text of the edit control into a char array ( please see the documentation ) and that is the only way to get the text from the edit control if it is a decimal number.

Since edit control's text must be stored in a string I must convert it to double, so I can properly store it in a database.

Again, let me clarify:

The database field is of type Double, INSERT query will use double, but edit control has text in it, and the only way to get that text is to store it into string with the call to GetWindowText.

There is no other way I know if you have a decimal number as edit control's text ( that is why I can not use GetDlgItemInt for example ). Therefore I must perform conversion from string to double.

I hope this clarifies things better.

Best regards.
Sergey Alexandrovich Kryukov 17-Mar-14 17:54pm    
Of course, there is no way to get to number, if it is entered by the user, but it does not create a situation where you have limitation by number of decimal positions. You first parse the text into double, and, from this moment, decimals become irrelevant, you have binary double...
—SA
AlwaysLearningNewStuff 17-Mar-14 19:09pm    
" You first parse the text into double, and, from this moment, decimals become irrelevant, you have binary double..."

Well, it seems that this is the point where I face the problem.

I believe that database has a fixed range of maximal decimal numbers it can store.

Let us say that range is from -100,5 to 100,5. If user enters 200,5 than an error will occur after I try to execute insert into database.

To protect myself from that, I have used EM_LIMITTEXT to limit the length of text entered text into edit control.

I use strings of fixed length to store the result of GetWindowText.

For example, if the maximal text length is 50, i use wchar_t ExampleString[50] for storing the result of GetWindowText.

If wtof adds a leading zero, and I programmatically load the number into edit control, the text length might be 51 due to the added leading zero. This will cause buffer overflow when I call GetWindowText.

Perhaps my entire approach of getting/storing the text from edit control is bad, but being a beginner I know no better. If you believe this may be a problem, then maybe it is best for me to ask a new question about it.

Best regards.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900