CBitmapButton and ENTER
Annabel -- Annabel.Worthington@FMR.Com
Tuesday, January 09, 1996
Is there a trick to making it so that when a CBitmapButton is in focus and
the user presses the Enter key, the message map function for that button
gets called?
I would think that mapping the resource ID of the button to a function with
either ON_COMMAND or ON_BN_CLICKED (I've tried both) would work just like it
does in regular CButtons, that is you can either click on the button or
press Enter, and the mapped function will get called. The CBitmapButton
only seems to respond correctly to the mouse click. Pressing Enter on the
CBitmapButton causes the dialog to exit directly with IDOK, without hitting
any of my mapped functions along the way. When I change the button back to
being a regular CButton, the Enter key causes my mapped function to be
called, as it should.
I'm using MSVC++ 2.2, and setting up the CBitmapButton exactly the way the
online help describes. It displays fine, and the right bitmaps appear when
it is up or down or in focus (I never disable it). The only problem is it
doesn't respond correctly to the Enter key.
I haven't been able to find anything in the online help, the FAQ, MSDN, or
the Web that describes a problem like this; perhaps there is somewhere I
haven't looked yet that I don't know about? I also tried the CTRLTEST
sample application provided with MSVC++ 2.2, and ran into the same problem.
Any clues will be greatly appreciated.
Thanks,
Annabel
bop@gandalf.se
Thursday, January 11, 1996
[Mini-digest: 2 responses]
> From "Worthington, Annabel"
> Is there a trick to making it so that when a CBitmapButton is in focus and
> the user presses the Enter key, the message map function for that button
> gets called?
>
> I would think that mapping the resource ID of the button to a function with
> either ON_COMMAND or ON_BN_CLICKED (I've tried both) would work just like it
> does in regular CButtons, that is you can either click on the button or
> press Enter, and the mapped function will get called. The CBitmapButton
> only seems to respond correctly to the mouse click. Pressing Enter on the
> CBitmapButton causes the dialog to exit directly with IDOK, without hitting
> any of my mapped functions along the way. When I change the button back to
> being a regular CButton, the Enter key causes my mapped function to be
> called, as it should.
> [..]
> Any clues will be greatly appreciated.
Not _exactly_ a solution to your problem, but here's what I did:
In the dialog class, override the OnOK function and check which
button has the focus when Enter is pressed. (My code is from a
chess program where you have to select a new piece when a
pawn is promoted.)
void CLitePromotionDlg::OnOK()
{
const UINT HasFocus = 0x0008;
if (QueenButton.GetState() & HasFocus)
EndDialog(LiteQueen);
else if (RookButton.GetState() & HasFocus)
EndDialog(LiteRook);
else if (BishopButton.GetState() & HasFocus)
EndDialog(LiteBishop);
else if (KnightButton.GetState() & HasFocus)
EndDialog(LiteKnight);
else
ASSERT(FALSE);
}
A related(?) tip:
How to stop the Esc key from closing the dialog.
// Cannot cancel, MUST select!
void CLitePromotionDlg::OnCancel()
{ };
Bo Persson
bop@gandalf.se
-----From: "Paul D. Bartholomew"
>>Is there a trick to making it so that when a CBitmapButton is in focus and
the user presses the Enter key, the message map function for that button
gets called?<<
Yes. When you press in a dialog, you are actually telling the
dialog to press the "default" button, which is usually the OK button. When
you tab to, say, the Cancel button, this becomes the default button, and
pressing activates it. The trouble is that a CBitmapButton can get
the focus of the dialog and still not be the default button. Therefore,
when you press , it doesn't press your CBitmapButton.
There are several ways to handle this, including trapping the various other
button functions (e.g., OnOK, OnCancel) and checking to see which button
actually has the focus. If it's your CBitmapButton, then you should call
its function and exit e.g., the OnOK function without calling the equivalent
CDialog::OnOK function.
The way I'm currently handling it is to override the CDialog::OnDrawItem
function as follows:
void CMyDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
if ( nIDCtl == MY_BUTTON && lpDrawItemStruct->itemAction & ODA_FOCUS )
{
if (lpDrawItemStruct->itemState & ODS_FOCUS)
SetDefID(nIDCtl);
else
SetDefID(IDOK);
}
CDialog::OnDrawItem(nIDCtl, lpDrawItemStruct);
}
Now that I think about it, I wonder if I can't handle it in a focus changed
message.....
Paul Bartholomew
pauldb@datastorm.com
| Вернуться в корень Архива
|