Handling KeyBoard messages/accelerators handling in MFC dialog based applications
-
I saw an article about this on the codeproject by
Nish Nishant
and it seems pretty simple first let me post his code
BOOL CPreTransTestApp::ProcessMessageFilter(int code, LPMSG lpMsg)
{
if(m_haccel)
{
if (::TranslateAccelerator(m_pMainWnd->m_hWnd, m_haccel, lpMsg))
return(TRUE);
}return CWinApp::ProcessMessageFilter(code, lpMsg);
}
Now let me expain my scenrio I am running a client server TCPI /IP program the server is a z/os mainframe and the client is a MFC C\C++ windows based program which displays data from the mainframe I can have up to 4 modeless dialog boxes which display data in a rich edit their pointers live are my derived CWinApp
CDBGRApp
I did all the front end work created the accelarator in my resource file had it as selection in my menu "MENUITEM" and put the appropriate message map and message handler in derived CDialog CProgDebug I then inserted the following code into my derived CWinAppp CDBGRApp
OOL CDBGRApp::ProcessMessageFilter(int code, LPMSG lpMsg)
{if (m\_haccel) { if (debugger\[0\] == NULL); else { if (debugger\[0\]->m\_hWnd == NULL); else { ::TranslateAccelerator(debugger\[0\]->m\_hWnd, m\_haccel, lpMsg); return(TRUE); } } } return CWinApp::ProcessMessageFilter(code, lpMsg); }
debugger[0] is the first of an array defined as
CProgDebug \*debugger\[4\];
After I created the CProgDebug with it rich edit the window didnt seem to take any input mouse or keyboard Nish in his code didnt specify that after doing TranslateAccelrator and would have to do TranslateMessage and DispatchMessage from the msg structure as I assume that is being taken care of somewhere down the line by the frameWork
You missed out a test - you should only return TRUE if
TranslateAccelerator()
succeeds. By the way, yourif(something); else
is quite confusing. -
I saw an article about this on the codeproject by
Nish Nishant
and it seems pretty simple first let me post his code
BOOL CPreTransTestApp::ProcessMessageFilter(int code, LPMSG lpMsg)
{
if(m_haccel)
{
if (::TranslateAccelerator(m_pMainWnd->m_hWnd, m_haccel, lpMsg))
return(TRUE);
}return CWinApp::ProcessMessageFilter(code, lpMsg);
}
Now let me expain my scenrio I am running a client server TCPI /IP program the server is a z/os mainframe and the client is a MFC C\C++ windows based program which displays data from the mainframe I can have up to 4 modeless dialog boxes which display data in a rich edit their pointers live are my derived CWinApp
CDBGRApp
I did all the front end work created the accelarator in my resource file had it as selection in my menu "MENUITEM" and put the appropriate message map and message handler in derived CDialog CProgDebug I then inserted the following code into my derived CWinAppp CDBGRApp
OOL CDBGRApp::ProcessMessageFilter(int code, LPMSG lpMsg)
{if (m\_haccel) { if (debugger\[0\] == NULL); else { if (debugger\[0\]->m\_hWnd == NULL); else { ::TranslateAccelerator(debugger\[0\]->m\_hWnd, m\_haccel, lpMsg); return(TRUE); } } } return CWinApp::ProcessMessageFilter(code, lpMsg); }
debugger[0] is the first of an array defined as
CProgDebug \*debugger\[4\];
After I created the CProgDebug with it rich edit the window didnt seem to take any input mouse or keyboard Nish in his code didnt specify that after doing TranslateAccelrator and would have to do TranslateMessage and DispatchMessage from the msg structure as I assume that is being taken care of somewhere down the line by the frameWork
-
got a compile error when it I did that but I had semi colon after the open paren so the logic should work regardless I'll work to change it thanks
-
You missed out a test - you should only return TRUE if
TranslateAccelerator()
succeeds. By the way, yourif(something); else
is quite confusing.I am changing that so if I get a zero from from
TranslateAccelerator(
that means (and can you confirm this) it wasnt one the key strokes I defined right not necessarly an error I would get a zero from TranslateAccelerator maybe thats the problem in my logic
-
Not to mention the semi-colons on the end of the if line, essentially making it entirely useless.
Asking questions is a skill CodeProject Forum Guidelines Google: C# How to debug code Seriously, go read these articles.
Dave Kreskowiak -
Not to mention the semi-colons on the end of the if line, essentially making it entirely useless.
Asking questions is a skill CodeProject Forum Guidelines Google: C# How to debug code Seriously, go read these articles.
Dave Kreskowiak -
I am changing that so if I get a zero from from
TranslateAccelerator(
that means (and can you confirm this) it wasnt one the key strokes I defined right not necessarly an error I would get a zero from TranslateAccelerator maybe thats the problem in my logic
Here's the Windows docs page: TranslateAcceleratorA function (winuser.h) - Win32 apps | Microsoft Docs[^] The function returns nonzero when it successfully translates the accelerator, which is when you should not pass the message through to the default handler. Your code is bypassing the default handler entirely when your
h_accel
and debug variables are set (without checking if the message was a translated keycode). -
Here's the Windows docs page: TranslateAcceleratorA function (winuser.h) - Win32 apps | Microsoft Docs[^] The function returns nonzero when it successfully translates the accelerator, which is when you should not pass the message through to the default handler. Your code is bypassing the default handler entirely when your
h_accel
and debug variables are set (without checking if the message was a translated keycode).thanks if so this code by Nish
BOOL CPreTransTestApp::ProcessMessageFilter(int code, LPMSG lpMsg)
{
if(m_haccel)
{
if (::TranslateAccelerator(m_pMainWnd->m_hWnd, m_haccel, lpMsg))
return(TRUE);
}return CWinApp::ProcessMessageFilter(code, lpMsg);
}
is incorrect this code from Microsoft docs is correct
MSG msg;
BOOL bRet;while ( (bRet = GetMessage(&msg, (HWND) NULL, 0, 0)) != 0)
{
if (bRet == -1)
{
// handle the error and possibly exit
}
else
{
// Check for accelerator keystrokes.if **(!**TranslateAccelerator( hwndMain, // handle to receiving window haccel, // handle to active accelerator table &msg)) // message data { TranslateMessage(&msg); DispatchMessage(&msg); } }
}
as it has not TranlateAccelterator wouldnt you agree
-
thanks if so this code by Nish
BOOL CPreTransTestApp::ProcessMessageFilter(int code, LPMSG lpMsg)
{
if(m_haccel)
{
if (::TranslateAccelerator(m_pMainWnd->m_hWnd, m_haccel, lpMsg))
return(TRUE);
}return CWinApp::ProcessMessageFilter(code, lpMsg);
}
is incorrect this code from Microsoft docs is correct
MSG msg;
BOOL bRet;while ( (bRet = GetMessage(&msg, (HWND) NULL, 0, 0)) != 0)
{
if (bRet == -1)
{
// handle the error and possibly exit
}
else
{
// Check for accelerator keystrokes.if **(!**TranslateAccelerator( hwndMain, // handle to receiving window haccel, // handle to active accelerator table &msg)) // message data { TranslateMessage(&msg); DispatchMessage(&msg); } }
}
as it has not TranlateAccelterator wouldnt you agree
They are both correct. The first one skips the default handler if the accelerator has been translated. The second one calls the default handler if the accelerator has not been translated.
-
They are both correct. The first one skips the default handler if the accelerator has been translated. The second one calls the default handler if the accelerator has not been translated.
-
thank you so much for your patience me However the way mine is set is INCORRECT as I dont have an IF testing for the validity of the TranlateAccelarator and that is why my keyboard gets locked becasue I havr return TRUE for all
Yes, that's right.