[comp.windows.ms.programmer] Accelerator question for the wizards...

dave@wucs1.wustl.edu (David T Mitchell III) (03/04/91)

Here's a tough one...  I'd like my program to create accelerator keys upon
startup.  I've looked everywhere, but I can't find anyway to make an
accelerator key table that isn't a resource.  What's the deal?  I can hardcode
menus, but not the assocciated accel keys?

Example:

Suppose I've got an array of items (say {"&Alaska", "A&rkansas", "Ari&zona")
that I hook up to a menu.  I'd like the accel keys to be Ctl+A, Ctl+R and
Ctl+Z, respectively.

If my items are a string resource, it's easy to change the & placement
to set different mneumonics (such as {"A&laska", "&Arkansas", A&razona"}).
It seems really silly and tedious to also have to change the related accel,
too.  So...

Is there some way I can make an ACCELERATORTABLE data stucture (based on my
array) rather than loading a resource?

Thanks!

dave	dave@wucs1.wustl.edu
	the mira corporation
	314/434-4343

goodearl@world.std.com (Robert Goodearl) (03/05/91)

In article <1991Mar4.081221.3709@cec1.wustl.edu> dave@wucs1.wustl.edu (David T Mitchell III) writes:
>Here's a tough one...  I'd like my program to create accelerator keys upon
>startup.  I've looked everywhere, but I can't find anyway to make an
>accelerator key table that isn't a resource.  What's the deal?  I can hardcode
>menus, but not the assocciated accel keys?
 ...
>It seems really silly and tedious to also have to change the related accel,
>too.  So...
>
>Is there some way I can make an ACCELERATORTABLE data stucture (based on my
>array) rather than loading a resource?
>

The answer I got when I queried Online about this was "no".  We ended up
-- 
Bob Goodearl -- goodearl@world.std.com

risto@tuura.UUCP (Risto Lankinen) (03/05/91)

dave@wucs1.wustl.edu (David T Mitchell III) writes:

>Is there some way I can make an ACCELERATORTABLE data stucture (based on my
>array) rather than loading a resource?

Hi!

I've once run into a similar problem.  I solved it by defining not just one
but a number of accelerator tables.  You need to have one handle only, and to
use the hAcc = LoadAccelerators( hInst,MAKEINTRESOURCE(wProperParam) ); when
you want the change.

I never really checked it out, but being afraid of possible side effects, I
never changed the value of hAcc while processing the WM_COMMAND (because the
command could have been initiated by pressing an accelerator, in which case
the TranslateAccelerator() would be busy dispatching the message while the
accelerator table is suddenly changed).  Instead, I posted myself a WM_USER
to signal having to handle this later.

Terveisin: Risto Lankinen
-- 
Risto Lankinen / product specialist ***************************************
Nokia Data Systems, Technology Dept *  2                              2   *
THIS SPACE INTENTIONALLY LEFT BLANK * 2 -1 is PRIME!  Now working on 2 +1 *
replies: risto@yj.data.nokia.fi     ***************************************

bonneau@hyper.hyper.com (Paul Bonneau) (03/07/91)

In article <1991Mar5.044334.26714@world.std.com> goodearl@world.std.com (Robert Goodearl) writes:
>The answer I got when I queried Online about this was "no".

Even though there is no "official" support for this,
emulating TranslateAccelerator() should not be difficult.
If you maintain in internal table, such as:

tytpedef struct
	{
	WORD	idm;	/* Menu-item id. */
	int	ch;	/* Accelerator character. */
	WORD	fkey;	/* Modifier keys (ie. control).
	} MAT;		/* My Accelerator Table entry. */

MAT	rgmat[MAXIMUM_MY_ACCELERATORS];

#define pmatNull	((MAT *)0)

Then you can write a routine such as:

BOOL FAR *
MyTranslateAcceletor(LPMSG lpmsg)
	{
	MAT *	pmat;

	/* Look up message in table. */
	if ((pmat = PmatInRgmat(lpmsg)) != pmatNull)
		{
		SendMessage(hwndTopLevel, WM_COMMAND, pmat->idm, 0L);
		return 1;
		}
	return 0;
	}

Then just call the routine in a loop.  Shouldn't be too hard
to maintain, and it has the added benefit of not "flashing" the top
level menu item while accelerating.

cheers - Paul Bonneau.