I have absolutely no clue why the following code works except for the following three characters: ç, à and è. It should rule out all non-digit characters from being written into an edit control. Because it let's those three pass trough I am forced to turn this:

if(!isdigit(editControl_Content[2]))

into this:

if(editControl_Content[2] == 'è' | editControl_Content[2] == 'ç' | editControl_Content[2] == 'à' | !isdigit(editControl_Content[2]))

This is the complete code:

char editControl_Content[2];
GetWindowText(GetDlgItem(hwnd, LOWORD(wParam)), &editControl_Content[2], 2);
            
if(editControl_Content[2] == 'è' | editControl_Content[2] == 'ç' | editControl_Content[2] == 'à' | !isdigit(editControl_Content[2])) {
  SetWindowText(GetDlgItem(hwnd, LOWORD(wParam)), NULL);
}
else if(lockOn == false) {
  SetFocus(GetDlgItem(hwnd, LOWORD(wParam)+1));
}

Any help would be very well appreciated.
Thank you.

Recommended Answers

All 12 Replies

First you're using the wrong "OR". For comparisons it's "||", not the bit-operation 'or' "|".

First you're using the wrong "OR". For comparisons it's "||", not the bit-operation 'or' "|".

My bad, it's 0.20 here, typed it wrong...

EDIT: is this because è, ç, à are Extended ASCII?

'ç' has a decimal value of -25, and isdigit() only works with positive signed integer values.

See if this works:

int isNum(char c)
{
    if((int)c > 47 && (int)c < 58) { return(true); }
    return(false);
}

You are not getting the window text properly, it should be

char editControl_Content[2];
// the following gets one char into editControl_Content[0] and sets
// editControl_Content[1] to '\0'
int charCount = GetWindowText(GetDlgItem(hwnd, LOWORD(wParam)), editControl_Content, 2);
if(charCount > 0)
{
    // got a char ...
}

And further on, when you use isdigit(), be sure to use the valid index (0) i.e.

if(isdigit(editControl_Content[0]))
...

Some notes about isdigit and non-ascii characters:

The isdigit is a C library function (the C library is a part of C++ library) so let's open the C language standard:

The header <ctype.h> declares several functions useful for classifying and mapping
characters. In all cases the argument is an int, the value of which shall be representable as an unsigned char or shall equal the value of the macro EOF. If the argument has any other value, the behavior is undefined.

So isdigit domain is 0..255 + EOF macros (usually -1). It's well known that char type may be signed or unsigned. If it's signed, all non-ascii char values implicitly converted to negative integers (formally bad values for all isXXX family).
Fortunately it's so simple to cope with the problem in platform-independent manner, for example:

if (isdigit(c&0xFF))    // 1st method
if ((unsigned char)c) // 2nd method
// C++ style radical method #3:
inline bool isDigit(char c) { return c >= '0' && c <= '9'; }

The 3rd method gets the fastest code with a good compiler.

Your second method is broken -- you forgot isdigit. Your third method is not radical.

Negative values will fail when a lookup table is used to implement the function -- they point in memory outside the lookup table.

Your second method is broken -- you forgot isdigit. Your third method is not radical.

Negative values will fail when a lookup table is used to implement the function -- they point in memory outside the lookup table.

#2 Yes, it's annoying misprint ;)
#3 Radical means that it's absolutely implementation-independent method with a very fast instructions generated.
The last remark is a truism.

You are not getting the window text properly, it should be

char editControl_Content[2];
// the following gets one char into editControl_Content[0] and sets
// editControl_Content[1] to '\0'
int charCount = GetWindowText(GetDlgItem(hwnd, LOWORD(wParam)), editControl_Content, 2);
if(charCount > 0)
{
    // got a char ...
}

And further on, when you use isdigit(), be sure to use the valid index (0) i.e.

if(isdigit(editControl_Content[0]))
...

That doesn't seem right because when I try this:

char editControl_Content[2];
GetDlgItemText(hwnd, LOWORD(wParam), &editControl_Content[2], 2);
            
aString<< editControl_Content[2];
MessageBox(hwnd, aString.str().c_str(), "title", MB_OK);

if I change aString<< editControl_Content[2]; to aString<< editControl_Content[0]; like you're saying I get jibberish, so I put jibberish as argument to isdigit().
Unless I'm mistaken, editControl_Content[2] is a valid argument for isdigit().

Thank

See if this works:

int isNum(char c)
{
    if((int)c > 47 && (int)c < 58) { return(true); }
    return(false);
}

I used your solution, thanks, I'm guessing this effectively rules out any other extended characters for example chinese ones...

Hmm, you have to understand that char editControl_Content[2]; allocates space for two chars.
The array indexes start from zero, meaning that the only indexes you are allowed to access in this case are:

1) editControl_Content[0]
2) editControl_Content[1]

So, to get the window text (or a single char in this case), use the following

char editControl_Content[2];
GetDlgItemText(hwnd, LOWORD(wParam), editControl_Content, 2);

Note that, if GetDlgItemText() succeeds, it will set editControl_Content[1] to '\0'.

The reason why you got gibberish, is that you passed an illegal address (&editControl_Content[2]) to GetDlgItemText() in the first place.

Hmm, you have to understand that char editControl_Content[2]; allocates space for two chars.
The array indexes start from zero, meaning that the only indexes you are allowed to access in this case are:

1) editControl_Content[0]
2) editControl_Content[1]

So, to get the window text (or a single char in this case), use the following

char editControl_Content[2];
GetDlgItemText(hwnd, LOWORD(wParam), editControl_Content, 2);

Note that, if GetDlgItemText() succeeds, it will set editControl_Content[1] to '\0'.

The reason why you got gibberish, is that you passed an illegal address (&editControl_Content[2]) to GetDlgItemText() in the first place.

Oh right, thanks for clearing that up for me, I really appreciate it!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.