15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


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





| Вернуться в корень Архива |