Reputation: 81
In a certain dialog I would like when the user presses the enter key for it to act as an "apply" button. So far I have at least been able to make the dialog not close upon pressing enter by overriding CWnd::PreTranslateMessage, so currently it just does nothing and I'm not sure how to send apply command from there.
Upvotes: 3
Views: 4639
Reputation: 51511
As Mark pointed out above the dialog manager already has all the logic built in to handle the Enter key by invoking the command associated with the default button. You can statically assign the BS_DEFPUSHBUTTON
style or handle the DM_GETDEFID
message.
The former is trivially easy and the latter is fairly simple to implement. Make sure you set the Default Button property to False for all buttons on your dialog. Now add a message handler for the DM_GETDEFID
message. There is no dedicated macro for this message so you have to use the generic handler:
BEGIN_MESSAGE_MAP(CMyDialog, CDialogEx)
...
ON_MESSAGE(DM_GETDEFID, OnGetDefId)
END_MESSAGE_MAP()
The message handler is equally simple and uses the default message handler signature:
LRESULT CMyDialog::OnGetDefId(WPARAM wParam, LPARAM lParam)
{
return MAKELRESULT(ID_APPLY, DC_HASDEFID);
}
The message handler must return a value whose high-order word contains DC_HASDEFID
and the low-order word contains the control ID.
If you navigate over the controls of the dialog you will see that the Apply button has the typical default button visual cue while focus is not on another command button. Pressing Enter while a non-button control has the input focus invokes the default button's command handler. No additional code required.
Upvotes: 2
Reputation: 308520
Every dialog should have one and only one button with the BS_DEFPUSHBUTTON
style, which indicates to the dialog that this is the button to activate with the Enter key. Usually this is the OK button, but you can make it the Apply button if you want to.
Upvotes: 4
Reputation: 4590
If your intent is to handle the Enter key without dismissing the dialog, you may be going about it incorrectly. Please take a look at this MSDN article. While using PreTranslateMessage should work, it is not the best way to handle these types of events.
Upvotes: 1
Reputation: 140
Another way to overwrite the message.
BOOL CMyDialog::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_KEYDOWN)
{
switch (pMsg->wParam)
{
case VK_RETURN:
{
UINT nID = ::GetDlgCtrlID(pMsg->hwnd);
if (nID == ID_APPLY)
{
//DO YOUR STUFF HERE
}
}
break;
default:
break;
}
}
return CDialog::PreTranslateMessage(pMsg);
}
Also, you don't need to use PreTranslateMessage if you are using ::OnKeyDown
Upvotes: 0
Reputation: 1866
You'll need to handle the OnKeyDown message, and handle the VK_RETURN character inside that function.
void MyCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if(nChar == VK_RETURN)
{
// Do Stuff
return;
}
CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
}
Upvotes: 0