Discussion:
Numeric keypad 0
(too old to reply)
Stephen Wolstenholme
2013-03-25 15:40:55 UTC
Permalink
Has anyone seen a problem with isalnum not seeing the zero key on the
numeric keyboard? Num lock is on. The zero key on the QWERTY keyboard
works. Adding char 96 to the test works but it should not be needed.

Steve
--
EasyNN-plus. Neural Networks plus. http://www.easynn.com
SwingNN. Forecast with Neural Networks. http://www.swingnn.com
JustNN. Just Neural Networks. http://www.justnn.com
R.Wieser
2013-03-25 20:52:43 UTC
Permalink
Stephen,

Have you already checked what data you are feeding to that "isalnum"
function (coming from the numeric keyboard) ?

Most likely the problem is related to the method/function you are using to
retrieve the data from the keyboard, not to the "isalnum" function.

Regards,
Rudy Wieser
Post by Stephen Wolstenholme
Has anyone seen a problem with isalnum not seeing the zero key on the
numeric keyboard? Num lock is on. The zero key on the QWERTY keyboard
works. Adding char 96 to the test works but it should not be needed.
Steve
Stephen Wolstenholme
2013-03-26 09:40:52 UTC
Permalink
Post by R.Wieser
Stephen,
Have you already checked what data you are feeding to that "isalnum"
function (coming from the numeric keyboard) ?
Most likely the problem is related to the method/function you are using to
retrieve the data from the keyboard, not to the "isalnum" function.
Regards,
Rudy Wieser
I use CScrollView::OnKeyDown(nChar, nRepCnt, nFlags);

Steve
--
EasyNN-plus. Neural Networks plus. http://www.easynn.com
SwingNN. Forecast with Neural Networks. http://www.swingnn.com
JustNN. Just Neural Networks. http://www.justnn.com
R.Wieser
2013-03-26 11:31:09 UTC
Permalink
Hello Stepehn,
Post by Stephen Wolstenholme
I use CScrollView::OnKeyDown(nChar, nRepCnt, nFlags);
My apologies, but I do not really know vc.mfc all that well (my
language-of-choice is a different one). That means that although I can help
you by pointing out the most common causes of certain problems you have to
do the actual checking yourself.

So, did you look at what result that that "CScrollView::OnKeyDown" function
returns ? Does it return different results when pressing a normal and a
numeric "0" ?

Regards,
Rudy Wieser
Post by Stephen Wolstenholme
Post by R.Wieser
Stephen,
Have you already checked what data you are feeding to that "isalnum"
function (coming from the numeric keyboard) ?
Most likely the problem is related to the method/function you are using to
retrieve the data from the keyboard, not to the "isalnum" function.
Regards,
Rudy Wieser
I use CScrollView::OnKeyDown(nChar, nRepCnt, nFlags);
Steve
--
EasyNN-plus. Neural Networks plus. http://www.easynn.com
SwingNN. Forecast with Neural Networks. http://www.swingnn.com
JustNN. Just Neural Networks. http://www.justnn.com
Stephen Wolstenholme
2013-03-26 11:53:05 UTC
Permalink
Post by R.Wieser
So, did you look at what result that that "CScrollView::OnKeyDown" function
returns ? Does it return different results when pressing a normal and a
numeric "0" ?
Regards,
Rudy Wieser
It returns the correct character code for all keys. The code for
numeric keypad 0 is 96, 1 is 97, 2 is 98 etc. For some reason isalnum
does not include 96 so I have had to use
if(isalnum(nChar) || nChar == 96 || other keys

Steve
--
EasyNN-plus. Neural Networks plus. http://www.easynn.com
SwingNN. Forecast with Neural Networks. http://www.swingnn.com
JustNN. Just Neural Networks. http://www.justnn.com
R.Wieser
2013-03-26 16:00:23 UTC
Permalink
Stephen,
Post by Stephen Wolstenholme
It returns the correct character code for all keys. The
code for numeric keypad 0 is 96, 1 is 97, 2 is 98 etc.
Actually, those are not near to "the correct character code" *at all* ...
:-\

The digit "0" is, in standard ASCII, equal to 48, going up to 57 for the
digit "9".

In standard ASCII 96 is a back-quote, 97 the "a", 98 the "b" and so on.

The problem is that your function returns *keycodes*, not characters.

Just try what happens when you type a normal character and than the same,
but now upper-case (shifted) one. For the second you will probably get two
codes, with the last one being equal to the non-shifted one (and the first
the keycode for the shift key).

In short: you're using the wrong command to retrieve your keyboard-data.

Regards,
Rudy Wieser
Post by Stephen Wolstenholme
Post by R.Wieser
So, did you look at what result that that "CScrollView::OnKeyDown" function
returns ? Does it return different results when pressing a normal and a
numeric "0" ?
Regards,
Rudy Wieser
It returns the correct character code for all keys. The code for
numeric keypad 0 is 96, 1 is 97, 2 is 98 etc. For some reason isalnum
does not include 96 so I have had to use
if(isalnum(nChar) || nChar == 96 || other keys
Steve
--
EasyNN-plus. Neural Networks plus. http://www.easynn.com
SwingNN. Forecast with Neural Networks. http://www.swingnn.com
JustNN. Just Neural Networks. http://www.justnn.com
Stephen Wolstenholme
2013-03-26 17:07:39 UTC
Permalink
Post by R.Wieser
Stephen,
Post by Stephen Wolstenholme
It returns the correct character code for all keys. The
code for numeric keypad 0 is 96, 1 is 97, 2 is 98 etc.
Actually, those are not near to "the correct character code" *at all* ...
:-\
The digit "0" is, in standard ASCII, equal to 48, going up to 57 for the
digit "9".
Those are ASCII rather than VC++ keycodes.
Post by R.Wieser
In standard ASCII 96 is a back-quote, 97 the "a", 98 the "b" and so on.
Again ASCII. The codes are not the same as ASCII.
Post by R.Wieser
The problem is that your function returns *keycodes*, not characters.
To be accurate the function uses virtual keycodes in VC++. Virtual key
codes need to converted to characters using MapVirtualKey.
Post by R.Wieser
Just try what happens when you type a normal character and than the same,
but now upper-case (shifted) one. For the second you will probably get two
codes, with the last one being equal to the non-shifted one (and the first
the keycode for the shift key).
In short: you're using the wrong command to retrieve your keyboard-data.
It the same code as I have used in lots of applications for many
years. We are at cross purposes aren't we! I'm talking VC++. It's
different to most other development software.

Steve
--
EasyNN-plus. Neural Networks plus. http://www.easynn.com
SwingNN. Forecast with Neural Networks. http://www.swingnn.com
JustNN. Just Neural Networks. http://www.justnn.com
R.Wieser
2013-03-26 23:54:20 UTC
Permalink
Stephen,
Post by Stephen Wolstenholme
Those are ASCII rather than VC++ keycodes.
Correct. Your "isalnum" function expects ASCII, not virtual keycodes.

Your "CScrollView::OnKeyDown" function on the other hand returns virtual
keycodes, not ASCII.

Both functions are simply not compatible with each other.
Post by Stephen Wolstenholme
Virtual key codes need to converted to characters using MapVirtualKey.
Thats one way to solve your problem, yes. Read keycode, *convert*, feed to
isalnum.
Post by Stephen Wolstenholme
It the same code as I have used in lots of applications
for many years.
Than you now have lots of applications all with a major(?) bug in them. :-\
Post by Stephen Wolstenholme
We are at cross purposes aren't we!
I think you're right. I was trying to find where it went wrong and help
you fix it. What are you trying to do here ?
Post by Stephen Wolstenholme
I'm talking VC++. It's different to most other development
software.
Not really. Besides, most programming languages have more similarities
than differences.

But hey, if you want to fight me because you can't handle you made a simple
mistake than I think I'm going to end our conversation here.

Regards,
Rudy Wieser

P.s.
Before you think of screaming your head off because, according to you, I do
not understand the first thing about programming or VC++, try feeding the
characters with ASCII codes 32 thru 126 (or even from 0 upto 255) to that
"isalnum" function of yours, and see if its results match the digits, upper-
and lower-case characters.

When you see it does you *could* come to the conclusion that that function
behaves as it should, and the problem lies elsewhere ...
Post by Stephen Wolstenholme
Post by R.Wieser
Stephen,
Post by Stephen Wolstenholme
It returns the correct character code for all keys. The
code for numeric keypad 0 is 96, 1 is 97, 2 is 98 etc.
Actually, those are not near to "the correct character code" *at all* ...
:-\
The digit "0" is, in standard ASCII, equal to 48, going up to 57 for the
digit "9".
Those are ASCII rather than VC++ keycodes.
Post by R.Wieser
In standard ASCII 96 is a back-quote, 97 the "a", 98 the "b" and so on.
Again ASCII. The codes are not the same as ASCII.
Post by R.Wieser
The problem is that your function returns *keycodes*, not characters.
To be accurate the function uses virtual keycodes in VC++. Virtual key
codes need to converted to characters using MapVirtualKey.
Post by R.Wieser
Just try what happens when you type a normal character and than the same,
but now upper-case (shifted) one. For the second you will probably get two
codes, with the last one being equal to the non-shifted one (and the first
the keycode for the shift key).
In short: you're using the wrong command to retrieve your keyboard-data.
It the same code as I have used in lots of applications for many
years. We are at cross purposes aren't we! I'm talking VC++. It's
different to most other development software.
Steve
Stephen Wolstenholme
2013-03-27 09:45:10 UTC
Permalink
Post by R.Wieser
But hey, if you want to fight me because you can't handle you made a simple
mistake than I think I'm going to end our conversation here.
I'm not fighting anyone. My original question was to find why it
happens rather than how to fix it. It has always been a simple fix but
it's still a mystery why numeric key 0 does not translate to an ASCII
while all other keys do.

Steve
--
EasyNN-plus. Neural Networks plus. http://www.easynn.com
SwingNN. Forecast with Neural Networks. http://www.swingnn.com
JustNN. Just Neural Networks. http://www.justnn.com
R.Wieser
2013-03-27 19:51:03 UTC
Permalink
Stephen,
Post by Stephen Wolstenholme
I'm not fighting anyone.
You could have fooled me.
Post by Stephen Wolstenholme
My original question was to find why it
happens rather than how to fix it.
I have told you that. Several times:

DO NOT FEED KEYCODES INTO A FUNCTION THAT EXPECTS ASCII.

Thats like putting diesel into a car that expects petrol, and than throwing
your hands up because you have no clue that, although both are fuel, they
are quite different.
Post by Stephen Wolstenholme
... but it's still a mystery why numeric key 0 does
not translate to an ASCII while all other keys do.
Than you haven't been listening to anything I said I'm afraid.

Did you ever wonder why a square peg does not fit into a round hole ? I
mean, most of that square peg does actually fit in there, its just the
corners that are not accepted by that round hole. Yeah, surely its all the
fault of that round hole. :-)



Lets put it all thogether, shall we ?

1)You post a problem with a certain function, claiming it does not behave as
it should.

Whats the chance that this function, used by many programmers and inside
lots of programs, is actually malfunctioning and has stayed undetected all
this time ? I would say very little (a chance nearing Zero).

Logic conclusion: Its either your code or method that is flawed.

2) Alas, your post does not contain any code, which denies us the
possibility to determine and point-out the actual problem.

When asked for more detailed information all you can do is to name a single,
second command. Dude, really ?

3) When trying to point out the problem with the difference between those
two functions you come up with a lecture about, quote: "Virtual key codes
need to converted to characters using MapVirtualKey." without as much as a
single word to how that has any bearing on your problem. Not a single word
on if you used it in your code and if so how.

Am I supposed to (if you did actually use it) have just read that directly
from your mind ?

3) Although you have a problem with a command you're using and although you
claim to have created programs for many years you have not learned anything
about bug-hunting.

4) When someone else tries to help you (me) you are *activily opposing*
him -- probably because you simply do not believe that your own code could
be at fault.

Dude, you're the achtype noob: You want to learn, but only if what we tell
you matches what you think is the problem/cause. Everything else is simply
ignored. Thats worse than dumb I'm afraid.

Oh well, you can't say I didn't try, which is more than I can say from you.

Regards,
Rudy Wieser


-- Origional message.
Post by Stephen Wolstenholme
Post by R.Wieser
But hey, if you want to fight me because you can't handle you made a simple
mistake than I think I'm going to end our conversation here.
I'm not fighting anyone. My original question was to find why it
happens rather than how to fix it. It has always been a simple fix but
it's still a mystery why numeric key 0 does not translate to an ASCII
while all other keys do.
Steve
--
EasyNN-plus. Neural Networks plus. http://www.easynn.com
SwingNN. Forecast with Neural Networks. http://www.swingnn.com
JustNN. Just Neural Networks. http://www.justnn.com
Stephen Wolstenholme
2013-03-28 09:44:26 UTC
Permalink
Post by R.Wieser
2) Alas, your post does not contain any code, which denies us the
possibility to determine and point-out the actual problem.
I did not to post the code but here it is:-

void CEasyNNView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if(theApp.m_nTraceLevel > 0)
theApp.Trace(_T("OnKeyDown"));

CEasyNNDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);

CDiagnostics dlgDiagnostics;

COrder dlgOrder;

int nResult = NOT_EDITED;

int nFound;

SHORT nLShift = 0;

SHORT nRShift = 0;

SHORT nControl = 0;

// Stop first click move
theApp.m_bInit = FALSE;

UINT nScroll;

CString strChar, strTemp;

CString strDefaults, strNames;

CFileStatus fileStatus;

BYTE byteKeyboardState[256];

switch(nChar)
{
case VK_HOME:

if(pDoc->m_bViewGrid)
{
if(m_bLastVert)
{
OnVScroll(SB_TOP, 0, GetScrollBarCtrl(SB_VERT));

GoTo(0, m_nCellCol);
}
else
{
OnHScroll(SB_LEFT, 0, GetScrollBarCtrl(SB_HORZ));

GoTo(m_nCellRow, 0);
}
}

if(pDoc->m_bViewGraphColumn || pDoc->m_bViewSensitivity)
{
m_nCellCol = 0;

pDoc->Refresh();

Invalidate();
}

if(pDoc->m_bViewAssociations)
OnVScroll(SB_TOP, 0, GetScrollBarCtrl(SB_VERT));

break;

case VK_END:

if(pDoc->m_bViewGrid)
{
if(m_bLastVert)
{
OnVScroll(SB_BOTTOM, 0, GetScrollBarCtrl(SB_VERT));

GoTo(pDoc->m_nRows - 1, m_nCellCol);
}
else
{
OnHScroll(SB_RIGHT, 0, GetScrollBarCtrl(SB_HORZ));

GoTo(m_nCellRow, pDoc->m_nCols - 1);
}
}

if(pDoc->m_bViewGraphColumn || pDoc->m_bViewSensitivity)
{
m_nCellCol = pDoc->m_nCols - 1;

pDoc->Refresh();

Invalidate();
}

if(pDoc->m_bViewAssociations)
OnVScroll(SB_BOTTOM, 0, GetScrollBarCtrl(SB_VERT));

break;

case VK_PRIOR:

OnVScroll(SB_PAGEUP, 0, GetScrollBarCtrl(SB_VERT));

m_bLastVert = TRUE;

break;

case VK_NEXT:

OnVScroll(SB_PAGEDOWN, 0, GetScrollBarCtrl(SB_VERT));

m_bLastVert = TRUE;

break;

case VK_DOWN:

if(pDoc->m_bViewGrid || pDoc->m_bViewGraphColumn)
{
if(m_nCellRow < pDoc->m_nRows)
{
m_nCellRow++;

if(CellTooLow() && pDoc->m_bViewGrid)
{
nScroll = GetVScrollInfo(POS);
SetVScrollInfo(POS, nScroll + m_nRowHeight);
m_nScrollRows++;
Invalidate();
}
}
}
else
OnVScroll(SB_LINEDOWN, 0, GetScrollBarCtrl(SB_VERT));

m_bLastVert = TRUE;

break;

case VK_UP:

if(pDoc->m_bViewGrid || pDoc->m_bViewGraphColumn)
{
if(m_nCellRow > 0)
{
m_nCellRow--;

if(CellTooHigh() && pDoc->m_bViewGrid)
{
nScroll = GetVScrollInfo(POS);
SetVScrollInfo(POS, nScroll - m_nRowHeight);
m_nScrollRows--;
Invalidate();
}
}
}
else
OnVScroll(SB_LINEUP, 0, GetScrollBarCtrl(SB_VERT));

m_bLastVert = TRUE;

break;

case VK_RIGHT:

case VK_TAB:

if(pDoc->m_bViewGrid)
{
if(m_nCellCol < pDoc->m_nCols)
{
m_nCellCol++;

if(CellTooRight())
{
nScroll = GetHScrollInfo(POS);
SetHScrollInfo(POS, nScroll + m_nColWidth);
m_nScrollCols++;
Invalidate();
}
}
}
else if(pDoc->m_bViewGraphColumn || pDoc->m_bViewSensitivity)
{
if(m_nCellCol < pDoc->m_nCols - 1)
m_nCellCol++;

if(m_nCellCol > pDoc->m_nCols - 1)
m_nCellCol = pDoc->m_nCols - 1;

if(pDoc->m_bViewSensitivity)
{
CInOut* pInOut = NULL;

pInOut = pDoc->GetInOut(m_nCellCol);

while(pInOut->m_nInOutType != IN_OUT_OUTPUT)
{
m_nCellCol++;

if(m_nCellCol > pDoc->m_nCols - 1)
{
m_nCellCol = pDoc->m_nCols - 1;

break;
}

pInOut = pDoc->GetInOut(m_nCellCol);
}
}

pDoc->Refresh();

Invalidate();
}
else
OnHScroll(SB_LINERIGHT, 0, GetScrollBarCtrl(SB_HORZ));

m_bLastVert = FALSE;

break;

case VK_LEFT:

case VK_BACK:

if(pDoc->m_bViewGrid)
{
if(m_nCellCol > 0)
{
m_nCellCol--;

if(CellTooLeft())
{
nScroll = GetHScrollInfo(POS);
SetHScrollInfo(POS, nScroll - m_nColWidth);
m_nScrollCols--;
Invalidate();
}
}
}
else if(pDoc->m_bViewGraphColumn || pDoc->m_bViewSensitivity)
{
if(m_nCellCol > 0)
m_nCellCol--;

if(m_nCellCol < 0)
m_nCellCol = 0;

if(pDoc->m_bViewSensitivity)
{
CInOut* pInOut = NULL;

pInOut = pDoc->GetInOut(m_nCellCol);

while(pInOut->m_nInOutType != IN_OUT_OUTPUT)
{
m_nCellCol--;

if(m_nCellCol < 0)
{
m_nCellCol = 0;

break;
}

pInOut = pDoc->GetInOut(m_nCellCol);
}
}

pDoc->Refresh();

Invalidate();
}
else
OnHScroll(SB_LINELEFT, 0, GetScrollBarCtrl(SB_HORZ));

m_bLastVert = FALSE;

break;

case VK_ESCAPE:

if(pDoc->m_bViewGrid)
{
pDoc->m_nSelectedCol = NONE;

pDoc->m_nSelectedRow = NONE;

Invalidate();
}

break;

case VK_F7:

if(pDoc->m_bIsLearning)
break;

if(theApp.m_bTrace)
{
theApp.m_bTrace = FALSE;

AfxMessageBox(_T("Tracing has been switched off"));

break;
}

dlgDiagnostics.m_nWarnLevel = 0;

dlgDiagnostics.m_nTraceLevel = theApp.m_nTraceLevel;

dlgDiagnostics.m_strEditTraceKeyword =
theApp.m_strTraceKeyword;

if(dlgDiagnostics.DoModal() == IDOK)
{
theApp.m_nWarnLevel = dlgDiagnostics.m_nWarnLevel;

theApp.m_nTraceLevel = dlgDiagnostics.m_nTraceLevel;

theApp.m_strTraceKeyword =
dlgDiagnostics.m_strEditTraceKeyword;

theApp.m_nTraceCount = 0;

theApp.m_nTraceRepeats = 0;

theApp.m_nTraceCycles = 0;

theApp.m_strLastTrace.Empty();

if(theApp.m_nTraceLevel > 0)
{
CFile file;

CFileException fileException;

theApp.m_strTraceName = _T("enntrace.txt");

CFileDialog dlgFile(FALSE, _T("txt"),
theApp.m_strTraceName, NULL, NULL);

// Create new trace file
dlgFile.m_ofn.lpstrTitle = _T("Open trace file");

if(dlgFile.DoModal() == IDOK)
{
theApp.m_strTraceName = dlgFile.GetPathName();

if(!file.Open(theApp.m_strTraceName,
CFile::modeCreate | CFile::modeNoTruncate, &fileException))
{
// Try again
if(!file.Open(theApp.m_strTraceName,
CFile::modeCreate | CFile::modeNoTruncate, &fileException))
{
theApp.m_bTrace = FALSE;

return;
}
}

file.Close();

theApp.m_bTrace = TRUE;
}
}
}

break;

case VK_F8:

if(pDoc->m_bIsLearning)
break;

strDefaults = theApp.GetProfileString(_T("Tips1"),
_T("OpenDefaults"), NULL);

theApp.m_nDisplayBool++;

if(theApp.IsDefault(ID_DEFAULTS_OPEN))
{
strTemp = _T("Bool Names = ");

nFound = strDefaults.Find(strTemp);

if(nFound > 0)
{
strTemp = strDefaults.Mid(nFound, strTemp.GetLength()
+ 2);

strNames.Format(_T("Bool Names = %d"),
theApp.m_nDisplayBool);

strDefaults.Replace(strTemp, strNames);

theApp.WriteProfileString(_T("Tips1"),
_T("OpenDefaults"), strDefaults);
}
}

Invalidate();

pDoc->SetModifiedFlag();

break;

case VK_F9:

if(pDoc->m_bIsLearning)
break;

theApp.m_nDisplayNumbers++;

if(theApp.m_nDisplayNumbers > 2)
theApp.m_nDisplayNumbers = 0;

pDoc->SetModifiedFlag();

break;

#ifdef TRIAL

case VK_F4:
case VK_F3:
case VK_F2:

if(pDoc->m_bIsLearning)
break;

dlgOrder.DoModal();

break;

#endif

default:

if(pDoc->m_bViewGrid)
{
theApp.m_bMove = FALSE;

theApp.m_bReturn = FALSE;

nLShift = GetAsyncKeyState(VK_LSHIFT);

nRShift = GetAsyncKeyState(VK_RSHIFT);

GetKeyboardState(byteKeyboardState);

if(theApp.m_bUndo)
pDoc->EnableCheckPoint();
else
pDoc->DisableCheckPoint();

if(theApp.m_bDemoRunning)
{
nControl = GetAsyncKeyState(VK_CONTROL);

if(nControl & 0x8000)
break;
}

if(isalnum(nChar) || nChar == 96 /* Num pad 0 */ || nChar
== 187 || nChar == 188 || nChar == 189 || nChar == 190 || nChar ==
191)
{
GoTo(m_nCellRow, m_nCellCol);

nChar = MapVirtualKey(nChar, 2);

nChar = tolower(nChar);

if(byteKeyboardState[VK_CAPITAL] || (nLShift & 0x8000)
|| (nRShift & 0x8000))
nChar = toupper(nChar);

nResult = EditGrid(nChar);

theApp.m_bMove = TRUE;
}

if(nChar == VK_RETURN || nChar == VK_SPACE)
{
GoTo(m_nCellRow, m_nCellCol);

// Must do before EditGrid
theApp.m_bReturn = TRUE;

nResult = EditGrid();
}

switch(nResult)
{
case NO_CELL:

pDoc->AddRow();

pDoc->AddCol(TRUE, FALSE, TRUE);

break;

case NO_ROW:

if(theApp.m_bPresets)
Insert(EXAMPLE_TRAINING, INSERT_ALL,
pDoc->m_nRows);
else
pDoc->AddRow();

break;

case NO_COL:

pDoc->AddCol(TRUE, FALSE, TRUE);

break;
}

if(nResult != NOT_EDITED)
{
Invalidate();

NextCell();

if(CellTooHigh())
{
nScroll = GetVScrollInfo(POS);
SetVScrollInfo(POS, nScroll - m_nRowHeight);
m_nScrollRows--;
Invalidate();
}
else if(CellTooLeft())
{
nScroll = GetHScrollInfo(POS);
SetHScrollInfo(POS, nScroll - m_nColWidth);
m_nScrollCols--;
Invalidate();
}
else if(CellTooRight())
{
nScroll = GetHScrollInfo(POS);
SetHScrollInfo(POS, nScroll + m_nColWidth);
m_nScrollCols++;
Invalidate();
}
else if(CellTooLow())
{
nScroll = GetVScrollInfo(POS);
SetVScrollInfo(POS, nScroll + m_nRowHeight);
m_nScrollRows++;
Invalidate();
}
}
}
}

theApp.m_bMark = FALSE;

MarkGridCell();

AlignVerticalScroll();

::PostMessage(AfxGetMainWnd()->m_hWnd, WM_APP_POSITION,
m_nCellRow, m_nCellCol);

if(!pDoc->m_bViewGrid)
m_bLastVert = TRUE;

CScrollView::OnKeyDown(nChar, nRepCnt, nFlags);
}
--
EasyNN-plus. Neural Networks plus. http://www.easynn.com
SwingNN. Forecast with Neural Networks. http://www.swingnn.com
JustNN. Just Neural Networks. http://www.justnn.com
R.Wieser
2013-03-28 13:09:57 UTC
Permalink
Stephen,

You appear to, just as you said and I understood, stuff the "nChar" virtual
keycode output of "CEasyNNView::OnKeyDown" straight into that "isalnum"
function, without any translation from virtual keycode to character.

As such I have no idea why you posted

"Virtual key codes need to converted to characters using MapVirtualKey"

without actually doing it.

Last suggestion (which you will probably also ignore, but you can't say
nobody tried to tell you) : Find yourself a list of virtual keycodes and
one with the ASCII codes. But them next to each other. You will see that
although there is some overlap (mostly letters and digits), some of the
symbols, like the numeric 1 thru 9 virtual keycodes, are not matched with
the same ones in the ASCII list.

Now if you press the button with the virtual keycode 106, being the numeric
multiply (*) symbol, you will see that it also is regarded as an
alphanumeric symbol. So will the F1 thru F11 (not the F12) keys.

Heck, even simpler : display the virtual keycode output of your
"CEasyNNView::OnKeyDown" function in a textbox (both the value and the
character please) and see what Windows itself thinks that they represent.

If you do you will notice that you will only get uppercase characters back,
no lowercase. Your numeric keys will also return something, but not what you
typed.
Also notice that all the control keys (both shifts, ctrls, alts and others)
return "characters"

If this doesn't convince to the difference of virtual keys and (ASCII)
characters you than I do not know what, if anything, will ...

Regards,
Rudy Wieser
Post by Stephen Wolstenholme
Post by R.Wieser
2) Alas, your post does not contain any code, which denies us the
possibility to determine and point-out the actual problem.
I did not to post the code but here it is:-
void CEasyNNView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if(theApp.m_nTraceLevel > 0)
theApp.Trace(_T("OnKeyDown"));
CEasyNNDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CDiagnostics dlgDiagnostics;
COrder dlgOrder;
int nResult = NOT_EDITED;
int nFound;
SHORT nLShift = 0;
SHORT nRShift = 0;
SHORT nControl = 0;
// Stop first click move
theApp.m_bInit = FALSE;
UINT nScroll;
CString strChar, strTemp;
CString strDefaults, strNames;
CFileStatus fileStatus;
BYTE byteKeyboardState[256];
switch(nChar)
{
if(pDoc->m_bViewGrid)
{
if(m_bLastVert)
{
OnVScroll(SB_TOP, 0, GetScrollBarCtrl(SB_VERT));
GoTo(0, m_nCellCol);
}
else
{
OnHScroll(SB_LEFT, 0, GetScrollBarCtrl(SB_HORZ));
GoTo(m_nCellRow, 0);
}
}
if(pDoc->m_bViewGraphColumn || pDoc->m_bViewSensitivity)
{
m_nCellCol = 0;
pDoc->Refresh();
Invalidate();
}
if(pDoc->m_bViewAssociations)
OnVScroll(SB_TOP, 0, GetScrollBarCtrl(SB_VERT));
break;
if(pDoc->m_bViewGrid)
{
if(m_bLastVert)
{
OnVScroll(SB_BOTTOM, 0, GetScrollBarCtrl(SB_VERT));
GoTo(pDoc->m_nRows - 1, m_nCellCol);
}
else
{
OnHScroll(SB_RIGHT, 0, GetScrollBarCtrl(SB_HORZ));
GoTo(m_nCellRow, pDoc->m_nCols - 1);
}
}
if(pDoc->m_bViewGraphColumn || pDoc->m_bViewSensitivity)
{
m_nCellCol = pDoc->m_nCols - 1;
pDoc->Refresh();
Invalidate();
}
if(pDoc->m_bViewAssociations)
OnVScroll(SB_BOTTOM, 0, GetScrollBarCtrl(SB_VERT));
break;
OnVScroll(SB_PAGEUP, 0, GetScrollBarCtrl(SB_VERT));
m_bLastVert = TRUE;
break;
OnVScroll(SB_PAGEDOWN, 0, GetScrollBarCtrl(SB_VERT));
m_bLastVert = TRUE;
break;
if(pDoc->m_bViewGrid || pDoc->m_bViewGraphColumn)
{
if(m_nCellRow < pDoc->m_nRows)
{
m_nCellRow++;
if(CellTooLow() && pDoc->m_bViewGrid)
{
nScroll = GetVScrollInfo(POS);
SetVScrollInfo(POS, nScroll + m_nRowHeight);
m_nScrollRows++;
Invalidate();
}
}
}
else
OnVScroll(SB_LINEDOWN, 0, GetScrollBarCtrl(SB_VERT));
m_bLastVert = TRUE;
break;
if(pDoc->m_bViewGrid || pDoc->m_bViewGraphColumn)
{
if(m_nCellRow > 0)
{
m_nCellRow--;
if(CellTooHigh() && pDoc->m_bViewGrid)
{
nScroll = GetVScrollInfo(POS);
SetVScrollInfo(POS, nScroll - m_nRowHeight);
m_nScrollRows--;
Invalidate();
}
}
}
else
OnVScroll(SB_LINEUP, 0, GetScrollBarCtrl(SB_VERT));
m_bLastVert = TRUE;
break;
if(pDoc->m_bViewGrid)
{
if(m_nCellCol < pDoc->m_nCols)
{
m_nCellCol++;
if(CellTooRight())
{
nScroll = GetHScrollInfo(POS);
SetHScrollInfo(POS, nScroll + m_nColWidth);
m_nScrollCols++;
Invalidate();
}
}
}
else if(pDoc->m_bViewGraphColumn || pDoc->m_bViewSensitivity)
{
if(m_nCellCol < pDoc->m_nCols - 1)
m_nCellCol++;
if(m_nCellCol > pDoc->m_nCols - 1)
m_nCellCol = pDoc->m_nCols - 1;
if(pDoc->m_bViewSensitivity)
{
CInOut* pInOut = NULL;
pInOut = pDoc->GetInOut(m_nCellCol);
while(pInOut->m_nInOutType != IN_OUT_OUTPUT)
{
m_nCellCol++;
if(m_nCellCol > pDoc->m_nCols - 1)
{
m_nCellCol = pDoc->m_nCols - 1;
break;
}
pInOut = pDoc->GetInOut(m_nCellCol);
}
}
pDoc->Refresh();
Invalidate();
}
else
OnHScroll(SB_LINERIGHT, 0, GetScrollBarCtrl(SB_HORZ));
m_bLastVert = FALSE;
break;
if(pDoc->m_bViewGrid)
{
if(m_nCellCol > 0)
{
m_nCellCol--;
if(CellTooLeft())
{
nScroll = GetHScrollInfo(POS);
SetHScrollInfo(POS, nScroll - m_nColWidth);
m_nScrollCols--;
Invalidate();
}
}
}
else if(pDoc->m_bViewGraphColumn || pDoc->m_bViewSensitivity)
{
if(m_nCellCol > 0)
m_nCellCol--;
if(m_nCellCol < 0)
m_nCellCol = 0;
if(pDoc->m_bViewSensitivity)
{
CInOut* pInOut = NULL;
pInOut = pDoc->GetInOut(m_nCellCol);
while(pInOut->m_nInOutType != IN_OUT_OUTPUT)
{
m_nCellCol--;
if(m_nCellCol < 0)
{
m_nCellCol = 0;
break;
}
pInOut = pDoc->GetInOut(m_nCellCol);
}
}
pDoc->Refresh();
Invalidate();
}
else
OnHScroll(SB_LINELEFT, 0, GetScrollBarCtrl(SB_HORZ));
m_bLastVert = FALSE;
break;
if(pDoc->m_bViewGrid)
{
pDoc->m_nSelectedCol = NONE;
pDoc->m_nSelectedRow = NONE;
Invalidate();
}
break;
if(pDoc->m_bIsLearning)
break;
if(theApp.m_bTrace)
{
theApp.m_bTrace = FALSE;
AfxMessageBox(_T("Tracing has been switched off"));
break;
}
dlgDiagnostics.m_nWarnLevel = 0;
dlgDiagnostics.m_nTraceLevel = theApp.m_nTraceLevel;
dlgDiagnostics.m_strEditTraceKeyword =
theApp.m_strTraceKeyword;
if(dlgDiagnostics.DoModal() == IDOK)
{
theApp.m_nWarnLevel = dlgDiagnostics.m_nWarnLevel;
theApp.m_nTraceLevel = dlgDiagnostics.m_nTraceLevel;
theApp.m_strTraceKeyword =
dlgDiagnostics.m_strEditTraceKeyword;
theApp.m_nTraceCount = 0;
theApp.m_nTraceRepeats = 0;
theApp.m_nTraceCycles = 0;
theApp.m_strLastTrace.Empty();
if(theApp.m_nTraceLevel > 0)
{
CFile file;
CFileException fileException;
theApp.m_strTraceName = _T("enntrace.txt");
CFileDialog dlgFile(FALSE, _T("txt"),
theApp.m_strTraceName, NULL, NULL);
// Create new trace file
dlgFile.m_ofn.lpstrTitle = _T("Open trace file");
if(dlgFile.DoModal() == IDOK)
{
theApp.m_strTraceName = dlgFile.GetPathName();
if(!file.Open(theApp.m_strTraceName,
CFile::modeCreate | CFile::modeNoTruncate, &fileException))
{
// Try again
if(!file.Open(theApp.m_strTraceName,
CFile::modeCreate | CFile::modeNoTruncate, &fileException))
{
theApp.m_bTrace = FALSE;
return;
}
}
file.Close();
theApp.m_bTrace = TRUE;
}
}
}
break;
if(pDoc->m_bIsLearning)
break;
strDefaults = theApp.GetProfileString(_T("Tips1"),
_T("OpenDefaults"), NULL);
theApp.m_nDisplayBool++;
if(theApp.IsDefault(ID_DEFAULTS_OPEN))
{
strTemp = _T("Bool Names = ");
nFound = strDefaults.Find(strTemp);
if(nFound > 0)
strTemp = strDefaults.Mid(nFound, strTemp.GetLength()
+ 2);
strNames.Format(_T("Bool Names = %d"),
theApp.m_nDisplayBool);
strDefaults.Replace(strTemp, strNames);
theApp.WriteProfileString(_T("Tips1"),
_T("OpenDefaults"), strDefaults);
}
}
Invalidate();
pDoc->SetModifiedFlag();
break;
if(pDoc->m_bIsLearning)
break;
theApp.m_nDisplayNumbers++;
if(theApp.m_nDisplayNumbers > 2)
theApp.m_nDisplayNumbers = 0;
pDoc->SetModifiedFlag();
break;
#ifdef TRIAL
if(pDoc->m_bIsLearning)
break;
dlgOrder.DoModal();
break;
#endif
if(pDoc->m_bViewGrid)
{
theApp.m_bMove = FALSE;
theApp.m_bReturn = FALSE;
nLShift = GetAsyncKeyState(VK_LSHIFT);
nRShift = GetAsyncKeyState(VK_RSHIFT);
GetKeyboardState(byteKeyboardState);
if(theApp.m_bUndo)
pDoc->EnableCheckPoint();
else
pDoc->DisableCheckPoint();
if(theApp.m_bDemoRunning)
{
nControl = GetAsyncKeyState(VK_CONTROL);
if(nControl & 0x8000)
break;
}
if(isalnum(nChar) || nChar == 96 /* Num pad 0 */ || nChar
== 187 || nChar == 188 || nChar == 189 || nChar == 190 || nChar ==
191)
{
GoTo(m_nCellRow, m_nCellCol);
nChar = MapVirtualKey(nChar, 2);
nChar = tolower(nChar);
if(byteKeyboardState[VK_CAPITAL] || (nLShift & 0x8000)
|| (nRShift & 0x8000))
nChar = toupper(nChar);
nResult = EditGrid(nChar);
theApp.m_bMove = TRUE;
}
if(nChar == VK_RETURN || nChar == VK_SPACE)
{
GoTo(m_nCellRow, m_nCellCol);
// Must do before EditGrid
theApp.m_bReturn = TRUE;
nResult = EditGrid();
}
switch(nResult)
{
pDoc->AddRow();
pDoc->AddCol(TRUE, FALSE, TRUE);
break;
if(theApp.m_bPresets)
Insert(EXAMPLE_TRAINING, INSERT_ALL,
pDoc->m_nRows);
else
pDoc->AddRow();
break;
pDoc->AddCol(TRUE, FALSE, TRUE);
break;
}
if(nResult != NOT_EDITED)
{
Invalidate();
NextCell();
if(CellTooHigh())
{
nScroll = GetVScrollInfo(POS);
SetVScrollInfo(POS, nScroll - m_nRowHeight);
m_nScrollRows--;
Invalidate();
}
else if(CellTooLeft())
{
nScroll = GetHScrollInfo(POS);
SetHScrollInfo(POS, nScroll - m_nColWidth);
m_nScrollCols--;
Invalidate();
}
else if(CellTooRight())
{
nScroll = GetHScrollInfo(POS);
SetHScrollInfo(POS, nScroll + m_nColWidth);
m_nScrollCols++;
Invalidate();
}
else if(CellTooLow())
{
nScroll = GetVScrollInfo(POS);
SetVScrollInfo(POS, nScroll + m_nRowHeight);
m_nScrollRows++;
Invalidate();
}
}
}
}
theApp.m_bMark = FALSE;
MarkGridCell();
AlignVerticalScroll();
::PostMessage(AfxGetMainWnd()->m_hWnd, WM_APP_POSITION,
m_nCellRow, m_nCellCol);
if(!pDoc->m_bViewGrid)
m_bLastVert = TRUE;
CScrollView::OnKeyDown(nChar, nRepCnt, nFlags);
}
--
EasyNN-plus. Neural Networks plus. http://www.easynn.com
SwingNN. Forecast with Neural Networks. http://www.swingnn.com
JustNN. Just Neural Networks. http://www.justnn.com
Stephen Wolstenholme
2013-03-28 13:44:26 UTC
Permalink
Post by R.Wieser
As such I have no idea why you posted
"Virtual key codes need to converted to characters using MapVirtualKey"
without actually doing it.
I do call it but only if the key code is alpha numeric as the virtual
key is equal to the character code for alpha numeric characters. It
works just as well as calling MapVirtualKey before isalnum but saves a
call.

Steve
--
EasyNN-plus. Neural Networks plus. http://www.easynn.com
SwingNN. Forecast with Neural Networks. http://www.swingnn.com
JustNN. Just Neural Networks. http://www.justnn.com
Geoff
2013-03-29 07:33:59 UTC
Permalink
On Thu, 28 Mar 2013 13:44:26 +0000, Stephen Wolstenholme
Post by Stephen Wolstenholme
I do call it but only if the key code is alpha numeric as the virtual
key is equal to the character code for alpha numeric characters. It
works just as well as calling MapVirtualKey before isalnum but saves a
call.
Why are you trying to save a call? Why not call MapVirtualKey in every
case and be done with all the issues. It seems to me your method is a
premature optimization.

Your big test, if(isalnum(nChar) || nChar == 96 /* Num pad 0 */ ||
nChar == 187 || nChar == 188 || nChar == 189 || nChar == 190 || nChar
== 191) is full of magic numbers and probably wastes more CPU cycles
and it is definitely harder to maintain than simply calling
MapVirtualKey unconditionally.

FYI, the zero key is ASCII zero, 0x30. The numeric pad zero key is
VK_NUMPAD0 or 0x60 as you have it in your conditional but it will fail
the isalnum since it's the ` key on the qwerty keyboard.

http://msdn.microsoft.com/en-us/library/dd375731(v=vs.85).aspx

Use MapVirtualKey, then you won't have to worry about what you are
feeding isalnum().
Stephen Wolstenholme
2013-03-29 10:23:04 UTC
Permalink
Post by Geoff
On Thu, 28 Mar 2013 13:44:26 +0000, Stephen Wolstenholme
Post by Stephen Wolstenholme
I do call it but only if the key code is alpha numeric as the virtual
key is equal to the character code for alpha numeric characters. It
works just as well as calling MapVirtualKey before isalnum but saves a
call.
Why are you trying to save a call? Why not call MapVirtualKey in every
case and be done with all the issues. It seems to me your method is a
premature optimization.
Your big test, if(isalnum(nChar) || nChar == 96 /* Num pad 0 */ ||
nChar == 187 || nChar == 188 || nChar == 189 || nChar == 190 || nChar
== 191) is full of magic numbers and probably wastes more CPU cycles
and it is definitely harder to maintain than simply calling
MapVirtualKey unconditionally.
FYI, the zero key is ASCII zero, 0x30. The numeric pad zero key is
VK_NUMPAD0 or 0x60 as you have it in your conditional but it will fail
the isalnum since it's the ` key on the qwerty keyboard.
http://msdn.microsoft.com/en-us/library/dd375731(v=vs.85).aspx
Use MapVirtualKey, then you won't have to worry about what you are
feeding isalnum().
I wrote that code about ten years ago and I can't remember why I wrote
it that way but I'm sure I had a good reason at the time. The only
reason I can see now is to avoid five calls. I was looking at the code
was because one of my users pointed out numeric pad with num lock key
0 didn't work. I still don't know why!

Steve
--
EasyNN-plus. Neural Networks plus. http://www.easynn.com
SwingNN. Forecast with Neural Networks. http://www.swingnn.com
JustNN. Just Neural Networks. http://www.justnn.com
R.Wieser
2013-03-29 11:57:37 UTC
Permalink
Stephen,
I was looking at the code was because one of my users
pointed out numeric pad with num lock key 0 didn't work.
I still don't know why!
Major facepalm.

So much explanation, from me as well as from Geof, and you still have no
idea ? It boggles the mind.

Regards,
Rudy Wieser
Post by Geoff
On Thu, 28 Mar 2013 13:44:26 +0000, Stephen Wolstenholme
Post by Stephen Wolstenholme
I do call it but only if the key code is alpha numeric as the virtual
key is equal to the character code for alpha numeric characters. It
works just as well as calling MapVirtualKey before isalnum but saves a
call.
Why are you trying to save a call? Why not call MapVirtualKey in every
case and be done with all the issues. It seems to me your method is a
premature optimization.
Your big test, if(isalnum(nChar) || nChar == 96 /* Num pad 0 */ ||
nChar == 187 || nChar == 188 || nChar == 189 || nChar == 190 || nChar
== 191) is full of magic numbers and probably wastes more CPU cycles
and it is definitely harder to maintain than simply calling
MapVirtualKey unconditionally.
FYI, the zero key is ASCII zero, 0x30. The numeric pad zero key is
VK_NUMPAD0 or 0x60 as you have it in your conditional but it will fail
the isalnum since it's the ` key on the qwerty keyboard.
http://msdn.microsoft.com/en-us/library/dd375731(v=vs.85).aspx
Use MapVirtualKey, then you won't have to worry about what you are
feeding isalnum().
it that way but I'm sure I had a good reason at the time. The only
reason I can see now is to avoid five calls. I was looking at the code
was because one of my users pointed out numeric pad with num lock key
0 didn't work. I still don't know why!
Steve
--
EasyNN-plus. Neural Networks plus. http://www.easynn.com
SwingNN. Forecast with Neural Networks. http://www.swingnn.com
JustNN. Just Neural Networks. http://www.justnn.com
R.Wieser
2013-03-29 11:53:31 UTC
Permalink
Stephen,
Post by Stephen Wolstenholme
I do call it but only if the key code is alpha numeric as
the virtual key is equal to the character code for alpha
numeric characters.
And now you know that that isn't always true.

Worse, the reason why it *seemed* to be true is that, by pure luck, those
most of those virtual keycodes for the numeric keyboard fell into a range of
lower-case letters in the ASCII table.

So, either use that MapVirtualKey every time to convert the virtual key to
an ASCII symbol before feeding it to the isalnum function, or do not use
that function at all but create a comparision to filter the three ranges of
virtual keycodes (letters, normal digits, numeric keyboard digits) yourself.

I would suggest to listen to Geoff in this respect though: comparing with
"magic numbers" will often bite you in the behind in the long run.

Regards,
Rudy Wieser
Post by Stephen Wolstenholme
Post by R.Wieser
As such I have no idea why you posted
"Virtual key codes need to converted to characters using MapVirtualKey"
without actually doing it.
I do call it but only if the key code is alpha numeric as the virtual
key is equal to the character code for alpha numeric characters. It
works just as well as calling MapVirtualKey before isalnum but saves a
call.
Steve
--
EasyNN-plus. Neural Networks plus. http://www.easynn.com
SwingNN. Forecast with Neural Networks. http://www.swingnn.com
JustNN. Just Neural Networks. http://www.justnn.com
Stephen Wolstenholme
2013-03-29 12:18:46 UTC
Permalink
Post by R.Wieser
I would suggest to listen to Geoff in this respect though: comparing with
"magic numbers" will often bite you in the behind in the long run.
The "magic numbers" are arithmetic functions. I have now changed the
code to call MapVirtualKey first. No doubt I will now find out why I
did it later in the thread!

Steve
--
EasyNN-plus. Neural Networks plus. http://www.easynn.com
SwingNN. Forecast with Neural Networks. http://www.swingnn.com
JustNN. Just Neural Networks. http://www.justnn.com
R.Wieser
2013-03-29 13:52:17 UTC
Permalink
Stephen,
Post by Stephen Wolstenholme
The "magic numbers" are arithmetic functions.
Another misconception I'm afraid. Numbers != arithmetic functions.

The "magic numbers" I referred to where the VK_* values you compare the
results of that KeyDown with. Like VK_NUMPAD0 for the virtual keycode of
the numeric "0"

Regards,
Rudy Wieser
Post by Stephen Wolstenholme
Post by R.Wieser
I would suggest to listen to Geoff in this respect though: comparing with
"magic numbers" will often bite you in the behind in the long run.
The "magic numbers" are arithmetic functions. I have now changed the
code to call MapVirtualKey first. No doubt I will now find out why I
did it later in the thread!
Steve
--
EasyNN-plus. Neural Networks plus. http://www.easynn.com
SwingNN. Forecast with Neural Networks. http://www.swingnn.com
JustNN. Just Neural Networks. http://www.justnn.com
Stephen Wolstenholme
2013-03-29 14:26:38 UTC
Permalink
Post by R.Wieser
Stephen,
Post by Stephen Wolstenholme
The "magic numbers" are arithmetic functions.
Another misconception I'm afraid. Numbers != arithmetic functions.
The "magic numbers" I referred to where the VK_* values you compare the
results of that KeyDown with. Like VK_NUMPAD0 for the virtual keycode of
the numeric "0"
Regards,
Rudy Wieser
I don't remember you referring to "magic numbers". I took the "magic
numbers" referred to by Geoff as the 187, 188, 189, 190, 191 in my
code representing the arithmetic +,-.*/ They are in the code so that
the editor can include simple arithmetic term. For example if a user
wants enter 2.7272727 they could use 30/11

Steve
--
EasyNN-plus. Neural Networks plus. http://www.easynn.com
SwingNN. Forecast with Neural Networks. http://www.swingnn.com
JustNN. Just Neural Networks. http://www.justnn.com
R.Wieser
2013-03-30 03:44:26 UTC
Permalink
Stephen,
Post by Stephen Wolstenholme
I don't remember you referring to "magic numbers".
Correct. I have to confess that I do have a bad habit: I also read other
peoples replies to a thread I'm involved in. Its allways possible they know
something I do not (yet) know. Next to that it helps me not to say exactly
the same as someone else already has.
Post by Stephen Wolstenholme
I took the "magic numbers" referred to by Geoff as
the 187, 188, 189, 190, 191
I'm sorry, but thats not what you said.

But yes, those numbers *are* "magic". *All* of them. Because you have found
them to work and *for that reason only* are using them. Without
understanding. Isn't that the definition of "working by magic" ?

But it gets even worse than that: The numbers you mentioned here are
specified in the Virtual Keycode list as being OEM (original equipment
manufacturers) codes, meaning that every company creating keyboards can
use/assign them as they see fit.

Such numbers which have only a meaning within the context of a specific
manufacturer are often referred to as "magic numbers".
Post by Stephen Wolstenholme
They are in the code so that the editor can include simple
arithmetic term. For example if a user wants enter 2.7272727
they could use 30/11
I understand. But take Geofs advice, first convert and than compare. The
result will be a much more maintainable and stable program.

Even if you would ignore the rather important "working exactly as intended"
/"working without side effects" (I think I already mentioned that, among
others, F1 thru F11 will cause strange effects. By the way: have you tried
that yet ? Why not ? )

You mentioned something in the line of not wanting to waste time on that
conversion ? Do you realize that most of the time the computer is just
*waiting for you* to press a key ? That the extra time needed for
conversion is a negligible fraction of that ?

Regards,
Rudy Wieser
Post by Stephen Wolstenholme
Post by R.Wieser
Stephen,
Post by Stephen Wolstenholme
The "magic numbers" are arithmetic functions.
Another misconception I'm afraid. Numbers != arithmetic functions.
The "magic numbers" I referred to where the VK_* values you compare the
results of that KeyDown with. Like VK_NUMPAD0 for the virtual keycode of
the numeric "0"
Regards,
Rudy Wieser
I don't remember you referring to "magic numbers". I took the "magic
numbers" referred to by Geoff as the 187, 188, 189, 190, 191 in my
code representing the arithmetic +,-.*/ They are in the code so that
the editor can include simple arithmetic term. For example if a user
wants enter 2.7272727 they could use 30/11
Steve
--
EasyNN-plus. Neural Networks plus. http://www.easynn.com
SwingNN. Forecast with Neural Networks. http://www.swingnn.com
JustNN. Just Neural Networks. http://www.justnn.com
Stephen Wolstenholme
2013-03-30 09:54:46 UTC
Permalink
Post by R.Wieser
Stephen,
Post by Stephen Wolstenholme
I don't remember you referring to "magic numbers".
Correct. I have to confess that I do have a bad habit: I also read other
peoples replies to a thread I'm involved in. Its allways possible they know
something I do not (yet) know. Next to that it helps me not to say exactly
the same as someone else already has.
Post by Stephen Wolstenholme
I took the "magic numbers" referred to by Geoff as
the 187, 188, 189, 190, 191
I'm sorry, but thats not what you said.
But yes, those numbers *are* "magic". *All* of them. Because you have found
them to work and *for that reason only* are using them. Without
understanding. Isn't that the definition of "working by magic" ?
But it gets even worse than that: The numbers you mentioned here are
specified in the Virtual Keycode list as being OEM (original equipment
manufacturers) codes, meaning that every company creating keyboards can
use/assign them as they see fit.
Such numbers which have only a meaning within the context of a specific
manufacturer are often referred to as "magic numbers".
Post by Stephen Wolstenholme
They are in the code so that the editor can include simple
arithmetic term. For example if a user wants enter 2.7272727
they could use 30/11
I understand. But take Geofs advice, first convert and than compare. The
result will be a much more maintainable and stable program.
Even if you would ignore the rather important "working exactly as intended"
/"working without side effects" (I think I already mentioned that, among
others, F1 thru F11 will cause strange effects. By the way: have you tried
that yet ? Why not ? )
You mentioned something in the line of not wanting to waste time on that
conversion ? Do you realize that most of the time the computer is just
*waiting for you* to press a key ? That the extra time needed for
conversion is a negligible fraction of that ?
Regards,
Rudy Wieser
The changes suggested by you and Geoff are included in the next
update.

F1 to F10 work as expected. The program does not use F11 in release
mode.

The time wasting I mentioned is related to a calculating thread
priority problem. One of the threads has to wait for all grid array
changes which may be new data being entered. This is also sorted out
in the next update.

Steve
--
EasyNN-plus. Neural Networks plus. http://www.easynn.com
SwingNN. Forecast with Neural Networks. http://www.swingnn.com
JustNN. Just Neural Networks. http://www.justnn.com
R.Wieser
2013-03-30 15:12:31 UTC
Permalink
Stephen.
Post by Stephen Wolstenholme
F1 to F10 work as expected.
Odd, as they should pass the "isalnum" test without a problem (check the
virtual keyodes for those keys, and what they are recognised as when
regarded as ASCII symbols). I guess that maybe the Virtual keymapping later
on filters them out.

I guess *some* things should go your way. :-)

Regards,
Rudy Wieser
Post by Stephen Wolstenholme
Post by R.Wieser
Stephen,
Post by Stephen Wolstenholme
I don't remember you referring to "magic numbers".
Correct. I have to confess that I do have a bad habit: I also read other
peoples replies to a thread I'm involved in. Its allways possible they know
something I do not (yet) know. Next to that it helps me not to say exactly
the same as someone else already has.
Post by Stephen Wolstenholme
I took the "magic numbers" referred to by Geoff as
the 187, 188, 189, 190, 191
I'm sorry, but thats not what you said.
But yes, those numbers *are* "magic". *All* of them. Because you have found
them to work and *for that reason only* are using them. Without
understanding. Isn't that the definition of "working by magic" ?
But it gets even worse than that: The numbers you mentioned here are
specified in the Virtual Keycode list as being OEM (original equipment
manufacturers) codes, meaning that every company creating keyboards can
use/assign them as they see fit.
Such numbers which have only a meaning within the context of a specific
manufacturer are often referred to as "magic numbers".
Post by Stephen Wolstenholme
They are in the code so that the editor can include simple
arithmetic term. For example if a user wants enter 2.7272727
they could use 30/11
I understand. But take Geofs advice, first convert and than compare.
The
Post by Stephen Wolstenholme
Post by R.Wieser
result will be a much more maintainable and stable program.
Even if you would ignore the rather important "working exactly as intended"
/"working without side effects" (I think I already mentioned that, among
others, F1 thru F11 will cause strange effects. By the way: have you tried
that yet ? Why not ? )
You mentioned something in the line of not wanting to waste time on that
conversion ? Do you realize that most of the time the computer is just
*waiting for you* to press a key ? That the extra time needed for
conversion is a negligible fraction of that ?
Regards,
Rudy Wieser
The changes suggested by you and Geoff are included in the next
update.
F1 to F10 work as expected. The program does not use F11 in release
mode.
The time wasting I mentioned is related to a calculating thread
priority problem. One of the threads has to wait for all grid array
changes which may be new data being entered. This is also sorted out
in the next update.
Steve
--
EasyNN-plus. Neural Networks plus. http://www.easynn.com
SwingNN. Forecast with Neural Networks. http://www.swingnn.com
JustNN. Just Neural Networks. http://www.justnn.com
Stephen Wolstenholme
2013-03-30 16:34:10 UTC
Permalink
Post by R.Wieser
Stephen.
Post by Stephen Wolstenholme
F1 to F10 work as expected.
Odd, as they should pass the "isalnum" test without a problem (check the
virtual keyodes for those keys, and what they are recognised as when
regarded as ASCII symbols). I guess that maybe the Virtual keymapping later
on filters them out.
I guess *some* things should go your way. :-)
Regards,
Rudy Wieser
Rudy,

VK_F1 to VK_F10 are accelerator resources as below and are handled
before the call to isalnum

Steve

IDR_MAINFRAME ACCELERATORS
BEGIN
"J", ID_ACTION_JOG, VIRTKEY, CONTROL, NOINVERT
VK_RETURN, ID_ACTION_REFRESH, VIRTKEY, CONTROL, NOINVERT
VK_SPACE, ID_ACTION_START_LEARNING, VIRTKEY, SHIFT, NOINVERT
VK_SPACE, ID_ACTION_STOP, VIRTKEY, CONTROL, NOINVERT
VK_F10, ID_CREDITS, VIRTKEY, CONTROL, ALT,
NOINVERT
"D", ID_DUMP, VIRTKEY, CONTROL, ALT,
NOINVERT
"Z", ID_EDIT_UNDO, VIRTKEY, CONTROL, NOINVERT
"Y", ID_EDIT_REDO, VIRTKEY, CONTROL, NOINVERT
"C", ID_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT
VK_INSERT, ID_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT
VK_DELETE, ID_EDIT_CUT, VIRTKEY, SHIFT, NOINVERT
"X", ID_EDIT_CUT, VIRTKEY, CONTROL, NOINVERT
VK_DELETE, ID_EDIT_DELETE, VIRTKEY, NOINVERT
"F", ID_EDIT_FIND, VIRTKEY, CONTROL, NOINVERT
"A", ID_EDIT_FIND_AGAIN, VIRTKEY, CONTROL, NOINVERT
VK_F3, ID_EDIT_FIND_AGAIN, VIRTKEY, NOINVERT
"G", ID_EDIT_GO_TO, VIRTKEY, CONTROL, NOINVERT
"T", ID_EDIT_GO_TO_AGAIN, VIRTKEY, CONTROL, NOINVERT
VK_F4, ID_EDIT_GO_TO_AGAIN, VIRTKEY, NOINVERT
"U", ID_EDIT_GO_TO_USED, VIRTKEY, CONTROL, NOINVERT
VK_F2, ID_EDIT_GO_TO_USED, VIRTKEY, NOINVERT
"V", ID_EDIT_PASTE, VIRTKEY, CONTROL, NOINVERT
VK_INSERT, ID_EDIT_PASTE, VIRTKEY, SHIFT, NOINVERT
"H", ID_EDIT_REPLACE_VALUES, VIRTKEY, CONTROL, NOINVERT
"N", ID_FILE_NEW, VIRTKEY, CONTROL, NOINVERT
"O", ID_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT
"P", ID_FILE_PRINT, VIRTKEY, CONTROL, NOINVERT
"S", ID_FILE_SAVE, VIRTKEY, CONTROL, NOINVERT
VK_F1, ID_HELP_CHM, VIRTKEY, NOINVERT
VK_F4, ID_MACRO_PLAY, VIRTKEY, CONTROL, NOINVERT
VK_F2, ID_MACRO_RECORD, VIRTKEY, CONTROL, NOINVERT
VK_F3, ID_MACRO_STOP, VIRTKEY, CONTROL, NOINVERT
VK_F6, ID_NEXT_PANE, VIRTKEY, NOINVERT
VK_F6, ID_PREV_PANE, VIRTKEY, SHIFT, NOINVERT
VK_F5, ID_REGISTER, VIRTKEY, CONTROL, NOINVERT
"Q", ID_VOLUME_DECREASE, VIRTKEY, CONTROL, NOINVERT
"W", ID_VOLUME_INCREASE, VIRTKEY, CONTROL, NOINVERT
END
Geoff
2013-03-30 04:00:27 UTC
Permalink
On Fri, 29 Mar 2013 14:26:38 +0000, Stephen Wolstenholme
Post by Stephen Wolstenholme
Post by R.Wieser
Stephen,
Post by Stephen Wolstenholme
The "magic numbers" are arithmetic functions.
Another misconception I'm afraid. Numbers != arithmetic functions.
The "magic numbers" I referred to where the VK_* values you compare the
results of that KeyDown with. Like VK_NUMPAD0 for the virtual keycode of
the numeric "0"
Regards,
Rudy Wieser
I don't remember you referring to "magic numbers". I took the "magic
numbers" referred to by Geoff as the 187, 188, 189, 190, 191 in my
code representing the arithmetic +,-.*/ They are in the code so that
the editor can include simple arithmetic term. For example if a user
wants enter 2.7272727 they could use 30/11
Steve
Yes, those are the magic numbers to which I was referring.

Those are the ASCII values of those characters you are trying to
filter but the virtual key codes for the numeric key pad VK_MULTIPLY
0x6A, VK_ADD 0x6B, VK_SUBTRACT 0x6D, VK_DIVIDE 0x6F are what you
should have been using from the start instead of numeric constants.

The numeric pad keys of those values, 187 to191 are:
VK_OEM_PLUS 0xBB, VK_OEM_COMMA 0xBC, VK_OEM_MINUS 0xBD, VK_OEM_PERIOD
0xBE, VK_OEM_2 0xBF, Used for miscellaneous characters; it can vary by
keyboard. For the US standard keyboard, the '/?' key

Had you been using the VK_* macros instead of magic numbers your code
would be self documenting and you would have been aware of the latent
bug in your program due to the fact you are passing VK codes to
isalnum() and not ASCII characters.

I have no doubt you will uncover some more bugs since nChar is very
problematic in the code you presented. In one case it's being
interpreted as ASCII, in another it's a VK code. I know what it's like
looking at code you wrote years ago. Perhaps with new eyes you can see
a better solution now.

I was going to mention the Win32 API function IsCharAlphaNumeric but I
think it won't work any better than isalum() other than it is aware of
the Windows keyboard locale and not stuck in the C locale like the
runtime. This may or may not matter to you depending on if you have
users in non-English/US locales.
Geoff
2013-03-30 06:05:55 UTC
Permalink
It took some time to fathom what you were trying to do but I think
this will work for you:

if(IsCharAlphaNumeric(MapVirtualKey(nChar, 2)) ||
nChar == VK_ADD ||
nChar == VK_SUBTRACT ||
nChar == VK_MULTIPLY ||
nChar == VK_DIVIDE ||
nChar == VK_DECIMAL)

At this point I don't know if you left VK_COMMA out of this filter
deliberately or by mistake since it was 188 in your code but you
didn't capture multiply in your magic numbers. I can only see that
your function would have failed for numpad keys / * - + . anyway.

I also would advise using CharLower and CharUpper for converting your
strings in place.
Stephen Wolstenholme
2013-03-30 10:02:13 UTC
Permalink
Thanks for the help Geoff. I am including all suggested changes in the
next update. I'm beginning to wonder why only one bug has been found
in the current release. It was beta tested by 200 users! The '0'
problem was the only bug reported.

Steve
--
EasyNN-plus. Neural Networks plus. http://www.easynn.com
SwingNN. Forecast with Neural Networks. http://www.swingnn.com
JustNN. Just Neural Networks. http://www.justnn.com
Geoff
2013-03-31 00:02:48 UTC
Permalink
On Sat, 30 Mar 2013 10:02:13 +0000, Stephen Wolstenholme
Post by Stephen Wolstenholme
Thanks for the help Geoff. I am including all suggested changes in the
next update. I'm beginning to wonder why only one bug has been found
in the current release. It was beta tested by 200 users! The '0'
problem was the only bug reported.
Steve
You're doing pretty good with only 1 bug reported in beta. :)

It sounds like your numpad users are in the minority. I know I never
got into the habit of using it. I only use it occasionally and seldom
for spreadsheets, I don't know why. I'm left handed so that might have
something to do with it.

Advisory: don't use CharLower and CharUpper on your nChar, wrong
variable type and nChar isn't a string and those functions require the
character/string be a valid (zero terminated) C string.
Stephen Wolstenholme
2013-04-01 09:55:01 UTC
Permalink
Post by Geoff
On Sat, 30 Mar 2013 10:02:13 +0000, Stephen Wolstenholme
Post by Stephen Wolstenholme
Thanks for the help Geoff. I am including all suggested changes in the
next update. I'm beginning to wonder why only one bug has been found
in the current release. It was beta tested by 200 users! The '0'
problem was the only bug reported.
Steve
You're doing pretty good with only 1 bug reported in beta. :)
It sounds like your numpad users are in the minority. I know I never
got into the habit of using it. I only use it occasionally and seldom
for spreadsheets, I don't know why. I'm left handed so that might have
something to do with it.
I'm left handed as well and never use the numpad. It seems that most
right handed people don't use it either.
Post by Geoff
Advisory: don't use CharLower and CharUpper on your nChar, wrong
variable type and nChar isn't a string and those functions require the
character/string be a valid (zero terminated) C string.
I don't use either.

Thanks

Steve
--
EasyNN-plus. Neural Networks plus. http://www.easynn.com
SwingNN. Forecast with Neural Networks. http://www.swingnn.com
JustNN. Just Neural Networks. http://www.justnn.com
Geoff
2013-04-01 17:52:01 UTC
Permalink
On Mon, 01 Apr 2013 10:55:01 +0100, Stephen Wolstenholme
Post by Stephen Wolstenholme
I'm left handed as well and never use the numpad. It seems that most
right handed people don't use it either.
I pretty much have my right hand on the mouse unless I am typing, then
both hands are on the qwerty keys, touch typing in the way I learned
back in HS. I am not a great touch typist but I manage.

I have a right handed friend who uses the numpad for all numeric
entries.

I have a left handed friend who uses his mouse left handed and
mirrored.

They both drive me nuts. :)

Geoff
2013-03-30 04:31:21 UTC
Permalink
On Thu, 28 Mar 2013 09:44:26 +0000, Stephen Wolstenholme
Post by Stephen Wolstenholme
if(isalnum(nChar) || nChar == 96 /* Num pad 0 */ || nChar
== 187 || nChar == 188 || nChar == 189 || nChar == 190 || nChar ==
191)
I suppose you could write this as

if(isalnum(MapVirtualKey(nChar, 2)) || nChar == 187 || nChar == 188 ||
nChar == 189 || nChar == 190 || nChar == 191)

without affecting the rest of your function but I still think you can
find a better solution.
Continue reading on narkive:
Loading...