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:
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
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):
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
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 “GetModuleHandle” with a call to “LoadLibrary” as follows:
SYS "LoadLibrary", "EXAMPLE.DLL" TO hmod%
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:
SYS "DestroyAcceleratorTable", hAccel%