i know that there are topics on accelerators, but it seems like i'm doing everything right, and yet my code doesn't work :/

accels	ACCEL <FCONTROL or FVIRTKEY, VK_F12, IDM_TEXTURE>

ACCEL <FCONTROL, "Z", IDM_UNDO>


		; Create accelerator table

call CreateAcceleratorTable, offset accels, 2
or eax, eax
jz dstrwnd
mov [hAccel], eax



align 4		; Message loop

msglp: mov esi, offset MessageStruct
jmp @@get_msg
align 4
@@msg_loop: call TranslateAccelerator, [hwndMain], [hAccel], esi
or eax, eax
jnz @@get_msg
call TranslateMessage, esi
call DispatchMessage, esi

@@get_msg: call GetMessage, esi, edi, edi, edi
inc eax
jz dstrwnd
dec eax
jnz @@msg_loop


it doesn't post any WM_COMMAND when i press CTRL+F12 or CTRL+Z :/
Posted on 2004-12-23 11:47:44 by ti_mo_n
Try using this structure instead of ACCEL:
ACCELERATOR STRUCT

fVirt WORD ?
key WORD ?
cmd WORD ?
ACCELERATOR ENDS

Hope that helps :)
Posted on 2004-12-26 18:45:30 by QvasiModo
nope, i still dont get any WM_COMMAND. debugging showed that TranslateAccelerators _ALWAYS_ returns 0 regardless of what i press :/

CreateAcceleratorTable succeedes, and TranslateAccelerators fails. strange... :roll:
Posted on 2004-12-26 19:11:56 by ti_mo_n
Is hwndMain filled with the correct value?
Posted on 2004-12-27 05:58:53 by roticv
Afternoon, ti_mo_n.

I don't know which examples you've gotten your info on how to use Accelerators, however I use the following:

Inside the application's *.rc file you have:
#define IDM_FILE_NEW 10001

#define IDM_FILE_OPEN 10002
#define IDM_FILE_SAVE 10003
#define IDM_FILE_SAVEAS 10004
#define IDM_FILE_PRINT 10005
#define IDM_FILE_EXIT 10006

IDAPP ACCELERATORS DISCARDABLE
{
VK_ESCAPE, IDM_FILE_EXIT, VIRTKEY, NOINVERT
"N", IDM_FILE_NEW, VIRTKEY, CONTROL, NOINVERT
"O", IDM_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT
"S", IDM_FILE_SAVE, VIRTKEY, CONTROL, NOINVERT
}

and you load it by using:


INVOKE LoadAccelerators, hInst, ADDR szIDATMO
mov hAccel, eax

where hInst is the Instance Handle supplied via WinMain proc. and


szIDATMO db "IDAPP",0
hAccel dd 0


The Message Pump is simply:



;===================================
; Loop until PostQuitMessage is sent
;===================================
.WHILE TRUE
INVOKE GetMessage, ADDR msg, 0,0,0
.BREAK .IF (!eax)
INVOKE TranslateAccelerator, hWindow, hAccel, ADDR msg

.IF !eax
INVOKE TranslateMessage, ADDR msg
INVOKE DispatchMessage, ADDR msg
.ENDIF
.ENDW


After that, just handle the message as if they were Menu messages.

Cheers,
Scronty
Posted on 2004-12-27 23:17:50 by Scronty
thanx Scronty, i'll test it soon, but i really wanted to do this using "createacceleratortable" from memory - WITHOUT using resources :/

roticv: hwnd is ok, because all other functions work (and also i doublechecked if it is, after you asked).
Posted on 2005-01-04 00:01:40 by ti_mo_n
Then that means that your accelator table is not created correctly in memory if I am not wrong... But I am not so sure since I never used that api before.
Posted on 2005-01-04 06:09:05 by roticv
The problem is that the defintion of the ACCEL structure in MASM32, at MSDN and everywhere else you will ever find it is wrong. This will work...

ACCEL Struct

fVirt DB ?
pad0 DB ?
key DW ?
cmd DW ?
ACCEL ENDS

.DATA
accels ACCEL <FCONTROL or FVIRTKEY, 0, VK_F12, IDM_TEXTURE>
ACCEL <FCONTROL or FVIRTKEY, 0, VK_Z, IDM_UNDO>


Don't use ascii, only VKeys, or it has problems for some bizarre reason.
Posted on 2005-01-05 00:07:46 by donkey
Afternoon, Donkey.

align 4

myAcceleratorKeys myACCEL <FVIRTKEY, 0, VK_ESCAPE, IDM_FILE_EXIT >
myACCEL <FCONTROL OR FVIRTKEY, 0, "N", IDM_FILE_NEW >
myACCEL <FCONTROL OR FVIRTKEY, 0, "O", IDM_FILE_OPEN >
myACCEL <FCONTROL OR FVIRTKEY, 0, "S", IDM_FILE_SAVE >

works fine.

If the ascii characters didn't work for you then it might've been a data alignment problem or the characters were given as lower-case.

Thanks for the correct definition of the ACCEL structure.

Cheers,
Scronty
Posted on 2005-01-05 03:18:40 by Scronty
Hi Scronty,

Maybe I explained badly, FVIRTKEY is not necessary if you are using the ascii value, so it should be

myACCEL <FCONTROL,  0, "N", IDM_FILE_NEW  >


Which is the ascii version he used in the original post and wouldn't work for some reason. You need to specify FVIRTKEY.
Posted on 2005-01-05 07:25:14 by donkey
yuppie! :) it finally started working! thanks donkey for the structure! :) i can confirm (like donkey said) that it is required to use virtual keys only, because it doesn't work elseway. even if i use '0'-'9' or 'A'-'Z' i need to type (the letters) uppercase and specify the FVIRTKEY flag.
Posted on 2005-01-05 09:43:07 by ti_mo_n
There is nothing wrong with the C++ declaration at MSDN because the default compiler settings align WORDs on WORD boundaries. Because the largest data type within the structure is a WORD, the structure will also be aligned on a WORD boundary by the C++ compiler. That means C++ adds a hidden pad byte in the structure.
Posted on 2005-01-05 15:29:39 by tenkey
Hi tenkey,

Though I understand what you mean, I think that any structure defintion that depends on the proper alignment switch to "add" a member, not just align the entry point, is wrong. MSDN documents the pad bytes in almost every struct I have seen that uses them except this one. So based on their past behaviour, this defintion is in error. The real pain is that there are not alot of places where you can find this little tidbit for such a useful API if you want user definable accelerator keys and all of the functions return normally, even the count of accels is good when queried.
Posted on 2005-01-05 21:02:28 by donkey
Its worth trying the standard MASM notation for structure alignment.


ACCEL STRUCT WORD
fVirt DB ?
key DW ?
cmd DW ?
ACCEL ENDS

See if this works and let me know if it does. I don't have any code handy to test it.
Posted on 2005-01-05 22:53:48 by hutch--
Afternoon, Steve.

Just modified the ACCEL structure definition in the windows.inc file I have to the one you've supplied, and adjusted my code to:
    myAcceleratorKeys       ACCEL <FVIRTKEY,             VK_ESCAPE,   IDM_FILE_EXIT >

ACCEL <FCONTROL or FVIRTKEY, "N", IDM_FILE_NEW >
ACCEL <FCONTROL or FVIRTKEY, "O", IDM_FILE_OPEN >
ACCEL <FCONTROL or FVIRTKEY, "S", IDM_FILE_SAVE >


It works fine, however it must be noted that the use of the FVIRTKEY flag is still a must.

Cheers,
Scronty
Posted on 2005-01-06 05:12:30 by Scronty