I got this code:



w.LoadAccelerators
(
hInst,
string(dword(word(IDR_ACCEL)))
);
mov( eax, hAccel );

forever

w.GetMessage( msg, NULL, 0, 0 );
breakif( !eax );

w.TranslateAccelerator(
hwnd,
hAccel,
&msg
);

if (! eax) then
w.TranslateMessage( msg );
w.DispatchMessage( msg );
endif;

endfor;


I got this from other threads. The

string(dword(word(IDR_ACCEL)))


is the MAKEINTRESOURCE macro from VC 6.0. The acceleratortable looks like this:



IDR_ACCEL ACCELERATORS PRELOAD MOVEABLE PURE
BEGIN
"O", IDM_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT
END


But the 'Ctrl+O' combination doesn't work.
Posted on 2004-02-23 09:17:25 by weelink
You must call TranslateAccelerator in your messageloop. If it returns non-zero, the message was a translator thingy and got processed. If it returns zero, it wasn't a translator message thingy, and you must call TranslateMessage + DispatchMessage.

Hope this helps.
Posted on 2004-02-23 10:25:25 by f0dder
	w.LoadAccelerators

(
hInst,
string(dword(word(IDR_ACCEL)))
);


This looks more complicated than it needs to be. You should be able to access it like this (if IDR_ACCEL is defined as a number in your resource).

w.LoadAccelerators(hInst, val IDR_ACCEL);

In your w.TranslateAccelerator, you access the address of msg (&msg). Use the value of msg instead.

Below is a sample of how I would have written it. It should not matter though if your TranslateAccelerator is outside or inside the loop as it returns results in eax.

w.LoadAccelerators ( hInst, val IDR_ACCEL); 

mov( eax, hAccel );


forever

w.GetMessage( msg, NULL, 0, 0 );
breakif( !eax );

if (! eax) then
if( ! w.TranslateAccelerator( hwnd, hAccel, msg ) then
w.TranslateMessage( msg );
w.DispatchMessage( msg );
endif;
endif;

endfor;


If your still having problems, you might want to check out the source code and resources of EditHLA in the HLA Rich Editor thread for a working example of accelerators in HLA:

http://win32asm.cjb.net/
Posted on 2004-02-23 15:53:43 by Kain
Thank you for your replies. I've copied+pasted almost every HLA-code there is. But nothing worked. In the WinAPI docs I found out that accelerator-messages have the high-order word set to one. If I clear this by doing this:



elseif( eax = (type MsgProcPtr_t [edx]).MessageValue ) then

// If the current message matches one of the values
// in the message dispatch table, then call the
// appropriate routine. Note that the routine address
// is still in ECX from the test above.

/*******************************************************/

push( eax ); // Save eax
mov( wParam, eax ); // Move the value of wParam into eax
and(%1111_1111_1111_1111, eax); // Clear the upperbits (= only save the lowerbits)
mov( eax, wParam ); // Move the value back into wParam
pop( eax ); // Restore eax

/*******************************************************/

push( hwnd ); // (type tMsgProc ecx)(hwnd, wParam, lParam)
push( wParam ); // This calls the associated routine after
push( lParam ); // pushing the necessary parameters.
call( ecx );

sub( eax, eax ); // Return value for function is zero.
break;

endif;


in the
WndProc
procedure it works.
Posted on 2004-02-25 06:43:00 by weelink