Announcement

Collapse
No announcement yet.

Trapping Keyboard Input; a basic question from a GUI programming novice

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • #21
    Yes, creating a gui program makes you have to deal
    with writting code that understands and uses message notification
    from the windows os. Coming from a dos or console programing background where if you did not use interrups in a high level language can test ones sanity in creating a gui program that validates keyboard presses.
    I have been writting a few gui programs and i hate having to deal with keyboard validation so i just do not. I check a controls input only after a compeletion of whole input until i grasp those skills which i believe every coder does at some point in time different from others and some people have more pain in learning those skills than others. Not a fault of powerbasic, just the way windows works to be a multitasking operating system.
    Last edited by Paul Purvis; 14 Oct 2010, 12:18 PM.
    p purvis

    Comment


    • #22
      Yes, seems pretty difficult to sort this out....so easy in the PBCC version of the program! And yes, checking keystrokes during data entry was such a great way to make sure correct user data was entered on forms. eg. if you want an answer between 1 and 3, then only allow keys 1, 2 and 3 to be pressed (and bleep for a wrong key!).

      Looks as though I could make a massive table of keyboard shortcuts as suggested by Michael Matthias, although this is hardly an elegant solution for mapping the whole keyboard along with SHIFT, ALT and CONTROL key combinations.

      Peter

      Comment


      • #23
        Looks as though I could make a massive table of keyboard shortcuts as suggested by Michael [Mattias], although this is hardly an elegant solution for mapping the whole keyboard along with SHIFT, ALT and CONTROL key combinations.
        News Flash: This is not MS-DOS. This is not a console program. In a Windows' GUI environment, keyboard accelerators is the elegant solution.

        Listen to what Mr. Purvis said. I remember when he was first doing GUI programs an looking for the "new way" to handle things and asking the same kinds of questions you are asking today.

        The difference I see is, Mr. Purvis was not prejudiced into thinking "trap keystrokes;" he was open to "the Windows GUI Way." Now he's a certified GUI veteran.

        MCM
        Michael Mattias
        Tal Systems (retired)
        Port Washington WI USA
        [email protected]
        http://www.talsystems.com

        Comment


        • #24
          You are doing this the hard way. This is something that is very easy to do
          with SDK programming where one has direct access to the message loop of the app.

          You dug yourself into a deep hole right of the bat with this
          Code:
          DIALOG SHOW MODAL ghDlg CALL MainDlgProc
          This requires a hook to access the message loop hidden in the OS which, as you have
          discovered, is going to get you into trouble with the hidden, internal modal message loop for
          menus and modal dialogs.

          Start anew using DIALOG SHOW MODELESS, install a message loop(aka pump), and
          do your key trapping within the message loop. Do not do it from the dialog callback.
          Do not bother with hooks, accelerator tables or subclassing which are not elegant solutions to a simple problem.
          Dominic Mitchell
          Phoenix Visual Designer
          http://www.phnxthunder.com

          Comment


          • #25
            Modeless in PBFORMS - original code by Semen Matusovski

            Code:
            #PBFORMS CREATED V2.01
            #COMPILE EXE  'MessagePumper.bas
            #DIM ALL
            '------------------------------------------------------------------------------
            '   ** Includes **
            '------------------------------------------------------------------------------
            #PBFORMS BEGIN INCLUDES
            %USEMACROS = 1
            #INCLUDE ONCE "WIN32API.INC"
            #PBFORMS END INCLUDES
            '------------------------------------------------------------------------------
            '   ** Constants **
            '------------------------------------------------------------------------------
            #PBFORMS BEGIN CONSTANTS
            %IDD_DIALOG1 = 1000
            %Label       =  101
            %Button1     =  201
            %Button2     =  202
            %Textbox1    =  301
            %Textbox2    =  302
            %ComboBox    =  401
            %IDR_MENU1   = 2000
            %MENU1       = 2001
            %Listbox     = 3001
            #PBFORMS END CONSTANTS
            '------------------------------------------------------------------------------
            '   ** Declarations **
            '------------------------------------------------------------------------------
            DECLARE FUNCTION AttachMENU1(BYVAL hDlg AS DWORD) AS DWORD
            DECLARE CALLBACK FUNCTION ShowDIALOG1Proc()
            DECLARE FUNCTION SampleComboBox(BYVAL hDlg AS DWORD, BYVAL lID AS LONG, BYVAL _
              lCount AS LONG) AS LONG
            DECLARE FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
            #PBFORMS DECLARATIONS
            '------------------------------------------------------------------------------
            '   ** Main Application Entry Point **
            '------------------------------------------------------------------------------
            FUNCTION PBMAIN()
              ShowDIALOG1 %HWND_DESKTOP
            END FUNCTION
             
            THREAD FUNCTION ListBoxCounter(BYVAL hDlg AS DWORD) AS DWORD
              'Clear the list box after so many items
              LOCAL ItemCount, x AS LONG
              DO
               LISTBOX GET COUNT hDlg, %LISTBOX TO ItemCount
               'LISTBOX ADD hDlg, %LISTBOX, STR$(ItemCount) + " items"
               IF ItemCount > 20 THEN
                  LISTBOX RESET hDlg, %LISTBOX
                  LISTBOX ADD hDlg, %LISTBOX,"LISTBOX RESET " + TIME$
               END IF
               SLEEP 250
              LOOP
            END FUNCTION
            '------------------------------------------------------------------------------
            '   ** Menus **
            '------------------------------------------------------------------------------
            FUNCTION AttachMENU1(BYVAL hDlg AS DWORD) AS DWORD
            #PBFORMS BEGIN MENU %IDR_MENU1->%IDD_DIALOG1
              LOCAL hMenu   AS DWORD
              LOCAL hPopUp1 AS DWORD
              MENU NEW BAR TO hMenu
              MENU NEW POPUP TO hPopUp1
              MENU ADD POPUP, hMenu, "Pop-up menu", hPopUp1, %MF_ENABLED
                MENU ADD STRING, hPopUp1, "Item 1", %MENU1, %MF_ENABLED
              MENU ATTACH hMenu, hDlg
            #PBFORMS END MENU
              FUNCTION = hMenu
            END FUNCTION
            '------------------------------------------------------------------------------
            '   ** CallBacks **
            '------------------------------------------------------------------------------
            CALLBACK FUNCTION ShowDIALOG1Proc()
              SELECT CASE AS LONG CB.MSG
                CASE %WM_INITDIALOG
                  LOCAL h AS DWORD
                  'clear listbox automatically
                  THREAD CREATE ListBoxCounter(CB.HNDL) TO h
                  THREAD CLOSE h TO h
                  ShowHelp CB.HNDL
                CASE %WM_NCACTIVATE
                  STATIC hWndSaveFocus AS DWORD
                  IF ISFALSE CB.WPARAM THEN
                    ' Save control focus
                    hWndSaveFocus = GetFocus()
                  ELSEIF hWndSaveFocus THEN
                    ' Restore control focus
                    SetFocus(hWndSaveFocus)
                    hWndSaveFocus = 0
                  END IF
                CASE %WM_COMMAND
                  SELECT CASE AS LONG CB.CTL
                    CASE %BUTTON1
                      IF CB.CTLMSG = %BN_CLICKED OR CB.CTLMSG = 1 THEN
                      END IF
                    CASE %BUTTON2
                      IF CB.CTLMSG = %BN_CLICKED OR CB.CTLMSG = 1 THEN
                        LISTBOX RESET CB.HNDL, %LISTBOX
                      END IF
                    CASE %MENU1
                      ? "Hi, Peter!"
                  END SELECT
                CASE %WM_CLOSE
                CASE %WM_DESTROY
              END SELECT
            END FUNCTION
            '------------------------------------------------------------------------------
            '   ** Sample Code **
            '------------------------------------------------------------------------------
            FUNCTION SampleComboBox(BYVAL hDlg AS DWORD, BYVAL lID AS LONG, BYVAL lCount _
              AS LONG) AS LONG
              LOCAL i AS LONG
              CONTROL SEND hDlg, lID, %CB_SETEXTENDEDUI, %TRUE, 0
              FOR i = 1 TO lCount
                COMBOBOX ADD hDlg, lID, USING$("Combo item #", i)
              NEXT i
            END FUNCTION
            '------------------------------------------------------------------------------
            '   ** Dialogs **
            '------------------------------------------------------------------------------
            FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
              LOCAL lRslt AS LONG
              LOCAL Msg  AS tagMsg
            #PBFORMS BEGIN DIALOG %IDD_DIALOG1->%IDR_MENU1->
              LOCAL hDlg   AS DWORD
              LOCAL hFont1 AS DWORD
              DIALOG NEW hParent, "Subclass?", 100, 50, 400, 300, %WS_POPUP OR %WS_BORDER OR %WS_DLGFRAME OR _
                %WS_CAPTION OR %WS_SYSMENU OR %WS_MINIMIZEBOX OR %WS_MAXIMIZEBOX OR _
                %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_MODALFRAME OR %DS_3DLOOK OR _
                %DS_NOFAILCREATE OR %DS_SETFONT, %WS_EX_CONTROLPARENT OR %WS_EX_LEFT OR _
                %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hDlg
              CONTROL ADD TEXTBOX,  hDlg, %Textbox1, "Textbox1", 10, 25, 111, 12
              CONTROL ADD TEXTBOX,  hDlg, %Textbox2, "Textbox2", 10, 45, 111, 40, _
                %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %ES_LEFT OR %ES_MULTILINE OR _
                %ES_WANTRETURN, %WS_EX_CLIENTEDGE OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR _
                %WS_EX_RIGHTSCROLLBAR
              CONTROL ADD COMBOBOX, hDlg, %ComboBox, , 10, 105, 111, 100, _
                %CBS_DROPDOWNLIST OR %WS_TABSTOP OR %WS_CHILD OR %WS_VISIBLE, _
                %WS_EX_LEFT OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR
              CONTROL ADD BUTTON,   hDlg, %Button1, "&Button1", 55, 5, 48, 12, %WS_CHILD _
                OR %WS_VISIBLE OR %BS_TEXT OR %BS_PUSHBUTTON OR %BS_CENTER OR _
                %BS_VCENTER, %WS_EX_LEFT OR %WS_EX_LTRREADING
              CONTROL ADD LABEL,    hDlg, %Label, "CTRL+A  select all in TextBox2", 5, _
                145, 270, 145
              CONTROL ADD LISTBOX,  hDlg, %Listbox, , 190, 5, 195, 195, %WS_CHILD OR _
                %WS_VISIBLE OR %WS_VSCROLL OR %LBS_NOTIFY, %WS_EX_CLIENTEDGE OR _
                %WS_EX_LEFT OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR
              CONTROL ADD BUTTON,   hDlg, %Button2, "Button2", 335, 211, 50, 15, _
                %WS_CHILD OR %WS_VISIBLE OR %BS_TEXT OR %BS_PUSHBUTTON OR %BS_CENTER OR _
                %BS_VCENTER, %WS_EX_LEFT OR %WS_EX_LTRREADING
              FONT NEW "Courier New", 8, 0, %ANSI_CHARSET TO hFont1
              CONTROL SET FONT hDlg, %Listbox, hFont1
              AttachMENU1 hDlg
            #PBFORMS END DIALOG
              SampleComboBox hDlg, %COMBOBOX, 10
              DIALOG SHOW MODELESS hDlg CALL ShowDIALOG1Proc TO lRslt
              WHILE GetMessage(Msg, %NULL, 0, 0)
                LOCAL Title$
                LOCAL k AS LONG
                Title$ = ""  'required!!
                SELECT CASE Msg.message
                  k = Msg.wParam
                  CASE %WM_SYSKEYDOWN
                    SELECT CASE k 'Msg.wParam
                      CASE %VK_LEFT : LISTBOX ADD hDlg, %LISTBOX, "ALT + LEFT ARROW"
                      CASE %VK_RIGHT: LISTBOX ADD hDlg, %LISTBOX , "ALT + RIGHT ARROW"
                      CASE %VK_DOWN : LISTBOX ADD hDlg, %LISTBOX , "ALT + ARROW DOWN"
                      CASE %VK_UP   : LISTBOX ADD hDlg, %LISTBOX , "ALT + ARROW UP"
                      CASE ELSE     : LISTBOX ADD hDlg, %LISTBOX , "ALT" + STR$(k)
                    END SELECT
                  CASE %WM_KEYDOWN
                    IF ISTRUE(LOWRD(GetKeyState(%VK_CONTROL)) AND &H8000) THEN
                      SELECT CASE k 'Msg.wParam
                        CASE %VK_LEFT   : LISTBOX ADD hDlg, %LISTBOX , "CONTROL + LEFT ARROW"
                          CASE %VK_RIGHT: LISTBOX ADD hDlg, %LISTBOX , "CONTROL + RIGHT ARROW"
                          CASE %VK_DOWN : LISTBOX ADD hDlg, %LISTBOX , "CONTROL + ARROW DOWN"
                          CASE %VK_UP   : LISTBOX ADD hDlg, %LISTBOX , "CONTROL + ARROW UP"
                          CASE %VK_A    : LISTBOX ADD hDlg, %LISTBOX , "CONTROL + A"
                                          CONTROL SET FOCUS hDlg, %TEXTBOX2
                                          CONTROL SEND hDlg,%TEXTBOX2, %EM_SETSEL,0,-1
                          CASE 65 TO 90 : LISTBOX ADD hDlg, %LISTBOX , "CONTROL + " + STR$(k)
                          CASE ELSE     : LISTBOX ADD hDlg, %LISTBOX , "CONTROL + " + STR$(k)
                      END SELECT
                    ELSEIF ISTRUE(LOWRD(GetKeyState(%VK_SHIFT)) AND &H8000) THEN
                      SELECT CASE k 'Msg.wParam
                        CASE %VK_LEFT : LISTBOX ADD hDlg, %LISTBOX , "SHIFT + LEFT ARROW"
                        CASE %VK_RIGHT: LISTBOX ADD hDlg, %LISTBOX , "SHIFT + RIGHT ARROW"
                        CASE %VK_DOWN : LISTBOX ADD hDlg, %LISTBOX , "SHIFT + ARROW DOWN"
                        CASE %VK_UP   : LISTBOX ADD hDlg, %LISTBOX , "SHIFT + ARROW UP"
                        CASE ELSE     : LISTBOX ADD hDlg, %LISTBOX , "SHIFT +" + STR$(k)
                                      'TranslateMessage Msg
                                      'DispatchMessage Msg
                      END SELECT
             '   ***   Handle single keystrokes ****
                    ELSE
                      'Here you can handle a keystroke or turn it into another value
                      SELECT CASE k
                          CASE  9 'TAB key
                          LISTBOX ADD hDlg, %LISTBOX, "TAB"
                        CASE 13 'ENTER converted to TAB unless in multi-line control
                          IF Msg.hWnd <> GetDlgItem(hDlg, %TEXTBOX2) THEN
                            msg.wParam = 9
                            LISTBOX ADD hDlg, %LISTBOX, "ENTER converted to TAB"
                          ELSE
                            LISTBOX ADD hDlg, %LISTBOX, "ENTER not to TAB in this control"
                          END IF
                        CASE ELSE
                          Title = FORMAT$(k)+ "/"+ CHR$(k)
                          TranslateMessage Msg
                          DispatchMessage Msg
                      END SELECT
                    END IF
                END SELECT
                IF LEN(Title$) THEN
                  IF Msg.hWnd = GetDlgItem(hDlg, %TEXTBOX1) THEN Title$ = Title + " TextBox1" ELSE _
                  IF Msg.hWnd = GetDlgItem(hDlg, %TEXTBOX2) THEN Title$ = Title + "   TextBox2" ELSE _
                  IF Msg.hWnd = GetDlgItem(hDlg, %COMBOBOX)THEN Title$ = Title +  "     ComboBox"
                  'SetWindowText hDlg, BYVAL STRPTR(Title$)
                  LISTBOX ADD hDlg, %LISTBOX, Title
                ELSEIF IsDialogMessage(hDlg, Msg) = %FALSE THEN  ' Don't touch Tab
                  TranslateMessage Msg
                  DispatchMessage Msg
                END IF
              LOOP WHILE IsWindow(hdlg)
            #PBFORMS BEGIN CLEANUP %IDD_DIALOG1
              FONT END hFont1
            #PBFORMS END CLEANUP
              FUNCTION = lRslt
            END FUNCTION
            SUB ShowHelp(hDlg AS DWORD)
              LOCAL s AS STRING
              LOCAL ds AS STRING
              ds = $CR + $CR
              s =     "CTRL+A select all text in TextBox2." + ds
              s = s + "Enter treated as TAB except in multi-line Textbox2." + ds
              s = s + "Listbox auto reset using a thread." + ds
              s = s + "Credit:" + $CR
              s = s + "Semen Matusovski code into PBFORMS post #12 2/29/2000" + $CR
              s = s + "[URL]http://www.powerbasic.com/support/pbforums/showthread.php?t=2037[/URL]" + ds
              s = s + "Placed into PBFORMS by Mike Doty 10/15/2010" + $CR
              s = s + "Please post problems or suggestions!" + ds
              s = s + "How to get rid of BEEPS?
              CONTROL SET TEXT hDlg, %LABEL, s
            END SUB
            Last edited by Mike Doty; 15 Oct 2010, 01:50 AM.

            Comment


            • #26
              Next step might be to write a function that keeps track of
              last control, current control, last key pressed, last click
              last mouse position, current mouse position.
              A modeless skeleton for PBFORMS.

              This is a stripped down version of the above program.
              Code:
              #PBFORMS CREATED V2.01
              #PBFORMS BEGIN INCLUDES
              #INCLUDE ONCE "WIN32API.INC"
              #PBFORMS END INCLUDES
              #PBFORMS BEGIN CONSTANTS
              %IDD_DIALOG1 = 1000
              %Textbox1    = 1001
              %Textbox2    = 1002
              %Label       = 2001
              #PBFORMS END CONSTANTS
              #PBFORMS DECLARATIONS
              FUNCTION PBMAIN()
                Form1 %HWND_DESKTOP
              END FUNCTION
              CALLBACK FUNCTION MyCallBack
                SELECT CASE AS LONG CB.MSG
                  CASE %WM_INITDIALOG
                  CASE %WM_NCACTIVATE
                    STATIC hWndSaveFocus AS DWORD
                    IF ISFALSE CB.WPARAM THEN
                      ' Save control focus
                      hWndSaveFocus = GetFocus()
                    ELSEIF hWndSaveFocus THEN
                      ' Restore control focus
                      SetFocus(hWndSaveFocus)
                      hWndSaveFocus = 0
                    END IF
                  CASE %WM_COMMAND
                    SELECT CASE AS LONG CB.CTL
                    END SELECT
                  CASE %WM_CLOSE
                  CASE %WM_DESTROY
                END SELECT
              END FUNCTION
              FUNCTION FORM1(BYVAL hParent AS DWORD) AS LONG
                LOCAL Result AS LONG
                LOCAL Msg  AS tagMsg
              #PBFORMS BEGIN DIALOG %IDD_DIALOG1->->
                LOCAL hDlg  AS DWORD
                DIALOG NEW hParent, "Message pump", 305, 116, 116, 114, %WS_POPUP OR _
                  %WS_BORDER OR %WS_DLGFRAME OR %WS_CAPTION OR %WS_SYSMENU OR _
                  %WS_MINIMIZEBOX OR %WS_MAXIMIZEBOX OR %WS_CLIPSIBLINGS OR %WS_VISIBLE OR _
                  %DS_MODALFRAME OR %DS_3DLOOK OR %DS_NOFAILCREATE OR %DS_SETFONT, _
                  %WS_EX_CONTROLPARENT OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR _
                  %WS_EX_RIGHTSCROLLBAR, TO hDlg
                CONTROL ADD TEXTBOX, hDlg, %Textbox1, "", 5, 10, 100, 13
                CONTROL ADD TEXTBOX, hDlg, %Textbox2, "", 5, 30, 100, 55, %WS_CHILD OR _
                  %WS_VISIBLE OR %WS_TABSTOP OR %ES_LEFT OR %ES_MULTILINE OR _
                  %ES_WANTRETURN, %WS_EX_CLIENTEDGE OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR _
                  %WS_EX_RIGHTSCROLLBAR
                CONTROL ADD LABEL,   hDlg, %Label, "Keystroke", 5, 95, 100, 10
              #PBFORMS END DIALOG
                DIALOG SHOW MODELESS hDlg CALL MyCallBack TO result
                WHILE GetMessage(Msg, %NULL, 0, 0)
                  LOCAL k AS LONG
                  SELECT CASE Msg.message
                    k = Msg.wParam
                    CASE %WM_SYSKEYDOWN
                      SELECT CASE k 'Msg.wParam
                        CASE %VK_LEFT
                        CASE %VK_RIGHT
                        CASE %VK_DOWN
                        CASE %VK_UP
                        CASE ELSE
                      END SELECT
                    CASE %WM_KEYDOWN
                      IF ISTRUE(LOWRD(GetKeyState(%VK_CONTROL)) AND &H8000) THEN
                        SELECT CASE k 'Msg.wParam
                          CASE %VK_LEFT
                            CASE %VK_RIGHT
                            CASE %VK_DOWN
                            CASE %VK_UP
                            CASE %VK_A
                            CASE 65 TO 90
                        END SELECT
                      ELSEIF ISTRUE(LOWRD(GetKeyState(%VK_SHIFT)) AND &H8000) THEN
                        SELECT CASE k 'Msg.wParam
                          CASE %VK_LEFT
                          CASE %VK_RIGHT
                          CASE %VK_DOWN
                          CASE %VK_UP
                          CASE ELSE
                        END SELECT
               '   ***   Handle single keystrokes ****
                      ELSE
                        'Here you can handle a keystroke or turn it into another value
                        SELECT CASE k
                            CASE  9 'TAB key
                          CASE 13 'ENTER converted to TAB unless in multi-line control
                            IF Msg.hWnd <> GetDlgItem(hDlg, %TEXTBOX2) THEN
                              msg.wParam = 9
                            END IF
                          CASE ELSE
                            CONTROL SET TEXT hDlg, %LABEL, FORMAT$(k)+ "/"+ CHR$(k)
                        END SELECT
                      END IF
                  END SELECT
                  'IF Msg.hWnd = GetDlgItem(hDlg, %TEXTBOX1)
                  IF IsDialogMessage(hDlg, Msg) = %FALSE THEN  ' Don't touch Tab
                    TranslateMessage Msg
                    DispatchMessage Msg
                  END IF
                LOOP WHILE isWindow(hDlg)
              #PBFORMS BEGIN CLEANUP %IDD_DIALOG1
              #PBFORMS END CLEANUP
                FUNCTION = result
              END FUNCTION
              Last edited by Mike Doty; 15 Oct 2010, 02:47 AM.

              Comment


              • #27
                Stupid and clumsy way....

                After the messages yesterday evening, I wrote out the following key accelerator table to reproduce ASCII and extended codes (1000 + code) from each key on the keyboard. This works fine with the line:

                Code:
                REM Add keyboard accelerator codes
                ACCEL ATTACH main_handle, ac() TO hAccelHandle
                in the CASE %WM_INITDIALOG section of the callback of the main dialog. It's all rather inelegant, although nice to have control of what the keys return (and obviously could be made to deviate from the old ASCII codes if necessary). I was wondering whether inserting such a large table into the callback would slow down its responsiveness to the keyboard (and to the callback generally).

                From the messages received since there is clearly a better way to achieve this using modeless dialogs, and I'll certainly have a try.

                Anyway, here is the table if it's of any use to anyone else:

                Code:
                    ' The key_offset variable adds a fixed number (eg. 5000) to the CBCTL code
                    ' to keep it away from other returned codes in the callback
                    
                    ' Keypresses that would return extended (2 byte) codes have 1000 added to the
                    ' return code so they can be identified separately in the callback
                
                    DIM ac(1 TO 304) AS ACCELAPI
                
                    ac(1).fvirt = %FVIRTKEY: ac(1).key = %VK_ADD:        ac(1).cmd = key_offset + 61
                    ac(2).fvirt = %FVIRTKEY: ac(2).key = %VK_BACK:       ac(2).cmd = key_offset + 8
                    ac(3).fvirt = %FVIRTKEY: ac(3).key = %VK_TAB:        ac(3).cmd = key_offset + 9
                    ac(4).fvirt = %FVIRTKEY: ac(4).key = %VK_SUBTRACT:   ac(4).cmd = key_offset + 45
                    ac(5).fvirt = %FVIRTKEY: ac(5).key = %VK_RETURN:     ac(5).cmd = key_offset + 13
                    ac(6).fvirt = %FVIRTKEY: ac(6).key = %VK_ESCAPE:     ac(6).cmd = key_offset + 27
                    ac(7).fvirt = %FVIRTKEY: ac(7).key = %VK_SPACE:      ac(7).cmd = key_offset + 32
                    ac(8).fvirt = %FVIRTKEY: ac(8).key = %VK_PGUP:       ac(8).cmd = key_offset + 1073
                    ac(9).fvirt = %FVIRTKEY: ac(9).key = %VK_PGDN:       ac(9).cmd = key_offset + 1081
                    ac(10).fvirt = %FVIRTKEY: ac(10).key = %VK_END:     ac(10).cmd = key_offset + 1079
                    ac(11).fvirt = %FVIRTKEY: ac(11).key = %VK_HOME:    ac(11).cmd = key_offset + 1071
                    ac(12).fvirt = %FVIRTKEY: ac(12).key = %VK_LEFT:    ac(12).cmd = key_offset + 1075
                    ac(13).fvirt = %FVIRTKEY: ac(13).key = %VK_UP:      ac(13).cmd = key_offset + 1072
                    ac(14).fvirt = %FVIRTKEY: ac(14).key = %VK_RIGHT:   ac(14).cmd = key_offset + 1077
                    ac(15).fvirt = %FVIRTKEY: ac(15).key = %VK_DOWN:    ac(15).cmd = key_offset + 1080
                    ac(16).fvirt = %FVIRTKEY: ac(16).key = %VK_INSERT:  ac(15).cmd = key_offset + 1082
                    ac(17).fvirt = %FVIRTKEY: ac(17).key = %VK_DELETE:  ac(16).cmd = key_offset + 1083
                    ac(18).fvirt = %FVIRTKEY: ac(18).key = %VK_HELP:    ac(17).cmd = key_offset + 1059
                
                    ac(19).fvirt = %FVIRTKEY: ac(19).key = %VK_A: ac(19).cmd = key_offset + 97
                    ac(20).fvirt = %FVIRTKEY: ac(20).key = %VK_B: ac(20).cmd = key_offset + 98
                    ac(21).fvirt = %FVIRTKEY: ac(21).key = %VK_C: ac(21).cmd = key_offset + 99
                    ac(22).fvirt = %FVIRTKEY: ac(22).key = %VK_D: ac(22).cmd = key_offset + 100
                    ac(23).fvirt = %FVIRTKEY: ac(23).key = %VK_E: ac(23).cmd = key_offset + 101
                    ac(24).fvirt = %FVIRTKEY: ac(24).key = %VK_F: ac(24).cmd = key_offset + 102
                    ac(25).fvirt = %FVIRTKEY: ac(25).key = %VK_G: ac(25).cmd = key_offset + 103
                    ac(26).fvirt = %FVIRTKEY: ac(26).key = %VK_H: ac(26).cmd = key_offset + 104
                    ac(27).fvirt = %FVIRTKEY: ac(27).key = %VK_I: ac(27).cmd = key_offset + 105
                    ac(28).fvirt = %FVIRTKEY: ac(28).key = %VK_J: ac(28).cmd = key_offset + 106
                    ac(29).fvirt = %FVIRTKEY: ac(29).key = %VK_K: ac(29).cmd = key_offset + 107
                    ac(30).fvirt = %FVIRTKEY: ac(30).key = %VK_L: ac(30).cmd = key_offset + 108
                    ac(31).fvirt = %FVIRTKEY: ac(31).key = %VK_M: ac(31).cmd = key_offset + 109
                    ac(32).fvirt = %FVIRTKEY: ac(32).key = %VK_N: ac(32).cmd = key_offset + 110
                    ac(33).fvirt = %FVIRTKEY: ac(33).key = %VK_O: ac(33).cmd = key_offset + 111
                    ac(34).fvirt = %FVIRTKEY: ac(34).key = %VK_P: ac(34).cmd = key_offset + 112
                    ac(35).fvirt = %FVIRTKEY: ac(35).key = %VK_Q: ac(35).cmd = key_offset + 113
                    ac(36).fvirt = %FVIRTKEY: ac(36).key = %VK_R: ac(36).cmd = key_offset + 114
                    ac(37).fvirt = %FVIRTKEY: ac(37).key = %VK_S: ac(37).cmd = key_offset + 115
                    ac(38).fvirt = %FVIRTKEY: ac(38).key = %VK_T: ac(38).cmd = key_offset + 116
                    ac(39).fvirt = %FVIRTKEY: ac(39).key = %VK_U: ac(39).cmd = key_offset + 117
                    ac(40).fvirt = %FVIRTKEY: ac(40).key = %VK_V: ac(40).cmd = key_offset + 118
                    ac(41).fvirt = %FVIRTKEY: ac(41).key = %VK_W: ac(41).cmd = key_offset + 119
                    ac(42).fvirt = %FVIRTKEY: ac(42).key = %VK_X: ac(42).cmd = key_offset + 120
                    ac(43).fvirt = %FVIRTKEY: ac(43).key = %VK_Y: ac(43).cmd = key_offset + 121
                    ac(44).fvirt = %FVIRTKEY: ac(44).key = %VK_Z: ac(44).cmd = key_offset + 122
                
                    ac(45).fvirt = %FVIRTKEY: ac(45).key = %VK_0: ac(45).cmd = key_offset + 48
                    ac(46).fvirt = %FVIRTKEY: ac(46).key = %VK_1: ac(46).cmd = key_offset + 49
                    ac(47).fvirt = %FVIRTKEY: ac(47).key = %VK_2: ac(47).cmd = key_offset + 50
                    ac(48).fvirt = %FVIRTKEY: ac(48).key = %VK_3: ac(48).cmd = key_offset + 51
                    ac(49).fvirt = %FVIRTKEY: ac(49).key = %VK_4: ac(49).cmd = key_offset + 52
                    ac(50).fvirt = %FVIRTKEY: ac(50).key = %VK_5: ac(50).cmd = key_offset + 53
                    ac(51).fvirt = %FVIRTKEY: ac(51).key = %VK_6: ac(51).cmd = key_offset + 54
                    ac(52).fvirt = %FVIRTKEY: ac(52).key = %VK_7: ac(52).cmd = key_offset + 55
                    ac(53).fvirt = %FVIRTKEY: ac(53).key = %VK_8: ac(53).cmd = key_offset + 56
                    ac(54).fvirt = %FVIRTKEY: ac(54).key = %VK_9: ac(54).cmd = key_offset + 57
                
                    ac(55).fvirt = %FVIRTKEY: ac(55).key = %VK_NUMPAD0: ac(55).cmd = key_offset + 48
                    ac(56).fvirt = %FVIRTKEY: ac(56).key = %VK_NUMPAD1: ac(56).cmd = key_offset + 49
                    ac(57).fvirt = %FVIRTKEY: ac(57).key = %VK_NUMPAD2: ac(57).cmd = key_offset + 50
                    ac(58).fvirt = %FVIRTKEY: ac(58).key = %VK_NUMPAD3: ac(58).cmd = key_offset + 51
                    ac(59).fvirt = %FVIRTKEY: ac(59).key = %VK_NUMPAD4: ac(59).cmd = key_offset + 52
                    ac(60).fvirt = %FVIRTKEY: ac(60).key = %VK_NUMPAD5: ac(60).cmd = key_offset + 53
                    ac(61).fvirt = %FVIRTKEY: ac(61).key = %VK_NUMPAD6: ac(61).cmd = key_offset + 54
                    ac(62).fvirt = %FVIRTKEY: ac(62).key = %VK_NUMPAD7: ac(62).cmd = key_offset + 55
                    ac(63).fvirt = %FVIRTKEY: ac(63).key = %VK_NUMPAD8: ac(63).cmd = key_offset + 56
                    ac(64).fvirt = %FVIRTKEY: ac(64).key = %VK_NUMPAD9: ac(64).cmd = key_offset + 57
                
                    ac(65).fvirt = %FVIRTKEY: ac(65).key = %VK_F1: ac(65).cmd = key_offset + 1059
                    ac(66).fvirt = %FVIRTKEY: ac(66).key = %VK_F2: ac(66).cmd = key_offset + 1060
                    ac(67).fvirt = %FVIRTKEY: ac(67).key = %VK_F3: ac(67).cmd = key_offset + 1061
                    ac(68).fvirt = %FVIRTKEY: ac(68).key = %VK_F4: ac(68).cmd = key_offset + 1062
                    ac(69).fvirt = %FVIRTKEY: ac(69).key = %VK_F5: ac(69).cmd = key_offset + 1063
                    ac(70).fvirt = %FVIRTKEY: ac(70).key = %VK_F6: ac(70).cmd = key_offset + 1064
                    ac(71).fvirt = %FVIRTKEY: ac(71).key = %VK_F7: ac(71).cmd = key_offset + 1065
                    ac(72).fvirt = %FVIRTKEY: ac(72).key = %VK_F8: ac(72).cmd = key_offset + 1066
                    ac(73).fvirt = %FVIRTKEY: ac(73).key = %VK_F9: ac(73).cmd = key_offset + 1067
                    ac(74).fvirt = %FVIRTKEY: ac(74).key = %VK_F10: ac(74).cmd = key_offset + 1068
                    ac(75).fvirt = %FVIRTKEY: ac(75).key = %VK_F11: ac(75).cmd = key_offset + 1133
                    ac(76).fvirt = %FVIRTKEY: ac(76).key = %VK_F12: ac(76).cmd = key_offset + 1134
                
                    REM SHIFT Keys
                    ac(76 + 1).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 1).key = %VK_ADD:       ac(76 + 1).cmd = key_offset + 43
                    ac(76 + 2).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 2).key = %VK_BACK:      ac(76 + 2).cmd = key_offset + 8
                    ac(76 + 3).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 3).key = %VK_TAB:       ac(76 + 3).cmd = key_offset + 1015
                    ac(76 + 4).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 4).key = %VK_SUBTRACT:  ac(76 + 4).cmd = key_offset + 95
                    ac(76 + 5).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 5).key = %VK_RETURN:    ac(76 + 5).cmd = key_offset + 13
                    ac(76 + 6).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 6).key = %VK_ESCAPE:    ac(76 + 6).cmd = key_offset + 27
                    ac(76 + 7).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 7).key = %VK_SPACE:     ac(76 + 7).cmd = key_offset + 32
                    ac(76 + 8).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 8).key = %VK_PGUP:      ac(76 + 8).cmd = key_offset + 57
                    ac(76 + 9).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 9).key = %VK_PGDN:      ac(76 + 9).cmd = key_offset + 51
                    ac(76 + 10).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 10).key = %VK_END:    ac(76 + 10).cmd = key_offset + 49
                    ac(76 + 11).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 11).key = %VK_HOME:   ac(76 + 11).cmd = key_offset + 55
                    ac(76 + 12).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 12).key = %VK_LEFT:   ac(76 + 12).cmd = key_offset + 52
                    ac(76 + 13).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 13).key = %VK_UP:     ac(76 + 13).cmd = key_offset + 56
                    ac(76 + 14).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 14).key = %VK_RIGHT:  ac(76 + 14).cmd = key_offset + 54
                    ac(76 + 15).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 15).key = %VK_DOWN:   ac(76 + 15).cmd = key_offset + 50
                    ac(76 + 16).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 16).key = %VK_INSERT: ac(76 + 15).cmd = key_offset + 82
                    ac(76 + 17).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 17).key = %VK_DELETE: ac(76 + 16).cmd = key_offset + 83
                    ac(76 + 18).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 18).key = %VK_HELP:   ac(76 + 17).cmd = key_offset + 59
                
                    ac(76 + 19).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 19).key = %VK_A: ac(76 + 19).cmd = key_offset + 65
                    ac(76 + 20).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 20).key = %VK_B: ac(76 + 20).cmd = key_offset + 66
                    ac(76 + 21).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 21).key = %VK_C: ac(76 + 21).cmd = key_offset + 67
                    ac(76 + 22).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 22).key = %VK_D: ac(76 + 22).cmd = key_offset + 68
                    ac(76 + 23).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 23).key = %VK_E: ac(76 + 23).cmd = key_offset + 69
                    ac(76 + 24).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 24).key = %VK_F: ac(76 + 24).cmd = key_offset + 70
                    ac(76 + 25).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 25).key = %VK_G: ac(76 + 25).cmd = key_offset + 71
                    ac(76 + 26).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 26).key = %VK_H: ac(76 + 26).cmd = key_offset + 72
                    ac(76 + 27).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 27).key = %VK_I: ac(76 + 27).cmd = key_offset + 73
                    ac(76 + 28).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 28).key = %VK_J: ac(76 + 28).cmd = key_offset + 74
                    ac(76 + 29).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 29).key = %VK_K: ac(76 + 29).cmd = key_offset + 75
                    ac(76 + 30).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 30).key = %VK_L: ac(76 + 30).cmd = key_offset + 76
                    ac(76 + 31).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 31).key = %VK_M: ac(76 + 31).cmd = key_offset + 77
                    ac(76 + 32).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 32).key = %VK_N: ac(76 + 32).cmd = key_offset + 78
                    ac(76 + 33).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 33).key = %VK_O: ac(76 + 33).cmd = key_offset + 79
                    ac(76 + 34).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 34).key = %VK_P: ac(76 + 34).cmd = key_offset + 80
                    ac(76 + 35).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 35).key = %VK_Q: ac(76 + 35).cmd = key_offset + 81
                    ac(76 + 36).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 36).key = %VK_R: ac(76 + 36).cmd = key_offset + 82
                    ac(76 + 37).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 37).key = %VK_S: ac(76 + 37).cmd = key_offset + 83
                    ac(76 + 38).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 38).key = %VK_T: ac(76 + 38).cmd = key_offset + 84
                    ac(76 + 39).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 39).key = %VK_U: ac(76 + 39).cmd = key_offset + 85
                    ac(76 + 40).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 40).key = %VK_V: ac(76 + 40).cmd = key_offset + 86
                    ac(76 + 41).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 41).key = %VK_W: ac(76 + 41).cmd = key_offset + 87
                    ac(76 + 42).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 42).key = %VK_X: ac(76 + 42).cmd = key_offset + 88
                    ac(76 + 43).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 43).key = %VK_Y: ac(76 + 43).cmd = key_offset + 89
                    ac(76 + 44).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 44).key = %VK_Z: ac(76 + 44).cmd = key_offset + 90
                
                    ac(76 + 45).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 45).key = %VK_0: ac(76 + 45).cmd = key_offset + 41
                    ac(76 + 46).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 46).key = %VK_1: ac(76 + 46).cmd = key_offset + 33
                    ac(76 + 47).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 47).key = %VK_2: ac(76 + 47).cmd = key_offset + 64
                    ac(76 + 48).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 48).key = %VK_3: ac(76 + 48).cmd = key_offset + 35
                    ac(76 + 49).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 49).key = %VK_4: ac(76 + 49).cmd = key_offset + 36
                    ac(76 + 50).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 50).key = %VK_5: ac(76 + 50).cmd = key_offset + 37
                    ac(76 + 51).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 51).key = %VK_6: ac(76 + 51).cmd = key_offset + 94
                    ac(76 + 52).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 52).key = %VK_7: ac(76 + 52).cmd = key_offset + 38
                    ac(76 + 53).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 53).key = %VK_8: ac(76 + 53).cmd = key_offset + 42
                    ac(76 + 54).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 54).key = %VK_9: ac(76 + 54).cmd = key_offset + 40
                
                    ac(76 + 55).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 55).key = %VK_NUMPAD0: ac(76 + 55).cmd = key_offset + 48
                    ac(76 + 56).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 56).key = %VK_NUMPAD1: ac(76 + 56).cmd = key_offset + 49
                    ac(76 + 57).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 57).key = %VK_NUMPAD2: ac(76 + 57).cmd = key_offset + 50
                    ac(76 + 58).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 58).key = %VK_NUMPAD3: ac(76 + 58).cmd = key_offset + 51
                    ac(76 + 59).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 59).key = %VK_NUMPAD4: ac(76 + 59).cmd = key_offset + 52
                    ac(76 + 60).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 60).key = %VK_NUMPAD5: ac(76 + 60).cmd = key_offset + 53
                    ac(76 + 61).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 61).key = %VK_NUMPAD6: ac(76 + 61).cmd = key_offset + 54
                    ac(76 + 62).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 62).key = %VK_NUMPAD7: ac(76 + 62).cmd = key_offset + 55
                    ac(76 + 63).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 63).key = %VK_NUMPAD8: ac(76 + 63).cmd = key_offset + 56
                    ac(76 + 64).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 64).key = %VK_NUMPAD9: ac(76 + 64).cmd = key_offset + 57
                
                    ac(76 + 65).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 65).key = %VK_F1: ac(76 + 65).cmd = key_offset + 1084
                    ac(76 + 66).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 66).key = %VK_F2: ac(76 + 66).cmd = key_offset + 1085
                    ac(76 + 67).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 67).key = %VK_F3: ac(76 + 67).cmd = key_offset + 1086
                    ac(76 + 68).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 68).key = %VK_F4: ac(76 + 68).cmd = key_offset + 1087
                    ac(76 + 69).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 69).key = %VK_F5: ac(76 + 69).cmd = key_offset + 1088
                    ac(76 + 70).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 70).key = %VK_F6: ac(76 + 70).cmd = key_offset + 1089
                    ac(76 + 71).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 71).key = %VK_F7: ac(76 + 71).cmd = key_offset + 1090
                    ac(76 + 72).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 72).key = %VK_F8: ac(76 + 72).cmd = key_offset + 1091
                    ac(76 + 73).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 73).key = %VK_F9: ac(76 + 73).cmd = key_offset + 1092
                    ac(76 + 74).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 74).key = %VK_F10: ac(76 + 74).cmd = key_offset + 1093
                    ac(76 + 75).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 75).key = %VK_F11: ac(76 + 75).cmd = key_offset + 1135
                    ac(76 + 76).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 76).key = %VK_F12: ac(76 + 76).cmd = key_offset + 1136
                
                    REM CONTROL Keys
                    ac(152 + 1).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 1).key = %VK_ADD:       ac(152 + 1).cmd = key_offset + 0
                    ac(152 + 2).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 2).key = %VK_BACK:      ac(152 + 2).cmd = key_offset + 127
                    ac(152 + 3).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 3).key = %VK_TAB:       ac(152 + 3).cmd = key_offset + 0
                    ac(152 + 4).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 4).key = %VK_SUBTRACT:  ac(152 + 4).cmd = key_offset + 31
                    ac(152 + 5).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 5).key = %VK_RETURN:    ac(152 + 5).cmd = key_offset + 10
                    ac(152 + 6).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 6).key = %VK_ESCAPE:    ac(152 + 6).cmd = key_offset + 27
                    ac(152 + 7).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 7).key = %VK_SPACE:     ac(152 + 7).cmd = key_offset + 32
                    ac(152 + 8).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 8).key = %VK_PGUP:      ac(152 + 8).cmd = key_offset + 1132
                    ac(152 + 9).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 9).key = %VK_PGDN:      ac(152 + 9).cmd = key_offset + 1118
                    ac(152 + 10).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 10).key = %VK_END:    ac(152 + 10).cmd = key_offset + 1117
                    ac(152 + 11).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 11).key = %VK_HOME:   ac(152 + 11).cmd = key_offset + 1119
                    ac(152 + 12).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 12).key = %VK_LEFT:   ac(152 + 12).cmd = key_offset + 1115
                    ac(152 + 13).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 13).key = %VK_UP:     ac(152 + 13).cmd = key_offset + 1141
                    ac(152 + 14).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 14).key = %VK_RIGHT:  ac(152 + 14).cmd = key_offset + 1116
                    ac(152 + 15).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 15).key = %VK_DOWN:   ac(152 + 15).cmd = key_offset + 1145
                    ac(152 + 16).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 16).key = %VK_INSERT: ac(152 + 15).cmd = key_offset + 1146
                    ac(152 + 17).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 17).key = %VK_DELETE: ac(152 + 16).cmd = key_offset + 1147
                    ac(152 + 18).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 18).key = %VK_HELP:   ac(152 + 17).cmd = key_offset + 1094
                    
                    ac(152 + 19).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 19).key = %VK_A: ac(152 + 19).cmd = key_offset + 1
                    ac(152 + 20).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 20).key = %VK_B: ac(152 + 20).cmd = key_offset + 2
                    ac(152 + 21).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 21).key = %VK_C: ac(152 + 21).cmd = key_offset + 3
                    ac(152 + 22).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 22).key = %VK_D: ac(152 + 22).cmd = key_offset + 4
                    ac(152 + 23).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 23).key = %VK_E: ac(152 + 23).cmd = key_offset + 5
                    ac(152 + 24).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 24).key = %VK_F: ac(152 + 24).cmd = key_offset + 6
                    ac(152 + 25).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 25).key = %VK_G: ac(152 + 25).cmd = key_offset + 7
                    ac(152 + 26).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 26).key = %VK_H: ac(152 + 26).cmd = key_offset + 8
                    ac(152 + 27).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 27).key = %VK_I: ac(152 + 27).cmd = key_offset + 9
                    ac(152 + 28).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 28).key = %VK_J: ac(152 + 28).cmd = key_offset + 10
                    ac(152 + 29).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 29).key = %VK_K: ac(152 + 29).cmd = key_offset + 11
                    ac(152 + 30).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 30).key = %VK_L: ac(152 + 30).cmd = key_offset + 12
                    ac(152 + 31).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 31).key = %VK_M: ac(152 + 31).cmd = key_offset + 13
                    ac(152 + 32).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 32).key = %VK_N: ac(152 + 32).cmd = key_offset + 14
                    ac(152 + 33).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 33).key = %VK_O: ac(152 + 33).cmd = key_offset + 15
                    ac(152 + 34).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 34).key = %VK_P: ac(152 + 34).cmd = key_offset + 16
                    ac(152 + 35).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 35).key = %VK_Q: ac(152 + 35).cmd = key_offset + 17
                    ac(152 + 36).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 36).key = %VK_R: ac(152 + 36).cmd = key_offset + 18
                    ac(152 + 37).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 37).key = %VK_S: ac(152 + 37).cmd = key_offset + 19
                    ac(152 + 38).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 38).key = %VK_T: ac(152 + 38).cmd = key_offset + 20
                    ac(152 + 39).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 39).key = %VK_U: ac(152 + 39).cmd = key_offset + 21
                    ac(152 + 40).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 40).key = %VK_V: ac(152 + 40).cmd = key_offset + 22
                    ac(152 + 41).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 41).key = %VK_W: ac(152 + 41).cmd = key_offset + 23
                    ac(152 + 42).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 42).key = %VK_X: ac(152 + 42).cmd = key_offset + 24
                    ac(152 + 43).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 43).key = %VK_Y: ac(152 + 43).cmd = key_offset + 25
                    ac(152 + 44).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 44).key = %VK_Z: ac(152 + 44).cmd = key_offset + 26
                
                    ac(152 + 45).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 45).key = %VK_0: ac(152 + 45).cmd = key_offset + 0
                    ac(152 + 46).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 46).key = %VK_1: ac(152 + 46).cmd = key_offset + 0
                    ac(152 + 47).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 47).key = %VK_2: ac(152 + 47).cmd = key_offset + 1003
                    ac(152 + 48).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 48).key = %VK_3: ac(152 + 48).cmd = key_offset + 0
                    ac(152 + 49).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 49).key = %VK_4: ac(152 + 49).cmd = key_offset + 0
                    ac(152 + 50).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 50).key = %VK_5: ac(152 + 50).cmd = key_offset + 0
                    ac(152 + 51).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 51).key = %VK_6: ac(152 + 51).cmd = key_offset + 30
                    ac(152 + 52).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 52).key = %VK_7: ac(152 + 52).cmd = key_offset + 0
                    ac(152 + 53).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 53).key = %VK_8: ac(152 + 53).cmd = key_offset + 0
                    ac(152 + 54).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 54).key = %VK_9: ac(152 + 54).cmd = key_offset + 0
                
                    ac(152 + 55).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 55).key = %VK_NUMPAD0: ac(152 + 55).cmd = key_offset + 48
                    ac(152 + 56).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 56).key = %VK_NUMPAD1: ac(152 + 56).cmd = key_offset + 49
                    ac(152 + 57).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 57).key = %VK_NUMPAD2: ac(152 + 57).cmd = key_offset + 50
                    ac(152 + 58).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 58).key = %VK_NUMPAD3: ac(152 + 58).cmd = key_offset + 51
                    ac(152 + 59).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 59).key = %VK_NUMPAD4: ac(152 + 59).cmd = key_offset + 52
                    ac(152 + 60).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 60).key = %VK_NUMPAD5: ac(152 + 60).cmd = key_offset + 53
                    ac(152 + 61).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 61).key = %VK_NUMPAD6: ac(152 + 61).cmd = key_offset + 54
                    ac(152 + 62).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 62).key = %VK_NUMPAD7: ac(152 + 62).cmd = key_offset + 55
                    ac(152 + 63).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 63).key = %VK_NUMPAD8: ac(152 + 63).cmd = key_offset + 56
                    ac(152 + 64).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 64).key = %VK_NUMPAD9: ac(152 + 64).cmd = key_offset + 57
                
                    ac(152 + 65).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 65).key = %VK_F1: ac(152 + 65).cmd = key_offset + 1094
                    ac(152 + 66).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 66).key = %VK_F2: ac(152 + 66).cmd = key_offset + 1095
                    ac(152 + 67).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 67).key = %VK_F3: ac(152 + 67).cmd = key_offset + 1096
                    ac(152 + 68).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 68).key = %VK_F4: ac(152 + 68).cmd = key_offset + 1097
                    ac(152 + 69).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 69).key = %VK_F5: ac(152 + 69).cmd = key_offset + 1098
                    ac(152 + 70).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 70).key = %VK_F6: ac(152 + 70).cmd = key_offset + 1099
                    ac(152 + 71).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 71).key = %VK_F7: ac(152 + 71).cmd = key_offset + 1100
                    ac(152 + 72).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 72).key = %VK_F8: ac(152 + 72).cmd = key_offset + 1101
                    ac(152 + 73).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 73).key = %VK_F9: ac(152 + 73).cmd = key_offset + 1102
                    ac(152 + 74).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 74).key = %VK_F10: ac(152 + 74).cmd = key_offset + 1103
                    ac(152 + 75).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 75).key = %VK_F11: ac(152 + 75).cmd = key_offset + 1137
                    ac(152 + 76).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 76).key = %VK_F12: ac(152 + 76).cmd = key_offset + 1138
                
                    REM ALT Keys
                    ac(228 + 1).fvirt = %FVIRTKEY OR %FALT: ac(228 + 1).key = %VK_ADD:      ac(228 + 1).cmd = key_offset + 1131
                    ac(228 + 2).fvirt = %FVIRTKEY OR %FALT: ac(228 + 2).key = %VK_BACK:     ac(228 + 2).cmd = key_offset + 0
                    ac(228 + 3).fvirt = %FVIRTKEY OR %FALT: ac(228 + 3).key = %VK_TAB:      ac(228 + 3).cmd = key_offset + 0
                    ac(228 + 4).fvirt = %FVIRTKEY OR %FALT: ac(228 + 4).key = %VK_SUBTRACT: ac(228 + 4).cmd = key_offset + 1130
                    ac(228 + 5).fvirt = %FVIRTKEY OR %FALT: ac(228 + 5).key = %VK_RETURN:   ac(228 + 5).cmd = key_offset + 0
                    ac(228 + 6).fvirt = %FVIRTKEY OR %FALT: ac(228 + 6).key = %VK_ESCAPE:   ac(228 + 6).cmd = key_offset + 0
                    ac(228 + 7).fvirt = %FVIRTKEY OR %FALT: ac(228 + 7).key = %VK_SPACE:    ac(228 + 7).cmd = key_offset + 1032
                    ac(228 + 8).fvirt = %FVIRTKEY OR %FALT: ac(228 + 8).key = %VK_PGUP:     ac(228 + 8).cmd = key_offset + 1153
                    ac(228 + 9).fvirt = %FVIRTKEY OR %FALT: ac(228 + 9).key = %VK_PGDN:     ac(228 + 9).cmd = key_offset + 1161
                    ac(228 + 10).fvirt = %FVIRTKEY OR %FALT: ac(228 + 10).key = %VK_END:    ac(228 + 10).cmd = key_offset + 1159
                    ac(228 + 11).fvirt = %FVIRTKEY OR %FALT: ac(228 + 11).key = %VK_HOME:   ac(228 + 11).cmd = key_offset + 1151
                    ac(228 + 12).fvirt = %FVIRTKEY OR %FALT: ac(228 + 12).key = %VK_LEFT:   ac(228 + 12).cmd = key_offset + 1155
                    ac(228 + 13).fvirt = %FVIRTKEY OR %FALT: ac(228 + 13).key = %VK_UP:     ac(228 + 13).cmd = key_offset + 1152
                    ac(228 + 14).fvirt = %FVIRTKEY OR %FALT: ac(228 + 14).key = %VK_RIGHT:  ac(228 + 14).cmd = key_offset + 1157
                    ac(228 + 15).fvirt = %FVIRTKEY OR %FALT: ac(228 + 15).key = %VK_DOWN:   ac(228 + 15).cmd = key_offset + 1160
                    ac(228 + 16).fvirt = %FVIRTKEY OR %FALT: ac(228 + 16).key = %VK_INSERT: ac(228 + 15).cmd = key_offset + 1162
                    ac(228 + 17).fvirt = %FVIRTKEY OR %FALT: ac(228 + 17).key = %VK_DELETE: ac(228 + 16).cmd = key_offset + 1163
                    ac(228 + 18).fvirt = %FVIRTKEY OR %FALT: ac(228 + 18).key = %VK_HELP:   ac(228 + 17).cmd = key_offset + 59
                
                    ac(228 + 19).fvirt = %FVIRTKEY OR %FALT: ac(228 + 19).key = %VK_A: ac(228 + 19).cmd = key_offset + 1030
                    ac(228 + 20).fvirt = %FVIRTKEY OR %FALT: ac(228 + 20).key = %VK_B: ac(228 + 20).cmd = key_offset + 1048
                    ac(228 + 21).fvirt = %FVIRTKEY OR %FALT: ac(228 + 21).key = %VK_C: ac(228 + 21).cmd = key_offset + 1046
                    ac(228 + 22).fvirt = %FVIRTKEY OR %FALT: ac(228 + 22).key = %VK_D: ac(228 + 22).cmd = key_offset + 1032
                    ac(228 + 23).fvirt = %FVIRTKEY OR %FALT: ac(228 + 23).key = %VK_E: ac(228 + 23).cmd = key_offset + 1018
                    ac(228 + 24).fvirt = %FVIRTKEY OR %FALT: ac(228 + 24).key = %VK_F: ac(228 + 24).cmd = key_offset + 1033
                    ac(228 + 25).fvirt = %FVIRTKEY OR %FALT: ac(228 + 25).key = %VK_G: ac(228 + 25).cmd = key_offset + 1034
                    ac(228 + 26).fvirt = %FVIRTKEY OR %FALT: ac(228 + 26).key = %VK_H: ac(228 + 26).cmd = key_offset + 1035
                    ac(228 + 27).fvirt = %FVIRTKEY OR %FALT: ac(228 + 27).key = %VK_I: ac(228 + 27).cmd = key_offset + 1023
                    ac(228 + 28).fvirt = %FVIRTKEY OR %FALT: ac(228 + 28).key = %VK_J: ac(228 + 28).cmd = key_offset + 1036
                    ac(228 + 29).fvirt = %FVIRTKEY OR %FALT: ac(228 + 29).key = %VK_K: ac(228 + 29).cmd = key_offset + 1037
                    ac(228 + 30).fvirt = %FVIRTKEY OR %FALT: ac(228 + 30).key = %VK_L: ac(228 + 30).cmd = key_offset + 1038
                    ac(228 + 31).fvirt = %FVIRTKEY OR %FALT: ac(228 + 31).key = %VK_M: ac(228 + 31).cmd = key_offset + 1050
                    ac(228 + 32).fvirt = %FVIRTKEY OR %FALT: ac(228 + 32).key = %VK_N: ac(228 + 32).cmd = key_offset + 1049
                    ac(228 + 33).fvirt = %FVIRTKEY OR %FALT: ac(228 + 33).key = %VK_O: ac(228 + 33).cmd = key_offset + 1024
                    ac(228 + 34).fvirt = %FVIRTKEY OR %FALT: ac(228 + 34).key = %VK_P: ac(228 + 34).cmd = key_offset + 1025
                    ac(228 + 35).fvirt = %FVIRTKEY OR %FALT: ac(228 + 35).key = %VK_Q: ac(228 + 35).cmd = key_offset + 1016
                    ac(228 + 36).fvirt = %FVIRTKEY OR %FALT: ac(228 + 36).key = %VK_R: ac(228 + 36).cmd = key_offset + 1019
                    ac(228 + 37).fvirt = %FVIRTKEY OR %FALT: ac(228 + 37).key = %VK_S: ac(228 + 37).cmd = key_offset + 1031
                    ac(228 + 38).fvirt = %FVIRTKEY OR %FALT: ac(228 + 38).key = %VK_T: ac(228 + 38).cmd = key_offset + 1020
                    ac(228 + 39).fvirt = %FVIRTKEY OR %FALT: ac(228 + 39).key = %VK_U: ac(228 + 39).cmd = key_offset + 1022
                    ac(228 + 40).fvirt = %FVIRTKEY OR %FALT: ac(228 + 40).key = %VK_V: ac(228 + 40).cmd = key_offset + 1047
                    ac(228 + 41).fvirt = %FVIRTKEY OR %FALT: ac(228 + 41).key = %VK_W: ac(228 + 41).cmd = key_offset + 1017
                    ac(228 + 42).fvirt = %FVIRTKEY OR %FALT: ac(228 + 42).key = %VK_X: ac(228 + 42).cmd = key_offset + 1045
                    ac(228 + 43).fvirt = %FVIRTKEY OR %FALT: ac(228 + 43).key = %VK_Y: ac(228 + 43).cmd = key_offset + 1021
                    ac(228 + 44).fvirt = %FVIRTKEY OR %FALT: ac(228 + 44).key = %VK_Z: ac(228 + 44).cmd = key_offset + 1044
                
                    ac(228 + 45).fvirt = %FVIRTKEY OR %FALT: ac(228 + 45).key = %VK_0: ac(228 + 45).cmd = key_offset + 1129
                    ac(228 + 46).fvirt = %FVIRTKEY OR %FALT: ac(228 + 46).key = %VK_1: ac(228 + 46).cmd = key_offset + 1120
                    ac(228 + 47).fvirt = %FVIRTKEY OR %FALT: ac(228 + 47).key = %VK_2: ac(228 + 47).cmd = key_offset + 1121
                    ac(228 + 48).fvirt = %FVIRTKEY OR %FALT: ac(228 + 48).key = %VK_3: ac(228 + 48).cmd = key_offset + 1122
                    ac(228 + 49).fvirt = %FVIRTKEY OR %FALT: ac(228 + 49).key = %VK_4: ac(228 + 49).cmd = key_offset + 1123
                    ac(228 + 50).fvirt = %FVIRTKEY OR %FALT: ac(228 + 50).key = %VK_5: ac(228 + 50).cmd = key_offset + 1124
                    ac(228 + 51).fvirt = %FVIRTKEY OR %FALT: ac(228 + 51).key = %VK_6: ac(228 + 51).cmd = key_offset + 1125
                    ac(228 + 52).fvirt = %FVIRTKEY OR %FALT: ac(228 + 52).key = %VK_7: ac(228 + 52).cmd = key_offset + 1126
                    ac(228 + 53).fvirt = %FVIRTKEY OR %FALT: ac(228 + 53).key = %VK_8: ac(228 + 53).cmd = key_offset + 1127
                    ac(228 + 54).fvirt = %FVIRTKEY OR %FALT: ac(228 + 54).key = %VK_9: ac(228 + 54).cmd = key_offset + 1128
                
                    ac(228 + 55).fvirt = %FVIRTKEY OR %FALT: ac(228 + 55).key = %VK_NUMPAD0: ac(228 + 55).cmd = key_offset + 48
                    ac(228 + 56).fvirt = %FVIRTKEY OR %FALT: ac(228 + 56).key = %VK_NUMPAD1: ac(228 + 56).cmd = key_offset + 49
                    ac(228 + 57).fvirt = %FVIRTKEY OR %FALT: ac(228 + 57).key = %VK_NUMPAD2: ac(228 + 57).cmd = key_offset + 50
                    ac(228 + 58).fvirt = %FVIRTKEY OR %FALT: ac(228 + 58).key = %VK_NUMPAD3: ac(228 + 58).cmd = key_offset + 51
                    ac(228 + 59).fvirt = %FVIRTKEY OR %FALT: ac(228 + 59).key = %VK_NUMPAD4: ac(228 + 59).cmd = key_offset + 52
                    ac(228 + 60).fvirt = %FVIRTKEY OR %FALT: ac(228 + 60).key = %VK_NUMPAD5: ac(228 + 60).cmd = key_offset + 53
                    ac(228 + 61).fvirt = %FVIRTKEY OR %FALT: ac(228 + 61).key = %VK_NUMPAD6: ac(228 + 61).cmd = key_offset + 54
                    ac(228 + 62).fvirt = %FVIRTKEY OR %FALT: ac(228 + 62).key = %VK_NUMPAD7: ac(228 + 62).cmd = key_offset + 55
                    ac(228 + 63).fvirt = %FVIRTKEY OR %FALT: ac(228 + 63).key = %VK_NUMPAD8: ac(228 + 63).cmd = key_offset + 56
                    ac(228 + 64).fvirt = %FVIRTKEY OR %FALT: ac(228 + 64).key = %VK_NUMPAD9: ac(228 + 64).cmd = key_offset + 57
                
                    ac(228 + 65).fvirt = %FVIRTKEY OR %FALT: ac(228 + 65).key = %VK_F1: ac(228 + 65).cmd = key_offset + 1104
                    ac(228 + 66).fvirt = %FVIRTKEY OR %FALT: ac(228 + 66).key = %VK_F2: ac(228 + 66).cmd = key_offset + 1105
                    ac(228 + 67).fvirt = %FVIRTKEY OR %FALT: ac(228 + 67).key = %VK_F3: ac(228 + 67).cmd = key_offset + 1106
                    ac(228 + 68).fvirt = %FVIRTKEY OR %FALT: ac(228 + 68).key = %VK_F4: ac(228 + 68).cmd = key_offset + 1107
                    ac(228 + 69).fvirt = %FVIRTKEY OR %FALT: ac(228 + 69).key = %VK_F5: ac(228 + 69).cmd = key_offset + 1108
                    ac(228 + 70).fvirt = %FVIRTKEY OR %FALT: ac(228 + 70).key = %VK_F6: ac(228 + 70).cmd = key_offset + 1109
                    ac(228 + 71).fvirt = %FVIRTKEY OR %FALT: ac(228 + 71).key = %VK_F7: ac(228 + 71).cmd = key_offset + 1110
                    ac(228 + 72).fvirt = %FVIRTKEY OR %FALT: ac(228 + 72).key = %VK_F8: ac(228 + 72).cmd = key_offset + 1111
                    ac(228 + 73).fvirt = %FVIRTKEY OR %FALT: ac(228 + 73).key = %VK_F9: ac(228 + 73).cmd = key_offset + 1112
                    ac(228 + 74).fvirt = %FVIRTKEY OR %FALT: ac(228 + 74).key = %VK_F10: ac(228 + 74).cmd = key_offset + 1113
                    ac(228 + 75).fvirt = %FVIRTKEY OR %FALT: ac(228 + 75).key = %VK_F11: ac(228 + 75).cmd = key_offset + 1139
                    ac(228 + 76).fvirt = %FVIRTKEY OR %FALT: ac(228 + 76).key = %VK_F12: ac(228 + 76).cmd = key_offset + 1140

                Comment


                • #28
                  Code:
                  WHILE GetMessage(Msg, %NULL, 0, 0)
                      LOCAL k AS LONG
                      SELECT CASE Msg.message
                        k = Msg.wParam
                        CASE %WM_SYSKEYDOWN
                          SELECT CASE k 'Msg.wParam
                            CASE %VK_LEFT
                            CASE %VK_RIGHT
                            CASE %VK_DOWN
                            CASE %VK_UP
                            CASE ELSE
                  ....
                  That will work, but as a matter of style I don't like playing with the message loop like this.

                  I prefer to use keyboard accelerators (post #27 from Mr. Simmonds), but only define "keys of interest" and then process the resulting WM_COMMAND notification messages in my window/dialog procedure.

                  Frankly I can't see what keys of interest you might have beyond F2 thru F12 (F1 already generates a WM_HELP notification message, but you can preempt that).

                  There is no reason in a gui program for the programmer to care about left/right/up/down arrows or delete or home keys, et al... the use of the proper controls will allow the system to process these keys "the Windows way".. meaning of course, the way your users expect those keys to behave in the Windows' environment.

                  MCM
                  Michael Mattias
                  Tal Systems (retired)
                  Port Washington WI USA
                  [email protected]
                  http://www.talsystems.com

                  Comment


                  • #29
                    Mike, thx for the "ENTER key to TAB"... much needed!!
                    3.14159265358979323846264338327950
                    "Ok, yes... I like pie... um, I meant, pi."

                    Comment


                    • #30
                      Michael

                      Well the program (which I am converting from PBCC) edits large blocks of nucleotide sequence data, often several thousand bases ling, windowed using the scrollbar. This can only be feasibly represented in a graphics screen onto which is placed a cursor that is required for editing, moving sequences etc. There are menus etc. but most of the activity associated with the program is editing the sequences themselves.

                      As for the possibility of using a text editor box (with built in keyboard support), the actual editing and display of sequences goes far beyond its capabilities. I therefore have to create the editing environment from the ground up, and that includes getting keyboard input. Left, right, up and down arrows for moving the cursor, ALT and CONTROL arrows for larger jumps, HOME, END, SHIFT arrows to drag sequences around, keyboard entry of bases (A, C, G, T) and amino acids, etc. etc.

                      Certainly the accelerator method you suggested works fine. Very easy to put something like this in the callback loop:

                      Code:
                      CASE %WM_COMMAND
                          ' Process control notifications
                      
                          SELECT CASE AS LONG CBCTL
                      
                              CASE Key_offset + 1 to Key_offset + 150
                      
                                  keycode = CBCTL - Key_offset
                                  CALL old_program(keycode): REM The keyboard processing loop for ASCII codes in the old program
                      There seems to be no slow down in the reaction time of the callback loop despite the huge table, so will probably stick with this method for the time being (until I come across the next problem!).
                      Last edited by Peter Simmonds; 15 Oct 2010, 09:57 AM.

                      Comment

                      Working...
                      X