Creating+a+keyboard+accelerator+table+from+a+resource

//by Jon Ripley, August 2007//

The normal method of checking for keyboard hot keys is to use [|INKEY] with a negative argument: code format="bb4w" SYS "GetForegroundWindow" TO hWnd% IF hWnd% = @hwnd% THEN IF INKEY-2 THEN IF INKEY-86 THEN PROCnew :REM Ctrl+N IF INKEY-55 THEN PROCopen :REM Ctrl+O ENDIF REM ... ENDIF code

However there may be circumstances where you want to use an accelerator table that has already been designed and its template is contained as a //resource// within a DLL or EXE file. In that case you can create the accelerator table in your program using the resource data. The code example below uses the accelerator table from the resource data for the BB4W IDE (in BBCWIN.EXE or BBCWDEM.EXE):

code format="bb4w" REM Acquire handle to BBCWIN.EXE or BBCWDEM.EXE SYS "GetModuleHandle", 0 TO hmod% REM Load the accelerator table SYS "LoadAccelerators", hmod%, "BBCWIN" TO hAccel% SYS "CopyAcceleratorTable", hAccel%, 0, 0 TO nAccel% DIM ACCEL{(nAccel% - 1) fVirt&, _&, key{l&,h&}, cmd{l&,h&}} SYS "CopyAcceleratorTableA", hAccel%, ACCEL{(0)}, nAccel% REM Virtual key to -ve INKEY conversion table DIM vTable(255) vTable = 0, -10, -12,  0, -11,   0,   0,   0, -48, -97,   0,   0,   0, -74,   0,   0, \ \        -1,  -2,  -3,   0, -65,   0,   0,   0,   0,   0,   0,-113,   0,   0,   0,   0, \      \        -99, -64, -79,-106, -63, -26, -58,-122, -42,   0,   0,   0, -33, -62, -90,   0, \      \        -40, -49, -50, -18, -19, -20, -53, -37, -22, -39,   0,   0,   0,   0,   0,   0, \      \          0, -66,-101, -83, -51, -35, -68, -84, -85, -38, -70, -71, -87,-102, -86, -55, \      \        -56, -17, -52, -82, -36, -54,-100, -34, -67, -69, -98,   0,   0,   0,   0,   0, \      \       -107,-108,-125,-109,-123,-124, -27, -28, -43, -44, -92, -59, -61, -60, -77, -75, \      \       -114,-115,-116, -21,-117,-118, -23,-119,-120, -31, -29, -30,   0,   0,   0,   0, \      \          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, \      \        -78, -32,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, \      \         -4,  -7,  -5,  -8,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, \      \          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, \      \          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, \      \          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, \      \          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, \      \          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0      ON CLOSE SYS "DestroyAcceleratorTable", hAccel%:QUIT REPEAT click% = 0 ON SYS click% = @wparam%:RETURN REPEAT REM Scan through accelerator table looking for matches SYS "GetForegroundWindow" TO hWnd% IF hWnd% = @hwnd% THEN FOR i% = 0 TO nAccel% - 1 IF -(4*INKEY-3 + 2*INKEY-2 + INKEY-1) = (ACCEL{(i%)}.fVirt&>>2) THEN IF INKEYvTable(ACCEL{(i%)}.key.l&) THEN IF ACCEL{(i%)}._& = 0 THEN SYS "SendMessage", @hwnd%, 273, ACCEL{(i%)}.cmd.l&+256*ACCEL{(i%)}.cmd.h&, 0 ACCEL{(i%)}._& = 1 ENDIF ELSE ACCEL{(i%)}._& = 0 ENDIF ENDIF NEXT i%         ENDIF WAIT 1 UNTIL click% REM Handle events... PRINT "click% = ";click% UNTIL FALSE code

Naturally this code will only run within the **BB4W IDE**, because if compiled to an executable file the accelerator table resource data will not be present.

To load an accelerator table from a different file (for example a DLL) then replace the call to with a call to  as follows: code format="bb4w" SYS "LoadLibrary", "EXAMPLE.DLL" TO hmod% code

When the program ends all accelerator tables must be destroyed using code similar to the following. Here **hAccel%** is the handle to the accelerator table: code format="bb4w" SYS "DestroyAcceleratorTable", hAccel% code