Using TranslateAccelerator in a CWnd
Jonas Yngvesson -- jonas-y@sectra.se
Friday, October 18, 1996
Environment: Window NT 3.51, VC++ 4.2
Hi,
I have an application which uses a small part of the MFC framework,
there is a CWinApp derived app. object which may have one or more
CWnd derived main windows. No Doc-View stuff, not even CFrameWnd's.
The CWnd's have menus and I now want to use accelerators for some of the
menu entries. I have created an accelerator table (one for each main
window) where I used the same command id as for the menu entries.
In the CWnd I now catch WM_KEYDOWN, do a GetCurrentMessage() and calls
TanslateAccelerator(), but nothing happens. My command handler is not
called.
I made an attempt to use PreTranslateMessage() in the CWnd but that
never got called at all.
Any clues?
--Jonas
Tony Headford -- tony@ktgroup.co.uk
Monday, October 21, 1996
[Mini-digest: 2 responses]
Have you loaded your accelerator table ?
If not check out the source/help for CFrameWnd::LoadAccelTable and
::LoadAccelerators
======================
Tony Headford
Software Developer
tony@rms.co.uk
======================
----------
> From: Jonas Yngvesson
> To: mfc-l@netcom.com
> Subject: Using TranslateAccelerator in a CWnd
> Date: 18 October 1996 16:26
>
> Environment: Window NT 3.51, VC++ 4.2
>
> Hi,
>
> I have an application which uses a small part of the MFC framework,
> there is a CWinApp derived app. object which may have one or more
> CWnd derived main windows. No Doc-View stuff, not even CFrameWnd's.
>
> The CWnd's have menus and I now want to use accelerators for some of the
> menu entries. I have created an accelerator table (one for each main
> window) where I used the same command id as for the menu entries.
>
> In the CWnd I now catch WM_KEYDOWN, do a GetCurrentMessage() and calls
> TanslateAccelerator(), but nothing happens. My command handler is not
> called.
>
> I made an attempt to use PreTranslateMessage() in the CWnd but that
> never got called at all.
>
> Any clues?
>
>
> --Jonas
-----From: Alex Sevugan
Hi,
You can try using the TranslateAccelerator in PreTranslateMessage virtual
function because Frame window handles it automatically for you and for
CWnd derived classes you are responsible for translating the Accelerators.
-alaks
Luiz Carlos C. Marques -- lmarques@cpqd.br
Tuesday, October 22, 1996
Jonas Yngvesson wrote:
>
> Environment: Window NT 3.51, VC++ 4.2
>
> Hi,
>
> I have an application which uses a small part of the MFC framework,
> there is a CWinApp derived app. object which may have one or more
> CWnd derived main windows. No Doc-View stuff, not even CFrameWnd's.
>
> The CWnd's have menus and I now want to use accelerators for some of the
> menu entries. I have created an accelerator table (one for each main
> window) where I used the same command id as for the menu entries.
>
> In the CWnd I now catch WM_KEYDOWN, do a GetCurrentMessage() and calls
> TanslateAccelerator(), but nothing happens. My command handler is not
> called.
>
> I made an attempt to use PreTranslateMessage() in the CWnd but that
> never got called at all.
>
> Any clues?
>
> --Jonas
Hello, Jonas.
I'm not sure my tip will solve your problem, but it may be a beginning.
Include a member
HACCEL m_hAccel;
in your CWnd derived class. Then, on the constructor your class, include
m_hAccel = ::LoadAccelerators(
AfxGetInstanceHandle(),
MAKEINTRESOURCE(IDR_TAB_ACCEL));
where IDR_TAB_ACCEL is your accelerator table resource.
This should ensure that you receive accelerators as messages to be
"PreTranslated". To let your accelerators be translated, include the
following code at the end of your PreTranslateMessage override:
if ( (m_hAccel != NULL) &&
::TranslateAccelerator(m_pCentral->m_hWnd, m_hAccel, pMsg))
return ( TRUE );
else
return CWnd::PreTranslateMessage(pMsg);
Hope it works.
See you around.
Luiz Marques - lmarques@cpqd.br
David Little -- dlittle@equinoxcorp.com
Tuesday, October 22, 1996
[Mini-digest: 2 responses]
Here is how to use Accelerators in CWnd:
BOOL CAuxInput::OnInitDialog()
{
...
...
...
hAccel = LoadAccel(IDR_SOMENUMBER);
...
...
}
BOOL CAuxInput::PreTranslateMessage (MSG * pMsg)
{
if (!(hAccel&& ::TranslateAccelerator (m_hWnd, hAccel, pMsg))) return
CDialog::PreTranslateMessage (pMsg);
else return TRUE;
}
-----From: Jonas Yngvesson
Environment: Window NT 3.51, VC++ 4.2
This is a followup to my own message where I tried to use accelerators
in a CWnd-derived window. It turned out PreTranslateMessage() was the way
to go after all (thanks for the answers).
However, things are still not quite A-OK. I build my accelerator tables
"by hand", ie I do not load them from resources, but it seems to be
impossible to use any other modifier than "Alt". If I specify control or
shift they are ignored and the unmodified key itself becomes the
accelerator.
Any suggestions?
Ob. code snippet (very straightforward...):
...
// accelerators_m is array of ACCELs
// n_accelerators_m is current number of ACCELs in accelerators_m
// acc_mod holds string with modifiers to use
if (acc_key) { // ASCII accelerator key
accelerators_m[n_accelerators_m].key = (WORD)(acc_key);
accelerators_m[n_accelerators_m].cmd = id_m; // Command id
accelerators_m[n_accelerators_m].fVirt = (BYTE)0;
if (strstr(acc_mod, "Ctrl")) {
accelerators_m[n_accelerators_m].fVirt |= FCONTROL;
}
if (strstr(acc_mod, "Alt")) {
accelerators_m[n_accelerators_m].fVirt |= FALT;
}
if (strstr(acc_mod, "Shift")) {
accelerators_m[n_accelerators_m].fVirt |= FSHIFT;
}
n_accelerators_m++;
}
...
if (n_accelerators_m > 0) {
acc_table_m = CreateAcceleratorTable(accelerators_m,
n_accelerators_m);
}
//
// Here is the place to accelerate...
//
BOOL
My_Main_window::PreTranslateMessage(MSG* msg)
{
// allow tooltip messages to be filtered
if (CWnd::PreTranslateMessage(msg)) {
return TRUE;
}
if (msg->message >= WM_KEYFIRST && msg->message <= WM_KEYLAST) {
return (acc_table_m != NULL
&& ::TranslateAccelerator(m_hWnd, acc_table_m, msg));
}
return FALSE;
}
--Jonas
| Вернуться в корень Архива
|