|
|
Comments and Discussions
|
|
 |

|
Thanks a lot for the information..
|
|
|
|

|
Exactly what I was looking for! With little MFC knowledge I could finally add keystrokes to a legacy MFC application, thank you!
|
|
|
|

|
Finally found what I was looking for, after 3 days of search. Superb site. Best forum for developers!
THANKS NISHANT!!!
THANKS CODEPROJECT!!!!
CHEERS!!!
Raj
|
|
|
|
|

|
Pretty good article. It works well with accelerators. Earlier I was trying to handle CTRL+ clicks in PreTranslateMessage, the main issue I faced was that if the control is with edit box or some other control, CTRL+ click would not work. For it to start working again, I had to click on the main window(to set focus). But with accelerator, it works really well. No issues faced.
One small problem I faced in the beginning was with m_pMainWnd->m_hWnd, which was not defined in the article, but it is actually pointer to CDialog class whose instance is called in InitInstance. One might come across few more problems related to declaring pointer to Cdialog class. One can declare the pointer globally and then assign &dlg to it.(CDialogMain dlg, in my case). All of this will be done in class derived from CWinApp.
Cheers,
|
|
|
|
|

|
I have implemented the given code. It is working fine for main dialog. But for child dialog accelerator keys are not working.
|
|
|
|

|
Its been forever since you posted this. Did you ever find a solution for this?
|
|
|
|

|
I have a dialog that needs to capture the Enter key mulitple times. I have impmlemented the PreTranslateMessage as such:
if( pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN )
{
SetSomeFlag();
return TRUE;
}
However, the message does not get handled correctly after the first one(by calling SetSomeFlag()) unless I have a break point set there.
|
|
|
|

|
I have defined this in my dialog class also declared a ON_WM_KEYDOWN()message map, any ideas?
|
|
|
|

|
hi all
i want to call click event of button with "Ctrl + Up" keyboard shortcut.
i have used ::PreTranslateMessage(MSG *pMsg) but tell me what could be
value of pMsg->message and pMsg->wParam to handle the same.
thanx
maulesh
|
|
|
|

|
how can i use my accelator in my dll?
Can you please the code for doing this?
and if i use shortcut keys it will work in the main application (My dll functionality as short cut keys)?
please give some code snippet, which is useful for my question.....
Rammy
|
|
|
|
|

|
Hello Nish I want to simulate the mouse behavior holding down a button with a key in a diglog application, and I tried it with your method. But it doesn't work. When i push down the key,the buton was down then up immeidately even if i am still holding down the key ,the button is just like being clicked not holded down as the mouse can do. I want some tips. regards BOOL CMyDlg::PreTranslateMessage(MSG* pMsg) { // TODO: Add your specialized code here and/or call the base class if(pMsg->wParam==VK_RIGHT){ if(pMsg->message==WM_KEYDOWN && ((pMsg->lParam>>30 & 1)==0)) m_myButton.SendMessage(WM_LBUTTONDOWN); if(pMsg->message==WM_KEYUP) m_myButton.SendMessage(WM_LBUTTONUP); } return CDialog::PreTranslateMessage(pMsg); } chenzd
|
|
|
|

|
I've run into a bit of a problem with this. I've implemented this solution and it works fine except that the accelerators are active not only for the dialog, but for all child dialogs as well.
For example, I set Insert, Delete, and Ctrl+A as accelerators to insert an item, delete an item, and select all items in a list control. This is fine, but when the Insert Item or Delete Prompt dialogs come up, those keys are still active and when pressed, perform their action.
It should not call TranslateAccelerator if a child dialog has the focus. I am working around this by having my main dialog have a member boolean which I set to false before running any child dialogs and back to true afterwards. I then change the ProcessMessageFilter function like so:
if (m_hAccel) {
to
if (m_hAccel&&((CFooBar*)m_pMainWnd)->m_Focus) {
I don't like this because it requires casting to the dialog type and accessing a variable (using an accessor function is even worse), and more importantly, it requires setting/clearing the flag before and after each child dialog.
Does anyone have a better solution?
Thanks.
--
Synetech
|
|
|
|

|
Hi,
I discussed this with Joe Newcomer who has this in one of his articles and we solved it. Just change this line in ProcessMessageFilter:
if(m_haccel)
to this:
if (m_hAccel && m_pMainWnd->IsWindowEnabled())
Works like a charm.
--
Synetech
|
|
|
|

|
Hi,
This works very well. I've been wondering why accelerators don't seem to work in my apps and now I know why (although I'm pretty sure I've read the reason before.) I've added those three tiny pieces of code and now my apps are alive with productivity.
Thanks a lot.
--
Synetech
|
|
|
|

|
In case,while I'm running another program(minimize the program that support Hots key)It will can't use hots key of the program that I minimize it.
If I want to make it always support although I use another program.
How I do for this case?
|
|
|
|
|

|
Why error???
I used POCKET PC 2003 // Win32(WCE emulator) Debug // POCKET PC 2003 emulator
Please, help me !!! thanks
BOOL CEX1App::ProcessMessageFilter(int code, LPMSG lpMsg)
{
// TODO: Add your specialized code here and/or call the base class
if(m_haccel)
{
if (::TranslateAccelerator(m_pMainWnd->m_hWnd, m_haccel, lpMsg))
return(TRUE);
}
return CWinApp::ProcessMessageFilter(code, lpMsg); // =>error C2039: 'ProcessMessageFilter' : is not a member of 'CWinApp'}
Thanks
|
|
|
|
|

|
Hi:
First thanks to the brief short article that gives a clear explaination.
I have an application that has main window and child windows. A dialog box under one child window needs to have accelerators.
How can I utilise the method suggested in this article?
Thank you for any suggestion/advice.
kezhu
|
|
|
|

|
Hello,
this is great, but how to call any function after press, for example, ctrl + D????
// in my Application Class:
BOOL CDialogApp::ProcessMessageFilter(int code, LPMSG lpMsg)
{
if(m_haccel)
{
if (::TranslateAccelerator(m_pMainWnd->m_hWnd, m_haccel, lpMsg))
{
OnClear(); // this funktion should be called after the user have press ctrl + D, this is a Dialogclass member!
return(TRUE); // the program run to here, but they dont call the OnClear(); Funktion???!! Why???
}
}
return CWinApp::ProcessMessageFilter(code, lpMsg);
}
regards
break;
-- modified at 8:01 Wednesday 11th January, 2006
|
|
|
|

|
Hi,
i make them like this, but im not sure that is the best solution!!!
BOOL CDialogApp::ProcessMessageFilter(int code, LPMSG lpMsg)
{
if(m_haccel) // m_haccel hat den "Alt + D" Code!
{
if (::TranslateAccelerator(m_pMainWnd->m_hWnd, m_haccel, lpMsg))
{
CDialogDlg *cDialog = (CDialogDlg*)AfxGetApp()->GetMainWnd(); // Referenz to the Dialogclass who have this OnClear() Funktion
cDialog->OnClear();
return(TRUE);
}
}
return CWinApp::ProcessMessageFilter(code, lpMsg);
}
Now when the user press "Alt + D" run this OnClear() Funktion and clear all items(controls) on my dialog, or any other Funktion!
break;
|
|
|
|
|

|
Thank you very much. Your article helped me to safe a lot time and money
|
|
|
|

|
Awesome job. The ProcessMessageFilter override works beautifully to handle Accelerator keys in a dialog based application.
There is one correction to the article which needs to be made however. Your sample code for the PreTranslateMessage override is incorrect. It must be overridden in the App class, not the Dlg class.
BOOL CPreTransTestDlg::PreTranslateMessage(MSG* pMsg)
{
if(pMsg->message==WM_KEYDOWN)
{
if(pMsg->wParam==VK_RETURN)
pMsg->wParam=VK_TAB;
}
return CDialog::PreTranslateMessage(pMsg);
}
If the dialog class received the KEYDOWN message we wouldn't need to mess with this in the first place, we could just implement a message handler. But since the dialog doesn't receive the WM_KEYDOWN message from the App, the PreTranslateMessage override will have no effect here.
However, if you override it in the App class and copy your existing code into that function, the workaround will work like a charm.
Again... Beautiful job. Thanks for sharing.
In business, if two people always agree, one of them is unnecessary.
|
|
|
|

|
I use this in my dialog class and capture KEYDOWN messages without any problems.
The dialog class does recieve KEYDOWN messages. However, if you have even one button or control
on your dialog the keypress messages will automatically get sent to the default control on the dialog. This is exactly why I started capturing the KEYPRESSES from PreTranslateMessage(..) to begin with.
Hope that makes sense.
PS: This info is based on my experience and my opinions.
|
|
|
|

|
hi anu did you get any solution for the problem?
|
|
|
|

|
sorry keesler i replied to wrong location ,this is for anu who is below your message
|
|
|
|

|
I have a sdi (single document) with a CSizingControlBarG(see http://www.datamekanix.com[^]) with a property sheet in it.
Obviously the property sheet thinks it is a modal dialog and does not route the
messages for accelerators.
I have solved the problem by calling in the propertysheet's PreTranslateMessage
BOOL CSomethingSheet::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_KEYDOWN && m_pMainFrame!=NULL)
{
int nVirtKey = (int) pMsg->wParam;
if (::TranslateAccelerator( m_pMainFrame->m_hWnd,m_pMainFrame->m_hAccelTable,pMsg))
return TRUE;
}
return CPropertySheet::PreTranslateMessage(pMsg);
}
where m_pMainframe is a pointer to the CMainFrame object of the application
If anyone has done this before and knows some problems that can show up or knows a better way to solve this, please let me know.
|
|
|
|

|
i have voted 5 for thiz.....
regardz...
ratz
"faith, hope, love remain, these three.....; but the greatest of these is love" -1 Corinthians 13:13
|
|
|
|

|
You saved me a couple of days of diggin' around MSDN & C. !
SoftechSoftware
Davide Calabro'
davide_calabro@yahoo.com
http://www.softechsoftware.it
|
|
|
|

|
Hi!
Your technique is quite ok. But i've tried my idea of using only PreTranslateMessage. It's a dialog based app and i created an accelerator table, IDR_KISAYOL, by resource editor. In my dialog's class, i added:
class CDiaGiris : public CDialog
{
// ...
HACCEL hKisaYol;
// ...
}
BOOL CDiaGiris::OnInitDialog()
{
// ...
hKisaYol=LoadAccelerators(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_KISAYOL));
// ...
}
And i overrided dear PreTranslateMessage as follows:
BOOL CDiaGiris::PreTranslateMessage(MSG* pMsg)
{
if(pMsg->message==WM_KEYDOWN || pMsg->message==WM_SYSKEYDOWN){
if(TranslateAccelerator(AfxGetMainWnd()->m_hWnd,hKisaYol,pMsg))return TRUE;
}
return CDialog::PreTranslateMessage(pMsg);
}
I had to handle not only WM_KEYDOWN but also WM_SYSKEYDOWN message too, because some keys like F10 come that way. And i know that some keys like VK_DELETE are suspicious to use as an accel key. By the way, when i use TranslateAccelerator without checking the value pMsg->message, my app crashes when it loses focus. Yes, strange.
Anyway, that's all i did. And my accelerator table working ok in my dialog based app now. I don't exactly know if there are some drawbacks but my app seems happy. If someone knows or finds a drawback or something, please let me know.
|
|
|
|

|
Just a note to say that this is the preferred solution for WinCE simply because CWinApp::ProcessMessageFilter is not available under WinCE!
|
|
|
|

|
I prefer to use m_hWnd instead of AfxGetMainWnd()->m_hWnd inorder not to limit this functionality to the application main window only
|
|
|
|

|
Hi;
How can I possibly limit the capturing of enter key in a particular control only? Like perhaps I want it to response only when I pressed entry key while I'm in combobox control. Because I believe that with the routine that you gave works in all controls.
Thanks in advance.
|
|
|
|

|
hi
i am doing a multidialog application, and i have to add accelerators to a menu in a child dialog(since the dialog has no app class i cant find the 'ProcessMessageFilter'.
Can anything be done about it.
anu
|
|
|
|

|
hi anu did you get solution for the problem you had?
|
|
|
|

|
Hi,
and how to access the keys "Alt + D" to call some Functions???
This ist what i want to do with the Accelerators!
regards
break;
|
|
|
|

|
Hi,
i make them like this, but im not sure that is the best solution!!!
BOOL CDialogApp::ProcessMessageFilter(int code, LPMSG lpMsg)
{
if(m_haccel) // m_haccel hat den "Alt + D" Code!
{
if (::TranslateAccelerator(m_pMainWnd->m_hWnd, m_haccel, lpMsg))
{
CDialogDlg *cDialog = (CDialogDlg*)AfxGetApp()->GetMainWnd(); // Referenz to the Dialogclass who have this OnClear() Funktion
cDialog->OnClear();
return(TRUE);
}
}
return CWinApp::ProcessMessageFilter(code, lpMsg);
}
Now when the user press "Alt + D" run this OnClear() Funktion and clear all items(controls) on my dialog, or any other Funktion!
break;
|
|
|
|

|
hi anu I got the solution for the problem and my applivation is now working fine if you want got the following link
http://www.codeguru.com/Cpp/W-D/dislog/tutorials/article.php/c4965"
and i think you had already done with that.
|
|
|
|

|
hi anu I got the solution for the problem and my application is now working fine if you want got the following link
http://www.codeguru.com/Cpp/W-D/dislog/tutorials/article.php/c4965"
and i think you had already done with that.
|
|
|
|

|
hi nishant
It helped me a lot.I used it for my dialog based application .And urs work fine for that.Thank u so much..............
divya
|
|
|
|

|
Hello,
I have been trying to make the keyboard accelerators (underlines below the function characters) always visible but I was not successful. When the app comes up, the ALT is toggles those accelerators to be visible or not, but never come up "already visible"...
First, I tried to use SendMessage to Query (0x129) and then Change (0x127) the UI State but the query always returned zero indicating that the keyboard & focus accelerator are On (not true).
Second, I tried to use SendMessage with Update command (0x128) to force the set visibility command to the keyboard accelerators (0x2 in high-order word, 0x1 in low-order word of wParam)
Finally, I tried to use CWnd::OnUpdateUIState function as stated in MSDN but then the function does not exist in Visual C++ 6.0
Did I do something wrong or miss something ?
|
|
|
|

|
It's a Windows "feature".Lies deeply burried in the display properties/appearance tab/effects (for XP)...
|
|
|
|

|
I have a app which uses dll.
how can i to control the message?
if i want to press key 'a' to call the function in first dll, and 'b' to call the function in second dll.
what should i do?
i try many times .it failed.
please help me. thanks.
|
|
|
|

|
I am using an instance of a view derived from CCtrlView. Inside this view i add 3 pages to a propertysheet. These 3 pages are created from a dialog resource using
CChildDialog* pDialog = new CChildDialog;
and add controls to it as
treeControl->SubclassDlgItem (IDC_TREE1, GetPage (nIndex));
Now as you said I have to add
m_haccel = LoadAccelerators(AfxGetInstanceHandle(),
MAKEINTRESOURCE(ID_HOT_KEY));
before the declaration of CDialog dlg;
I tried at diff places, e.g. just after the
if (!ProcessShellCommand(cmdInfo))
return FALSE;
just before the call
CChildDialog* pDialog = new CChildDialog;
But none of these worked. These dialogs are modeless.
Can you provide a solution for this?
Thanks,
|
|
|
|
|

|
Here is the problem. I have a "Dialog Based Application".I made two "Check Boxes" in a Dialog. So I want , whenever i press "UP Arrow Key" , a check box is "checked". And when i release "Up Arrow" a check box is "un- checked".
If anyone know this, then plz help me as soon as possible . I shall be thankful to you. EsHbAn BaHaDuR
|
|
|
|
 |
|
|
General News Suggestion Question Bug Answer Joke Rant Admin
|
This article explains how you can override PreTranslateMessage and ProcessMessageFilter in dialog based apps
| Type | Article |
| Licence | CPOL |
| First Posted | 1 Dec 2001 |
| Views | 309,303 |
| Bookmarked | 97 times |
|
|